Node&Redis:Redis客户端

假设您在Redis中有多个数据库,您希望插入和/或删除数据。 你有一个像

  • 将数据插入到DB#1
  • 在第一次插入的callback后,做一些东西,并将数据插入到数据库#2
  • 第二次插入callback后,再次做一些事情,最后插入数据到数据库#3

我使用一个名为redisClient的variables,它基本上被创build为;

redisClient = redis.createClient(); 

而select一个新的数据库,我使用select命令与额外的预警callback,所以我的select命令就像;

 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) } }); 

然而事情总是混合在一起。 我想指出的是,redisClientvariables已经被分配了一次,后来在整个应用程序中使用。 现在我想知道, Redis中的每个数据库使用单独的redisClient是多合理的。 所以会是这样的;

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

我想知道这样做是否合理,或者对于每秒能接收4K请求并即将进入生产模式的应用程序来说,这是一个正确的方法。 这个模型可能面临什么问题

就像Carl Zulauf所说 ,最好打开3个不同的连接(每个DB一个):

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

在服务器的初始化过程中最好打开一次所有连接:

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

所以,在创buildredisClient对象并初始化之后,可以使用它来处理所有的redis操作。

如果你使用redis这种方法,节点将为每个节点进程打开3个(并且只有3个)连接。


注意把它全部放入一个节点模块也是一个好主意:

 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); } }; 

那么你可以通过调用一次init函数来初始化所有的redis连接(因为节点cachingrequire调用):

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

然后当require('./lib/my_redis').DB1.set('key','val')将在你的模块中被调用时, DB1将被初始化。

对3个不同的数据库使用3个连接是正确的方法。 有额外的连接打开,但开销很小。

像数百个开放连接一样,开销会开始成为一个问题。 我不确定您的应用程序有多less个实例可以运行,但是在每个进程只有3个连接的情况下猜测,您将无法获得有问题的数字。

如果Google把你带到这里,请帮忙:不要使用多个数据库支持。 使用名称空间密钥或多个redis实例。

我在自己的asynchronous环境中挣扎了多个数据库支持之后就这么说了。 有趣的是,我访问了Freenode的#redis,并得到Redis的作者Salvatore Sanfilippo的以下陈述:

我认为Redis的多个数据库错误是我在Redisdevise中最糟糕的决定……我希望在某些时候我们可以放弃多个数据库的支持,但是我认为这可能太晚了,因为有一些人依靠这个function对于他们的工作。

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

依靠作者遗憾的function,你真的想三思。

而不是有3个不同的连接3个不同的数据库,你可以使用MULTI/EXEC块为此:

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

对每个数据库使用一个实例是正确的方法。 但是如果您需要重用或节制昂贵的资源(如数据库连接),那么数据库连接池可能是一个不错的select。 假设我们selectgenerics池 (node.js的generics池解决scheme),您可以这样编码:

 // 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); }); });