Вопрос

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

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

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

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

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

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

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

Это было полезно?

Решение

@Msalters

Re 'Queue':

Операция по умолчанию Rabbitmq - это именно то, что вы описываете: Transiet Pubsub. Но с TCP вместо UDP.

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

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

Re udp:

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

Я не могу вспомнить многие многопользовательские игры, которые нуждаются в задержке обратной связи ниже 300 микросекунд. Вы можете получить ниже 300us с TCP. TCP Windowing является Более дороже, чем сырой UDP, но если вы используете UDP, чтобы идти быстрее, и добавите пользовательский перевод потерь или Seqno/ACK/Resend Manager, это может снова замедлить вас. Все зависит от вашего варианта использования. Если вам действительно действительно нужно использовать UDP и Lazy Acks и так далее, то вы можете лишить TCP RabbitMQ и, вероятно, справиться с этим.

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

Другие советы

I am building such a system now, actually.

I have done a fair amount of evaluation of several MQs, including RabbitMQ, Qpid, and ZeroMQ. The latency and throughput of any of those are more than adequate for this type of application. What is not good, however, is queue creation time in the midst of half a million queues or more. Qpid in particular degrades quite severely after a few thousand queues. To circumvent that problem, you will typically have to create your own routing mechanisms (smaller number of total queues, and consumers on those queues are getting messages that they don't have an interest in).

My current system will probably use ZeroMQ, but in a fairly limited way, inside the cluster. Connections from clients are handled with a custom sim. daemon that I built using libev and is entirely single-threaded (and is showing very good scaling -- it should be able to handle 50,000 connections on one box without any problems -- our sim. tick rate is quite low though, and there are no physics).

XML (and therefore XMPP) is very much not suited to this, as you'll peg the CPU processing XML long before you become bound on I/O, which isn't what you want. We're using Google Protocol Buffers, at the moment, and those seem well suited to our particular needs. We're also using TCP for the client connections. I have had experience using both UDP and TCP for this in the past, and as pointed out by others, UDP does have some advantage, but it's slightly more difficult to work with.

Hopefully when we're a little closer to launch, I'll be able to share more details.

Jon, this sounds like an ideal use case for AMQP and RabbitMQ.

I am not sure why you say that AMQP users are all large enterprise-type corporations. More than half of our customers are in the 'web' space ranging from huge to tiny companies. Lots of games, betting systems, chat systems, twittery type systems, and cloud computing infras have been built out of RabbitMQ. There are even mobile phone applications. Workflows are just one of many use cases.

We try to keep track of what is going on here:

http://www.rabbitmq.com/how.html (make sure you click through to the lists of use cases on del.icio.us too!)

Please do take a look. We are here to help. Feel free to email us at info@rabbitmq.com or hit me on twitter (@monadic).

FWIW, for cases where intermediate results are not important (like positioning info) Qpid has a "last-value queue" that can deliver only the most recent value to a subscriber.

My experience was with a non-open alternative, BizTalk. The most painful lesson we learnt is that these complex systems are NOT fast. And as you figured from the hardware requirements, that translates directly into significant costs.

For that reason, don't even go near XML for the core interfaces. Your server cluster will be parsing 2 million messages per second. That could easily be 2-20 GB/sec of XML! However, most messages will be for a few queues, while most queues are in fact low-traffic.

Therefore, design your architecture so that it's easy to start with COTS queue servers and then move each queue (type) to a custom queue server when a bottleneck is identified.

Also, for similar reasons, don't assume that a message queue architecture is the best for all comminication needs your application has. Take your "entity location in an instance" example. This is a classic case where you don't want guaranteed message delivery. The reason that you need to share this information is because it changes all the time. So, if a message is lost, you don't want to spend time recovering it. You'd only send the old locatiom of the affected entity. Instead, you'd want to send the current location of that entity. Technology-wise this means you want UDP, not TCP and a custom loss-recovery mechanism.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top