Redis и Node.js и Socket.io Вопросы - PullRequest
6 голосов
/ 20 января 2012

Я только что изучил redis и node.js У меня есть два вопроса, на которые я не смог найти удовлетворительного ответа.

Мой первый вопрос касается повторного использования клиентов Redis в файле node.js. Я нашел этот вопрос и ответ: Как повторно использовать соединение redis в socket.io?, но это меня не удовлетворило достаточно.

Теперь, если я создам клиента redis в событии подключения, он будет порождаться для каждого подключения. Таким образом, если у меня 20k одновременных пользователей, будет 20k redis-клиентов.

Если я поставлю его вне события подключения, оно будет порождено только один раз.

В ответе говорится, что он создает три клиента для каждой функции вне события подключения.

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

Итак, даже если вы создадите три разных клиента redis для каждой функции, если у вас есть 30k одновременно работающих пользователей, которые одновременно отправляют 2k сообщения, вы должны столкнуться с той же проблемой, верно? Таким образом, каждый «пользователь» должен иметь свой собственный клиент Redis в событии подключения. Я прав? Если нет, то как node.js или redis обрабатывают параллельные запросы, в отличие от MySQL? Если он имеет собственный механизм и создает что-то вроде дочерних процессов в клиенте Redis, зачем нам тогда создавать три разных клиента Redis? Одного должно быть достаточно.

Надеюсь, вопрос был ясен.

- ОБНОВЛЕНИЕ -

Я нашел ответ на следующий вопрос. http://howtonode.org/control-flow Не нужно отвечать, но мой первый вопрос остается в силе.

- ОБНОВЛЕНИЕ -

Мой второй вопрос такой. Я также не очень хорош в JS и Node.js. Итак, насколько я знаю, если вам нужно ждать события, вам нужно инкапсулировать вторую функцию в первой. (Я еще не знаю терминологию). Позвольте мне привести пример;

socket.on('startGame', function() {
    getUser();
    socket.get('game', function (gameErr, gameId) {
        socket.get('channel', function (channelErr, channel) {
            console.log(user);
            client.get('games:' + channel + '::' + gameId + ':owner', function (err, owner) { //games:channel.32:game.14
                if(owner === user.uid) {
   //do something
                }
            });
        }
    });
});

Так что, если я учусь правильно, мне нужно запустить каждую функцию внутри функции, если мне нужно дождаться ответа ввода / вывода. В противном случае неблокирующий механизм node.js позволит запустить первую функцию, в этом случае он получит результат параллельно, но вторая функция может не иметь результата, если для ее получения потребуется время. Итак, если вы получаете результат от Redis, например, и будете использовать результат во второй функции, вы должны инкапсулировать его в функцию get Redis. В противном случае вторая функция будет запущена без получения результата.

Итак, в этом случае, если мне нужно запустить 7 различных функций, а функция 8. будет нуждаться в результате их всех, мне нужно написать их рекурсивно так? Или я что-то упустил.

Надеюсь, это тоже понятно.

Большое спасибо,

Ответы [ 3 ]

2 голосов
/ 21 января 2012

Итак, каждый «пользователь» должен иметь своего собственного клиента Redis в событии подключения.Я прав?

На самом деле вы не:)

Дело в том, что node.js очень отличается от, например, PHP.node.js не порождает дочерние процессы в новых соединениях, что является одной из основных причин, по которой он может легко обрабатывать большое количество одновременных соединений, в том числе долговременных (Comet, Websockets и т. д.).node.js обрабатывает события последовательно, используя очередь событий в одном процессе.Если вы хотите использовать несколько процессов, чтобы использовать преимущества многоядерных серверов или нескольких серверов, вам придется делать это вручную (хотя это не входит в задачу этого вопроса).

Следовательно,Это совершенно правильная стратегия - использовать одно соединение Redis (или MySQL) для обслуживания большого количества клиентов.Это позволяет избежать накладных расходов на создание и разрыв соединения с базой данных для каждого клиентского запроса.

0 голосов
/ 28 декабря 2014

По первому вопросу: «Правильный ответ» может заставить вас думать, что вы хороши с одним подключением. В действительности, когда вы делаете что-то, что ожидает ввода-вывода, таймера и т. Д., Вы фактически заставляете узел запускать метод ожидания в очереди. Следовательно, если вы используете только одно соединение, вы фактически ограничите производительность потока, над которым вы работаете (один процессор), до скорости redis - которая, вероятно, составляет несколько сотен обратных вызовов в секунду (ожидающие обратные вызовы без повторного вызова будут все еще продолжайте) - хотя это не плохая производительность, нет никаких причин для создания такого рода ограничений. Рекомендуется создать несколько (5-10) соединений, чтобы избежать этой проблемы в целом. Это число увеличивается для более медленных баз данных, например MySQL, но зависит от типа запросов и особенностей кода.

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

0 голосов
/ 21 января 2012

Таким образом, каждый «пользователь» должен иметь свой собственный клиент Redis в событие подключения. Я прав?

Вы не должны создавать новый клиент Redis для каждого подключенного пользователя, это неправильный способ сделать это. Вместо этого просто создайте максимум 2-3 клиентов и используйте их.

Для получения дополнительной информации оформите этот вопрос:

Как повторно использовать соединение redis в socket.io?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...