
Netflix to lider rynku telewizji internetowej – firma, która stworzyła i aktywnie rozwija ten segment. Netflix jest znany nie tylko z rozbudowanego katalogu filmów i seriali dostępnych z prawie każdego zakątka świata i na każdym urządzeniu z wyświetlaczem, ale także z niezawodnej infrastruktury i unikalnej kultury inżynieryjnej.
Przykład podejścia Netflix do rozwijania i wspierania złożonych systemów został zaprezentowany na DevOops 2019. – dyrektor ds. rozwoju w Netflix. Absolwent Wydziału Matematyki, Informatyki i Mechaniki Uniwersytetu Nizhegorodzkiego im. Lobaczewskiego, Siergiej jest jednym z pierwszych inżynierów w Open Connect – zespole CDN w Netflix. Zbudował systemy monitorowania i analizy danych wideo, uruchomił popularną usługę do oceny prędkości połączenia internetowego FAST.com i przez ostatnie kilka lat pracował nad optymalizacją zapytań internetowych, aby aplikacja Netflix działała jak najszybciej dla użytkowników.
Prezentacja zdobyła najlepsze opinie od uczestników konferencji, a my przygotowaliśmy dla was wersję tekstową.

W prezentacji Siergiej szczegółowo omówił
- czynniki wpływające na opóźnienia w zapytaniach internetowych między klientem a serwerem;
- jak te opóźnienia zredukować;
- jak projektować, utrzymywać i monitorować systemy odporne na błędy;
- jak osiągać rezultaty w krótkim czasie przy minimalnym ryzyku dla biznesu;
- jak analizować wyniki i uczyć się na błędach.
Odpowiedzi na te pytania są ważne nie tylko dla osób pracujących w dużych korporacjach.
Przedstawione zasady i techniki powinien znać i stosować każdy, kto rozwija i wspiera produkty internetowe.
Dalsza część to relacja z punktu widzenia mówcy.
Znaczenie prędkości internetu
Prędkość zapytań internetowych ma bezpośredni związek z biznesem. Rozważmy obszar zakupów: firma Amazon w 2009 roku że opóźnienie o 100 ms prowadzi do utraty 1% sprzedaży.
Coraz więcej jest urządzeń mobilnych, a za nimi mobilnych stron i aplikacji. Jeśli twoja strona ładuje się dłużej niż 3 sekundy, tracisz około połowy użytkowników. Od Google bierze pod uwagę prędkość ładowania twojej strony w wynikach wyszukiwania: im szybsza strona, tym wyższa jej pozycja w Google.
Prędkość połączenia jest również ważna w instytucjach finansowych, gdzie opóźnienia są krytyczne. W 2015 roku firma Hibernia Networks kabel do łączenia Nowego Jorku z Londynem za 400 mln dolarów, aby zmniejszyć opóźnienie między miastami o 6 ms. Wyobraź sobie, 66 mln dolarów za zmniejszenie opóźnienia o 1 ms!
Zgodnie z , prędkość połączenia powyżej 5 Mbit/s przestaje bezpośrednio wpływać na czas ładowania typowej strony internetowej. Niemniej jednak między opóźnieniem połączenia a prędkością ładowania strony istnieje liniowa zależność:

Jednak Netflix to nie typowy produkt. Wpływ opóźnienia i prędkości na użytkownika to obszar intensywnych analiz i rozwoju. Istnieje ładowanie aplikacji oraz wybór treści, które zależą od opóźnienia, ale ładowanie elementów statycznych i strumieniowanie również zależą od prędkości połączenia. Analiza i optymalizacja kluczowych czynników wpływających na jakość usługi dla użytkowników to aktywne pole działalności kilku zespołów w Netflix. Jednym z zadań jest zmniejszenie opóźnienia zapytań między urządzeniami Netflix a infrastrukturą chmurową.
W tym raporcie skoncentrujemy się na zmniejszeniu opóźnień (latency) na przykładzie infrastruktury Netflix. Z praktycznego punktu widzenia zbadamy, jak podchodzić do procesów projektowania, rozwoju i operowania złożonymi systemami rozproszonymi, aby skupić się na innowacjach i wynikach, a nie na diagnozowaniu problemów operacyjnych i usterek.
Wewnątrz Netflix
Tysiące różnych urządzeń wspierają aplikacje Netflix. Ich rozwój jest realizowany przez cztery różne zespoły, które tworzą oddzielne wersje klienta dla Androida, iOS, TV i przeglądarek internetowych. Wkładamy ogromny wysiłek w poprawę i personalizację interfejsu użytkownika. W tym celu równolegle uruchamiamy setki testów A/B.
Personalizacja jest wspierana dzięki setkom mikroserwisów w chmurze AWS, które dostarczają spersonalizowane dane dla użytkowników, zarządzają zapytaniami, zapewniają telemetrię, Big Data i transkodowanie. Wizualizacja ruchu wygląda następująco:
Po lewej stronie znajduje się punkt wejścia, a następnie ruch jest rozdzielany między kilkaset mikroserwisów, które są wspierane przez różne zespoły backendowe.
Kolejnym ważnym komponentem naszej infrastruktury jest Open Connect CDN, który dostarcza do końcowego użytkownika statyczne treści — wideo, obrazy, kod dla klientów itp. CDN znajduje się na niestandardowych serwerach (OCA — Open Connect Appliance). Wewnątrz znajdują się macierze dysków SSD i HDD zarządzane przez zoptymalizowany system FreeBSD, z NGINX oraz zestawem usług. Projektujemy i optymalizujemy komponenty sprzętowe i programowe w taki sposób, aby serwer CDN mógł przesyłać jak najwięcej danych do użytkowników.
„Ściana” z tych serwerów w punkcie wymiany ruchu internetowego (Internet eXchange — IX) wygląda następująco:

Internet Exchange umożliwia dostawcom internetu i dostawcom treści „połączenie się” ze sobą w celu bardziej bezpośredniej wymiany danych w internecie. Na całym świecie jest około 70-80 punktów Internet Exchange, w których zainstalowane są nasze serwery, a my zajmujemy się ich instalacją i konserwacją samodzielnie:

Oprócz tego dostarczamy również serwery bezpośrednio dostawcom internetu, którzy instalują je w swojej sieci, poprawiając lokalizację ruchu Netflix i jakość streamingu dla użytkowników:

Zestaw usług AWS odpowiada za kierowanie zapytań wideo od klientów do serwerów CDN, a także konfigurowanie samych serwerów — aktualizację treści, kodu programowego, ustawień itp. W tym celu zbudowaliśmy również sieć backbone, która łączy serwery w punktach Internet Exchange z AWS. Sieć backbone to globalna sieć kabli światłowodowych i routerów, które możemy projektować i konfigurować w zależności od naszych potrzeb.
Według , nasza infrastruktura CDN dostarcza w godzinach szczytu około ⅛ światowego ruchu internetowego i ⅓ ruchu w Ameryce Północnej, gdzie Netflix działa najdłużej. Imponujące liczby, ale dla mnie jednym z najwspanialszych osiągnięć jest to, że cały system CDN jest opracowywany i utrzymywany przez zespół liczący mniej niż 150 osób.
Początkowo infrastruktura CDN została zaprojektowana do dostarczania danych wideo. Jednak z biegiem czasu zrozumieliśmy, że możemy ją wykorzystać również do optymalizacji dynamicznych zapytań od klientów w chmurze AWS.
O przyspieszaniu internetu
Dzisiaj Netflix ma trzy regiony AWS, a opóźnienie żądań w chmurze będzie zależało od tego, jak daleko klient znajduje się od najbliższego regionu. Posiadamy również wiele serwerów CDN, które są wykorzystywane do dostarczania statycznych treści. Czy można jakoś wykorzystać tę infrastrukturę do przyspieszenia dynamicznych żądań? Niestety, nie można tych żądań buforować — API są spersonalizowane, a każdy wynik jest unikalny.
Utwórzmy proxy na serwerze CDN i zacznijmy przepuszczać przez niego ruch. Czy to będzie szybsze?
Sprzęt
Przypomnijmy sobie, jak działają protokoły sieciowe. Dzisiaj większość ruchu w internecie korzysta z HTTPs, który opiera się na protokołach niższego poziomu TCP i TLS. Aby klient połączył się z serwerem, przeprowadza handshake, a do nawiązania zabezpieczonego połączenia klient musi wymienić wiadomości z serwerem trzy razy i jeszcze co najmniej raz, aby przesłać dane. Przy opóźnieniu jednego wymiany (RTT) wynoszącym 100 ms potrzeba 400 ms, aby otrzymać pierwszy bit danych:

Jeśli certyfikaty zostaną umieszczone na serwerze CDN, czas „uścisku dłoni” między klientem a serwerem można znacznie skrócić, jeśli CDN znajduje się bliżej. Załóżmy, że opóźnienie do serwera CDN wynosi 30 ms. W takim przypadku uzyskanie pierwszego bitu zajmie już 220 ms:

Jednak korzyści na tym się nie kończą. Po nawiązaniu połączenia TCP zwiększa congestion window (liczba informacji, którą może przesyłać przez to połączenie równolegle). Jeśli utracony zostanie pakiet danych, klasyczne realizacje protokołu TCP (takie jak TCP New Reno) zmniejszają otwarte „okno” o połowę. Wzrost congestion window oraz szybkość jego odbudowy po utracie znów zależy od opóźnienia (RTT) do serwera. Jeśli to połączenie prowadzi tylko do serwera CDN, odbudowa będzie szybsza. Przy tym utrata pakietów to standardowe zjawisko, szczególnie w sieciach bezprzewodowych.
Przepustowość internetu może maleć, szczególnie w godzinach szczytu z powodu ruchu od użytkowników, co może prowadzić do "korków". W internecie nie ma sposobu, aby nadać priorytet jednym zapytaniom w stosunku do innych. Na przykład, nadać priorytet małym, opóźnieniowym zapytaniom w porównaniu do "ciężkich" strumieni danych, które obciążają sieć. Jednak w naszym przypadku posiadanie własnej sieci backbone pozwala na to na części trasy zapytania – między CDN a chmurą, i możemy ją całkowicie skonfigurować. Można tak ustawić, aby małe i spóźnione pakiety były priorytetowe, a duże strumienie danych przeszły nieco później. Im bliżej CDN do klienta, tym większa efektywność.
Na opóźnienie wpływają również protokoły aplikacji (OSI Level 7). Nowe protokoły, takie jak HTTP/2, pozwalają na optymalizację wydajności równoległych zapytań. Jednak mamy klientów Netflixa z starymi urządzeniami, które nie obsługują nowych protokołów. Nie wszystkich klientów można zaktualizować lub optymalnie skonfigurować. Przy tym mamy pełną kontrolę między CDN a chmurą oraz możliwość korzystania z nowych, optymalnych protokołów i ustawień. Nieefektywna część ze starymi protokołami działa tylko między klientem a serwerem CDN. Co więcej, możemy multiplexować zapytania na już ustanowionym połączeniu między CDN a chmurą, poprawiając wykorzystanie połączenia na poziomie TCP.

Mierzymy
Mimo że teoria obiecuje poprawę, nie rzucamy się od razu na uruchomienie systemu w produkcji. Zamiast tego musimy najpierw udowodnić, że pomysł zadziała w praktyce. W tym celu musimy odpowiedzieć na kilka pytań:
- Szybkość: czy proxy będzie szybsze?
- Niezawodność: czy będzie się częściej psuć?
- Trudność: jak zintegrować z aplikacjami?
- Koszt: ile kosztuje wdrożenie dodatkowej infrastruktury?
Szczegółowo przyjrzyjmy się naszemu podejściu do oceny pierwszego punktu. Pozostałe będą analizowane w podobny sposób.
Aby przeanalizować szybkość zapytań, chcemy uzyskać dane dla wszystkich użytkowników, nie poświęcając dużo czasu na rozwój i nie psując produkcji. Istnieje kilka podejść, aby to osiągnąć:
- RUM, czyli pasywne mierzenie zapytań. Mierzymy czas realizacji bieżących zapytań od użytkowników i zapewniamy pełne pokrycie użytkowników. Wada — sygnał jest dość niestabilny z powodu wielu czynników, takich jak różne rozmiary zapytań, czas przetwarzania na serwerze i kliencie. Ponadto nie można przetestować nowej konfiguracji bez wpływu na produkcję.
- Testy laboratoryjne. Specjalne serwery i infrastruktura, które imitują klientów. Przy ich pomocy przeprowadzamy niezbędne testy. W ten sposób uzyskujemy pełną kontrolę nad wynikami pomiarów i wyraźny sygnał. Jednak nie ma pełnego pokrycia urządzeń i lokalizacji użytkowników (szczególnie w przypadku usług na całym świecie i wsparcia dla tysięcy modeli urządzeń).
Jak można połączyć zalety obu metod?
Nasz zespół znalazł rozwiązanie. Napisaliśmy mały fragment kodu — próbnik — który wbudowaliśmy w nasze aplikacje. Próbki pozwalają nam przeprowadzać w pełni kontrolowane testy sieciowe z naszych urządzeń. Działa to w następujący sposób:
- Niedługo po załadowaniu aplikacji i zakończeniu wstępnej aktywności uruchamiamy nasze próbki.
- Klient wysyła zapytanie do serwera i otrzymuje „przepis” testu. Przepis to lista adresów URL, do których należy wykonać zapytania HTTP(s). Oprócz tego przepis konfiguruje parametry zapytań: opóźnienia między zapytaniami, objętość żądanych danych, nagłówki HTTP(s), itp. Możemy równocześnie testować kilka różnych przepisów — podczas żądania konfiguracji losowo określamy, który przepis wydać.
- Czas uruchomienia próbki jest wybierany tak, aby nie kolidował z aktywnym używaniem zasobów sieciowych przez klienta. W zasadzie wybiera się czas, gdy klient nie jest aktywny.
- Po otrzymaniu przepisu klient wykonuje zapytania do każdego z adresów URL równolegle. Zapytanie do każdego z adresów może być powtarzane — tzw. „pulsacje”. Podczas pierwszej pulsacji mierzymy, ile czasu zajęło nawiązanie połączenia i pobranie danych. Podczas drugiej pulsacji mierzymy czas ładowania danych przez już nawiązane połączenie. Przed trzecią pulsacją możemy nałożyć opóźnienie i zmierzyć prędkość nawiązania ponownego połączenia itd.
Podczas testu mierzmy wszystkie parametry, które może uzyskać urządzenie:
- czas zapytania DNS;
- czas nawiązywania połączenia przez TCP;
- czas nawiązywania połączenia przez TLS;
- czas otrzymywania pierwszego bajtu danych;
- całkowity czas ładowania;
- status kodu rezultatu.
- Po zakończeniu wszystkich pulsów próbka ładuje wyniki wszystkich pomiarów do analizy.

Kluczowymi elementami są minimalna zależność od logiki po stronie klienta, przetwarzania danych po stronie serwera oraz pomiar równoległych zapytań. Dzięki temu zyskujemy możliwość izolowania i testowania wpływu różnych czynników na wydajność zapytań, wariując je w ramach jednego przepisu, i uzyskiwania wyników z rzeczywistych klientów.
Taka infrastruktura okazała się użyteczna nie tylko do analizy wydajności zapytań. Obecnie mamy 14 aktywnych przepisów, ponad 6000 prób na sekundę, zbierających dane z całego świata i z pełnym pokryciem urządzeń. Gdyby Netflix kupiłby taką usługę od zewnętrznych firm, kosztowałaby ona miliony dolarów rocznie, z o wiele gorszym pokryciem.
Sprawdzamy teorię w praktyce: prototyp
Z takim systemem uzyskaliśmy możliwość oceny efektywności proxy CDN na opóźnienie zapytań. Teraz trzeba:
- stworzyć prototyp proxy;
- umieścić prototyp na CDN;
- określić, jak kierować klientów do proxy na konkretnym serwerze CDN;
- porównać wydajność z zapytaniami do AWS bez proxy.
Zadanie — jak najszybciej ocenić efektywność proponowanego rozwiązania. Do realizacji prototypu wybraliśmy Go, dzięki dostępności dobrych bibliotek sieciowych. Na każdym serwerze CDN zainstalowaliśmy prototyp proxy jako statyczny plik binarny, aby zminimalizować zależności i uprościć integrację. W początkowej realizacji maksymalnie wykorzystaliśmy standardowe komponenty i niewielkie modyfikacje dla HTTP/2 connection pooling oraz request multiplexing.
Aby zrównoważyć obciążenie między regionami AWS, użyliśmy geograficznej bazy danych DNS, tej samej, która jest wykorzystywana do równoważenia klientów. Do wyboru serwera CDN dla klienta używamy TCP Anycast dla serwerów w Internet Exchange (IX). W tym przypadku używamy jednego adresu IP dla wszystkich serwerów CDN, a klient będzie kierowany do serwera CDN z najmniejszą liczbą skoków IP. Na serwerach CDN zainstalowanych u dostawców internetowych (ISP) nie mamy kontroli nad routerem w celu skonfigurowania TCP Anycast, dlatego stosujemy , na której klienci kierowani są do dostawców internetowych w celu streamingu wideo.
Mamy więc trzy typy tras dla żądania: do chmury przez otwarty internet, przez serwer CDN w IX lub przez serwer CDN zlokalizowany u dostawcy internetowego. Naszym celem jest zrozumienie, która trasa jest lepsza i jakie są korzyści z proxy w porównaniu do sposobu, w jaki zapytania są kierowane do produkcji. W tym celu korzystamy z systemu prób w następujący sposób:

Każda trasa staje się oddzielnym celem, a my patrzymy na uzyskany czas. Dla analizy łączymy wyniki proxy w jedną grupę (wybieramy najlepszy czas między proxy IX a proxy ISP) i porównujemy z czasem zapytań do chmury bez proxy:

Jak widać, wyniki były niejednoznaczne — w większości przypadków proxy zapewnia dobre przyspieszenie, ale istnieje również wystarczająca liczba klientów, dla których sytuacja znacznie się pogarsza.
Ostatecznie zrobiliśmy kilka ważnych rzeczy:
- Oceniliśmy oczekiwaną wydajność zapytań od klientów do chmury przez proxy CDN.
- Uzyskaliśmy dane od rzeczywistych klientów z różnych typów urządzeń.
- Zrozumieliśmy, że teoria nie potwierdziła się w 100% i początkowa propozycja z proxy CDN dla nas nie zadziała.
- Nie ryzykowaliśmy — nie zmienialiśmy konfiguracji produkcji dla klientów.
- Nie zepsuliśmy niczego.
Prototyp 2.0
Wróćmy więc do deski kreślarskiej i powtórzmy proces od nowa.
Pomysł — zamiast 100% proxy dla każdego klienta określimy najszybszą trasę i tam będziemy kierować zapytania — czyli będziemy robić to, co nazywa się klientem steering.

Jak to zrealizować? Nie możemy używać logiki po stronie serwera, ponieważ celem jest połączenie się z tym serwerem. Należy to jakoś zrealizować po stronie klienta. Idealnie, żeby zrobić to z minimalną ilością skomplikowanej logiki, unikając problemów z integracją z szeroką gamą platform klienckich.
Odpowiedzią jest wykorzystanie DNS. W naszym przypadku mamy własną infrastrukturę DNS, i możemy skonfigurować strefę domenową, dla której nasze serwery będą autorytatywne. Działa to w ten sposób:
- Klient wysyła zapytanie do serwera DNS, używając hosta, na przykład api.netflix.com.
- Zapytanie trafia na nasz serwer DNS.
- Serwer DNS wie, która ścieżka dla tego klienta jest najszybsza i wydaje odpowiedni adres IP.
W rozwiązaniu pojawia się dodatkowa złożoność: autorytatywne dostawcy DNS nie widzą adresu IP klienta i mogą dostrzegać tylko adres IP rekurencyjnego resolvera, którego używa klient.
W rezultacie nasz autorytatywny resolver musi podejmować decyzje nie dla pojedynczego klienta, ale dla grupy klientów na podstawie rekurencyjnego resolvera.
Dla rozwiązania wykorzystujemy te same próby, agregujemy wyniki pomiarów od klientów z każdego z rekurencyjnych resolverów i decydujemy, dokąd skierować tę grupę — przez IX za pomocą TCP Anycast, przez proxy ISP lub bezpośrednio do chmury.
Otrzymujemy taki system:

Uzyskany model sterowania DNS umożliwia kierowanie klientów na podstawie historycznych obserwacji prędkości połączeń od klientów do chmury.
Ponownie, pytanie — jak skutecznie sprawdzi się takie podejście? Aby na to odpowiedzieć, ponownie wykorzystujemy nasz system prób. Dlatego konfigurujemy konfigurację recency, gdzie jeden z targetów kieruje się w stronę sterowania DNS, a drugi — bezpośrednio w chmurę (aktualna produkcja).

Na koniec porównujemy wyniki i uzyskujemy ocenę skuteczności:

W rezultacie poznaliśmy kilka ważnych rzeczy:
- Oceniliśmy oczekiwaną wydajność zapytań od klientów do chmury z wykorzystaniem DNS Steering.
- Uzyskaliśmy dane od rzeczywistych klientów z różnych typów urządzeń.
- Udowodniliśmy skuteczność zaproponowanej idei.
- Nie ryzykowaliśmy — nie zmienialiśmy konfiguracji produkcji dla klientów.
- Nie zepsuliśmy niczego.
Teraz do trudniejsze — uruchamiamy w produkcji.
Najłatwiejsze jest już za nami — mamy działający prototyp. Teraz trudna część — uruchomienie rozwiązania dla całego ruchu Netflix, wdrożenie na 150 milionach użytkowników, tysiącach urządzeń, setkach mikroserwisów oraz ciągle zmieniających się produktów i infrastruktury. Na serwery Netflix wpływają miliony zapytań na sekundę, a nieostrożne działanie może łatwo złamać usługę. Chcemy jednocześnie dynamicznie kierować ruch przez tysiące serwerów CDN, w internecie, gdzie coś się zmienia i psuje stale w najgorszym momencie.
I mimo to w zespole są 3 inżynierowie odpowiedzialni za rozwój, wdrożenie i pełne wsparcie systemu.
Zatem dalej porozmawiamy o spokojnym i zdrowym śnie.
Jak kontynuować rozwój, a nie tracić całego czasu na wsparcie? Podstawą naszego podejścia są 3 zasady:
- Minimalizujemy potencjalny zakres awarii (blast radius).
- Przygotowujemy się na niespodzianki — spodziewamy się, że coś się popsuje, mimo testów i osobistego doświadczenia.
- Stopniowa degradacja (graceful degradation) — jeśli coś nie działa, powinno być naprawiane automatycznie, nawet jeśli nie w najskuteczniejszy sposób.
Okazało się, że w naszym przypadku, przy takim podejściu do problemu, można znaleźć proste i skuteczne rozwiązanie oraz znacznie uprościć wsparcie systemu. Zrozumieliśmy, że możemy dodać do klienta mały fragment kodu, który będzie monitorował błędy zapytań sieciowych spowodowane problemami z połączeniem. W przypadku błędów sieciowych dokonujemy fallbacku bezpośrednio do chmury. Takie rozwiązanie nie wymaga znacznych wysiłków ze strony zespołów klienckich, ale znacznie zmniejsza ryzyko niespodziewanych awarii i niespodzianek dla nas.
Oczywiście pomimo fallbacku, przestrzegamy jasnej dyscypliny w trakcie rozwoju:
- Test na próbkach.
- Testy A/B lub Canaries.
- Stopniowe wdrożenie (progressive rollout).
Podejście do testów na próbkach zostało opisane — zmiany są najpierw testowane za pomocą dostosowanego przepisu.
Aby przeprowadzić testy canary, potrzebujemy uzyskać porównywalne pary serwerów, na których można porównać, jak działa system przed i po zmianach. W tym celu z naszych licznych witryn CDN losujemy pary serwerów, które otrzymują porównywalny ruch:

Następnie wdrażamy zmiany na serwery Canary. Aby ocenić wyniki, uruchamiamy system, który porównuje około 100-150 metryk z grupą kontrolnych serwerów:

Jeśli testowanie na Canarze przebiegło pomyślnie, wprowadzamy wydanie stopniowo, falami. Na każdym z serwisów nie aktualizujemy serwerów jednocześnie — utrata całej strony w przypadku problemów ma znacznie większy wpływ na usługi dla użytkowników niż utrata takiej samej liczby serwerów, ale w różnych miejscach.
Ogólnie skuteczność i bezpieczeństwo takiego podejścia zależą od liczby i jakości zebranych metryk. W naszym systemie przyspieszania zapytań zbieramy metryki ze wszystkich możliwych komponentów:
- od klientów — liczba sesji i zapytań, wskaźniki fallback;
- proxy — statystyki dotyczące liczby i czasu zapytań;
- DNS — liczba i wyniki zapytań;
- cloud edge — liczba oraz czas przetwarzania zapytań w chmurze.
Wszystko to zbierane jest w jedną linię przetwarzania, a w zależności od potrzeb decydujemy, które metryki wysłać do analityki w czasie rzeczywistym, a które do Elasticsearch lub Big Data w celu dokładniejszej diagnostyki.
Monitorujemy

W naszym przypadku wprowadzamy zmiany w krytycznej ścieżce zapytań między klientem a serwerem. Liczba różnych komponentów po stronie klienta, serwera oraz na drodze przez internet jest ogromna. Zmiany po stronie klienta i serwera zachodzą nieustannie — w trakcie pracy dziesiątek zespołów oraz naturalnych zmian w ekosystemie. Jesteśmy pośrodku — podczas diagnostyki problemów istnieje duże prawdopodobieństwo, że będziemy w to zaangażowani. Dlatego musimy jasno rozumieć, jak definiować, zbierać i analizować metryki w celu szybkiej lokalizacji problemów.
Idealnie — pełny dostęp do wszystkich rodzajów metryk i filtrów w czasie rzeczywistym. Ale metryk jest bardzo wiele, więc pojawia się pytanie o koszty. W naszym przypadku dzielimy metryki i narzędzia developerskie w następujący sposób:

Do wykrywania i triage problemów używamy naszego własnego systemu w czasie rzeczywistym z otwartym kodem i — do wizualizacji. Przechowuje zagregowane metryki w pamięci, jest niezawodny i integruje się z systemem powiadamiania. Do lokalizacji i diagnostyki mamy dostęp do logów z Elasticsearch i Kibana. Do analizy statystycznej i modelowania wykorzystujemy big data i wizualizację w Tableau.
Wydaje się, że z takim podejściem bardzo trudno jest pracować. Jednak przy hierarchicznej organizacji metryk i narzędzi możemy szybko przeanalizować problem, określić jego typ, a następnie zejść do szczegółowych metryk. Na zidentyfikowanie źródła awarii zazwyczaj poświęcamy około 1-2 minut. Po tym już współpracujemy z konkretnym zespołem nad diagnozą — od kilku dziesięciu minut do kilku godzin.
Nawet jeśli diagnostyka odbywa się szybko, nie chcemy, aby zdarzało się to zbyt często. W idealnym przypadku chcielibyśmy otrzymywać krytyczne powiadomienia tylko wtedy, gdy ma to znaczący wpływ na usługę. Dla naszego systemu przyspieszania zapytań mamy tylko 2 powiadomienia, które będą informować:
- procent Client Fallback — ocena zachowania klientów;
- procent Probe errors — dane o stabilności komponentów sieciowych.
Te krytyczne powiadomienia monitorują, czy system działa dla większości użytkowników. Sprawdzamy, ile klientów skorzystało z fallback, jeśli nie mogli uzyskać przyspieszenia zapytań. Średnio mamy mniej niż 1 krytyczne powiadomienie w tygodniu, mimo ogromnej liczby zmian w systemie. Dlaczego to wystarcza?
- Występuje client fallback w przypadku, gdy nasza proxy nie działa.
- Istnieje automatyczny system kierowania, który reaguje na problemy.
O tym ostatnim więcej. Nasz system probe oraz system automatycznego określania optymalnej ścieżki dla zapytań od klienta do chmury umożliwiają automatyczne radzenie sobie z niektórymi problemami.
Wracając do naszej konfiguracji probe i 3 kategorii ścieżek. Oprócz czasu ładowania możemy sprawdzać sam fakt dostarczenia. Jeśli nie udało się załadować danych, patrząc na wyniki różnych ścieżek możemy określić, gdzie i co się zepsuło, a także czy możemy to naprawić automatycznie, zmieniając ścieżkę zapytania.
Przykłady:



Ten proces można zautomatyzować. Włączyć go do systemu kierowania. I nauczyć go reagować na problemy z wydajnością i niezawodnością. Jeśli coś zaczyna się psuć — reagować, jeśli jest lepsza opcja. Przy tym natychmiastowa reakcja nie jest krytyczna, dzięki fallbackowi na klientach.
W ten sposób zasady wsparcia systemu można sformułować następująco:
- zmniejszamy skalę awarii;
- zbieramy metryki;
- automatycznie naprawiamy awarie, jeśli to możliwe;
- jeśli to niemożliwe — informujemy;
- pracujemy nad dashboardami i zestawem narzędzi triage, aby szybko reagować.
Wyciągnięte lekcje
Nie potrzeba dużo czasu na napisanie prototypu. W naszym przypadku był gotowy już po 4 miesiącach. Dzięki niemu uzyskaliśmy nowe metryki, a po 10 miesiącach od rozpoczęcia prac otrzymaliśmy pierwszy ruch produkcyjny. Następnie zaczęła się nużąca i bardzo skomplikowana praca: stopniowe wprowadzenie produktu na rynek i skalowanie systemu, migracja głównego ruchu i uczenie się na błędach. Przy tym skuteczny proces nie będzie liniowy — mimo wszelkich starań, nie można wszystkiego przewidzieć. O wiele bardziej skuteczna jest szybka iteracja i reagowanie na nowe dane.

Na podstawie naszego doświadczenia możemy polecić następujące:
- Nie wierzcie intuicji.
Nasza intuicja nieustannie nas zawodziła, mimo ogromnego doświadczenia członków zespołu. Na przykład błędnie przewidywaliśmy oczekiwane przyspieszenie korzystania z proxy CDN, czy zachowanie TCP Anycast.
- Pozyskujcie dane z produkcji.
Ważne jest, aby jak najszybciej uzyskać dostęp chociaż do niewielkiej ilości danych produkcyjnych. Liczba unikalnych przypadków, konfiguracji, ustawień w warunkach laboratoryjnych jest praktycznie niemożliwa do osiągnięcia. Szybki dostęp do wyników pozwoli szybciej wykryć potencjalne problemy i uwzględnić je w architekturze systemu.
- Nie podążajcie za cudzymi radami i wynikami — zbierajcie swoje dane.
Stosujcie zasady dotyczące zbierania i analizy danych, ale nie przyjmujcie bezkrytycznie cudzych wyników i stwierdzeń. Tylko wy możecie dokładnie wiedzieć, co działa dla waszych użytkowników. Wasze systemy i klienci mogą znacznie różnić się od innych firm. Na szczęście narzędzia do analizy są obecnie dostępne i łatwe w użyciu. Wasze wyniki mogą nie zgadzać się z tym, co twierdzi Netflix, Facebook, Akamai i inne firmy. W naszym przypadku wydajność TLS, HTTP2 czy statystyki dotyczące zapytań DNS różnią się od wyników Facebooka, Ubera, Akamai — ponieważ mamy inne urządzenia, klientów i przepływy danych.
- Nie dążcie do modnych trendów bez potrzeby i oceny efektywności.
Zaczynajcie od prostego. Lepiej stworzyć prosty działający system w krótkim czasie, niż spędzić ogromną ilość czasu na rozwijaniu niepotrzebnych wam komponentów. Rozwiązujcie zadania i problemy, które są ważne na podstawie waszych pomiarów i wyników.
- Bądź gotowy na nowe zastosowania.
Tak jak trudno przewidzieć wszystkie problemy — trudno również z wyprzedzeniem przewidzieć zalety i zastosowania. Weź przykład ze startupów — ich zdolność do dostosowywania się do potrzeb klientów. W twoim przypadku — możesz odkrywać nowe problemy i ich rozwiązania. W naszym projekcie postawiliśmy sobie za cel zmniejszenie opóźnienia zapytań. Jednak w trakcie analizy i dyskusji zrozumieliśmy, że serwery proxy możemy również stosować:
- do równoważenia ruchu w regionach AWS, oraz redukcji kosztów;
- do modelowania stabilności CDN;
- do konfigurowania DNS;
- do konfigurowania TLS/TCP.
Podsumowanie
W raporcie opisałem, jak Netflix rozwiązuje problem przyspieszania zapytań internetowych między klientami a chmurą. Jak zbieramy dane z wykorzystaniem systemu prób na klientach i wykorzystujemy zebrane dane historyczne do kierowania zapytań produkcyjnych od klientów przez najszybszą trasę w internecie. Jak wykorzystujemy zasady działania protokołów sieciowych, naszą infrastrukturę CDN, sieć backbone i serwery DNS, aby osiągnąć ten cel.
Jednak nasze rozwiązanie to tylko przykład tego, jak w Netflix wdrożyliśmy taki system. Co zadziałało dla nas. Praktyczna część mojego raportu dla Ciebie — zasady projektowania i utrzymywania, których przestrzegamy i dzięki którym osiągamy dobre wyniki.
Nasze rozwiązanie problemu może nie pasować do Ciebie. Jednak teoria i zasady projektowania pozostają, nawet jeśli nie masz własnej infrastruktury CDN lub jeśli znacznie różni się ona od naszej.
Waży również pozostaje znaczenie szybkości zapytań dla biznesu. Nawet dla prostego serwisu należy podejmować decyzje: między dostawcami „chmurowymi”, lokalizacją serwerów, dostawcami CDN i DNS. Twój wybór wpłynie na efektywność zapytań internetowych dla twoich klientów. Ważne jest, aby mierzyć i rozumieć ten wpływ.
Zacznij od prostych rozwiązań, dbaj o to, jak zmieniasz produkt. Ucz się w trakcie procesu i doskonal system na podstawie danych od swoich klientów, swojej infrastruktury i swojego biznesu. Myśl o możliwości nieoczekiwanych awarii w procesie projektowania. Wtedy będziesz mógł przyspieszyć swój proces rozwoju, poprawić efektywność rozwiązania, uniknąć nadmiernego obciążenia wsparcia i spać spokojnie.
W tym roku w formacie online. Będzie można zadać pytania jednemu z ojców DevOps, samemu Johnowi Willisowi!
Źródło: habr.com
