Kolejkowanie wiadomości o niskim opóźnieniu i dużej skali

Przechodzę przez trochę ponowne myślenie o wielkoskalowych grach multiplayer w dobie aplikacji Facebook i cloud computing.

Przypuśćmy, że mam zbudować coś na bazie istniejących otwartych protokołów i chcę obsługiwać 1 000 000 jednoczesnych graczy, tylko po to, by rozwiązać problem.

Załóżmy, że każdy gracz ma kolejkę wiadomości przychodzących (do czatu i czatu) i średnio jeszcze jedną kolejkę wiadomości przychodzących (Gildie, strefy, instancje, aukcje,...) mamy więc 2 000 000 kolejek. Gracz będzie słuchał 1-10 kolejek na raz. Każda kolejka będzie miała średnio 1 wiadomość na sekundę, ale niektóre kolejki będą miały znacznie wyższą częstotliwość i większą liczbę słuchaczy (powiedzmy, Kolejka" lokalizacji encji " dla instancji poziomu). Załóżmy, że nie więcej niż 100 milisekund opóźnienia kolejkowania systemu, co jest OK dla gier lekko zorientowanych na akcję (ale nie gier takich jak Quake czy Unreal Tournament).

Z innych systemów wiem, że obsługa 10 000 użytkowników na jednym 1U lub blade box jest rozsądne oczekiwanie (zakładając, że nie dzieje się nic innego kosztownego, jak symulacja fizyki czy cokolwiek innego).

Tak więc, z systemem klastrów poprzecznych, w którym klienci łączą się z bramami połączeniowymi, które z kolei łączą się z serwerami kolejek komunikatów, otrzymywalibyśmy 10 000 użytkowników na bramę ze 100 maszynami do bramek i 20 000 kolejek na serwer kolejki ze 100 maszynami do kolejek. Jeszcze raz, tylko dla ogólnego rozpoznania. Liczba połączeń na każdej maszynie MQ byłaby niewielka: około 100, do rozmowy każda z bram. Liczba połączeń na bramkach byłaby znacznie wyższa: 10,100 dla klientów + połączenia do wszystkich serwerów kolejki. (Do tego dodaj kilka połączeń dla serwerów symulacji świata gier, ale na razie staram się to oddzielić)

Gdybym nie chciał budować tego od zera, musiałbym użyć istniejącej infrastruktury komunikacyjnej i / lub kolejkowej. Dwa otwarte protokoły, które mogę znaleźć to AMQP i XMPP. Zamierzone użycie XMPP jest trochę bardziej jak to, co ten system gry musiałby, ale narzut jest dość zauważalny (XML, Plus szczegółowe dane obecności, plus różne inne kanały, które muszą być zbudowane na górze). Rzeczywisty model danych AMQP jest bliższy temu, co opisuję powyżej, ale wszyscy użytkownicy wydają się być dużymi korporacjami, a obciążenia wydają się być związane z przepływem pracy, a nie aktualizacją gier w czasie rzeczywistym.

Czy ktoś ma jakieś doświadczenie z tymi technologiami lub ich implementacjami, którym możesz się podzielić?

Author: Jon Watte, 2009-12-17

5 answers

@ MSalters

Re 'Kolejka komunikatów':

Domyślna operacja RabbitMQ jest dokładnie tym, co opisujesz: transient pubsub. Ale z TCP zamiast UDP.

Jeśli chcesz mieć gwarancję dostawy i inne funkcje uporczywości i odzyskiwania, to też możesz to mieć - jest to opcja. O to właśnie chodzi w RabbitMQ i AMQP - możesz mieć wiele zachowań za pomocą jednego systemu dostarczania wiadomości.

Model, który opisujesz, jest zachowaniem domyślnym, czyli transient, "fire and forget" i przekierowanie Wiadomości do miejsca, w którym znajdują się odbiorcy. Ludzie używają RabbitMQ do wykrywania multicastów na EC2 właśnie z tego powodu. Możesz uzyskać zachowania typu UDP przez unicast TCP pubsub. Nieźle, co?

Re UDP:

Nie jestem pewien, czy UDP byłby tu przydatny. Jeśli wyłączysz Nagling, opóźnienie pojedynczej wiadomości RabbitMQ (klient-broker-Klient) zostanie zmierzone na 250-300 mikrosekund. Zobacz tutaj porównanie z opóźnieniem systemu Windows (które było trochę wyżej) http://old.nabble.com/High%28er%29-latency-with-1.5.1--p21663105.html

Nie przychodzi mi do głowy wiele gier multiplayer, które wymagają opóźnienia w obie strony poniżej 300 mikrosekund. Możesz uzyskać poniżej 300us z TCP. TCP windowing jest droższy niż raw UDP, ale jeśli używasz UDP, aby przejść szybciej i dodać niestandardowy Menedżer odzyskiwania strat lub seqno/ack / resend, to może cię to ponownie spowolnić. Wszystko zależy od Twojego przypadku użycia. Jeśli naprawdę naprawdę musisz używaj UDP i lazy acks i tak dalej, wtedy możesz rozebrać TCP RabbitMQ i pewnie to ściągniesz.

Mam nadzieję, że to pomoże wyjaśnić, dlaczego poleciłem RabbitMQ dla przypadku użycia Jona.

 11
Author: alexis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 16:48:33

Właśnie buduję taki system.

Zrobiłem sporo oceny kilku MQs, w tym RabbitMQ, Qpid i ZeroMQ. Opóźnienia i przepustowość któregokolwiek z nich są więcej niż odpowiednie dla tego typu aplikacji. Co jednak nie jest dobre, to czas tworzenia kolejki w środku pół miliona kolejek lub więcej. W szczególności Qpid dość poważnie spada po kilku tysiącach kolejek. Aby obejść ten problem, zazwyczaj będziesz musiał stworzyć swój własny mechanizmy routingu (mniejsza liczba kolejek ogółem, a konsumenci w tych kolejkach dostają wiadomości, którymi się nie interesują).

Mój obecny system prawdopodobnie będzie używał ZeroMQ, ale w dość ograniczony sposób, wewnątrz klastra. Połączenia z klientami są obsługiwane za pomocą niestandardowej karty sim. daemon, który zbudowałem przy użyciu libev i jest całkowicie jednowątkowy (i wykazuje bardzo dobre skalowanie-powinien być w stanie obsłużyć 50 000 połączeń na jednym pudełku bez żadnych problemów-nasz sim. wskaźnik kleszczy jest jednak dość niski i nie ma fizyki).

XML (a więc XMPP) bardzo nie nadaje się do tego, ponieważ procesor będzie przetwarzał XML na długo przed tym, zanim zostaniesz związany z I / O, co nie jest tym, czego chcesz. W tej chwili używamy buforów protokołu Google, a te wydają się dobrze dopasowane do naszych szczególnych potrzeb. Korzystamy również z protokołu TCP dla połączeń klienckich. Miałem doświadczenie w używaniu zarówno UDP, jak i TCP do tego w przeszłości i jak zauważyli inni, UDP robi mieć jakąś przewagę, ale jest to nieco trudniejsze do pracy.

Mam nadzieję, że kiedy będziemy bliżej premiery, będę mógł podzielić się więcej szczegółami.

 10
Author: Tim McClarren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-03 18:15:41

Jon, to brzmi jak idealny przypadek użycia AMQP i RabbitMQ.

Nie jestem pewien, dlaczego mówisz, że użytkownicy AMQP są dużymi korporacjami typu enterprise. Ponad połowa naszych klientów znajduje się w przestrzeni "internetowej", od wielkich po małe firmy. Z RabbitMQ powstało wiele gier, systemów bukmacherskich, systemów czatowych, systemów typu twittery oraz INFRA-cloud computing. Istnieją nawet aplikacje na telefony komórkowe. Obiegi pracy to tylko jeden z wielu przypadków użycia.

Staramy się track of what is going on here:

Http://www.rabbitmq.com/how.html (upewnij się, że przejdziesz do listy przypadków użycia na del.icio.us też!)

Proszę spojrzeć. Jesteśmy tu, aby pomóc. Napisz do nas na adres [email protected] lub uderz mnie na Twitterze (@monadic).

 5
Author: alexis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 16:48:05

FWIW, dla przypadków, w których wyniki pośrednie nie są ważne (np. informacje o pozycjonowaniu) Qpid posiada "kolejkę ostatniej wartości", która może dostarczyć Subskrybentowi tylko ostatnią wartość.

 3
Author: Steve Huston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 17:37:43

Moje doświadczenie było z nie-otwartą alternatywą, BizTalk. Najbardziej bolesną lekcją, jaką wyciągnęliśmy, jest to, że te złożone systemy nie są szybkie. A jak się domyśliłeś z wymagań sprzętowych, przekłada się to bezpośrednio na znaczne koszty.

Z tego powodu, nawet nie zbliżaj się do XML dla podstawowych interfejsów. Twój klaster serwerów będzie parsował 2 miliony wiadomości na sekundę. To może być 2-20 GB / s XML! Jednak większość wiadomości będzie za kilka kolejek, podczas gdy większość kolejek jest w fakt mały ruch.

Dlatego zaprojektuj swoją architekturę tak, aby łatwo było zacząć od serwerów kolejek COTS, a następnie przenieść każdą kolejkę (typ) do niestandardowego serwera kolejek, gdy zidentyfikowane zostanie wąskie gardło.

Również, z podobnych powodów, nie zakładaj, że architektura kolejki komunikatów jest najlepsza dla wszystkich potrzeb związanych z komunikacją, jakie ma Twoja aplikacja. Weźmy przykład "lokalizacja obiektu w instancji". Jest to klasyczny przypadek, w którym nie chcesz gwarantowanego dostarczania wiadomości. Na powodem, dla którego musisz udostępnić te informacje, jest to, że zmieniają się one cały czas. Jeśli więc wiadomość zostanie utracona, nie chcesz tracić czasu na jej odzyskanie. Wyślesz tylko starą lokalizację dotkniętej istoty. Zamiast tego chcesz wysłać bieżącą lokalizację tego obiektu. Pod względem technologicznym oznacza to, że chcesz UDP, a nie TCP i Niestandardowy mechanizm odzyskiwania strat.

 2
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-18 14:38:26