в узлах.js, почему я должен предпочесть хранилища ключ-значение переменной приложения?
Я разрабатываю приложение реального времени с поддержкой Socket.IO в Node.JS, который будет использоваться парой сотен пользователей одновременно в любой данный момент, и мне нужно сохранить некоторые основные сведения о каждом подключенном клиенте (и удалить эти сведения при отключении клиента).
Я читал, что использование хранилища ключ-значение (такого как Redis) является предпочтительным выбором для хранения таких данных.
Почему хранение данных в обычной переменной in-app (object, например var connectedClientsData = {}
) плохо по сравнению с хранение данных в хранилище значений ключей, таком как Redis?
Это только для поддержки масштабирования (например, несколько серверов приложений на основе NodeJS могут подключаться к одному центральному хранилищу ключей и значений), или есть более серьезные недостатки?
3 ответа:
Есть пара проблем в игре:
1) да, масштабирование. Не только к нескольким серверам, но и к нескольким процессорам через что-то вроде "кластера" (который вы можете найти на npm).
2) В настоящее время V8 имеет ограничения памяти, основанные на его браузерном наследии. Они в какой-то степени поддаются настройке и более тщательно удаляются в следующей версии V8, но это все еще нужно учитывать.
Кроме того, вы гораздо чаще перезапускаете процесс узла (чтобы обновить приложение), чем вы должны перезапустить redis, тем самым потеряв все сеансы.
Сохранение данных - ваши данные сохраняются в более надежном и долговечном хранилище, которое построено для работы с этим материалом. Например, redis имеет моментальные снимки набора данных на диске и поддерживает расширенные структуры данных, которые предлагают вам больше возможностей при работе с вашими данными.
Централизация данных - ваши данные хранятся и доступны из центрального места, где не только ваше основное приложение, но и другие приложения могут получить к ним доступ и управлять ими. с этими данными. Например, если вам нужно разделить состояние/данные между двумя системами, гораздо проще сделать это с помощью KV store, выделенного для этой цели.
Выгрузка основного приложения - при использовании KV store вы выгружаете основное приложение, что может повысить его производительность и значительно снизить потребление памяти. Тогда масштабирование вашего основного приложения может быть намного проще.
Масштабируемость магазина KV - Многие магазины KV имеют встроенный возможности масштабирования, которые в противном случае было бы сложнее реализовать в главном приложении (например, совместное использование состояния между несколькими экземплярами приложения). Эта функциональность также тщательно протестирована и хорошо документирована, так что вам не нужно беспокоиться об этих вещах.
Говорят, что хранилища ключ-значение лучше подходят для храненияпостоянных данных по сравнению с реляционными базами данных, а не с несуществующими объектами в памяти.
Но я подозреваю, что база данных ключ-значение имеет преимущества по сравнению с объектными переменными, даже если в постоянстве нет необходимости. Они могут быть разделены между приложениями и могут сэкономить потребление памяти. Даже Redis, который хранит все значения в памяти, может сохранить вам память от вашегоприложения сервера, потому что он может быть перенесен на другой сервер при потреблении большого количества гигабайт.Кроме того, общий объект в памяти имеет тенденцию становиться сложным для поддержания с течением времени. Если вы решите использовать его, я рекомендую вам абстрагироваться от его природы. Есть объект, где вы просто делаете что-то вроде этого в своем коде:
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); };
Резюмируя: я бы рекомендовал использовать некоторое хранилище ключей-значений, но я уверен, что вы также можете использовать некоторое хранилище объектов. Однако, если вы решили использовать объект в памяти, просто абстрагируйте эту деталь реализации, чтобы в будущем вы могли легко перейти к реализации хранилища ключей и значений. Абстрагирование вашего решения кажется более важным, чем ваше решение о реализации.