У меня есть много данных для вставки (SET\INCR) в redis DB, поэтому я ищу конвейер\массовое вложение через node.js.
Я не мог найти хороший пример /API для этого в node.js, поэтому любая помощь была бы замечательной!
У меня есть много данных для вставки (SET\INCR) в redis DB, поэтому я ищу конвейер\массовое вложение через node.js.
Я не мог найти хороший пример /API для этого в node.js, поэтому любая помощь была бы замечательной!
Да, я должен согласиться с тем, что для этого нет примеров, но мне удалось создать поток, на который я отправил несколько команд вставки в пакетном режиме.
Вы должны установить модуль для потока 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 модуль
В node_redis все команды конвейерны:
https://github.com/mranney/node_redis/issues/539#issuecomment-32203325
Возможно, вы захотите посмотреть и на 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 заключается в том, что если что-то не работает, вы либо теряете все это, либо должны вставлять его снова и снова.