Treści na tej stronie zostały przetłumaczone przy użyciu sztucznej inteligencji (AI) lub technologii tłumaczenia maszynowego i mogą zawierać błędy.

Skip to content

Zapewnienie niezawodności platformy na dużą skalę

Prowadzenie dowolnej skalowalnej platformy rozproszonej wymaga zaangażowania w zapewnienie niezawodności, aby klienci mieli to, czego potrzebują, kiedy tego potrzebują. Zależności mogą być dość skomplikowane, zwłaszcza w przypadku platformy tak dużej jak Roblox. Tworzenie niezawodnych usług oznacza, że niezależnie od złożoności i statusu zależności, dana usługa nie zostanie przerwana (tj. będzie wysoce dostępna), będzie działać bez błędów (tj. będzie wysokiej jakości) i bez usterek (tj. będzie odporna na awarie).

Dlaczego niezawodność ma znaczenie

Nasz zespół ds. tożsamości kont dąży do osiągnięcia wyższej niezawodności, ponieważ stworzone przez nas usługi zgodności są podstawowymi komponentami platformy. Naruszenie zgodności może mieć poważne konsekwencje. Koszt zablokowania naturalnego działania Roblox jest bardzo wysoki, a przywrócenie działania po awarii wymaga dodatkowych zasobów i osłabia komfort użytkowania.

Typowe podejście do niezawodności koncentruje się przede wszystkim na dostępności, ale w niektórych przypadkach terminy te są mieszane i nadużywane. Większość pomiarów dostępności polega jedynie na ocenie, czy usługi działają, podczas gdy aspekty takie jak odporność na partycjonowanie i spójność są czasami pomijane lub niezrozumiałe. 

Zgodnie z twierdzeniem CAP każdy system rozproszony może zagwarantować tylko dwa z tych trzech aspektów, więc nasze usługi zapewniające zgodność z przepisami poświęcają część spójności, aby zapewnić wysoką dostępność i odporność na partycjonowanie. Niemniej jednak nasze usługi poświęciły niewiele i znalazły mechanizmy pozwalające osiągnąć dobrą spójność przy rozsądnych zmianach architektonicznych, które wyjaśniono poniżej.

Proces osiągania wyższej niezawodności ma charakter iteracyjny, a ścisłe pomiary idą w parze z ciągłą pracą mającą na celu zapobieganie, wykrywanie i naprawianie usterek, zanim dojdzie do incydentów. Nasz zespół dostrzegł dużą wartość w następujących praktykach:

  • Właściwe pomiary – zapewnienie pełnej obserwowalności w zakresie tego, w jaki sposób jakość jest dostarczana klientom oraz w jaki sposób zależności zapewniają nam jakość.
  • Proaktywne przewidywanie – przeprowadzanie działań takich jak przeglądy architektury i oceny ryzyka związanego z zależnościami.
  • Priorytetowe traktowanie korekt – zwracanie większej uwagi na rozwiązywanie zgłoszeń dotyczących incydentów w odniesieniu do usługi i zależności powiązanych z naszą usługą.

Budowanie wyższej niezawodności wymaga kultury jakości. Nasz zespół już wcześniej inwestował w rozwój oparty na wydajności i wie, że sukces procesu zależy od jego wdrożenia. Zespół w pełni przyjął ten proces i zastosował te praktyki jako standard. Poniższy diagram przedstawia elementy tego procesu:

Siła właściwego pomiaru

Zanim zagłębimy się w temat wskaźników, należy krótko wyjaśnić kwestię pomiarów poziomu usług.

  • SLO (cel poziomu usług) to cel niezawodności, do którego dąży nasz zespół (np. 99,999%).
  • SLI (Service Level Indicator) to osiągnięta niezawodność w danym przedziale czasowym (np. 99,975% w lutym ubiegłego roku).
  • SLA (Service Level Agreement) to uzgodniony poziom niezawodności, który ma być zapewniony i którego oczekują nasi klienci w danym przedziale czasowym (np. 99,99% w ciągu tygodnia).

SLI powinien odzwierciedlać dostępność (brak nieobsłużonych lub brakujących odpowiedzi), tolerancję na awarie (brak błędów usługi) oraz osiągniętą jakość (brak nieoczekiwanych błędów). Dlatego zdefiniowaliśmy nasz SLI jako „wskaźnik sukcesu” pomiaru udanych odpowiedzi w stosunku do całkowitej liczby żądań wysłanych do usługi. Udane odpowiedzi to te żądania, które zostały wysłane na czas i w odpowiedniej formie, co oznacza, że nie wystąpiły żadne błędy łączności, usługi ani nieoczekiwane błędy.

Ten wskaźnik SLI lub wskaźnik sukcesu jest gromadzony z punktu widzenia konsumentów (tj. klientów). Celem jest pomiar rzeczywistych wrażeń użytkownika od początku do końca, dostarczanych naszym konsumentom, abyśmy mieli pewność, że umowy SLA są realizowane. Niezastosowanie się do tego stworzyłoby fałszywe poczucie niezawodności, ignorujące wszelkie obawy dotyczące infrastruktury niezbędnej do połączenia się z naszymi klientami. Podobnie jak w przypadku wskaźnika SLI dla konsumentów, gromadzimy wskaźnik SLI zależności, aby śledzić wszelkie potencjalne ryzyko. W praktyce wszystkie SLA zależności powinny być zgodne z SLA usługi i istnieje między nimi bezpośrednia zależność. Awaria jednego oznacza awarię wszystkich. Śledzimy również i raportujemy wskaźniki z samej usługi (tj. serwera), ale nie jest to praktyczne źródło wysokiej niezawodności.

Oprócz wskaźników SLI każda kompilacja gromadzi wskaźniki jakości, które są raportowane przez nasz proces CI. Praktyka ta pomaga w ścisłym egzekwowaniu bram jakości (tj. pokrycia kodu) oraz raportowaniu innych istotnych wskaźników, takich jak zgodność ze standardami kodowania i statyczna analiza kodu. Temat ten został wcześniej omówiony w innym artykule, Tworzenie mikrousług opartych na wydajności. Rzetelne przestrzeganie standardów jakości ma znaczenie, gdy mowa o niezawodności, ponieważ im więcej inwestujemy w osiąganie doskonałych wyników, tym większą mamy pewność, że system nie zawiedzie w niekorzystnych warunkach.

Nasz zespół ma dwa pulpity nawigacyjne. Jeden zapewnia pełny wgląd zarówno w wskaźniki SLI konsumentów, jak i wskaźniki SLI zależności. Drugi pokazuje wszystkie wskaźniki jakości. Pracujemy nad połączeniem wszystkiego w jednym pulpicie nawigacyjnym, tak aby wszystkie aspekty, na których nam zależy, były skonsolidowane i gotowe do raportowania w dowolnym przedziale czasowym.

Przewidywanie awarii

Przeprowadzanie przeglądów architektury jest fundamentalną częścią zapewnienia niezawodności. Najpierw ustalamy, czy istnieje redundancja i czy usługa ma środki, aby przetrwać awarię zależności. Oprócz typowych rozwiązań replikacyjnych większość naszych usług wykorzystywała ulepszone techniki podwójnego uzupełniania pamięci podręcznej, podwójne strategie odzyskiwania (takie jak lokalne kolejki przełączania awaryjnego) lub strategie na wypadek utraty danych (takie jak obsługa transakcji). Tematy te są na tyle obszerne, że zasługują na osobny wpis na blogu, ale ostatecznie najlepszą rekomendacją jest wdrażanie rozwiązań uwzględniających scenariusze awaryjne i minimalizujących spadek wydajności.

Kolejnym ważnym aspektem, który należy przewidzieć, jest wszystko, co może poprawić łączność. Oznacza to agresywne dążenie do niskiego opóźnienia dla klientów oraz przygotowanie ich na bardzo duży ruch przy użyciu technik kontroli pamięci podręcznej, sidecarów oraz wydajnych zasad dotyczących limitów czasu, wyłączników obwodów i ponownych prób. Praktyki te mają zastosowanie do wszystkich klientów, w tym pamięci podręcznych, magazynów, kolejek i współzależnych klientów w HTTP i gRPC. Oznacza to również poprawę sygnałów o dobrym stanie usług oraz zrozumienie, że kontrole stanu odgrywają ważną rolę we wszystkich systemach orkiestracji kontenerów. Większość naszych usług generuje lepsze sygnały o pogorszeniu stanu w ramach informacji zwrotnej z kontroli stanu i weryfikuje, czy wszystkie krytyczne komponenty działają, zanim wyśle sygnały o dobrym stanie.

Podział usług na elementy krytyczne i niekrytyczne okazał się przydatny w skupieniu się na funkcjonalnościach, które mają największe znaczenie. Kiedyś mieliśmy punkty końcowe przeznaczone wyłącznie dla administratorów w tej samej usłudze i chociaż nie były one często używane, miały wpływ na ogólne wskaźniki opóźnień. Przeniesienie ich do osobnej usługi wpłynęło pozytywnie na wszystkie wskaźniki.

Ocena ryzyka zależności jest ważnym narzędziem do identyfikacji potencjalnych problemów z zależnościami. Oznacza to, że identyfikujemy zależności o niskim SLI i prosimy o dostosowanie SLA. Zależności te wymagają szczególnej uwagi podczas etapów integracji, więc poświęcamy dodatkowy czas na benchmarki i testy, aby sprawdzić, czy nowe zależności są wystarczająco dojrzałe dla naszych planów. Dobrym przykładem jest wczesne wdrożenie usługi Roblox Storage-as-a-Service. Integracja z tą usługą wymagała zgłaszania błędów i okresowych spotkań synchronizacyjnych w celu przekazania ustaleń i informacji zwrotnych. Cała ta praca jest oznaczona tagiem „niezawodność”, dzięki czemu możemy szybko zidentyfikować jej źródło i priorytety. Charakterystyka była przeprowadzana często, aż uzyskaliśmy pewność, że nowa zależność jest dla nas gotowa. Ta dodatkowa praca pomogła doprowadzić zależność do wymaganego poziomu niezawodności, którego oczekujemy, działając wspólnie na rzecz wspólnego celu.

Wprowadź porządek w chaos

Incydenty nigdy nie są pożądane. Jednak gdy już się zdarzają, można zebrać z nich istotne informacje i wyciągnąć wnioski, aby zwiększyć niezawodność. Nasz zespół posiada raport incydentów, który wykracza poza typowy raport obejmujący całą firmę, dzięki czemu skupiamy się na wszystkich incydentach, niezależnie od skali ich wpływu. Wskazujemy przyczynę źródłową i ustalamy priorytety wszystkich działań, aby ją wyeliminować w przyszłości. W ramach tego raportu angażujemy inne zespoły do naprawy incydentów zależności o wysokim priorytecie, śledzimy właściwe rozwiązania, analizujemy sytuację i szukamy wzorców, które mogą mieć zastosowanie w naszym przypadku.

Zespół sporządza miesięczny raport niezawodności dla każdej usługi, który zawiera wszystkie wskaźniki SLI wyjaśnione tutaj, wszystkie zgłoszenia otwarte z powodu niezawodności oraz wszelkie możliwe incydenty związane z daną usługą. Jesteśmy tak przyzwyczajeni do generowania tych raportów, że kolejnym naturalnym krokiem jest automatyzacja ich wyodrębniania. Wykonywanie tej okresowej czynności jest ważne i przypomina nam, że niezawodność jest stale monitorowana i brana pod uwagę w naszym rozwoju.

Nasze narzędzia obejmują niestandardowe wskaźniki i ulepszone alerty, dzięki czemu jesteśmy powiadamiani jak najszybciej, gdy pojawiają się znane i spodziewane problemy. Wszystkie alerty, w tym fałszywe alarmy, są sprawdzane co tydzień. W tym momencie ważne jest dopracowanie całej dokumentacji, aby nasi klienci wiedzieli, czego mogą się spodziewać, gdy uruchamiają się alerty i pojawiają się błędy, a wtedy wszyscy wiedzą, co robić (np. procedury i wytyczne dotyczące integracji są często aktualizowane i dostosowywane).

Ostatecznie przyjęcie kultury jakości jest najważniejszym i decydującym czynnikiem w osiąganiu wyższej niezawodności. Widzimy, jak te praktyki stosowane w naszej codziennej pracy już przynoszą efekty. Nasz zespół ma obsesję na punkcie niezawodności i jest to nasze najważniejsze osiągnięcie. Zwiększyliśmy naszą świadomość wpływu, jaki mogą mieć potencjalne usterki, oraz tego, kiedy mogą się pojawić. Usługi, w których wdrożono te praktyki, konsekwentnie osiągają swoje SLO i SLA. Raporty dotyczące niezawodności, które pomagają nam śledzić wszystkie nasze działania, są świadectwem pracy naszego zespołu i stanowią bezcenne lekcje, które mogą posłużyć innym zespołom. W ten sposób kultura niezawodności wpływa na wszystkie elementy naszej platformy.

Droga do większej niezawodności nie jest łatwa, ale jest konieczna, jeśli chcesz zbudować zaufaną platformę, która na nowo definiuje sposób, w jaki ludzie się spotykają.

Alberto jest głównym inżynierem oprogramowania w zespole Account Identity w Roblox. Od dawna działa w branży gier, ma na koncie wiele tytułów gier AAA i platform mediów społecznościowych, ze szczególnym naciskiem na wysoce skalowalne architektury. Obecnie pomaga Roblox osiągnąć wzrost i dojrzałość poprzez stosowanie najlepszych praktyk programistycznych.