2012-12-20 68 views
15

假設您有多個 Redis中的數據庫要插入和/或從中刪除數據。你有一個像;Node&Redis:Redis客戶端

  • 插入數據DB#1
  • 第一個插入的回調後做一些東西,然後插入數據DB#2
  • 第二齣入的回調後再次做一些東西並最後插入數據到DB#3

我使用e變量稱爲redisClient即基本創建爲;

redisClient = redis.createClient(); 

雖然選擇一個新的數據庫,我用選擇命令與格外小心前的回調,所以我選擇指令等;

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變量只能在整個應用程序中使用一次而後使用。現在我想知道,使用單獨的RedisClients對於Redis中的每個DB有多合理。所以它會是這樣的;

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

我想知道這將是合理的,或者這將是將接收每秒和即將前往的生產模式4K請求的應用程序的正確方法。什麼問題這個模型可能會面臨什麼?

回答

11

對3個不同的數據庫使用3個連接是正確的方法。有額外的連接打開,但開銷很小。

由於像數百個開放連接之類的東西,開銷會開始成爲一個問題。我不確定您的應用程序有多少實例可以運行,但是在每個進程只有3個連接的情況下猜測,您將無法獲得接近有問題的數字。

+0

是的!爲每個連接使用單獨的客戶端是順便去的:) – mekwall

2

而是有3個不同的數據塊3間不同的連接,你可以如用MULTI/EXEC塊這樣的:

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

正如Carl Zulauf said,最好開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個)連接。


N.B.這也是一個好主意,把它所有到一個節點模塊:

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

然後你就可以初始化所有的Redis連接調用init函數一次(因爲節點緩存require電話):

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

然後當require('./lib/my_redis').DB1.set('key','val')將您的任何模塊DB1的調用將已初始化。

1

對每個數據庫使用一個實例是正確的方法。但是,如果您需要重新使用或節制昂貴的資源(如數據庫連接),那麼數據庫連接池可能是一個不錯的選擇。比方說,我們選擇generic-pool(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); 
    }); 
}); 
+0

你知道問題是關於Redis的,對嗎? – Nirmal

+0

你可以使用'mysql'模塊本身進行池化:https://github.com/felixge/node-mysql/ #pooling-connections – Nirmal

5

如果谷歌把你帶到這裏,請你幫個忙:不使用多個數據庫的支持。使用名稱空間密鑰或多個redis實例。

我在異步環境中自己多DB支持具有掙扎後說這個。在束手無策,我Freenode上訪問#redis,被Redis的作者,薩爾瓦託雷聖菲利波提到了如下聲明:

我認爲Redis的多個數據庫錯誤,我在Redis的 設計最糟糕的決定在所有...我希望 在某些時候我們可以放棄多個數據庫支持,但我認爲 可能太遲了,因爲有很多人依靠這個 功能來完成他們的工作。

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

你真的想依靠功能筆者感到遺憾的是最前要三思而後行。

+0

使用此功能的實際問題是什麼? – UpTheCreek

+1

您必須將您的整個服務作爲DB select命令的回調來啓動。主要作爲配置回調是很尷尬的,特別是當多個配置元素以這種方式工作時。首先,它使得不可能在配置錯誤上快速失敗。 – sheldonh