Как конвейер в node.js перерисовать?

У меня есть много данных для вставки (SET\INCR) в redis DB, поэтому я ищу конвейер\массовое вложение через node.js.

Я не мог найти хороший пример /API для этого в node.js, поэтому любая помощь была бы замечательной!

Ответ 1

Да, я должен согласиться с тем, что для этого нет примеров, но мне удалось создать поток, на который я отправил несколько команд вставки в пакетном режиме.

Вы должны установить модуль для потока 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 stream в node.js на redis-stream node модуль

Ответ 3

Возможно, вы захотите посмотреть и на 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 заключается в том, что если что-то не работает, вы либо теряете все это, либо должны вставлять его снова и снова.