Подтвердить что ты не робот

Малоядерная, крупномасштабная очередь сообщений

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

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

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

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

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

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

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

4b9b3361

Ответ 1

@MSalters

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

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

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

Модель, которую вы описываете, - это поведение ПО УМОЛЧАНИЮ, которое является временным, "огонь и забыть" и маршрутизирует сообщения туда, где есть получатели. Люди используют RabbitMQ для многократного обнаружения на EC2 именно по этой причине. Вы можете получить поведение типа UDP через одноадресный TCP pubsub. Аккуратно, да?

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 и ленивы, и так далее, тогда вы можете вырезать RabbitMQ TCP и, возможно, отключите это.

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

Ответ 2

Сейчас я создаю такую ​​систему.

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

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

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

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

Ответ 3

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

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

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

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

Пожалуйста, взгляните. Мы здесь, чтобы помочь. Не стесняйтесь писать нам по электронной почте [email protected] или ударить меня по twitter (@monadic).

Ответ 4

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

Ответ 5

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

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

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

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