簡體   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