Почему в Node.js я должен отдавать предпочтение хранилищам значений ключей, а не переменным приложения? - PullRequest
5 голосов
/ 20 сентября 2011

Я занимаюсь разработкой приложения реального времени с поддержкой Socket.IO в Node.JS, которое будет одновременно использоваться сотнями пользователей одновременно, и мне нужно сохранить некоторые основные сведения о каждом подключенном клиенте (и удалитьэти подробности при отключении клиента).

Я прочитал, что использование хранилища значений ключей (например, Redis) является предпочтительным выбором для хранения таких данных.

Почему хранение данныхв обычной переменной приложения (объект, например, var connectedClientsData = {}) плохо по сравнению с хранением данных в хранилище значений ключей, таких как Redis?

Это только для поддержки масштабирования (например, несколько NodeJS-серверы приложений могут подключаться к одному центральному хранилищу значений ключей), или есть более серьезные недостатки?

Ответы [ 3 ]

4 голосов
/ 20 сентября 2011

В игре есть пара вопросов:

1) Да, масштабирование. Не только для нескольких серверов, но и для нескольких процессоров через нечто вроде «кластера» (которое вы можете найти в npm).

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

Кроме того, у вас гораздо больше шансов перезапустить процесс вашего узла (чтобы обновить приложение), чем при перезапуске redis, что приведет к потере всех сеансов.

2 голосов
/ 20 сентября 2011
  • Постоянство данных - ваши данные сохраняются в более надежном и долговечном хранилище, которое предназначено для решения этих задач. Например, Redis имеет снимки набора данных на диске и поддерживает расширенные структуры данных, которые предлагают вам больше возможностей при работе с вашими данными.

  • Централизация данных - ваши данные хранятся и доступны из центрального места, где не только ваше основное приложение, но и другие приложения могут получить к нему доступ и манипулировать этими данными. Например, если вам нужно обмениваться данными о состоянии / состоянии между двумя системами, это гораздо проще сделать с помощью хранилища KV, предназначенного для этой цели.

  • Выгрузка основного приложения - когда вы используете KV store, вы выгружаете свое основное приложение, что может повысить его производительность и значительно снизить потребление памяти. Тогда масштабирование вашего основного приложения может быть намного проще.

  • Масштабируемость хранилища KV - во многих хранилищах KV есть встроенные возможности масштабирования, которые в противном случае было бы сложнее реализовать в вашем основном приложении (например, совместно использовать состояние между несколькими экземплярами вашего приложения). Эта функциональность также тщательно протестирована и хорошо документирована, поэтому вам не нужно сильно беспокоиться об этих вещах.

0 голосов
/ 20 сентября 2011

Говорят, что хранилища значений ключей лучше хранить постоянных данных по сравнению с реляционными базами данных, а не с непостоянными объектами в памяти.

Но я подозреваю, что база данных ключ-значение имеет преимущества по сравнению с объектными переменными, даже если постоянство не является необходимым. Они могут быть разделены между приложениями и могут сэкономить потребление памяти. Даже Redis, который хранит все значения в памяти, может сохранить вашу память с вашего сервера application , поскольку его можно перенести на другой сервер при использовании большого количества гигабайт.

Кроме того, совместно используемый объект в памяти становится сложным для поддержания с течением времени. Если вы решите использовать его, я рекомендую вам абстрагироваться от его характера. В вашем коде есть объект, где вы просто делаете что-то подобное:

var storage = new Storage();
storage.registerClientDisconnection("client_id_1");

Тогда ваш Storage.registerClientDisconnection() может быть либо

Storage.proptotype.registerClientDisconnection = function(clientId) {
    this.info[clientId].connected = false;
};

или

Storage.proptotype.registerClientDisconnection = function(clientId) {
    var client = redis.createClient();
    client.set("clientId:"+clientId+":connected", false);
};

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

...