Как подключить node.js к Redis?

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

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


person Aviram Netanel    schedule 28.01.2014    source источник


Ответы (4)


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

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

person Toni    schedule 07.02.2014
comment
Спасибо Тони! знаете ли вы, как это работает со сценариями Lua? - person Aviram Netanel; 07.02.2014
comment
Хм, я не пробовал, но я думаю, что вы можете загрузить сценарии в экземпляр Redis и запустить их, используя команды eval или evalsha, отправленные через конвейер. - person Toni; 11.02.2014
comment
Я запустил ваш код дословно, и ни один из ключей не был установлен. Вызов ключей * через redis-cli впоследствии дает пустой набор. - person Jake; 22.03.2015
comment
@Джейк, ты прав. Спасибо за отчет. Это устарело. Проверил сейчас новую версию redis-stream и команды изменились, ну в этом примере только одна: Вместо: stream.write( ... ) В новой версии это: stream.redis.write( ... ) - person Toni; 25.03.2015

В node_redis все команды конвейеризированы:

https://github.com/mranney/node_redis/issues/539#issuecomment-32203325

person sundagy    schedule 10.02.2014
comment
Спасибо! Я действительно пытался использовать multi и eval & exec, но производительность была еще хуже... - person Aviram Netanel; 11.02.2014

Вы также можете посмотреть на 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 для этого (для чего требовался файл на диске), но он не поддерживал массовые вставки, поэтому работал медленно. На 30 000 записей ушло почти 2 часа.

Одно из преимуществ потокового подхода (без поддержки диска) заключается в том, что вы делаете огромную вставку из другого источника данных. Предполагая, что источник данных возвращает много данных, а на вашем сервере недостаточно места на жестком диске для их поддержки, вместо этого вы можете передавать их в потоковом режиме. Опять же, вы рискуете потерпеть неудачу.

Я оказался в таком положении, когда создаю образ Docker, который будет работать на сервере с недостаточным дисковым пространством для размещения больших наборов данных. Конечно, намного проще, если вы можете разместить все на жестком диске сервера... Но если нет, то единственным вариантом может быть потоковая передача на redis-cli.

Если вы действительно регулярно обмениваетесь большим количеством данных, я бы, если честно, порекомендовал бы fluentd. Он поставляется с множеством замечательных функций, которые гарантируют, что ваши данные попадут туда, куда они направляются, и если что-то пойдет не так, они могут возобновиться.

Одна проблема со всеми этими подходами Node.js заключается в том, что если что-то терпит неудачу, вы либо теряете все это, либо должны вставлять все заново.

person Tom    schedule 05.05.2016

По умолчанию node_redis, библиотека Node.js отправляет команды в конвейеры и автоматически выбирает, сколько команд будет отправлено в каждый конвейер [(https://github.com/NodeRedis/node-redis/issues/539#issuecomment-32203325)][1]. Поэтому вам не нужно беспокоиться об этом. Однако другие клиенты Redis могут не использовать конвейеры по умолчанию; вам нужно будет ознакомиться с клиентской документацией, чтобы узнать, как воспользоваться преимуществами конвейеров.

person Ossy    schedule 31.05.2020