Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Hallo zusammen, mein Name ist Alexander, ich arbeite bei CIAN als Ingenieur und beschäftige mich mit der Systemadministration und Automatisierung von Infrastrukturprozessen. In den Kommentaren zu einem der vorherigen Artikel wurden wir gebeten zu verraten, woher wir 4 TB Protokolle pro Tag bekommen und was wir damit machen. Ja, wir haben viele Protokolle und für deren Verarbeitung wurde ein separater Infrastruktur-Cluster erstellt, der uns eine schnelle Lösung von Problemen ermöglicht. In diesem Artikel werde ich darüber sprechen, wie wir es im Laufe eines Jahres angepasst haben, um mit einem ständig wachsenden Datenfluss zu arbeiten.

Wo haben wir angefangen?

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

In den letzten Jahren ist die Auslastung von cian.ru sehr schnell gewachsen, und im dritten Quartal 2018 erreichte der Ressourcenverkehr 11.2 Millionen Unique User pro Monat. Damals verloren wir in kritischen Momenten bis zu 40 % der Protokolle, weshalb wir Vorfälle nicht schnell bearbeiten konnten und viel Zeit und Mühe in deren Lösung investierten. Außerdem konnten wir die Ursache des Problems oft nicht finden und es trat nach einiger Zeit erneut auf. Es war die Hölle und es musste etwas dagegen getan werden.

Zu diesem Zeitpunkt verwendeten wir einen Cluster aus 10 Datenknoten mit ElasticSearch Version 5.5.2 mit Standardindexeinstellungen zum Speichern von Protokollen. Es wurde vor mehr als einem Jahr als beliebte und kostengünstige Lösung eingeführt: Damals war der Protokollfluss noch nicht so groß, es hatte keinen Sinn, nicht standardmäßige Konfigurationen zu entwickeln. 

Die Verarbeitung eingehender Protokolle wurde von Logstash auf verschiedenen Ports von fünf ElasticSearch-Koordinatoren bereitgestellt. Ein Index bestand unabhängig von der Größe aus fünf Shards. Es wurde eine stündliche und tägliche Rotation organisiert, wodurch stündlich etwa 100 neue Shards im Cluster erschienen. Obwohl es nicht sehr viele Protokolle gab, kam der Cluster gut zurecht und niemand achtete auf seine Einstellungen. 

Die Herausforderungen des schnellen Wachstums

Das Volumen der generierten Protokolle wuchs sehr schnell, da sich zwei Prozesse überschnitten. Einerseits wuchs die Zahl der Nutzer des Dienstes. Andererseits begannen wir aktiv mit der Umstellung auf eine Microservice-Architektur und zersägten unsere alten Monolithen in C# und Python. Mehrere Dutzend neue Microservices, die Teile des Monolithen ersetzten, generierten deutlich mehr Protokolle für den Infrastrukturcluster. 

Es war die Skalierung, die uns an den Punkt brachte, an dem der Cluster praktisch nicht mehr zu bewältigen war. Als die Protokolle mit einer Geschwindigkeit von 20 Nachrichten pro Sekunde eintrafen, erhöhte sich die Anzahl der Shards durch häufige nutzlose Rotation auf 6, und es gab mehr als 600 Shards pro Knoten. 

Dies führte zu Problemen bei der RAM-Zuweisung, und wenn ein Knoten abstürzte, begannen sich alle Shards gleichzeitig zu bewegen, was den Datenverkehr vervielfachte und andere Knoten belastete, was es nahezu unmöglich machte, Daten in den Cluster zu schreiben. Und während dieser Zeit blieben wir ohne Protokolle. Und wenn es ein Problem mit dem Server gab, verloren wir im Grunde 1/10 des Clusters. Eine große Anzahl kleiner Indizes erhöhte die Komplexität.

Ohne Protokolle konnten wir die Gründe für den Vorfall nicht nachvollziehen und konnten früher oder später erneut auf denselben Rechen treten, was in der Ideologie unseres Teams inakzeptabel war, da alle unsere Arbeitsmechanismen genau das Gegenteil bewirken sollen – sich nie wiederholen die gleichen Probleme. Dazu benötigten wir die gesamte Menge an Protokollen und deren Bereitstellung nahezu in Echtzeit, da ein Team diensthabender Ingenieure Warnungen nicht nur anhand von Metriken, sondern auch anhand von Protokollen überwachte. Um das Ausmaß des Problems zu verstehen, betrug das Gesamtvolumen der Protokolle zu diesem Zeitpunkt etwa 2 TB pro Tag. 

Wir haben uns zum Ziel gesetzt, den Verlust von Protokollen vollständig zu verhindern und die Zeit ihrer Übermittlung an den ELK-Cluster im Falle höherer Gewalt auf maximal 15 Minuten zu verkürzen (wir haben diese Zahl später als internen KPI herangezogen).

Neuer Rotationsmechanismus und Heiß-Warm-Knoten

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Wir haben die Clusterkonvertierung gestartet, indem wir die ElasticSearch-Version von 5.5.2 auf 6.4.3 aktualisiert haben. Wieder einmal ist unser Cluster der Version 5 ausgefallen und wir haben beschlossen, ihn auszuschalten und vollständig zu aktualisieren – es gibt immer noch keine Protokolle. Wir haben diesen Übergang also in nur wenigen Stunden geschafft.

Die umfangreichste Transformation zu diesem Zeitpunkt war die Implementierung von Apache Kafka auf drei Knoten mit einem Koordinator als Zwischenpuffer. Der Message Broker hat uns vor dem Verlust von Protokollen bei Problemen mit ElasticSearch bewahrt. Gleichzeitig haben wir dem Cluster zwei Knoten hinzugefügt und auf eine Hot-Warm-Architektur mit drei „heißen“ Knoten umgestellt, die sich in verschiedenen Racks im Rechenzentrum befinden. Wir haben Protokolle mithilfe einer Maske, die unter keinen Umständen verloren gehen sollte, an sie umgeleitet – Nginx – sowie Anwendungsfehlerprotokolle. An die verbleibenden Knoten wurden kleinere Protokolle gesendet – Debug, Warnung usw., und nach 2 Stunden wurden „wichtige“ Protokolle von „heißen“ Knoten übertragen.

Um die Anzahl der kleinen Indizes nicht zu erhöhen, haben wir von der Zeitrotation auf den Rollover-Mechanismus umgestellt. In den Foren gab es viele Informationen darüber, dass die Rotation nach Indexgröße sehr unzuverlässig ist, daher haben wir uns entschieden, die Rotation nach der Anzahl der Dokumente im Index zu verwenden. Wir haben jeden Index analysiert und die Anzahl der Dokumente erfasst, nach denen die Rotation funktionieren sollte. Damit haben wir die optimale Shard-Größe erreicht – nicht mehr als 50 GB. 

Clusteroptimierung

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Allerdings haben wir die Probleme noch nicht ganz aus der Welt geschafft. Leider tauchten immer noch kleine Indizes auf: Sie erreichten nicht das angegebene Volumen, wurden nicht rotiert und wurden durch die globale Bereinigung von Indizes gelöscht, die älter als drei Tage waren, da wir die Rotation nach Datum entfernt hatten. Dies führte zu Datenverlust, da der Index vollständig aus dem Cluster verschwand und der Versuch, in einen nicht vorhandenen Index zu schreiben, die Logik des Kurators, den wir für die Verwaltung verwendet hatten, durchbrach. Alias ​​​​für das Schreiben wurde in einen Index umgewandelt und brach die Rollover-Logik, was zu einem unkontrollierten Wachstum einiger Indizes auf bis zu 600 GB führte. 

Beispiel für die Rotationskonfiguration:

сurator-elk-rollover.yaml

---
actions:
  1:
    action: rollover
    options:
      name: "nginx_write"
      conditions:
        max_docs: 100000000
  2:
    action: rollover
    options:
      name: "python_error_write"
      conditions:
        max_docs: 10000000

Wenn kein Rollover-Alias ​​vorhanden war, ist ein Fehler aufgetreten:

ERROR     alias "nginx_write" not found.
ERROR     Failed to complete action: rollover.  <type 'exceptions.ValueError'>: Unable to perform index rollover with alias "nginx_write".

Die Lösung dieses Problems haben wir der nächsten Iteration überlassen und uns einem anderen Thema zugewandt: Wir sind auf die Pull-Logik von Logstash umgestiegen, die eingehende Protokolle verarbeitet (unnötige Informationen entfernt und anreichert). Wir haben es in Docker platziert, das wir über Docker-Compose starten, und wir haben dort auch Logstash-Exporter platziert, der Metriken zur Betriebsüberwachung des Protokollstreams an Prometheus sendet. Auf diese Weise haben wir uns die Möglichkeit gegeben, die Anzahl der Logstash-Instanzen, die für die Verarbeitung jedes Protokolltyps verantwortlich sind, reibungslos zu ändern.

Während wir den Cluster verbesserten, stieg der Traffic von cian.ru auf 12,8 Millionen Unique User pro Monat. Infolgedessen stellte sich heraus, dass unsere Transformationen den Änderungen in der Produktion etwas hinterherhinkten und wir mit der Tatsache konfrontiert wurden, dass die „warmen“ Knoten der Last nicht gewachsen waren und die gesamte Protokolllieferung verlangsamten. Wir haben „heiße“ Daten ohne Ausfälle erhalten, mussten jedoch in die Bereitstellung des Rests eingreifen und einen manuellen Rollover durchführen, um die Indizes gleichmäßig zu verteilen. 

Gleichzeitig wurde das Skalieren und Ändern der Einstellungen von Logstash-Instanzen im Cluster dadurch erschwert, dass es sich um ein lokales Docker-Compose handelte und alle Aktionen manuell ausgeführt wurden (um neue Enden hinzuzufügen, musste alles manuell durchgegangen werden). die Server und führen Sie überall docker-compose up -d aus).

Protokollumverteilung

Im September dieses Jahres waren wir immer noch dabei, den Monolithen zu zerlegen, die Belastung des Clusters nahm zu und der Protokollfluss näherte sich 30 Nachrichten pro Sekunde. 

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Wir haben die nächste Iteration mit einem Hardware-Update gestartet. Wir haben von fünf auf drei Koordinatoren umgestellt, Datenknoten ausgetauscht und Geld und Speicherplatz gewonnen. Für Knoten verwenden wir zwei Konfigurationen: 

  • Für „heiße“ Knoten: E3-1270 v6 / 960 GB SSD / 32 GB x 3 x 2 (3 für Hot1 und 3 für Hot2).
  • Für „warme“ Knoten: E3-1230 v6 / 4 TB SSD / 32 GB x 4.

Bei dieser Iteration haben wir den Index mit Zugriffsprotokollen von Microservices, der den gleichen Platz wie Frontline-Nginx-Protokolle einnimmt, in die zweite Gruppe von drei „heißen“ Knoten verschoben. Wir speichern nun Daten 20 Stunden lang auf „heißen“ Knoten und übertragen sie dann auf „warme“ Knoten in die restlichen Protokolle. 

Wir haben das Problem des Verschwindens kleiner Indizes gelöst, indem wir ihre Rotation neu konfiguriert haben. Jetzt werden die Indizes auf jeden Fall alle 23 Stunden rotiert, auch wenn dort nur wenige Daten vorhanden sind. Dadurch erhöhte sich die Anzahl der Shards leicht (es waren etwa 800), aber aus Sicht der Clusterleistung ist dies erträglich. 

Infolgedessen gab es im Cluster sechs „heiße“ und nur vier „warme“ Knoten. Dies führt zu einer leichten Verzögerung bei Anfragen über lange Zeitintervalle, aber eine Erhöhung der Anzahl der Knoten in der Zukunft wird dieses Problem lösen.

Diese Iteration behebt auch das Problem der fehlenden halbautomatischen Skalierung. Zu diesem Zweck haben wir einen Infrastruktur-Nomad-Cluster bereitgestellt – ähnlich dem, was wir bereits in der Produktion bereitgestellt haben. Die Menge an Logstash ändert sich vorerst nicht automatisch je nach Auslastung, aber dazu kommen wir noch.

Wie wir bei CIAN Terabytes an Protokollen gezähmt haben

Pläne für die Zukunft

Die implementierte Konfiguration lässt sich perfekt skalieren, und jetzt speichern wir 13,3 TB Daten – alle Protokolle für 4 Tage, was für die Notfallanalyse von Alarmen erforderlich ist. Wir wandeln einige der Protokolle in Metriken um, die wir Graphite hinzufügen. Um den Ingenieuren die Arbeit zu erleichtern, verfügen wir über Metriken für den Infrastruktur-Cluster und Skripte zur halbautomatischen Behebung häufiger Probleme. Nach der für nächstes Jahr geplanten Erhöhung der Anzahl der Datenknoten werden wir auf die Datenspeicherung von 4 auf 7 Tage umstellen. Dies wird für die operative Arbeit ausreichen, da wir stets versuchen, Vorfälle so schnell wie möglich zu untersuchen, und für langfristige Untersuchungen stehen Telemetriedaten zur Verfügung. 

Im Oktober 2019 war der Traffic auf cian.ru bereits auf 15,3 Millionen Unique User pro Monat angewachsen. Dies wurde zu einem ernsthaften Test der architektonischen Lösung für die Bereitstellung von Protokollen. 

Jetzt bereiten wir die Aktualisierung von ElasticSearch auf Version 7 vor. Dafür müssen wir jedoch die Zuordnung vieler Indizes in ElasticSearch aktualisieren, da diese von Version 5.5 verschoben wurden und in Version 6 als veraltet deklariert wurden (sie sind in Version einfach nicht vorhanden). 7). Das bedeutet, dass es während des Update-Vorgangs definitiv zu höherer Gewalt kommen wird, die dazu führt, dass wir keine Protokolle mehr haben, solange das Problem behoben ist. Von Version 7 freuen wir uns am meisten auf Kibana mit einer verbesserten Oberfläche und neuen Filtern. 

Wir haben unser Hauptziel erreicht: Wir haben den Verlust von Protokollen gestoppt und die Ausfallzeit des Infrastrukturclusters von 2-3 Abstürzen pro Woche auf ein paar Stunden Wartungsarbeit pro Monat reduziert. All diese Arbeiten in der Produktion sind nahezu unsichtbar. Jetzt können wir jedoch genau feststellen, was mit unserem Dienst passiert. Wir können dies schnell im stillen Modus tun und müssen uns keine Sorgen machen, dass die Protokolle verloren gehen. Im Allgemeinen sind wir zufrieden, glücklich und bereiten uns auf neue Heldentaten vor, über die wir später sprechen werden.

Source: habr.com

Kommentar hinzufügen