Wie wir bei CIAN Terabytes von Logs bÀndigen

Wie wir bei CIAN Terabytes von Logs bÀndigen

Hallo zusammen, mein Name ist Alexander, ich arbeite als Ingenieur bei CIAN und beschĂ€ftige mich mit Systemadministration und Automatisierung von Infrastrukturprozessen. In den Kommentaren zu einem unserer frĂŒheren Artikel wurden wir gebeten, zu erzĂ€hlen, woher wir tĂ€glich 4 TB Logs beziehen und was wir damit machen. Ja, wir haben viele Logs, und zur Verarbeitung wurde ein eigener Infrastruktur-Cluster eingerichtet, der es uns ermöglicht, Probleme schnell zu lösen. In diesem Artikel werde ich darĂŒber berichten, wie wir ihn im Laufe eines Jahres an die stĂ€ndig wachsenden Datenströme angepasst haben.

Wie wir angefangen haben

Wie wir bei CIAN Terabytes von Logs bÀndigen

In den letzten Jahren ist die Last auf cian.ru sehr schnell gewachsen, und im dritten Quartal 2018 erreichte die Besucherzahl der Plattform 11,2 Millionen eindeutige Nutzer pro Monat. In kritischen Momenten verloren wir damals bis zu 40 % der Logs, was es uns nicht ermöglichte, VorfĂ€lle zĂŒgig zu bearbeiten, und wir investierten viel Zeit und Energie in deren Lösung. Außerdem konnten wir oft die Ursache des Problems nicht finden, und es trat nach einer gewissen Zeit wieder auf. Es war die Hölle, und wir mussten etwas daran Ă€ndern.

Zu diesem Zeitpunkt verwendeten wir zum Speichern der Logs einen Cluster aus 10 Datenknoten mit ElasticSearch Version 5.5.2 mit standardmĂ€ĂŸigen Indexeinstellungen. Dieses wurde vor mehr als einem Jahr als populĂ€re und zugĂ€ngliche Lösung implementiert: Damals war der Logstrom nicht so groß, und es machte keinen Sinn, unkonventionelle Konfigurationen zu entwickeln. 

Die Verarbeitung der eingehenden Logs erfolgte durch Logstash auf verschiedenen Ports auf fĂŒnf ElasticSearch-Koordinatoren. Ein Index, unabhĂ€ngig von der GrĂ¶ĂŸe, bestand aus fĂŒnf Shards. Es gab eine stĂŒndliche und tĂ€gliche Rotation, wodurch jede Stunde etwa 100 neue Shards im Cluster erstellt wurden. Solange die Logs nicht zu viele waren, kam der Cluster damit zurecht, und niemand achtete auf seine Einstellungen. 

Probleme des schnellen Wachstums

Das Volumen der generierten Logs wuchs sehr schnell, da zwei Prozesse aufeinandertrafen. Einerseits gab es immer mehr Nutzer des Dienstes. Andererseits begannen wir aktiv, auf eine Mikroservice-Architektur umzusteigen, indem wir unsere alten Monolithe in C# und Python aufteilten. Mehrere Dutzend neuer Mikroservices, die Teile des Monolithen ersetzten, generierten deutlich mehr Logs fĂŒr den Infrastruktur-Cluster. 

Das Skalieren hat dazu gefĂŒhrt, dass der Cluster praktisch unverwaltbar wurde. Als die Protokolle mit einer Geschwindigkeit von 20.000 Nachrichten pro Sekunde eintrafen, erhöhte die hĂ€ufige, nutzlose Rotation die Anzahl der Shards auf 6.000, und es kamen mehr als 600 Shards auf einen Knoten. 

Dies fĂŒhrte zu Problemen mit dem Arbeitsspeicher, und bei dem Ausfall eines Knotens begann der gleichzeitige Umzug aller Shards, was den Datenverkehr vervielfachte und die anderen Knoten belastete, wodurch das Schreiben von Daten in den Cluster fast unmöglich wurde. In dieser Zeit hatten wir keine Protokolle. Und bei einem Problem mit Server verloren wir im Prinzip 1/10 des Clusters. Eine Vielzahl von Indizes kleiner GrĂ¶ĂŸe machte die Situation noch komplizierter.

Ohne Protokolle konnten wir die Ursachen des Vorfalls nicht verstehen und hĂ€tten frĂŒher oder spĂ€ter die gleichen Fehler wiederholen können. In der Ideologie unseres Teams war das unakzeptabel, da alle unsere Arbeitsmechanismen darauf ausgelegt sind, die gleichen Probleme niemals zu wiederholen. Dazu benötigten wir das vollstĂ€ndige Protokollvolumen und deren Zustellung fast in Echtzeit, da das Team der Bereitschaftsingenieure nicht nur Alerts von Metriken, sondern auch von Protokollen ĂŒberwachte. Um das Ausmaß des Problems zu verstehen: Zu diesem Zeitpunkt betrug das gesamte Protokollvolumen etwa 2 TB pro Tag. 

Wir haben uns zum Ziel gesetzt, den Verlust von Protokollen vollstĂ€ndig auszuschließen und die Lieferzeit in den ELK-Cluster im Maximum auf 15 Minuten wĂ€hrend von NotfĂ€llen zu reduzieren (auf diese Zahl stĂŒtzten wir uns spĂ€ter als internes KPI).

Neuer Rotationsmechanismus und Hot-Warm-Knoten

Wie wir bei CIAN Terabytes von Logs bÀndigen

Mit der Umstellung des Clusters begannen wir mit der Aktualisierung der ElasticSearch-Version von 5.5.2 auf 6.4.3. Der Cluster der Version 5 fiel erneut aus, und wir beschlossen, ihn abzuschalten und komplett zu aktualisieren — schließlich gab es ohnehin keine Protokolle. Daher haben wir diesen Wechsel in nur wenigen Stunden vollzogen.

Die umfangreichste Umstellung in dieser Phase war die Implementierung von Apache Kafka auf drei Knoten mit dem Koordinator als Zwischenpuffer. Der Nachrichtensbroker hat uns vor dem Verlust von Logs wĂ€hrend Problemen mit ElasticSearch bewahrt. Gleichzeitig haben wir 2 Knoten zum Cluster hinzugefĂŒgt und sind auf eine Hot-Warm-Architektur mit drei "hot" Knoten umgestiegen, die in verschiedenen Racks im Rechenzentrum platziert sind. Auf diesen haben wir die Logs umgeleitet, die auf keinen Fall verloren gehen dĂŒrfen — nginx sowie Logs der Anwendungsfehler. Auf die anderen Knoten gingen weniger wichtige Logs — debug, warning usw., und nach 24 Stunden wurden "wichtige" Logs von den "hot" Knoten verschoben.

Um die Anzahl kleiner Indizes nicht zu erhöhen, sind wir von der zeitbasierten Rotation auf das Mechanismus des Rollovers umgestiegen. In den Foren gab es viele Informationen, dass die Rotation nach der IndexgrĂ¶ĂŸe sehr unzuverlĂ€ssig ist, weshalb wir beschlossen haben, die Rotation nach der Anzahl der Dokumente im Index zu verwenden. Wir haben jeden Index analysiert und die Anzahl der Dokumente festgehalten, nach der die Rotation erfolgen sollte. So haben wir die optimale Shard-GrĂ¶ĂŸe erreicht — nicht mehr als 50 GB. 

Cluster-Optimierung

Wie wir bei CIAN Terabytes von Logs bÀndigen

Wir haben jedoch die Probleme nicht vollstĂ€ndig beseitigt. Leider tauchten weiterhin kleine Indizes auf: Sie erreichten nicht das vorgesehene Volumen, wurden nicht rotiert und gelöscht durch eine globale Bereinigung der Indizes, die Ă€lter als drei Tage sind, da wir die zeitgesteuerte Rotation entfernt hatten. Dies fĂŒhrte zu Datenverlusten, da der Index vollstĂ€ndig aus dem Cluster verschwand, und der Versuch, in einen nicht existierenden Index zu schreiben, brach die Logik des Curators, den wir zur Verwaltung verwendeten. Alias zum Schreiben verwandelte sich in einen Index und brach die Logik des Rollovers, was zu einem unkontrollierten Wachstum einiger Indizes auf bis zu 600 GB fĂŒhrte. 

Zum Beispiel fĂŒr die Rollover-Konfiguration:

curator-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

Bei fehlendem Rollover-Alias trat ein Fehler auf:

ERROR     alias "nginx_write" nicht gefunden.
ERROR     Aktion konnte nicht abgeschlossen werden: rollover.  : Unable to perform index rollover with alias "nginx_write".

Die Lösung dieses Problems haben wir auf die nĂ€chste Iteration verschoben und uns einer anderen Frage gewidmet: Wir sind zur Pull-Logik von Logstash ĂŒbergegangen, die sich mit der Verarbeitung eingehender Protokolle (Entfernung ĂŒberflĂŒssiger Informationen und Anreicherung) beschĂ€ftigt. Wir haben es in Docker platziert, das wir ĂŒber Docker-Compose ausfĂŒhren, und dort auch den Logstash-Exporter untergebracht, der Metriken an Prometheus zur EchtzeitĂŒberwachung des Protokollflusses ĂŒbergibt. So haben wir uns die Möglichkeit gegeben, die Anzahl der Logstash-Instanzen, die fĂŒr die Verarbeitung jeder Art von Protokollen zustĂ€ndig sind, flexibel zu Ă€ndern.

WĂ€hrend wir den Cluster optimierten, wuchs die Besucherzahl von cian.ru auf 12,8 Millionen einzigartige Nutzer pro Monat. Infolgedessen stellte sich heraus, dass unsere Transformationen nicht ganz mit den Änderungen in der Produktion Schritt hielten, und wir sahen uns dem Problem gegenĂŒber, dass die "warmen" Knoten mit der Last ĂŒberfordert waren und die gesamte Protokolllieferung verlangsamten. "Heiße" Daten erhielten wir ohne AusfĂ€lle, aber bei der Lieferung der anderen mussten wir manuell eingreifen und einen Roll-over durchfĂŒhren, um die Indizes gleichmĂ€ĂŸig zu verteilen. 

Das Skalieren und Anpassen der Einstellungen der Logstash-Instanzen im Cluster wurde dadurch erschwert, dass es sich um ein lokales Docker-Compose handelte und alle Aktionen manuell durchgefĂŒhrt werden mussten (um neue Endpunkte hinzuzufĂŒgen, musste man manuell auf allen Servern Docker-Compose up -d ausfĂŒhren).

Neuverteilung der Protokolle

Im September dieses Jahres setzten wir weiterhin den Monolithen auseinander, die Last im Cluster nahm zu und der Protokollfluss nÀherte sich 30.000 Nachrichten pro Sekunde. 

Wie wir bei CIAN Terabytes von Logs bÀndigen

Die nĂ€chste Iteration begannen wir mit einem Hardware-Upgrade. Von fĂŒnf Koordinatoren gingen wir auf drei ĂŒber, tauschten die Datenknoten aus und gewannen sowohl finanziell als auch in Bezug auf den Speicherplatz. FĂŒr die Knoten verwenden wir zwei Konfigurationen: 

  • FĂŒr "heiße" Knoten: E3-1270 v6 / 960Gb SSD / 32 Gb x 3 x 2 (3 fĂŒr Hot1 und 3 fĂŒr Hot2).
  • FĂŒr "warme" Knoten: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

In dieser Iteration haben wir den Index mit den Access-Logs der Mikrodienste, der den gleichen Platz wie die Logs der Frontend-Nginx einnimmt, in die zweite Gruppe aus drei "heißen" Knoten verschoben. Daten auf den "heißen" Knoten speichern wir jetzt 20 Stunden und ĂŒbertragen sie dann zu den "warmen" Knoten mit den anderen Protokollen. 

Wir haben das Problem mit dem Verschwinden kleiner Indizes durch eine Neuausrichtung ihrer Rotation gelöst. Jetzt rotieren die Indizes in jedem Fall alle 23 Stunden, auch wenn nur wenige Daten vorhanden sind. Das hat die Anzahl der Shards leicht erhöht (auf etwa 800), was jedoch aus Sicht der Cluster-Leistung akzeptabel ist. 

Im Cluster gibt es nun sechs "heiße" und nur vier "warme" Knoten. Dies verursacht eine kleine Verzögerung bei Anfragen ĂŒber große ZeitrĂ€ume hinweg, aber die Erhöhung der Knotenanzahl in der Zukunft wird dieses Problem lösen.

In dieser Iteration haben wir auch das Problem der fehlenden halbautomatischen Skalierung behoben. Dazu haben wir ein infrastrukturelles Nomad-Cluster bereitgestellt – Ă€hnlich dem, das bereits bei uns in der Produktion eingesetzt wird. Momentan variiert die Anzahl der Logstash-Instanzen noch nicht automatisch je nach Last, aber wir werden auch dies in Angriff nehmen.

Wie wir bei CIAN Terabytes von Logs bÀndigen

ZukunftsplÀne

Die implementierte Konfiguration skaliert hervorragend und derzeit speichern wir 13,3 TB Daten – alle Logs von 4 Tagen, die fĂŒr die dringende Analyse von Alerts benötigt werden. Teile der Logs wandeln wir in Metriken um, die wir in Graphite speichern. Um die Arbeit der Ingenieure zu erleichtern, haben wir Metriken fĂŒr das Infrastruktur-Cluster sowie Skripte zur halbautomatischen Behebung typischer Probleme. Nach der geplanten Erhöhung der Anzahl an Datenknoten im nĂ€chsten Jahr werden wir die Datenspeicherung von 4 auf 7 Tage umstellen. Das wird fĂŒr die operative Arbeit ausreichend sein, da wir immer versuchen, VorfĂ€lle so schnell wie möglich zu untersuchen, und fĂŒr langfristige Ermittlungen stehen Telemetriedaten zur VerfĂŒgung. 

Im Oktober 2019 stieg die Besucherzahl von cian.ru bereits auf 15,3 Millionen einzigartige Nutzer pro Monat. Dies stellte eine ernsthafte PrĂŒfung der architektonischen Lösung zur Log-Übertragung dar. 

Jetzt bereiten wir das Update auf ElasticSearch Version 7 vor. Allerdings mĂŒssen wir dafĂŒr das Mapping vieler Indizes in ElasticSearch aktualisieren, da sie von Version 5.5 stammen und in Version 6 als veraltet gekennzeichnet wurden (in Version 7 sind sie einfach nicht mehr vorhanden). Das bedeutet, dass es wĂ€hrend des Updates mit Sicherheit zu unvorhergesehenen Problemen kommen wird, die uns kurzfristig ohne Logs lassen. Von Version 7 erhoffen wir uns vor allem Kibana mit einer verbesserten BenutzeroberflĂ€che und neuen Filtern. 

Wir haben unser Hauptziel erreicht: Wir haben aufgehört, Protokolle zu verlieren, und die Ausfallzeit unseres Infrastrukturclusters von 2-3 AbstĂŒrzen pro Woche auf ein paar Stunden Wartungsarbeiten pro Monat reduziert. All diese Arbeit ist in der Produktion fast unbemerkt. Dennoch können wir nun genau bestimmen, was mit unserem Service passiert, können dies schnell in einem ruhigen Modus tun und uns keine Sorgen machen, dass Protokolle verloren gehen. Insgesamt sind wir zufrieden, glĂŒcklich und bereiten uns auf neue Heldentaten vor, ĂŒber die wir spĂ€ter berichten werden.

Quelle: habr.com

60GB SSD 8Gb DDR4