28 sierpnia 2019 roku o 16:45 czasu brytyjskiego w kolejkach do czterech najbardziej obleganych europejskich realmów World of Warcraft Classic stało łącznie 41 313 osób: Firemaw (11 456), Gehennas (10 065), Golemagg (9 953) i Shazzrah (9 839), z szacowanym czasem oczekiwania od 110 do 407 minut. Pomiar pochodził z publicznego trackera Wowhead: jest to odczyt z zewnątrz, a nie oficjalna statystyka Blizzarda.
Ta kolejka nie była awarią. Była jedynym elementem premiery, który zadziałał dokładnie tak, jak go zaprojektowano. Awaria wyglądałaby inaczej:
✪ Gracz wchodzi do świata, po czym jego postać cofa się o kilkanaście metrów
✪ Ekwipunek wraca do stanu sprzed minuty
✪ Dom aukcyjny odmawia przyjęcia oferty
Różnica między jednym a drugim rozstrzyga się w warstwie, której gracz nigdy nie widzi: w bazie danych przechowującej stan postaci.
Kliknięcie „zaloguj” uruchamia sekwencję, w której renderowanie świata jest ostatnim i najtańszym krokiem. Wcześniej system musi:
1. Uwierzytelnić konto
2. Pobrać listę postaci
3. Odczytać pozycję, ekwipunek, walutę, przypisania klawiszy i stan zadań
4. Zacząć to wszystko natychmiast zapisywać z powrotem
Każda z tych operacji kończy się w tej samej bazie danych, a przy premierze przychodzą one ścianą, a nie strumieniem. Kolejka jest celową odpowiedzią na tę ścianę. Serwer przyjmujący więcej żądań, niż jest w stanie obsłużyć, wchodzi w awarię kaskadową (narastającą w czasie na skutek dodatniego sprzężenia zwrotnego). Zalecenie jest tu odwrotne do intuicji: kolejka powinna być krótka względem puli wątków (najlepiej do połowy jej długości). Dzięki temu serwer odrzuca nadmiarowe żądania wcześnie, zamiast przyjmować wszystkie i nie obsłużyć żadnego.
Studia najczęściej reagują na premierę dostawieniem serwerów gry. To działa dla wszystkiego, co da się policzyć osobno, i nie działa dla niczego, co musi zostać zapisane wspólnie. Dziesięć dodatkowych instancji świata to dziesięć dodatkowych zestawów połączeń do tej samej bazy: więcej równoległych zapisów, więcej rywalizacji o te same wiersze i szybsze zapchanie wąskiego gardła.
Tę ścianę połączeń da się policzyć z góry. Według dokumentacji MySQL serwer domyślnie przyjmuje 151 jednoczesnych połączeń, a PostgreSQL zwykle 100. Dlatego między serwery gry a bazę wstawia się pulę połączeń (connection pooling): PgBouncer przed PostgreSQL, ProxySQL przed MySQL. Setki procesów świata dzielą wtedy kilkadziesiąt rzeczywistych połączeń.
Drugą warstwą jest pamięć podręczna przed bazą, na przykład Valkey lub Redis. Trafiają do niej odczyty listy postaci czy profilu, a w wariancie write-behind także część zapisów, które spływają do bazy partiami. Ceną jest ryzyko utraty ostatnich zmian przy awarii cache'u, więc write-behind stosuje się tylko tam, gdzie taka strata nie boli.
Pojęcie headroom oznacza tutaj zapas mocy trzymany ponad zwykłym obciążeniem: wolne rdzenie CPU, wolne operacje wejścia/wyjścia (IOPS), wolne sloty połączeń i niewykorzystana przepustowość zapisu. Nie chodzi o wolne miejsce na dysku. Baza bez zapasu wygląda przy normalnym ruchu identycznie jak baza z zapasem. Różnica ujawnia się w godzinie premiery i wtedy nie da się jej już nadrobić. Najbardziej wrażliwe są punkty, w których wielu graczy pisze po tym samym wierszu jednocześnie:
✪ Dom aukcyjny: każda oferta na popularny przedmiot dotyka tego samego zestawu wierszy.
✪ Liczniki zdarzeń światowych: wspólny stan dla całego serwera.
✪ Kolejki do instancji: jednoczesny dostęp do pierwszych lochów.
Blokada na poziomie wiersza (row-level locking) szereguje oferty w domu aukcyjnym, ale przy tysiącach licytujących sama kolejka blokad staje się wąskim gardłem. Alternatywą jest współbieżność optymistyczna: oferta zapisuje się tylko wtedy, gdy wersja wiersza się nie zmieniła, a przegrany ponawia próbę. Działa to dobrze, dopóki konflikty są rzadkie, czyli nie przy przedmiocie, o który walczy pół serwera.
W pomiarze z 2019 roku 41 313 osób nie stało w jednej kolejce, tylko w czterech. To nie jest szczegół organizacyjny, tylko architektura: realm jest w praktyce shardem, czyli osobnym wycinkiem bazy stanu gracza z własnym limitem pojemności. Gra z milionami kont nie musi mieć bazy obsługującej milion kont naraz, o ile podział na realmy zaplanowano przed premierą.
Zaplanowanie tego podziału zbyt późno bywa kosztowne. Riot Games przez lata budował serwery ręcznie, a każdy nowy serwer trafiał na własny VLAN z ręcznie pisanymi regułami routingu i zaporą. Skala League of Legends (start w październiku 2009 r.) wymusiła całkowitą przebudowę architektury.
Kolejka ma własną pojemność i sama bywa pierwszą rzeczą, która pęka. Przy premierze dodatku Endwalker do Final Fantasy XIV (grudzień 2021 r.) błąd 2002 pojawiał się wtedy, gdy w kolejce logowania do jednego centrum danych czekało ponad 17 000 osób. Gracz odbierał to jako wyrzucenie z kolejki i logował się ponownie. To jest dodatnie sprzężenie zwrotne w praktyce: im dłużej stoi kolejka, tym więcej ponowień, a im więcej ponowień, tym dłużej stoi kolejka. Trzy techniki z warstwy serwerowej mają tu większe znaczenie niż moc sprzętu:
1. Ponawianie z losowym opóźnieniem wykładniczym (exponential backoff with jitter): zapobiega jednoczesnemu uderzeniu wszystkich klientów po błędzie.
2. Budżet ponowień (retry budget): po przekroczeniu progu proces przestaje próbować i zwraca jawny błąd.
3. Shedding (odrzucanie ruchu): świadome odrzucanie części żądań, zanim system ulegnie przeciążeniu.
W usłudze logowania tę samą rolę pełni kontrola dopuszczenia (admission control): limit wpuszczeń na sekundę i ograniczanie liczby prób z jednego konta lub adresu (rate limiting). Wartości tych limitów nie zgaduje się, tylko ustala w testach obciążeniowych przed premierą, odtwarzających falę logowań, a nie średni ruch z bety.
Nie wszystko, co gra pokazuje, musi być prawdą w tej samej sekundzie. Ranking, historia rynku, statystyki sezonu czy profil postaci na stronie WWW nie rozstrzygają o tym, co gracz ma w plecaku. Takie odczyty przenosi się na repliki: wszystkie zapisy i aktualizacje trafiają do serwera źródłowego (Primary), natomiast odczyty można skalować wszerz na wiele replik.
Zapotrzebowanie w tygodniu premiery bywa wielokrotnie większe niż w trzecim miesiącu życia gry. Zamiast kupować fizyczny sprzęt pod jeden weekend, sięga się po bazy danych w chmurze: wynajmuje się Cloud Database jako usługę zarządzaną (dostawca odpowiada za instalację, kopie zapasowe, skalowalność i SLA w regionach 1-AZ lub 3-AZ z rozliczeniem godzinowym). Co ta architektura naprawia, a czego nie:
✪ Co naprawia: Repliki zwiększają przepustowość odczytu i pozwalają bezproblemowo skalować ruch podglądu/statystyk.
✪ Czego NIE naprawia: Zapisów. Premiera jest obciążeniem zapisowym. Kod wykonujący kilkanaście niepotrzebnych zapisów przy zalogowaniu będzie się dławił na dowolnie drogiej infrastrukturze.
✪ Ryzyko asynchronii: Replikacja jest domyślnie asynchroniczna. Replika awansowana na źródło może nie mieć ostatnich transakcji przyjętych przez oryginał.
Jak kosztowne bywa to ryzyko, pokazuje analiza awarii GitHuba z 21 października 2018 roku. Łączność między centrami danych wróciła po 43 sekundach, ale po przełączeniu źródła na drugie wybrzeże USA oba klastry MySQL miały zapisy, których brakowało po drugiej stronie. Serwis działał w stanie obniżonej sprawności przez 24 godziny i 11 minut. W dniu premiery obserwuje się więc trzy liczby: opóźnienie replikacji (replication lag), opóźnienie p99 zapytań i IOPS na serwerze źródłowym. Średnie wyglądają dobrze do ostatniej chwili, ogon rozkładu nie.
Z zewnątrz gracz widzi jedną liczbę, ale jej zachowanie mówi, o którą warstwę potknęła się premiera.
| Co widzi gracz | Co to zwykle oznacza | Gdzie jest wąskie gardło |
|---|---|---|
| Kolejka stoi długo, ale numer spada równomiernie | Limit wpuszczeń działa zgodnie z projektem | Celowy hamulec przed bazą danych |
| Numer nie zmienia się, po czym wyskakuje błąd logowania | Przepełniła się sama kolejka, nie świat gry | Usługa logowania i kolejkowania |
| Wejście się udaje, ale postać cofa się i ekwipunek wraca | Zapisy stanu nie nadążają za ruchem | Warstwa zapisu w bazie danych |
| Ranking i historia rynku pokazują nieaktualne dane | Odczyt idzie z repliki z opóźnieniem | Replikacja, zwykle asynchroniczna |
Pierwszy wiersz opisuje studio, które wie, ile jego baza wytrzyma. Trzeci opisuje studio, które się tego dowiaduje w dniu premiery. Kolejka na 40 tysięcy osób jest jedyną liczbą całej premiery, którą studio ustawia samo. Zainteresowania graczy nikt nie planuje, ruchu nie da się zamówić, a terminu nie da się przesunąć w nieskończoność.
Wybiera się natomiast moment, w którym ruch zostaje zatrzymany, i wybiera się go tygodnie wcześniej, projektując podział na realmy, zapas mocy i to, co w ogóle trafia do zapisu. Kolejka jest tylko miejscem, w którym ta decyzja staje się widoczna dla wszystkich naraz.


Portal MMO Team
Nasza misja to łączenie pasji do gier, przełomowych technologii i zarabiania online z trendami w mediach, aby dostarczać Wam najbardziej wartościowe informacje, analizy, rankingi i zestawienia.
Rodzaj: Fantasy MMORPG
Grafika: 3D • Premiera: 2019 • PvP: Tak • PvE: Tak •
Koszt: Darmowa ✪ Mikropłatności • Platformy: PC ✪ Windows • Wersja PL: Tak •
Producent: NCsoft • Wydawca: Innova Co. SARL • Tematyka: MMORPG z dynamiczną walką ✪ Rozwijaj postać i odkrywaj świat
| Ocena | Premiera | |
| 6. Metin1 | 7.8 | 2000 |
| 7. Ragnarok Online 2: Legend of the Second | 7.8 | 2012 |
| 8. Hero Wars | 7.8 | 2016 |
| 9. Lineage 2 Classic | 7.8 | 2018 |
| 10. Lineage 2 Eve | 7.8 | 2023 |