2012-12-20 31 views
15

Si supponga di avere multipli db in Redis da inserire e/o rimuovere dati da. Hai un flusso simile;Node e Redis: Clienti Redis

  • dati Inserisci per DB # 1
  • Dopo callback del primo inserimento fare alcune cose e inserire i dati per DB # 2
  • Dopo callback del secondo inserimento fare di nuovo un po 'di roba e infine inserire i dati in DB # 3

Io uso su La variabile denominata redisClient è fondamentalmente creata come;

redisClient = redis.createClient(); 

E mentre la selezione di un nuovo DB, io uso selezionare comando con l'extra callback pre-cautela, quindi il mio comando di selezione è come;

redisClient.select(1, function(err) { 
    //Some programming logic (Insertion, deletion and stuff) 
    redisClient.select(2, function(err) { 
    //Do some additional programming logic (Insertion, deletion and stuff) 
    } 
}); 

Tuttavia le cose si mescolano costantemente. Vorrei sottolineare che la variabile redisClient è stata assegnata solo una volta e in seguito su tutta l'intera applicazione. Ora mi chiedevo, quanto sarebbe ragionevole usare redisClients separati per ogni DB che ho in Redis. Quindi sarebbe come;

redisClientForDB1 = redis.createClient(); 
redisClientForDB2 = redis.createClient(); 
redisClientForDB3 = redis.createClient(); 

mi chiedevo sarebbe ragionevole, o sarebbe un modo giusto per un'applicazione che riceverà 4K richieste al secondo e in procinto di passare alla modalità di produzione. Quali problemi questo modello potrebbe affrontare?

risposta

11

L'utilizzo di 3 connessioni per 3 diversi database rappresenta l'approccio corretto. Vi è un sovraccarico per l'apertura di connessioni aggiuntive, ma l'overhead è molto piccolo.

Con qualcosa come centinaia di connessioni aperte, il sovraccarico inizia ad essere un problema. Non sono sicuro di quante istanze della tua app eseguirai, ma indovinerò con solo 3 connessioni per processo che non ti porteranno vicino a numeri problematici.

+0

Sì! Usare client separati per ogni connessione è la strada da percorrere :) – mekwall

2

Invece di avere 3 diverse connessioni per 3 diversi DB è possibile anche utilizzare MULTI/EXEC blocco per questo:

redisClient.multi().select(1).set("my_key_in_db_1","myval").exec() 
12

Proprio come Carl Zulauf said, è meglio aprire 3 diverse connessioni (uno per DB):

redisClient = { 
    DB1: redis.createClient(), 
    DB2: redis.createClient(), 
    DB3: redis.createClient() 
}; 

E 'meglio aprire tutte le connessioni una volta durante l'inizializzazione del server:

async.parallel([ 
    DB1.select.bind(DB1, 1), 
    DB2.select.bind(DB2, 2), 
    DB3.select.bind(DB3, 3) 
], next); 

Quindi, dopo aver creato l'oggetto redisClient e inizializzato, è possibile utilizzarlo per gestire tutte le operazioni redis.

Se si utilizzano i redis in questo modo il nodo aprirà 3 (e solo 3) connessioni per processo del nodo.


N.B. E 'anche una buona idea di mettere tutto in un unico modulo nodo:

module.exports = { 
    DB1: redis.createClient(), 
    DB2: redis.createClient(), 
    DB3: redis.createClient(), 
    init: function(next) { 
    var select = redis.RedisClient.prototype.select; 
    require('async').parallel([ 
     select.bind(this.DB1, 1), 
     select.bind(this.DB2, 2), 
     select.bind(this.DB3, 3) 
    ], next); 
    } 
}; 

allora sarete in grado di inizializzare tutte le vostre Redis connessioni chiamando init funzione di una volta (perché nodo caching require chiamate):

require('./lib/my_redis').init(function(err) { 
    if (err) throw err; 
    server.listen(); 
}); 

Quindi quando require('./lib/my_redis').DB1.set('key','val') verrà chiamato in uno qualsiasi dei moduli DB1 sarà già inizializzato.

1

L'utilizzo di un'istanza per ciascun database rappresenta l'approccio corretto. Ma se è necessario riutilizzare o limitare le risorse costose come le connessioni al database, un pool di connessioni al database potrebbe essere una buona scelta. Diciamo che abbiamo scelto generic-pool (una soluzione di pooling generica per node.js), è possibile codificare in questo modo:

// Step 1 - Create pool using a factory object 
var mysql= require('mysql'), 
    generic_pool = require('generic-pool'); 

var pool = generic_pool.Pool({ 
    name: 'mysql pool 1', 
    min: 1, 
    max: 50, 
    idleTimeoutMillis : 30000, 
    create : function(callback) { 
     var Client = mysql.Client; 
     var c = new Client(); 
     c.user  = 'myusername'; 
     c.password = 'mypassword'; 
     c.database = 'mydb'; 
     c.connect(); 

     callback(null, c); 
    }, 
    destroy : function(client) { client.end(); } 
}); 

// Step 2 - Use the pool in your code to acquire/release resources 
pool.acquire(function(err, client) { 
    if (err) { 
     // handle error 
     return res.end("CONNECTION error: " + err); 
    } 
    client.query("select * from foo", [], function() { 
     // return object back to pool 
     pool.release(client); 
    }); 
}); 
+0

Sai che la domanda riguarda Redis, giusto? – Nirmal

+0

E si può fare il pooling usando il modulo 'mysql' stesso: https://github.com/felixge/node-mysql/#pooling-connections – Nirmal

5

Se Google ti ha portato qui, fatevi un favore: non utilizzare il supporto per più DB. Utilizza chiavi con nomi assegnati o più istanze di redis.

Dico questo dopo aver lottato con più supporto DB in un ambiente asincrono io stesso. Alla fine ingegno, ho visitato #redis su Freenode ed è stato denominato la seguente dichiarazione per autore Redis', Salvatore Sanfilippo:

considero Redis errori del database più il mio peggior decisionali in Redis progettazione a tutti ... io spero che a un certo punto possiamo abbandonare il supporto di più DB a tutti, ma penso che è probabilmente troppo tardi perché c'è un numero di persone che si affidano a questa funzione per il loro lavoro.

https://groups.google.com/d/msg/redis-db/vS5wX8X4Cjg/8ounBXitG4sJ

si vuole veramente pensare due volte prima di fare affidamento sulla la funzione l'autore si rammarica di più.

+0

Quali sono i problemi pratici dell'utilizzo di questa funzione? – UpTheCreek

+1

È necessario avviare l'intero servizio come richiamo al comando di selezione DB. È scomodo avere una chiamata di configurazione principale, in particolare quando più elementi di configurazione funzionano in questo modo. Per prima cosa, rende impossibile fallire velocemente sugli errori di configurazione. – sheldonh