2014-01-28 81 views

回答

10

是的,我必須同意,缺乏這方面的例子,但我設法創建了我批量發送幾個插入命令的流。

您應該安裝模塊的Redis流:

npm install redis-stream 

這是你如何使用流:

var redis = require('redis-stream'), 
    client = new redis(6379, '127.0.0.1'); 

// Open stream 
var stream = client.stream(); 

// Example of setting 10000 records 
for(var record = 0; record < 10000; record++) { 

    // Command is an array of arguments: 
    var command = ['set', 'key' + record, 'value']; 

    // Send command to stream, but parse it before 
    stream.redis.write(redis.parse(command)); 
} 

// Create event when stream is closed 
stream.on('close', function() { 
    console.log('Completed!'); 

    // Here you can create stream for reading results or similar 
}); 

// Close the stream after batch insert 
stream.end(); 

此外,您還可以創建許多河流,只要你想和開放/隨時關閉它們。

幾個例子使用的Redis的在node.js中流redis-stream node module

+0

謝謝託尼!你知道它是否以及如何與Lua腳本一起工作? –

+1

嗯,我還沒有嘗試過,但我認爲你可以在redis實例中加載腳本,並使用通過管道發送的'eval'或'evalsha'命令來運行它們。 – Toni

+0

我逐字運行你的代碼,沒有設置任何鍵。之後通過redis-cli調用「keys *」會產生一個空集。 – Jake

2

你可能想看看batch()太。 multi()之所以比較慢,是因爲它是事務性的。如果失敗了,什麼都不會執行。這可能是你想要的,但你在這裏有速度的選擇。

redis-stream軟件包似乎並沒有利用Redis的大容量插入功能,因此它比Redis的網站繼續與redis-cli談論的質量插入慢。

另一個想法是使用Redis的-CLI,並給它一個文件從,此NPM包確實給流:https://github.com/almeida/redis-mass

並不熱衷於第一寫入到磁盤上的文件?此回購:https://github.com/eugeneiiim/node-redis-pipe/blob/master/example.js

...也流到Redis,但沒有寫入文件。它流入一個產生的進程並經常刷新緩衝區。

在Redis的網站下插入(http://redis.io/topics/mass-insert),你可以看到一個小小的Ruby例子。上面的回購基本上將其移植到Node.js,然後直接將其流入產生的redis-cli進程。

所以在Node.js的,我們有:

var redisPipe = spawn('redis-cli', ['--pipe']);

spawn()到一個子進程可以通過管道返回到與stdin參考。例如:redisPipe.stdin.write()

您可以繼續寫入緩衝區,將其傳輸到子進程,然後每隔一段時間清理一次。然後這樣就不會填滿它,因此在內存方面會比內存中的node_redis包更好一些(雖然我沒有深入地研究它,但是它的文檔中的數據保存在內存中)不知道內存佔用是多少。它可能會做同樣的事情。

當然要記住,如果出現問題,它都會失敗。這就是爲fluentd創建的工具(這是另一個選項:http://www.fluentd.org/plugins/all - 它有幾個Redis插件)......但同樣,這意味着您在某種程度上支持磁盤上的數據。我也親自使用過Embulk也這樣做(這需要在磁盤上的文件),但它不支持大量插入,所以它很慢。花費了近2個小時的30,000條記錄。

流式方法(不受磁盤支持)的一個好處是如果您從另一個數據源執行大量插入操作。假設數據源返回大量數據,並且您的服務器沒有硬盤空間來支持所有數據 - 您可以改爲使用它。再一次,你冒失敗的風險。

我發現自己處於這個位置,因爲我正在構建Docker映像,該映像將在服務器上運行,但沒有足夠的磁盤空間來容納大型數據集。當然,如果你可以將所有東西放在服務器的硬盤上,它會容易得多......但是如果你不能,流式傳輸到redis-cli可能是你唯一的選擇。

如果你真的在定期推送大量數據,我可能會建議fluentd說實話。它具有許多很棒的功能,可以確保您的數據能夠傳送到正在發生的位置,並且如果出現故障,它可以恢復。

所有這些Node.js方法的一個問題是,如果失敗了,您要麼全部丟失,要麼必須重新插入。