Крупномасштабная очередь сообщений с низкой задержкой - PullRequest
43 голосов
/ 17 декабря 2009

Я немного переосмыслил масштабные многопользовательские игры в эпоху приложений Facebook и облачных вычислений.

Предположим, я должен был что-то построить поверх существующих открытых протоколов, и я хочу обслуживать 1 000 000 одновременных игроков, просто чтобы решить проблему.

Предположим, у каждого игрока есть очередь входящих сообщений (для чата и еще много чего), и в среднем еще одна очередь входящих сообщений (гильдии, зоны, экземпляры, аукцион, ...), поэтому у нас есть 2 000 000 очередей. Игрок будет слушать 1-10 очередей одновременно. Каждая очередь будет иметь в среднем, может быть, 1 сообщение в секунду, но у определенных очередей будет гораздо более высокая скорость и большее число слушателей (скажем, очередь «расположения объекта» для экземпляра уровня). Давайте предположим, что время ожидания системной очереди составляет не более 100 миллисекунд, что нормально для игр с умеренным действием (но не для таких игр, как Quake или Unreal Tournament).

Из других систем я знаю, что обслуживать 10 000 пользователей в одном блоке 1U или блейд-модуле - разумное ожидание (при условии, что ничего более дорогого не происходит, как физическое моделирование или еще много чего).

Итак, с помощью кластерной системы с перекрестными кластерами, где клиенты подключаются к шлюзам подключения, которые, в свою очередь, подключаются к серверам очередей сообщений, мы получаем 10000 пользователей на шлюз с 100 компьютерами шлюзов и 20 000 очередей сообщений на сервер очередей с 100 очередями. машины. Опять же, просто для общего обзора. Количество соединений на каждой машине MQ будет крошечным: около 100, чтобы общаться с каждым из шлюзов. Количество соединений на шлюзах будет намного выше: 10 100 для клиентов + соединения со всеми серверами очереди. (Вдобавок к этому, добавьте несколько соединений для серверов симуляции игрового мира или еще чего-нибудь, но сейчас я пытаюсь сохранить это отдельно)

Если бы я не хотел создавать это с нуля, мне пришлось бы использовать существующую инфраструктуру обмена сообщениями и / или организации очередей. Я могу найти два открытых протокола AMQP и XMPP. Предполагаемое использование XMPP немного больше похоже на то, что понадобится этой игровой системе, но накладные расходы весьма заметны (XML, подробные данные о присутствии, а также различные другие каналы, которые должны быть построены сверху). Фактическая модель данных AMQP ближе к тому, что я описал выше, но все пользователи кажутся крупными корпорациями корпоративного типа, и рабочие нагрузки, по-видимому, связаны с рабочим процессом, а не с обновлением игры в реальном времени.

Есть ли у кого-нибудь дневной опыт использования этих технологий или их реализаций, которым вы можете поделиться?

Ответы [ 5 ]

11 голосов
/ 18 декабря 2009

@ MSalters

Re 'очередь сообщений':

Операция RabbitMQ по умолчанию - именно то, что вы описываете: временный pubsub. Но с TCP вместо UDP.

Если вы хотите гарантированную возможную доставку и другие функции сохранения и восстановления, то вы МОЖЕТЕ это иметь - это вариант. В этом весь смысл RabbitMQ и AMQP - вы можете иметь множество вариантов поведения только с одной системой доставки сообщений.

Модель, которую вы описываете, является поведением DEFAULT, которое является временным, «запускай и забывай» и направляет сообщения туда, где находятся получатели. Именно по этой причине люди используют RabbitMQ для многоадресного обнаружения в EC2. Вы можете получить поведение типа UDP через одноадресную TCP-публикацию. Аккуратно, а?

Re UDP:

Я не уверен, будет ли здесь полезен UDP. Если вы отключите Nagling, то задержка прохождения одного сообщения RabbitMQ (клиент-брокер-клиент) будет измеряться в 250-300 микросекунд. Смотрите здесь для сравнения с задержкой Windows (которая была немного выше) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

Я не могу вспомнить о многих многопользовательских играх, для которых задержка в оба конца меньше 300 микросекунд. Вы можете получить ниже 300us с TCP. Окно TCP на дороже, чем сырой UDP, но если вы используете UDP для ускорения и добавляете собственный менеджер восстановления после потери или seqno / ack / resend, то это может снова замедлить работу. Все зависит от вашего варианта использования. Если вам действительно действительно нужно использовать UDP и lazy acks и т. Д., То вы можете удалить TCP из RabbitMQ и, вероятно, выполнить это.

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

10 голосов
/ 03 февраля 2010

Я сейчас строю такую ​​систему.

Я провел достаточную оценку нескольких MQ, включая RabbitMQ, Qpid и ZeroMQ. Задержка и пропускная способность любого из них более чем достаточны для этого типа приложений. Однако, что не хорошо, так это время создания очереди в полмиллиона или более очередей. Qpid, в частности, довольно сильно ухудшается после нескольких тысяч очередей. Чтобы обойти эту проблему, вам, как правило, придется создавать свои собственные механизмы маршрутизации (меньшее количество общих очередей, и потребители в этих очередях получают сообщения, в которых они не заинтересованы).

Моя текущая система, вероятно, будет использовать ZeroMQ, но довольно ограниченным образом, внутри кластера. Соединения с клиентами обрабатываются с помощью пользовательского сима. демон, который я создал с использованием libev и является полностью однопоточным (и демонстрирует очень хорошее масштабирование - он должен без проблем обрабатывать 50 000 подключений на одном блоке - наш показатель тика на сим довольно низкий, и есть нет физики).

XML (и, следовательно, XMPP) очень не подходит для этого, так как вы привязываете процессорный XML к обработке задолго до того, как станете привязанными к вводу / выводу, а это не то, что вам нужно. В настоящее время мы используем буферы протокола Google, и они, похоже, хорошо соответствуют нашим конкретным потребностям. Мы также используем TCP для клиентских подключений. У меня был опыт использования как UDP, так и TCP для этого в прошлом, и, как отмечали другие, UDP имеет некоторые преимущества, но работать с ним немного сложнее.

Надеюсь, когда мы немного приблизимся к запуску, я смогу поделиться более подробной информацией.

5 голосов
/ 18 декабря 2009

Джон, это звучит как идеальный вариант использования AMQP и RabbitMQ.

Я не уверен, почему вы говорите, что пользователи AMQP - все крупные корпорации корпоративного типа. Более половины наших клиентов находятся в «сетевом» пространстве - от огромных до крошечных компаний. Множество игр, систем ставок, чатов, твиттер-систем и облачных вычислений были созданы на основе RabbitMQ. Есть даже приложения для мобильных телефонов. Рабочие процессы являются лишь одним из многих вариантов использования.

Мы стараемся следить за тем, что здесь происходит:

http://www.rabbitmq.com/how.html (убедитесь, что вы просматриваете списки вариантов использования на del.icio.us!)

Пожалуйста, посмотрите. Мы здесь, чтобы помочь. Не стесняйтесь, напишите нам на info@rabbitmq.com или напишите мне в твиттер (@monadic).

3 голосов
/ 29 декабря 2009

FWIW, для случаев, когда промежуточные результаты не важны (например, информация о позиционировании) Qpid имеет «очередь последних значений», которая может доставлять подписчику только самое последнее значение.

2 голосов
/ 18 декабря 2009

Мой опыт был с не открытой альтернативой, BizTalk. Самый болезненный урок, который мы усвоили, состоит в том, что эти сложные системы НЕ быстры. И, как вы поняли из требований к оборудованию, это напрямую приводит к значительным затратам.

По этой причине даже не подходите к XML для основных интерфейсов. Ваш кластер серверов будет анализировать 2 миллиона сообщений в секунду. Это легко может быть 2-20 ГБ / с XML! Тем не менее, большинство сообщений будет для нескольких очередей, в то время как большинство очередей на самом деле с низким трафиком.

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

Кроме того, по аналогичным причинам не следует полагать, что архитектура очереди сообщений является наилучшей для всех потребностей в коммуникации, которые есть в вашем приложении. Возьмите пример «расположение объекта в экземпляре». Это классический случай, когда вы не хотите получить гарантированную доставку сообщений. Причина, по которой вам нужно делиться этой информацией, заключается в том, что она постоянно меняется. Таким образом, если сообщение потеряно, вы не хотите тратить время на его восстановление. Вы бы отправили только старую локацию пострадавшего лица. Вместо этого вы хотите отправить текущее местоположение этой сущности. С технологической точки зрения это означает, что вам нужен UDP, а не TCP и специальный механизм восстановления после потери.

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