Najlepszy fakapov Cyjan

Najlepszy fakapov Cyjan

Wszystko dobrze! 

Nazywam się Nikita, jestem liderem zespołu inżynierów Cian. Jednym z moich obowiązków w firmie jest ograniczenie do zera liczby incydentów związanych z infrastrukturą produkcyjną.
To, co zostanie omówione poniżej, sprawiło nam wiele bólu, a celem tego artykułu jest uniemożliwienie innym osobom powtarzania naszych błędów lub przynajmniej zminimalizowanie ich skutków. 

Preambuła

Dawno temu, kiedy Cian składał się z monolitów i nie było jeszcze żadnych śladów mikroserwisów, dostępność zasobu mierzyliśmy sprawdzając 3-5 stron. 

Odpowiadają - wszystko w porządku, jeśli nie odpowiadają przez dłuższy czas - alarm. Uczestnicy spotkań ustalali, jak długo musieli być nieobecni w pracy, aby można było uznać to za incydent. W dochodzenie w sprawie incydentu zawsze zaangażowany był zespół inżynierów. Po zakończeniu śledztwa spisali sekcję zwłok – rodzaj raportu drogą mailową w formacie: co się stało, jak długo to trwało, co robiliśmy w tej chwili, co będziemy robić w przyszłości. 

Główne strony serwisu, czyli jak rozumiemy, że osiągnęliśmy dno

 
Aby w jakiś sposób zrozumieć priorytet błędu, zidentyfikowaliśmy strony witryny najbardziej krytyczne dla funkcjonalności biznesowej. Za ich pomocą zliczamy liczbę udanych/nieudanych żądań oraz przekroczeń limitów czasu. W ten sposób mierzymy czas sprawności. 

Załóżmy, że dowiedzieliśmy się, że istnieje wiele bardzo ważnych sekcji witryny odpowiedzialnych za główną usługę - wyszukiwanie i przesyłanie reklam. Jeśli liczba żądań zakończonych niepowodzeniem przekracza 1%, jest to incydent krytyczny. Jeśli w ciągu 15 minut w godzinach największej oglądalności poziom błędów przekroczy 0,1%, wówczas jest to również uważane za incydent krytyczny. Kryteria te obejmują większość incydentów, reszta wykracza poza zakres tego artykułu.

Najlepszy fakapov Cyjan

Najlepsze najlepsze incydenty Cyan

Zdecydowanie nauczyliśmy się więc ustalać fakt, że zdarzenie miało miejsce. 

Teraz każde wydarzenie jest szczegółowo opisane i odzwierciedlone w epopei Jira. Swoją drogą: w tym celu rozpoczęliśmy osobny projekt o nazwie FAIL - można w nim tworzyć tylko eposy. 

Jeśli zsumować wszystkie niepowodzenia z ostatnich kilku lat, liderami są: 

  • incydenty związane z mssql;
  • zdarzenia spowodowane czynnikami zewnętrznymi;
  • błędy administratora.

Przyjrzyjmy się bardziej szczegółowo błędom administratorów, a także innym interesującym awariom.

Piąte miejsce – „Uporządkowanie sytuacji w DNS”

To był burzliwy wtorek. Postanowiliśmy przywrócić porządek w klastrze DNS. 

Chciałem przenieść wewnętrzne serwery DNS z binda na powerdns, przydzielając do tego zupełnie osobne serwery, gdzie nie ma nic poza DNSem. 

W każdej lokalizacji naszych DC umieściliśmy po jednym serwerze DNS i przyszedł moment na przeniesienie stref z bind na powerdns i przełączenie infrastruktury na nowe serwery. 

W trakcie przenoszenia ze wszystkich serwerów określonych w powiązaniach lokalnego buforowania na wszystkich serwerach pozostał tylko jeden, który znajdował się w centrum danych w St. Petersburgu. Ten DC został początkowo uznany za niekrytyczny dla nas, ale nagle stał się pojedynczym punktem awarii.
To właśnie w okresie przeprowadzki zawalił się kanał między Moskwą a Sankt Petersburgiem. Właściwie zostaliśmy bez DNS na pięć minut i wróciliśmy, gdy hoster naprawił problem. 

Wnioski:

Jeśli wcześniej zaniedbaliśmy czynniki zewnętrzne podczas przygotowań do pracy, teraz i one znajdują się na liście tego, do czego się przygotowujemy. A teraz dążymy do tego, aby wszystkie składowe były zarezerwowane na n-2, a w trakcie prac możemy obniżyć ten poziom do n-1.

  • Tworząc plan działania, zaznacz punkty, w których usługa może zawieść, i z góry przemyśl scenariusz, w którym wszystko poszło „ze złego na gorsze”.
  • Rozmieść wewnętrzne serwery DNS w różnych geolokalizacjach/centrach danych/rackach/przełącznikach/wejściach.
  • Na każdym serwerze zainstaluj lokalny buforujący serwer DNS, który przekierowuje żądania do głównych serwerów DNS, a jeśli będzie niedostępny, odpowie z pamięci podręcznej. 

Czwarte miejsce – „Sprzątanie w Nginx”

Pewnego pięknego dnia nasz zespół zdecydował, że „mamy tego dość” i rozpoczął się proces refaktoryzacji konfiguracji Nginx. Głównym celem jest doprowadzenie konfiguracji do intuicyjnej struktury. Wcześniej wszystko było „historycznie ustalone” i nie niosło ze sobą żadnej logiki. Teraz każda nazwa_serwera została przeniesiona do pliku o tej samej nazwie, a wszystkie konfiguracje zostały rozesłane do folderów. Nawiasem mówiąc, konfiguracja zawiera 253949 linii lub 7836520 znaków i zajmuje prawie 7 megabajtów. Najwyższy poziom struktury: 

Struktura Nginxa

├── access
│   ├── allow.list
...
│   └── whitelist.conf
├── geobase
│   ├── exclude.conf
...
│   └── geo_ip_to_region_id.conf
├── geodb
│   ├── GeoIP.dat
│   ├── GeoIP2-Country.mmdb
│   └── GeoLiteCity.dat
├── inc
│   ├── error.inc
...
│   └── proxy.inc
├── lists.d
│   ├── bot.conf
...
│   ├── dynamic
│   └── geo.conf
├── lua
│   ├── cookie.lua
│   ├── log
│   │   └── log.lua
│   ├── logics
│   │   ├── include.lua
│   │   ├── ...
│   │   └── utils.lua
│   └── prom
│       ├── stats.lua
│       └── stats_prometheus.lua
├── map.d
│   ├── access.conf
│   ├── .. 
│   └── zones.conf
├── nginx.conf
├── robots.txt
├── server.d
│   ├── cian.ru
│   │   ├── cian.ru.conf
│   │   ├── ...
│   │   └── my.cian.ru.conf
├── service.d
│   ├── ...
│   └── status.conf
└── upstream.d
    ├── cian-mcs.conf
    ├── ...
    └── wafserver.conf

Stało się znacznie lepiej, ale w procesie zmiany nazwy i dystrybucji konfiguracji niektóre z nich miały niewłaściwe rozszerzenie i nie zostały uwzględnione w dyrektywie include *.conf. W rezultacie niektóre hosty stały się niedostępne i zwróciły 301 na stronę główną. Ze względu na to, że kodem odpowiedzi nie był 5xx/4xx, nie zauważono tego od razu, a dopiero rano. Następnie zaczęliśmy pisać testy sprawdzające komponenty infrastruktury.

Wnioski: 

  • Ustrukturyzuj poprawnie swoje konfiguracje (nie tylko nginx) i przemyśl strukturę na wczesnym etapie projektu. W ten sposób uczynisz je bardziej zrozumiałymi dla zespołu, co z kolei zmniejszy TTM.
  • Napisz testy dla niektórych komponentów infrastruktury. Na przykład: sprawdzenie, czy wszystkie kluczowe nazwy_serwerów podają poprawny status + treść odpowiedzi. Wystarczy mieć pod ręką kilka skryptów sprawdzających podstawowe funkcje komponentu, aby o 3 w nocy gorączkowo nie pamiętać, co jeszcze należy sprawdzić. 

Trzecie miejsce – „Nagle zabrakło miejsca w Cassandrze”

Dane rosły stale i wszystko było w porządku, aż do momentu, gdy naprawa dużych przestrzeni dyskowych w klastrze Cassandra zaczęła się nie udać, ponieważ zagęszczanie nie mogło na nich zadziałać. 

Pewnego burzliwego dnia gromada prawie zamieniła się w dynię, a mianowicie:

  • w klastrze pozostało około 20% całkowitej przestrzeni;
  • Niemożliwe jest pełne dodanie węzłów, ponieważ po dodaniu węzła nie następuje czyszczenie ze względu na brak miejsca na partycjach;
  • wydajność stopniowo spada, gdy zagęszczanie nie działa; 
  • Klaster znajduje się w trybie awaryjnym.

Najlepszy fakapov Cyjan

Exit - dodaliśmy jeszcze 5 węzłów bez porządkowania, po czym zaczęliśmy systematycznie usuwać je z klastra i ponownie do nich wchodzić, niczym puste węzły, którym zabrakło miejsca. Spędziliśmy dużo więcej czasu niż byśmy chcieli. Istniało ryzyko częściowej lub całkowitej niedostępności klastra. 

Wnioski:

  • Na wszystkich serwerach Cassandra nie powinno być zajęte więcej niż 60% miejsca na każdej partycji. 
  • Powinny być obciążone nie więcej niż 50% procesora.
  • Nie należy zapominać o planowaniu wydajności i trzeba to przemyśleć dla każdego komponentu, biorąc pod uwagę jego specyfikę.
  • Im więcej węzłów w klastrze, tym lepiej. Serwery zawierające niewielką ilość danych szybciej ulegają przeciążeniu, a taki klaster łatwiej jest ożywić. 

Drugie miejsce – „Dane zniknęły z magazynu klucz-wartość konsula”

Do wykrywania usług, podobnie jak wielu, używamy consul. Ale używamy również jego pary klucz-wartość dla niebiesko-zielonego układu monolitu. Przechowuje informacje o aktywnych i nieaktywnych upstreamach, które zmieniają miejsce podczas wdrażania. W tym celu napisano usługę wdrożeniową, która wchodzi w interakcję z KV. W pewnym momencie zniknęły dane z KV. Przywrócono z pamięci, ale z wieloma błędami. W rezultacie podczas przesyłania obciążenie serwerów nadrzędnych było nierównomiernie rozłożone i otrzymaliśmy wiele błędów 502 z powodu przeciążenia backendów procesora. W rezultacie przenieśliśmy się z consul KV do postgres, skąd nie jest już tak łatwo je usunąć.  

Wnioski:

  • Usługi bez jakiejkolwiek autoryzacji nie powinny zawierać danych krytycznych dla działania serwisu. Przykładowo, jeśli nie masz autoryzacji w ES, lepiej odmówić dostępu na poziomie sieci ze wszystkich miejsc, gdzie nie jest to potrzebne, zostawić tylko te niezbędne, a także ustawić action.destructive_requires_name: true.
  • Z wyprzedzeniem przećwicz mechanizm tworzenia kopii zapasowych i odzyskiwania. Na przykład utwórz wcześniej skrypt (na przykład w Pythonie), który będzie mógł tworzyć kopie zapasowe i przywracać.

I miejsce – „Kapitan Nieoczywisty” 

W pewnym momencie zauważyliśmy nierówny rozkład obciążenia na serwerach nadrzędnych Nginx w przypadkach, gdy w backendzie znajdowało się ponad 10 serwerów. Ze względu na to, że round-robin wysyłał żądania od 1. do ostatniego upstreamu w kolejności, a każde przeładowanie nginx zaczynało się od nowa, pierwsze upstreamy zawsze otrzymywały więcej żądań niż pozostałe, w rezultacie działały wolniej i ucierpiała na tym cała witryna. Stało się to coraz bardziej zauważalne wraz ze wzrostem natężenia ruchu. Zwykła aktualizacja Nginx w celu włączenia trybu losowego nie zadziałała - musimy przerobić kilka kodów Lua, które nie wystartowały w wersji 1.15 (w tym momencie). Musieliśmy załatać nasz nginx 1.14.2, wprowadzając do niego losową obsługę. To rozwiązało problem. Ten błąd wygrywa w kategorii „Kapitan Nieoczywistość”.

Wnioski:

Badanie tego błędu było bardzo interesujące i ekscytujące). 

  • Zorganizuj swój monitoring tak, aby pomagał szybko wykryć takie wahania. Na przykład możesz użyć ELK do monitorowania Rps na każdym backendzie każdego upstream, monitoruj ich czas odpowiedzi z punktu widzenia Nginx. W tym przypadku pomogło nam to zidentyfikować problem. 

W rezultacie większości niepowodzeń można było uniknąć, stosując bardziej skrupulatne podejście do tego, co się robi. Zawsze musimy pamiętać o prawie Murphy’ego: Wszystko, co może pójść źle, pójdzie źle, i na ich podstawie budować komponenty. 

Źródło: www.habr.com

Dodaj komentarz