Najlepszy fakapov Cyjan

Najlepszy fakapov Cyjan

Wszystko dobrze! 

Nazywam się Nikita i 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 nastąpiło później, sprawiło nam wiele bólu i celem tego artykułu jest powstrzymanie innych przed powtarzaniem naszych błędów, a przynajmniej zminimalizowanie ich wpływu. 

Preambuła

Dawno temu, gdy Cian składał się z monolitów i nie było śladu mikrousług, dostępność zasobów ocenialiśmy, sprawdzając 3–5 stron. 

Odbierają - wszystko w porządku, jeśli nie odbierają przez dłuższy czas - alarm. O tym, jak długo musieli być nieobecni w pracy, aby uznać to za incydent, decydowali ludzie na spotkaniach. W badaniu incydentu zawsze brał udział zespół inżynierów. Po zakończeniu śledztwa sporządzono raport z sekcji zwłok – rodzaj raportu przesyłanego pocztą elektroniczną w następującej formie: co się wydarzyło, jak długo to trwało, co zrobiono w tej chwili, co zrobimy w przyszłości. 

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

 
Aby zrozumieć priorytet błędu, zidentyfikowaliśmy strony o najważniejszym znaczeniu dla funkcjonalności biznesowej witryny. Używamy ich do zliczania liczby pomyślnych/niepomyślnych żądań oraz przekroczeń limitu czasu. W ten sposób mierzymy czas sprawności. 

Załóżmy, że odkryliśmy, że na stronie jest kilka niezwykle ważnych sekcji, które odpowiadają za główną usługę — wyszukiwanie i zamieszczanie reklam. Jeśli liczba nieodebranych żądań przekroczy 1%, jest to incydent krytyczny. Jeżeli w ciągu 15 minut w czasie największej oglądalności wskaźnik błędów przekroczy 0,1%, zdarzenie to również uznaje się za incydent krytyczny. Kryteria te obejmują większość incydentów, reszta wykracza poza zakres tego artykułu.

Najlepszy fakapov Cyjan

Najlepsze incydenty z cyjanem

Zatem na pewno nauczyliśmy się ustalać fakt wystąpienia zdarzenia. 

Teraz każdy incydent jest szczegółowo opisany i odzwierciedlony w epiku Jira. Przy okazji: w tym celu stworzyliśmy osobny projekt, nazwaliśmy go FAIL - można w nim tworzyć wyłącznie eposy. 

Jeśli zbierzesz wszystkie porażki z ostatnich kilku lat, liderami są: 

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

Przyjrzyjmy się bliżej błędom administratorów oraz innym ciekawym wpadkom.

Piąte miejsce - „Uporządkujmy sprawy w DNS”

Był ponury wtorek. Postanowiliśmy uporządkować sprawy w klastrze DNS. 

Chciałem przenieść wewnętrzne serwery DNS z bind do powerdns, przydzielając do tego celu zupełnie oddzielne serwery, na których nie będzie nic poza DNS. 

Umieściliśmy po jednym serwerze DNS w każdej lokalizacji naszego kontrolera domeny, a następnie nadszedł czas na przeniesienie stref z bind do powerdns i przełączenie infrastruktury na nowe serwery. 

Wśród przeprowadzek, ze wszystkich ludzi serwerySpośród serwerów określonych w lokalnych powiązaniach buforowania, pozostał tylko jeden – ten w centrum danych w Sankt Petersburgu. Początkowo to centrum danych zostało uznane za niekrytyczne dla nas, ale nagle stało się pojedynczym punktem awarii.
To właśnie w tym okresie przejściowym kanał między Moskwą a Petersburgiem uległ awarii. W efekcie przez pięć minut byliśmy bez DNS i odzyskaliśmy łączność, gdy… gospodarz rozwiązano problemy. 

Wnioski:

Jeśli wcześniej zaniedbywaliśmy czynniki zewnętrzne podczas przygotowań do pracy, to teraz znalazły się one również na liście rzeczy, do których się przygotowujemy. I teraz dążymy do tego, aby wszystkie komponenty były zarezerwowane n-2, a w trakcie pracy możemy obniżyć ten poziom do n-1.

  • Tworząc plan działania, zwróć uwagę na punkty, w których usługa może zawieść i z wyprzedzeniem przemyśl scenariusz, w którym sytuacja pójdzie „najgorzej”.
  • Rozłóż wewnętrzne serwery DNS w różnych lokalizacjach geograficznych/centrach danych/stojakach/przełącznikach/wejściach.
  • Na każdym serwerze zainstaluj lokalny serwer buforujący DNS, który przekierowuje żądania do głównych serwerów DNS, a jeśli jest niedostępny, będzie odpowiadał z pamięci podręcznej. 

Czwarte miejsce – „Sprzątanie Nginx”

Pewnego dnia nasz zespół uznał, że „dość” i rozpoczął proces refaktoryzacji konfiguracji nginx. Głównym celem jest zapewnienie intuicyjnej struktury konfiguracji. Wcześniej wszystko było „ustalone historycznie” i nie miało żadnej logiki. Teraz każda nazwa_serwera została przeniesiona do pliku o tej samej nazwie, a wszystkie konfiguracje zostały rozmieszczone w folderach. Nawiasem mówiąc, konfiguracja zawiera 253949 linii lub 7836520 znaków i zajmuje prawie 7 megabajtów. Struktura najwyższego poziomu: 

Struktura Nginx

├── 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

Sytuacja znacznie się poprawiła, ale w procesie zmiany nazw i dystrybucji konfiguracji, niektóre z nich miały niewłaściwe rozszerzenia i nie zostały uwzględnione w dyrektywie include *.conf. W rezultacie niektórzy hostowie stali się niedostępni i zwrócili kod 301 do strony głównej. Ponieważ kod odpowiedzi nie był 5xx/4xx, nie zauważono go od razu, lecz dopiero rano. Następnie zaczęliśmy pisać testy sprawdzające komponenty infrastruktury.

Wnioski: 

  • Uporządkuj prawidłowo swoje konfiguracje (nie tylko nginx) i przemyśl strukturę już na wczesnym etapie projektu. Dzięki temu staną się one bardziej zrozumiałe dla zespołu, co z kolei skróci czas potrzebny do wdrożenia (TTM).
  • Napisz testy dla niektórych komponentów infrastruktury. Na przykład: sprawdzenie, czy wszystkie klucze server_name zwracają poprawny status + treść odpowiedzi. Wystarczy mieć pod ręką kilka skryptów sprawdzających najważniejsze funkcje komponentu, dzięki czemu o trzeciej w nocy nie będziesz musiał gorączkowo przypominać sobie, co jeszcze trzeba sprawdzić. 

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

Dane rosły systematycznie i wszystko szło dobrze aż do momentu, gdy naprawa dużych przestrzeni kluczy w klastrze Cassandra zaczęła zawodzić, ponieważ nie można było na nich przeprowadzić kompresji. 

Pewnego deszczowego dnia gromada ta niemal zamieniła się w dynię, a mianowicie:

  • w klastrze pozostało łącznie około 20% wolnego miejsca;
  • nie jest możliwe pełne dodanie węzłów, ponieważ czyszczenie nie odbywa się po dodaniu węzła z powodu braku miejsca na partycjach;
  • wydajność stopniowo spada, ponieważ zagęszczanie nie działa; 
  • Klaster pracuje w trybie awaryjnym.

Najlepszy fakapov Cyjan

Rozwiązaniem było dodanie 5 kolejnych węzłów bez czyszczenia, po czym zaczęto je systematycznie usuwać z klastra i ponownie wprowadzać jako puste węzły, którym zabrakło miejsca. Spędziłem tam znacznie więcej czasu, niż bym chciał. Istniało ryzyko częściowej lub całkowitej niedostępności klastra. 

Wnioski:

  • Żaden z serwerów Cassandra nie powinien mieć zajętego więcej niż 60% przestrzeni na każdej partycji. 
  • Nie powinny one obciążać procesora w stopniu większym niż 50%.
  • Nie należy zapominać o planowaniu pojemności; musisz to dokładnie 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 zapełniają się szybciej, a taki klaster jest łatwiejszy do reanimacji. 

Drugie miejsce – „Dane zniknęły z magazynu kluczy i wartości konsularnych”

Do wyszukiwania usług, my, podobnie jak wielu innych, używamy konsulatu. Ale używamy również tej pary klucz-wartość do niebiesko-zielonego układu monolitu. Przechowuje informacje o aktywnych i nieaktywnych strumieniach, które zmieniają swoje miejsca podczas wdrażania. W tym celu napisano usługę wdrażania, która współpracowała z KV. W pewnym momencie dane z KV zniknęły. Przywrócono z pamięci, ale z wieloma błędami. W rezultacie obciążenie serwerów źródłowych podczas wdrażania było nierównomiernie rozłożone, a z powodu przeciążenia procesora procesora wystąpiło wiele błędów 502. W efekcie przeszliśmy z konsula KV na postgres, skąd nie jest już tak łatwo je usunąć.  

Wnioski:

  • Usługi nieobjęte autoryzacją nie powinny zawierać danych mających krytyczne znaczenie dla działania serwisu. Na przykład, jeśli nie masz autoryzacji w ES, lepiej będzie zabronić dostępu na poziomie sieci wszędzie tam, gdzie nie jest on potrzebny, pozostawić tylko niezbędne osoby i ustawić action.destructive_requires_name: true.
  • Zawczasu przećwicz mechanizm tworzenia kopii zapasowych i odzyskiwania danych. Na przykład utwórz wcześniej skrypt (np. w Pythonie), który będzie umożliwiał zarówno tworzenie kopii zapasowej, jak i jej przywracanie.

Pierwsze miejsce – „Kapitan Oczywisty” 

W pewnym momencie zauważyliśmy nierównomierne rozłożenie obciążenia na serwerach upstream nginx w przypadkach, gdy w zapleczu znajdowało się ponad 10 serwerów. Ponieważ metoda round-robin kierowała żądania od 1 do ostatniego serwera nadrzędnego w kolejności, a nginx rozpoczynał każde przeładowanie od początku, pierwsze serwery nadrzędne zawsze miały więcej żądań niż pozostałe. W rezultacie działały wolniej i cała witryna ucierpiała. Stawało się to coraz bardziej zauważalne w miarę wzrostu natężenia ruchu. Prosta aktualizacja nginx w celu włączenia losowości nie zadziałała — trzeba było przepisać sporo kodu LUA, który nie działał w wersji 1.15 (w tamtym czasie). Musieliśmy zaktualizować nasz nginx 1.14.2, aby dodać obsługę losowości. To rozwiązało problem. Ten błąd wygrywa nagrodę „Kapitana Oczywistego”.

Wnioski:

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

  • Skonfiguruj monitorowanie, które pomoże Ci szybko wykryć takie wahania. Na przykład możesz użyć ELK do monitorowania rps dla każdego zaplecza każdego źródła, monitorując ich czasy odpowiedzi z perspektywy nginx. W tym przypadku to właśnie pomogło nam zidentyfikować problem. 

W rezultacie większości błędów można by uniknąć, gdybyś wykazał się większą starannością w podejmowanych działaniach. Należy zawsze pamiętać o prawie Murphy'ego: Wszystko co może pójść źle, pójdzie źle. i budować na jego podstawie komponenty. 

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

Dodaj komentarz