繁体   English   中英

Node&Redis:Redis客户端

[英]Node & Redis: Redis Clients

假设您在Redis中有多个数据库,您想插入和/或删除数据。 你有一个流动;

  • 将数据插入DB#1
  • 在第一次插入后, 回调执行一些操作并将数据插入到DB#2中
  • 在第二次插入后, 回调再次执行一些操作,最后将数据插入到DB#3中

我使用一个名为redisClient的变量,基本上创建为;

redisClient = redis.createClient();

虽然选择一个新的数据库,我用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)
  }
});

然而事情变得不断混合。 我想要注意的是,redisClient变量只被分配了一次,后来在整个应用程序中使用。 现在我想知道,对Redis中的每个数据库使用单独的redisClients是多么合理。 所以它会是这样的;

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

因此,在创建redisClient对象并初始化它之后,您可以使用它来处理所有redis操作。

如果您将以这种方式使用redis,则节点将为每个节点进程打开3个(且仅3个)连接。


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

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连接(因为节点缓存require调用):

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

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

对3个不同的数据库使用3个连接是正确的方法。 打开额外连接会产生开销,但开销非常小。

有了数百个开放连接,开销就会成为一个问题。 我不确定您将运行多少个应用程序实例,但每个进程只猜测3个连接,您将无法获得有问题的数字。

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

在我自己在异步环境中努力解决多个数据库支持之后,我这样说了。 最后,我访问了Freenode上的#redis,并参考了Redis的作者Salvatore Sanfilippo的以下声明:

我认为Redis的多个数据库错误是我在Redis设计中最糟糕的决定...我希望在某些时候我们可以放弃多个DB支持,但我认为可能为时已晚,因为有很多人依赖这个功能对他们的工作。

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

你真的想依靠笔者感到遗憾的是大部分功能之前,要三思而后行。

您可以使用MULTI/EXEC块来代替3个不同DB的3个不同连接:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM