Top Fakapov Cyan

Top Fakapov Cyan

Alles gut! 

Mein Name ist Nikita, ich bin der Teamleiter des Cian-Ingenieurteams. Eine meiner Aufgaben im Unternehmen besteht darin, die Anzahl der Vorfälle im Zusammenhang mit der Infrastruktur in der Produktion auf Null zu reduzieren.
Was im Folgenden besprochen wird, hat uns viel Schmerz bereitet, und der Zweck dieses Artikels besteht darin, zu verhindern, dass andere Menschen unsere Fehler wiederholen, oder deren Auswirkungen zumindest zu minimieren. 

Präambel

Vor langer Zeit, als Cian aus Monolithen bestand und es noch keine Hinweise auf Microservices gab, haben wir die Verfügbarkeit einer Ressource gemessen, indem wir drei bis fünf Seiten überprüft haben. 

Sie antworten – alles ist in Ordnung, wenn sie längere Zeit nicht antworten – Alarm. Wie lange sie von der Arbeit fernbleiben mussten, damit es als Vorfall galt, wurde in Besprechungen entschieden. An der Untersuchung des Vorfalls war stets ein Team von Ingenieuren beteiligt. Als die Untersuchung abgeschlossen war, verfassten sie ein Postmortem – eine Art Bericht per E-Mail im Format: Was ist passiert, wie lange hat es gedauert, was haben wir im Moment getan, was werden wir in Zukunft tun? 

Die Hauptseiten der Website oder wie wir verstehen, dass wir ganz unten angekommen sind

 
Um die Priorität des Fehlers irgendwie zu verstehen, haben wir die kritischsten Seiten der Website für die Geschäftsfunktionalität identifiziert. Mit ihnen zählen wir die Anzahl erfolgreicher/nicht erfolgreicher Anfragen und Timeouts. So messen wir die Betriebszeit. 

Nehmen wir an, wir haben herausgefunden, dass es eine Reihe äußerst wichtiger Bereiche der Website gibt, die für den Hauptdienst zuständig sind – das Suchen und Einreichen von Anzeigen. Wenn die Anzahl der fehlgeschlagenen Anfragen 1 % übersteigt, handelt es sich um einen kritischen Vorfall. Wenn innerhalb von 15 Minuten zur Hauptsendezeit die Fehlerquote 0,1 % übersteigt, gilt dies ebenfalls als kritischer Vorfall. Diese Kriterien decken die meisten Vorfälle ab; der Rest geht über den Rahmen dieses Artikels hinaus.

Top Fakapov Cyan

Top beste Vorfälle Cyan

Wir haben also definitiv gelernt, die Tatsache festzustellen, dass ein Vorfall passiert ist. 

Jetzt wird jeder Vorfall detailliert beschrieben und im Jira-Epos widergespiegelt. Übrigens: Dafür haben wir ein eigenes Projekt gestartet, genannt FAIL – darin können nur Epics erstellt werden. 

Wenn man alle Misserfolge der letzten Jahre zusammenfasst, sind die Spitzenreiter: 

  • MSSQL-bezogene Vorfälle;
  • Vorfälle, die durch externe Faktoren verursacht wurden;
  • Admin-Fehler.

Schauen wir uns die Fehler der Administratoren sowie einige andere interessante Fehler genauer an.

Fünfter Platz – „Ordnung im DNS schaffen“

Es war ein stürmischer Dienstag. Wir haben uns entschieden, die Ordnung im DNS-Cluster wiederherzustellen. 

Ich wollte interne DNS-Server von bind auf powerdns übertragen und dafür völlig separate Server zuweisen, auf denen es außer DNS nichts gibt. 

Wir haben an jedem Standort unserer DCs einen DNS-Server platziert und es war an der Zeit, die Zonen von bind auf powerdns zu verschieben und die Infrastruktur auf neue Server umzustellen. 

Während des Umzugs blieb von allen Servern, die in lokalen Caching-Bindungen auf allen Servern angegeben waren, nur einer übrig, und zwar im Rechenzentrum in St. Petersburg. Dieser DC wurde zunächst als unkritisch für uns deklariert, wurde aber plötzlich zu einem Single Point of Failure.
In dieser Zeit der Umsiedlung kam es zum Einsturz des Kanals zwischen Moskau und St. Petersburg. Wir waren tatsächlich fünf Minuten lang ohne DNS und kamen wieder zurück, als der Hoster das Problem behoben hatte. 

Schlussfolgerungen:

Haben wir früher bei der Vorbereitung auf die Arbeit äußere Faktoren vernachlässigt, so gehören sie nun auch in die Liste dessen, worauf wir uns vorbereiten. Und jetzt bemühen wir uns sicherzustellen, dass alle Komponenten n-2 reserviert sind, und während der Arbeit können wir dieses Niveau auf n-1 senken.

  • Markieren Sie bei der Erstellung eines Aktionsplans die Punkte, an denen der Dienst möglicherweise scheitern könnte, und überlegen Sie sich im Voraus ein Szenario, in dem alles „immer schlimmer“ wird.
  • Verteilen Sie interne DNS-Server auf verschiedene Standorte/Rechenzentren/Racks/Switches/Eingänge.
  • Installieren Sie auf jedem Server einen lokalen Caching-DNS-Server, der Anfragen an die Haupt-DNS-Server umleitet. Wenn er nicht verfügbar ist, antwortet er aus dem Cache. 

Vierter Platz – „In Nginx Ordnung schaffen“

Eines schönen Tages entschied unser Team, dass „wir genug davon haben“ und der Prozess der Umgestaltung der Nginx-Konfigurationen begann. Das Hauptziel besteht darin, die Konfigurationen in eine intuitive Struktur zu bringen. Bisher war alles „historisch begründet“ und hatte keine Logik. Jetzt wurde jeder Servername in eine Datei mit demselben Namen verschoben und alle Konfigurationen wurden in Ordner verteilt. Die Konfiguration enthält übrigens 253949 Zeilen bzw. 7836520 Zeichen und belegt knapp 7 Megabyte. Oberste Strukturebene: 

Nginx-Struktur

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

Es wurde viel besser, aber beim Umbenennen und Verteilen von Konfigurationen hatten einige von ihnen die falsche Erweiterung und waren nicht in der Anweisung include *.conf enthalten. Dies hatte zur Folge, dass einige Hosts nicht mehr erreichbar waren und 301 auf die Hauptseite zurückleiteten. Aufgrund der Tatsache, dass der Antwortcode nicht 5xx/4xx war, fiel dies nicht sofort auf, sondern erst am Morgen. Danach begannen wir mit dem Schreiben von Tests zur Überprüfung von Infrastrukturkomponenten.

Schlussfolgerungen: 

  • Strukturieren Sie Ihre Konfigurationen richtig (nicht nur Nginx) und denken Sie in einem frühen Stadium des Projekts über die Struktur nach. Auf diese Weise machen Sie sie für das Team verständlicher, was wiederum die TTM reduziert.
  • Schreiben Sie Tests für einige Infrastrukturkomponenten. Beispiel: Überprüfen, ob alle wichtigen Servernamen den richtigen Status + Antworttext liefern. Es wird ausreichen, nur ein paar Skripte zur Hand zu haben, die die Grundfunktionen der Komponente überprüfen, um nicht um 3 Uhr morgens hektisch daran zu denken, was sonst noch überprüft werden muss. 

Dritter Platz – „In Cassandra war plötzlich kein Platz mehr“

Die Daten wuchsen stetig und alles war in Ordnung, bis die Reparatur großer Casespaces im Cassandra-Cluster zu scheitern begann, weil die Komprimierung bei ihnen nicht funktionieren konnte. 

An einem stürmischen Tag verwandelte sich die Traube fast in einen Kürbis, nämlich:

  • es waren noch etwa 20 % des gesamten Platzes im Cluster übrig;
  • Es ist nicht möglich, Knoten vollständig hinzuzufügen, da die Bereinigung nach dem Hinzufügen eines Knotens aufgrund von Platzmangel auf den Partitionen nicht durchgeführt wird.
  • Die Produktivität sinkt allmählich, weil die Verdichtung nicht funktioniert. 
  • Der Cluster befindet sich im Notfallmodus.

Top Fakapov Cyan

Beenden – Wir haben 5 weitere Knoten ohne Bereinigung hinzugefügt und anschließend begonnen, sie systematisch aus dem Cluster zu entfernen und wieder einzugeben, wie leere Knoten, denen der Speicherplatz ausgegangen ist. Es wurde viel mehr Zeit aufgewendet, als uns lieb war. Es bestand die Gefahr einer teilweisen oder vollständigen Nichtverfügbarkeit des Clusters. 

Schlussfolgerungen:

  • Auf allen Cassandra-Servern sollten nicht mehr als 60 % des Speicherplatzes auf jeder Partition belegt sein. 
  • Sie sollten mit nicht mehr als 50 % CPU ausgelastet sein.
  • Sie sollten die Kapazitätsplanung nicht vergessen und müssen diese für jede Komponente auf der Grundlage ihrer Besonderheiten durchdenken.
  • Je mehr Knoten im Cluster vorhanden sind, desto besser. Server mit kleinen Datenmengen werden schneller überlastet und ein solcher Cluster lässt sich leichter wiederbeleben. 

Zweiter Platz – „Daten aus dem Consul-Schlüsselwertspeicher verschwunden“

Für die Serviceerkennung verwenden wir, wie viele andere auch, Consul. Wir verwenden seinen Schlüsselwert aber auch für das Blau-Grün-Layout des Monolithen. Es speichert Informationen über aktive und inaktive Upstreams, die während der Bereitstellung ihren Platz wechseln. Zu diesem Zweck wurde ein Bereitstellungsdienst geschrieben, der mit KV interagierte. Irgendwann verschwanden die Daten von KV. Aus dem Speicher wiederhergestellt, jedoch mit einer Reihe von Fehlern. Dadurch war die Last auf den Upstreams während des Uploads ungleichmäßig verteilt und wir bekamen viele 502-Fehler, weil die Backends die CPU überlasteten. Infolgedessen sind wir von Consul KV zu Postgres gewechselt, von wo aus es nicht mehr so ​​einfach ist, sie zu entfernen.  

Schlussfolgerungen:

  • Dienste ohne Genehmigung dürfen keine für den Betrieb der Website kritischen Daten enthalten. Wenn Sie beispielsweise keine Berechtigung in ES haben, ist es besser, den Zugriff auf Netzwerkebene von überall dort zu verweigern, wo er nicht benötigt wird, nur die notwendigen zu belassen und außerdem action.destructive_requires_name: true festzulegen.
  • Üben Sie Ihren Sicherungs- und Wiederherstellungsmechanismus im Voraus. Erstellen Sie beispielsweise im Voraus ein Skript (z. B. in Python), das Sicherungen und Wiederherstellungen durchführen kann.

Erster Platz – „Captain Unobvious“ 

Irgendwann bemerkten wir eine ungleichmäßige Lastverteilung auf Nginx-Upstreams in Fällen, in denen mehr als 10 Server im Backend vorhanden waren. Aufgrund der Tatsache, dass das Round-Robin-Verfahren der Reihe nach Anfragen vom ersten bis zum letzten Upstream sendete und jedes Nginx-Neuladen von vorne begann, erhielten die ersten Upstreams immer mehr Anfragen als der Rest. Infolgedessen arbeiteten sie langsamer und die gesamte Site litt darunter. Dies machte sich mit zunehmendem Verkehrsaufkommen immer deutlicher bemerkbar. Ein einfaches Aktualisieren von Nginx, um den Zufallsgenerator zu aktivieren, hat nicht funktioniert – wir müssen eine Menge Lua-Code wiederholen, der in Version 1 (zu diesem Zeitpunkt) nicht funktionierte. Wir mussten unser Nginx 1.15 patchen und zufällige Unterstützung einführen. Dadurch wurde das Problem gelöst. Dieser Fehler gewinnt die Kategorie „Captain Non-Obviousness“.

Schlussfolgerungen:

Es war sehr interessant und aufregend, diesen Fehler zu untersuchen. 

  • Organisieren Sie Ihr Monitoring so, dass es Ihnen hilft, solche Schwankungen schnell zu erkennen. Sie können beispielsweise ELK verwenden, um RPS auf jedem Backend jedes Upstreams zu überwachen und deren Antwortzeit aus der Sicht von Nginx zu überwachen. In diesem Fall hat uns dies geholfen, das Problem zu identifizieren. 

Infolgedessen hätten die meisten Fehler durch eine sorgfältigere Herangehensweise an Ihre Arbeit vermieden werden können. Wir müssen uns immer an Murphys Gesetz erinnern: Alles, was schief gehen kann, wird schief gehen, und darauf basierende Komponenten bauen. 

Source: habr.com

Kommentar hinzufügen