Kapitel 4. Operative Sichtbarkeit

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

Sichtbarkeit (oft auch als Monitoring bezeichnet) ist der Eckpfeiler des Datenbank-Reliability-Engineerings. Betriebliche Sichtbarkeit bedeutet, dass wir durch regelmäßiges Messen und Sammeln von Datenpunkten über die verschiedenen Komponenten ein Bewusstsein für die Arbeitseigenschaften eines Datenbankdienstes haben. Warum ist das wichtig? Warum brauchen wir betriebliche Sichtbarkeit? Hier sind nur einige der Gründe:

Störungsbehebung und Alarmierung

Wir müssen wissen, wann Dinge kaputt gehen oder kurz davor stehen, damit wir sie reparieren können, damit wir nicht gegen unsere Service-Level Objectives (SLOs) verstoßen.

Leistungs- und Verhaltensanalyse

Es ist wichtig, die Latenzverteilung in unseren Anwendungen zu verstehen, einschließlich der Ausreißer, und wir müssen die Trends im Laufe der Zeit kennen. Diese Daten sind wichtig, um die Auswirkungen von neuen Funktionen, Experimenten und Optimierungen zu verstehen.

Kapazitätsplanung

Die Möglichkeit, das Nutzerverhalten und die Effizienz der Anwendung mit den tatsächlichen Ressourcen (CPU, Netzwerk, Speicherung, Durchsatz, Speicher) zu korrelieren, ist entscheidend, um sicherzustellen, dass du in einem geschäftskritischen Moment nicht in Kapazitätsengpässe gerätst.

Fehlersuche und Postmortems

Schnelllebigkeit bedeutet, dass Dinge kaputt gehen. Eine gute Betriebstransparenz gibt dir die Möglichkeit, Fehlerquellen und Optimierungspunkte schnell zu erkennen, um zukünftige Risiken zu minimieren. Menschliches Versagen ist nie die Hauptursache, aber Systeme können immer verbessert und widerstandsfähiger gemacht werden.

Unternehmensanalyse

Zu verstehen, wie deine Geschäftsfunktionen genutzt werden, kann ein wichtiger Indikator für Probleme sein, aber es ist auch wichtig für alle, zu sehen, wie die Leute deine Funktionen nutzen und wie viel Wert im Vergleich zu den Kosten erzielt wird.

Korrelation und Kausalität

Indem du Ereignisse in der Infrastruktur und der Anwendung in deinem Operational Visibility Stack registrierst, kannst du Änderungen der Arbeitslast, des Verhaltens und der Verfügbarkeit schnell korrelieren. Beispiele für solche Ereignisse sind Anwendungsimplementierungen, Infrastrukturänderungen und Änderungen des Datenbankschemas.

So ziemlich jede Facette deines Unternehmens benötigt echte operative Sichtbarkeit - OpViz. Unser Ziel in diesem Kapitel ist es, dir zu helfen, die Beobachtbarkeit in den Architekturen, mit denen du arbeiten wirst, zu verstehen. Es gibt zwar nicht die eine Reihe von Tools, die wir befürworten, aber es gibt Grundsätze, eine allgemeine Taxonomie und Nutzungsmuster, die du lernen kannst. Wir stellen dies anhand zahlreicher Fallstudien und Beispielansätze vor. Betrachten wir zunächst die Entwicklung von OpViz von den traditionellen Ansätzen zu den heute verwendeten.

Betriebliche Sichtbarkeit ist eine große Sache! Wir brauchen einige Regeln dafür, wie wir diesen wichtigen Prozess gestalten, aufbauen und nutzen.

Die neuen Regeln der operativen Sichtbarkeit

Moderne betriebliche Sichtbarkeit geht davon aus, dass die Datenbestände verteilt sind, oft sogar massiv. Sie erkennt an, dass die Sammlung und sogar die Präsentation von Daten nicht so wichtig sind wie die Analyse. Es werden immer zwei Fragen gestellt, die hoffentlich schnell beantwortet werden können: "Wie wirkt sich das auf meine SLOs aus?" und "Wie ist das kaputt und warum?". Mit anderen Worten: Du darfst deinen OpViz-Stack nicht als eine Reihe von Hilfsprogrammen behandeln, die dem Ops-Team überlassen werden, sondern musst ihn als Business Intelligence (BI)-Plattform entwickeln, aufbauen und pflegen. Das heißt, du musst sie genauso behandeln wie ein Data Warehouse oder eine Big Data-Plattform. Die Spielregeln haben sich geändert, um dies widerzuspiegeln.

OpViz-Systeme wie BI-Systeme behandeln

Wenn du ein BI-System entwickelst, denkst du zuerst über die Fragen nach, die deine Nutzer stellen werden, und baust darauf auf. Berücksichtige die Bedürfnisse deiner Nutzer in Bezug auf Datenlatenz ("Wie schnell sind die Daten verfügbar?"), Datenauflösung ("Wie tief kann der Nutzer in die Tiefe gehen?") und Datenverfügbarkeit. Mit anderen Worten: Du definierst SLOs für deinen OpViz-Dienst. (Siehe Kapitel 2.)

Eine ausgereifte OpViz-Plattform zeichnet sich dadurch aus, dass sie nicht nur den Zustand der Infrastruktur, auf der die Anwendung läuft, darstellen kann, sondern auch das Verhalten der Anwendungen, die auf dieser Infrastruktur laufen. Letztlich sollte sie auch in der Lage sein, jedem zu zeigen, wie das Geschäft läuft und wie es von der Infrastruktur und den Anwendungen, auf die sich das Unternehmen verlässt, beeinflusst wird. In diesem Sinne muss die OpViz-Plattform Betriebs- und Datenbankingenieure, Softwareentwickler, Geschäftsanalysten und Führungskräfte unterstützen.

Verteilte ephemere Umgebungen auf dem Weg zur Norm

Wir haben bereits darüber gesprochen, dass die Lebenszyklen unserer Datenbankinstanzen mit der Einführung virtueller Infrastrukturen tendenziell abnehmen. Auch wenn sie immer noch viel langlebiger sind als andere Infrastrukturkomponenten, müssen wir in der Lage sein, Kennzahlen für Dienste zu sammeln, die aus kurzlebigen Komponenten bestehen, die aggregiert sind und nicht aus einzelnen Datenbankhosts.

Abbildung 4-1 zeigt ein relativ stabiles Master/Replikat-Setup für einen relationalen Datenspeicher, in dem an einem Tag zahlreiche Aktivitäten stattfinden können . Am Ende des Tages können wir ein völlig neues Setup sehen, wie in Abbildung 4-2 dargestellt.

Abbildung 4-1. Typisches Master/Replikat-Setup
Abbildung 4-2. Ende von Tag 1

Diese Art von dynamischer Infrastruktur erfordert, dass wir Metriken auf Basis von Rollen und nicht von Hostnamen oder IPs speichern. Anstatt also eine Reihe von Metriken als DB01 zu speichern, würden wir die Metriken der Rolle "Master" hinzufügen, damit wir das gesamte Verhalten des Masters auch nach dem Wechsel zu einem neuen Master sehen können. Service Discovery Systeme leisten gute Arbeit, indem sie die Abstraktion über die dynamischen Teile der Infrastruktur aufrechterhalten, um dies zu erleichtern.

Speichere mit hoher Auflösung für wichtige Metriken

Wie in Kapitel 2 beschrieben, ist eine hohe Auflösung entscheidend für das Verständnis der Arbeitslast von Anwendungen. Alles, was mit deinen SLOs zu tun hat, sollte zumindest mit einer Abtastrate von einer Sekunde oder weniger erfasst werden, um sicherzustellen, dass du verstehst, was im System vor sich geht. Eine gute Faustregel ist, dass du dir überlegst, ob die Metrik genügend Schwankungen aufweist, um deine SLOs in einer Spanne von 1 bis 10 Sekunden zu beeinflussen, und dass du die Granularität danach ausrichtest.

Wenn du z. B. eine begrenzte Ressource wie die CPU überprüfst, solltest du diese Daten mit einer Abtastrate von einer Sekunde oder weniger erfassen, da sich CPU-Warteschlangen recht schnell aufbauen und wieder abbauen können. Bei Latenz-SLOs im Millisekundenbereich müssen diese Daten gut genug sein, um zu erkennen, ob die CPU-Sättigung der Grund für die Beeinträchtigung der Latenz deiner Anwendung ist. Warteschlangen für Datenbankverbindungen sind ein weiterer Bereich, der ohne sehr häufige Stichproben übersehen werden kann.

Umgekehrt kannst du bei sich selten ändernden Daten wie Festplattenspeicher oder Serviceverfügbarkeit mit einminütigen oder höheren Abtastraten messen, ohne Daten zu verlieren. Hohe Abtastraten verbrauchen eine Menge Ressourcen und du solltest sie mit Bedacht einsetzen. Ebenso solltest du weniger als fünf verschiedene Abtastraten verwenden, um die Einfachheit und Struktur deiner OpViz-Plattform zu erhalten.

Ein Beispiel für die Auswirkungen einer zu hohen Abtastrate ist das Diagramm in Abbildung 4-3.

Abbildung 4-3. Reale Arbeitslast mit Spikes

Abbildung 4-3 zeigt zwei Ausschläge, gefolgt von einem langen Anstieg. Wenn wir diese Metrik nun in Intervallen von einer Minute abfragen, würde die Grafik wie in Abbildung 4-4 aussehen.

Beachte, dass wir keinen einzigen Spike sehen, und die zweite Grafik sieht viel harmloser aus. Tatsächlich wird unsere Alarmierungsschwelle erst in Minute drei überschritten. Wenn wir von einem einminütigen Zeitplan für die Speicherung und die Überprüfung der Alarmregeln ausgehen, würden wir erst 7,5 Minuten nach dem Verstoß gegen die Regel einen Alarm an den Betreiber senden!

Abbildung 4-4. Visualisierung der Arbeitsbelastung durch eine einminütige Stichprobe.

Halte deine Architektur einfach

Bei einer wachsenden Plattform ist es nicht ungewöhnlich, dass 10.000 oder mehr Metriken auf verschiedenen Granularitätsebenen für eine beliebige Anzahl von Instanzen/Servern, die in der Infrastruktur jederzeit ein- und ausgeschaltet werden, überprüft werden. Dein Ziel ist es, die oben genannten Fragen schnell zu beantworten, was bedeutet, dass du ständig darauf hinarbeiten musst, den Signal-Rausch-Abstand zu verringern. Das bedeutet, dass du die Datenmenge, die du in dein System einspeisen kannst, rücksichtslos reduzieren musst, vor allem an den Punkten, an denen du mit Menschen interagierst, wie z.B. bei der Präsentation und der Alarmierung.

"Überwache alles" ist schon seit geraumer Zeit ein geflügeltes Wort und war eine Reaktion auf Umgebungen, in denen die Überwachung spärlich und ad hoc war. Die Wahrheit ist jedoch, dass verteilte Systeme und Multiservice-Anwendungen zu viele Metriken erzeugen. Unternehmen in der Anfangsphase haben weder das Geld noch die Zeit, diese Menge an Überwachungsdaten zu verwalten. Größere Unternehmen sollten das Wissen haben, sich auf das zu konzentrieren, was für ihre Systeme entscheidend ist.

Zur Vereinfachung und Signalverstärkung gehört auch die Standardisierung. Das bedeutet, dass Templating, Auflösungen, Retentionen und alle anderen Knöpfe und Funktionen, die den Ingenieuren präsentiert werden, standardisiert werden. So stellst du sicher, dass dein System leicht zu verstehen und damit benutzerfreundlich für die Beantwortung von Fragen und die Identifizierung von Problemen ist.

Wenn du dich an diese vier Regeln erinnerst, wirst du bei der Entwicklung und dem Aufbau von unglaublich wertvollen und nützlichen Überwachungssystemen auf Kurs bleiben. Wenn du feststellst, dass du gegen sie verstößt, frage dich, warum. Wenn du keine wirklich gute Antwort hast, solltest du zu den Grundlagen zurückkehren.

Ein OpViz-Framework

Wir könnten ein ganzes Buch über dieses Thema schreiben. Wenn du anfängst, die richtigen Daten für die OpViz-Plattform zu sammeln und vorzubereiten, damit du deine Arbeit machen kannst, solltest du in der Lage sein, eine gute Plattform zu erkennen und dich für eine bessere Plattform einzusetzen. Das ist unser Ziel in diesem Abschnitt.

Betrachten wir unsere OpViz-Plattform als ein großes, verteiltes E/A-Gerät. Die Daten werden hineingeschickt, weitergeleitet, strukturiert und kommen schließlich auf der anderen Seite in nützlicher Form wieder heraus. Das hilft dir, deine Systeme besser zu verstehen, Verhaltensweisen zu erkennen, die durch defekte oder bald defekte Komponenten verursacht werden, und deine SLOs zu erfüllen. Schauen wir uns den Prozess einmal genauer an:

  • Die Daten werden von den Agenten auf den Clients generiert und dann an einen zentralen Collector für den jeweiligen Datentyp gesendet (d.h. Metriken an Sensu oder CollectD, Ereignisse an Graphite, Logs an Logstash oder Splunk):

    • Gelegentlich führt ein zentralisiertes Überwachungssystem (wie Sensu oder Nagios) neben der oben erwähnten Push-Methode auch Prüfungen über eine Pull-Methode durch.

    • Ein Vorteil der verteilten Prüfung - die App generiert Prüfungen und leitet sie weiter - ist, dass deutlich weniger Konfigurationsmanagement erforderlich ist als bei eng gekoppelten Systemen wie Nagios, bei denen du den Agenten und den Überwachungsserver gemeinsam konfigurieren musst.

  • Die Collectors speichern Daten (in Systemen wie Graphite, InfluxDB oder ElasticSearch) oder leiten sie an Event-Router/Prozessoren (wie Riemann) weiter.

  • Event-Router verwenden Heuristiken, um Daten an die richtigen Stellen zu senden.

  • Die Datenausgabe umfasst eine langfristige Speicherung, Diagramme, Warnungen, Tickets und externe Anrufe.

Anhand dieser Ausgaben können wir den wahren Wert unseres OpViz-Stacks ermitteln.

Daten Eingang

Um Ergebnisse zu erzielen, brauchen wir gute Inputs. Wann immer es möglich ist, solltest du Daten verwenden, die bereits von deiner Umgebung generiert werden, anstatt künstliche Sonden zu verwenden. Wenn du einen Nutzer simulierst, indem du eine Anfrage an das System sendest, nennt man das Blackbox Monitoring. Beim Blackbox-Monitoring schickst du "Kanarienvögel", oder beobachtest die Ein- und Ausgänge von der Internetkante aus. Blackbox-Monitoring kann sehr effektiv sein, wenn du nur wenig Datenverkehr hast oder die Daten nicht häufig genug abgerufen werden, um sie zu überwachen. Wenn du aber genügend Daten generierst, sind echte Kennzahlen, auch Whitebox-Monitoring genannt, unendlich viel attraktiver. Whitebox-Tests setzen voraus, dass du eine Menge über deine Anwendung weißt, und am spezifischsten ist es, wenn du die Interna der Anwendung instrumentierst. Gute Tools dafür sind AppDynamics, NewRelic oder Honeycomb. Mit solchen Tools kannst du den Weg eines einzelnen Nutzers durch die Anwendung bis hin zur Datenbank verfolgen.

Ein Vorteil dieses Ansatzes ist, dass alles, was Daten erzeugt, zu einem Agenten wird. Eine zentralisierte, monolithische Lösung, die Checks und Probes generiert, lässt sich nur schwer skalieren, wenn du wächst. Bei Whitebox-Tests hingegen hast du diese Aufgabe über deine gesamte Architektur verteilt. Diese Art von Architektur ermöglicht es außerdem, dass sich neue Dienste und Komponenten problemlos bei deiner Sammelschicht an- und abmelden können, was nach unseren OpViz-Regeln eine gute Sache ist. Trotzdem gibt es immer wieder Situationen, in denen ein Überwachungssystem, das Remote-Ausführungen im Pull-Verfahren durchführen kann, von großem Nutzen ist, z. B. um zu prüfen, ob ein Dienst läuft, ob die Replikation läuft oder ob ein wichtiger Parameter auf deinen Datenbankhosts aktiviert ist.

OK, wir wollen also all diese wertvollen Daten an unsere OpViz-Plattform senden. Über welche Art von Daten reden wir überhaupt?

Telemetrie/Metrik

Ah, Metriken! So vielfältig. So allgegenwärtig. Eine Metrik ist die Messung einer Eigenschaft, die eine Anwendung oder eine Komponente deiner Infrastruktur besitzt. Metriken werden in regelmäßigen Abständen beobachtet, wodurch eine Zeitreihe entsteht, die die Eigenschaft(en), den Zeitstempel und den Wert enthält. Zu den Eigenschaften gehören z. B. der Host, der Dienst oder das Rechenzentrum. Der wahre Wert dieser Daten liegt in der Beobachtung im Zeitverlauf durch Visualisierungen wie Diagramme.

Metriken werden in der Regel auf vier verschiedene Arten gespeichert:

Zähler

Dies sind kumulative Messwerte, die angeben, wie oft ein bestimmtes Ereignis aufgetreten ist.

Gauges

Das sind Kennzahlen, die sich in eine beliebige Richtung ändern und einen aktuellen Wert anzeigen, z. B. Temperatur, Aufträge in der Warteschlange oder aktive Sperren.

Histogramme

Eine Reihe von Ereignissen, die in konfigurierte Bereiche aufgeteilt sind, um die Verteilung zu zeigen.

Zusammenfassungen

Diese Funktion ähnelt dem Histogramm, konzentriert sich aber auf den Nachweis von Zählungen in gleitenden Zeitfenstern.

Metriken werden oft mit mathematischen Funktionen versehen, um den Menschen zu helfen, einen Wert aus ihren Visualisierungen abzuleiten. Diese Funktionen schaffen mehr Wert, aber es ist wichtig, sich daran zu erinnern, dass es sich um abgeleitete Daten handelt und dass die Rohdaten genauso wichtig sind. Wenn du Mittelwerte pro Minute ermittelst, aber nicht über die zugrunde liegenden Daten verfügst, kannst du keine Mittelwerte für größere Zeitfenster wie Stunden oder Tage erstellen. Im Folgenden findest du einige der Funktionen:

  • Graf

  • Summe

  • Durchschnitt

  • Median

  • Perzentile

  • Standardabweichung

  • Raten der Veränderung

  • Ausschüttungen

Verteilungen visualisieren

Die Visualisierung einer Verteilung ist sehr wertvoll, um die Art von Daten zu betrachten, die oft in Web-Architekturen erzeugt werden. Diese Daten sind selten normal verteilt und haben oft lange Schwänze. Es kann schwierig sein, dies in normalen Diagrammen zu erkennen. Mit der Möglichkeit, Verteilungsdiagramme über einen bestimmten Zeitraum zu erstellen, kannst du neue Darstellungsformen wie Histogramme im Zeitverlauf und Flammendiagramme erstellen, die einem menschlichen Operator helfen, die Arbeitslast in deinen Systemen zu visualisieren.1

Metriken sind die Quelle für die Identifizierung von Symptomen zugrundeliegender Probleme und daher entscheidend für die frühzeitige Erkennung und schnelle Lösung einer Vielzahl von Problemen, die deine SLOs beeinträchtigen könnten.

Veranstaltungen

Ein Ereignis ist eine diskrete Aktion, die in der Umgebung stattgefunden hat. Eine Änderung an einer Konfiguration ist ein Ereignis. Ein Code-Einsatz ist ein Ereignis. Ein Datenbank-Master-Failover ist ein Ereignis. Jedes dieser Ereignisse kann ein Signal sein, das dazu dient, Symptome mit Ursachen in Verbindung zu bringen.

Logs

Ein Log wird für ein Ereignis erstellt, daher kannst du Log-Ereignisse als eine Teilmenge eines Ereignisses betrachten. Betriebssysteme, Datenbanken und Anwendungen erstellen alle bei bestimmten Ereignissen Protokolle. Im Gegensatz zu Metriken können Protokolle zusätzliche Daten und Kontext zu einem Ereignis liefern. Ein Datenbankabfrageprotokoll kann dir zum Beispiel sagen, wann eine Abfrage ausgeführt wurde, wichtige Metriken über diese Abfrage und sogar den Datenbankbenutzer, der sie ausgeführt hat.

Daten raus

Die Daten fließen also in unsere Systeme, was zwar schön und gut ist, uns aber nicht dabei hilft, unsere Fragen zu beantworten oder unsere SLOs zu erfüllen, nicht wahr? Was sollten wir in diesem OpViz-Rahmen erstellen? Schauen wir uns das mal genauer an:

Warnungen

Ein Alarm ist eine Unterbrechung für einen Menschen, die ihn anweist, seine Arbeit zu unterbrechen und einen Regelverstoß zu untersuchen, der den Alarm ausgelöst hat. Dies ist ein kostspieliger Vorgang und sollte nur dann eingesetzt werden, wenn die SLOs unmittelbar von einer Verletzung bedroht sind.

Tickets/Aufgaben

Tickets und Aufgaben werden erstellt, wenn Arbeit erledigt werden muss, aber keine Katastrophe unmittelbar bevorsteht. Das Ergebnis der Überwachung sollten Tickets/Aufgaben sein, die in die Warteschlangen der Ingenieure für die Arbeit aufgenommen werden.

Benachrichtigungen

Manchmal willst du einfach nur festhalten, dass ein Ereignis eingetreten ist, um den Kontext für andere zu schaffen, z.B. wenn Code-Implementierungsereignisse registriert werden. Benachrichtigungen werden oft an einen Chatroom, ein Wiki oder ein Kollaborationstool weitergeleitet, um sie sichtbar zu machen, ohne den Arbeitsablauf zu unterbrechen.

Automatisierung

Es gibt Zeiten, in denen Daten, insbesondere Auslastungsdaten, darauf hinweisen, dass mehr oder weniger Kapazität benötigt wird. Autoskalierungsgruppen können in solchen Fällen aufgerufen werden, um Ressourcenpools zu verändern. Dies ist nur ein Beispiel für die Automatisierung als Ergebnis der Überwachung.

Visualisierung

Diagramme sind eine der häufigsten Ausgaben von OpViz. Sie werden zu Dashboards zusammengestellt, die den Bedürfnissen einer bestimmten Nutzergemeinschaft entsprechen, und sind ein wichtiges Werkzeug, mit dem Menschen Mustererkennung betreiben können.

Bootstrapping deiner Überwachung

Wenn du wie die meisten vernünftigen Menschen bist, fühlst du dich vielleicht von all den Dingen, die passieren sollten, überwältigt. Das ist ganz normal! Dies ist ein guter Zeitpunkt, um dich daran zu erinnern, dass alles, was wir hier aufbauen, Teil eines iterativen Prozesses ist. Fang klein an, lass die Dinge sich entwickeln und füge mehr hinzu, wenn du es brauchst. Nirgendwo ist das so wichtig wie in einem Startup.

Als brandneues Startup fängst du bei Null an. Keine Metriken, keine Warnmeldungen, keine Sichtbarkeit - nur ein Haufen Ingenieure, die übermäßig optimistischen Code schreiben. Viele Start-ups haben irgendwo in einer öffentlichen Cloud eine Instanz, die als Prototyp oder Testumgebung diente und dann irgendwie zu ihrer Hauptproduktionsdatenbank wurde. Kopf? Das ist der Schreibtisch!

Vielleicht wurdest du gerade als erster Ops/Database Engineer in einem jungen Startup eingestellt und du siehst, was die Softwareentwickler in Sachen Überwachung oder Sichtbarkeit entwickelt haben, und es ist praktisch... null.

Kommt dir das bekannt vor? Wenn du Erfahrung mit Start-ups hast, sollte es das. Das ist nichts, wofür du dich schämen musst! So wird die Wurst in einem Startup gemacht. Ein Startup, das damit anfängt, ein ausgeklügeltes Ökosystem für die betriebliche Sichtbarkeit aufzubauen, bevor es tatsächlich gebraucht wird, ist ein dummes Startup. Startups sind erfolgreich, wenn sie sich auf ihr Kernprodukt konzentrieren, schnell iterieren, aggressiv nach Kunden suchen, auf Kundenfeedback und Produktionsrealitäten reagieren und schwierige Entscheidungen darüber treffen, wo sie ihre wertvollen technischen Ressourcen einsetzen. Startups sind erfolgreich, wenn sie aufwändige Systeme zur Leistungsüberwachung einrichten, sobald sie sie brauchen, nicht vorher. Startups schlagen immer wieder fehl, aber in der Regel nicht, weil die Ingenieure es versäumt haben, jede denkbare Kennzahl für die Speicherung im Voraus zu ermitteln und zu messen. Was wir brauchen, ist ein Minimum Viable Monitoring Set.

Es gibt unendlich viele Metriken, die du zwischen der Datenbank, dem System, der Speicherung und den verschiedenen Anwendungsschichten überwachen kannst. Im Zustand der physiologischen Bedürfnisse solltest du in der Lage sein, festzustellen, ob deine Datenbank in Betrieb ist oder nicht. Wenn du darauf hinarbeitest, den Zustand "Wertschätzung" zu erreichen, beginnst du damit, andere Symptome zu überwachen, die du identifiziert hast und die mit echten Problemen korrelieren, wie z.B. die Anzahl der Verbindungen oder der Prozentsatz der Sperren. Ein üblicher Verlauf sieht wie folgt aus:

  • Überprüfe, ob deine Datenbanken aktiv sind oder nicht (Pull-Checks).

  • Überwache allgemeine Latenz-/Fehlermetriken und End-to-End-Gesundheitschecks (Push-Checks).

  • Instrumentiere die Anwendungsschicht, um die Latenz/Fehler bei jedem Datenbankaufruf zu messen (Push-Checks).

  • Erfasse so viele Metriken wie möglich über das System, die Speicherung, die Datenbank und die Anwendungsebenen, unabhängig davon, ob du sie für nützlich hältst. Die meisten Betriebssysteme, Dienste und Datenbanken haben Plug-ins, die ziemlich umfassend sind.

  • Erstelle spezielle Prüfungen für bekannte Probleme. Zum Beispiel Prüfungen, die auf dem Verlust von x Prozent der Datenbankknoten oder einem zu hohen Prozentsatz an globalen Sperren basieren (führe dies sowohl iterativ als auch proaktiv durch, siehe Kapitel 3).

Manchmal kannst du eine Abkürzung zur Ebene "Wertschätzung" nehmen, indem du Überwachungsdienste von Drittanbietern wie VividCortex, Circonus, HoneyComb oder NewRelic einbindest. Aber es ist ein ziemlicher Hack, wenn du diese Datenbankmetriken in einem System speicherst, das vom Rest deiner Überwachung getrennt ist. Wenn du sie in unterschiedlichen Systemen speicherst, wird es schwieriger, Symptome über mehrere Überwachungsplattformen hinweg zu korrelieren. Wir sagen nicht, dass dies schlecht ist oder dass du es nicht tun solltest; elegante Hacks können dich sehr weit bringen! Aber die Phase der "Selbstverwirklichung" beinhaltet in der Regel die Konsolidierung aller Überwachungsdaten in einer einzigen Quelle der Wahrheit.

Gut. Jetzt, wo du dich dagegen abgesichert hast, dass dein Unternehmen Pleite geht, weil du eine Festplatte verlierst oder ein Techniker einen Tippfehler macht, kannst du dir Fragen über den Zustand deines Dienstes stellen. Die wichtigsten Fragen, die du dir als Startup stellen solltest, sind: "Sind meine Daten sicher?" "Ist mein Dienst in Betrieb?" und "Haben meine Kunden Probleme?" Dies ist dein Minimum Viable Product Monitoring Set.

Sind die Daten sicher?

Für geschäftskritische Daten, die dir wirklich am Herzen liegen, solltest du es vermeiden, mit weniger als drei Live-Kopien zu arbeiten. Das sind eine primäre und zwei plus sekundäre Kopien für Leader-Follower-Datenspeicher wie MySQL oder MongoDB oder ein Replikationsfaktor von drei für verteilte Datenspeicher wie Cassandra oder Hadoop. Denn du willst nie in die Situation kommen, dass du nur eine einzige Kopie der Daten hast, die dir wichtig sind, niemals. Das bedeutet, dass du in der Lage sein musst, eine Instanz zu verlieren, ohne dass die Redundanz darunter leidet. Deshalb sind drei Kopien das Minimum, nicht zwei. Auch wenn du als kleines Startup jeden Monat auf den Pfennig achten musst, sind geschäftskritische Daten nicht der richtige Ort, um diese Kosten zu senken. (Wir besprechen die Verfügbarkeitsarchitektur in Kapitel 5, Infrastrukturtechnik).

Aber nicht alle Daten sind gleich wertvoll! Wenn du es dir leisten kannst, einige Daten zu verlieren, oder wenn du die Daten notfalls aus unveränderlichen Protokollen rekonstruieren kannst, ist es völlig in Ordnung, mit n + 1 Kopien zu arbeiten (wobei n die erforderliche Anzahl von Knoten für normale Aktivitäten ist). Das ist eine Ermessensentscheidung - nur du kannst wissen, wie wichtig und unersetzlich die einzelnen Datensätze für dein Unternehmen sind und wie knapp deine finanziellen Ressourcen sind. Außerdem brauchst du Backups, und du musst regelmäßig überprüfen, ob die Backups wiederherstellbar sind und ob der Backup-Prozess erfolgreich abgeschlossen wird. Wenn du nicht überwachst, dass deine Backups gut sind, kannst du nicht davon ausgehen, dass deine Daten sicher sind.

Musterdaten Sicherheitsmonitore

Einige Beispiele für Sicherheitskontrollen, die du in deine Überwachung einbeziehen solltest, sind:

  • Drei Datenknoten aufwärts

  • Replikations-Threads laufen

  • Replikation auf mindestens einem Knoten <1 Sekunde hinter

  • Letzte erfolgreiche Sicherung

  • Die letzte automatische Wiederherstellung von Replikaten aus Backups war erfolgreich

Ist der Dienst verfügbar?

End-to-End-Prüfungen sind das mächtigste Werkzeug in deinem Arsenal, weil sie das Kundenerlebnis am besten widerspiegeln. Du solltest einen Gesundheitscheck auf oberster Ebene haben, der nicht nur die Funktionsfähigkeit der Web- oder Anwendungsschicht, sondern auch alle Datenbankverbindungen im kritischen Pfad überprüft. Wenn deine Daten über mehrere Hosts verteilt sind, sollte der Check ein Objekt auf jeder Partition abrufen und automatisch die vollständige Liste der Partitionen oder Shards erkennen, damit du nicht jedes Mal neue Checks manuell hinzufügen musst, wenn du die Kapazität erhöhst.

Allerdings - und das ist wichtig - solltest du einen einfacheren Aliveness-Check für deine Load Balancer verwenden, der nicht alle deine Datenbankverbindungen beansprucht. Sonst kann es leicht passieren, dass du dich selbst zu Tode überprüfst.

Exzessive Gesundheitsprüfung

Charity arbeitete einmal an einem System, bei dem ein Haproxy-Gesundheitscheck-Endpunkt ein einfaches SELECT LIMIT 1 aus einer Mysql-Tabelle durchführte. Eines Tages verdoppelten sie die Kapazität einiger zustandsloser Dienste und damit auch die Anzahl der Proxy-Server, die diese Gesundheitsprüfungen durchführen. Die Kapazitätserweiterung anderer Systeme brachte versehentlich die gesamte Website zum Absturz, weil die Datenbankserver mit den Gesundheitsprüfungen überlastet wurden. Mehr als 95 % aller Datenbankabfragen waren diese dummen Gesundheitsprüfungen. Tu das nicht!

Apropos Lektionen, die du auf die harte Art und Weise gelernt hast: Du solltest immer eine gewisse Überwachung außerhalb deines Standorts haben - wenn es nichts anderes ist, einen Offsite-Gesundheitscheck für deinen Überwachungsdienst selbst. Es spielt keine Rolle, wie großartig und robust dein Überwachungssystem vor Ort ist, wenn dein Rechenzentrum oder deine Cloud-Region ausfällt und deinen gesamten Überwachungsapparat mit sich reißt. Es ist eine bewährte Methode, einen externen Check für jedes wichtige Produkt oder jeden Dienst sowie einen Gesundheitscheck für den Überwachungsdienst selbst einzurichten.

Beispiele für Datenbank-Verfügbarkeitsmonitore

Hier sind einige Beispiele für Möglichkeiten, um zu messen, ob dein System verfügbar ist oder kurz vor der Unverfügbarkeit steht:

  • Gesundheitscheck auf Anwendungsebene, der alle Frontend-Datenspeicher abfragt

  • Abfrage für jede Partition in jedem Datenspeichermitglied, für jeden Datenspeicher

  • Drohende Kapazitätsprobleme

    • Festplattenkapazität

    • Datenbankverbindungen

  • Fehlerprotokoll-Scraping

    • DB-Neustarts (schneller als dein Monitor!)

    • Korruption

Haben die Verbraucherinnen und Verbraucher Schmerzen?

Okay, du überwachst, dass dein Dienst am Leben ist. Der Patient hat einen Herzschlag. Gute Arbeit!

Aber was ist, wenn sich deine Latenzzeit verdoppelt oder verdreifacht oder wenn 10 % deiner Anfragen auf eine Art und Weise fehlerhaft sind, die es geschickt vermeidet, deinen Health Check auszulösen? Was ist, wenn deine Datenbank nicht beschreibbar ist, aber gelesen werden kann, oder wenn die Replikate sich verzögern, was dazu führt, dass die meisten Schreibanfragen hängen bleiben? Was ist, wenn dein RAID-Array ein Volume verloren hat und im degradierten Modus läuft, wenn du einen Index aufbaust oder wenn du Hotspots bei Aktualisierungen einer einzelnen Zeile feststellst?

Das ist der Grund, warum Systemtechnik und insbesondere Datenbanken so viel Spaß machen. Es gibt unendlich viele Möglichkeiten, wie deine Systeme fehlschlagen können, und du kannst wahrscheinlich nur etwa fünf Prozent davon im Voraus erahnen. Juhu!

Deshalb solltest du nach und nach eine Bibliothek mit umfassenden Metriken über den Zustand des Dienstes aufbauen - Gesundheitschecks, Fehlerraten, Latenzzeiten. Alles, was dein Kundenerlebnis wesentlich beeinflusst und stört. Und dann? Arbeite eine Zeit lang an etwas anderem und schau, was kaputt geht.

Wir meinen das fast ganz ernst. Wie in Kapitel 3 beschrieben, bringt es nicht viel, wenn du nur rumsitzt und versuchst zu erraten, wie dein Dienst zusammenbrechen wird. Du hast einfach noch nicht die Daten. Du kannst genauso gut noch mehr Dinge bauen, darauf warten, dass sie kaputt gehen, und dann ganz genau hinschauen, wenn die Dinge tatsächlich fehlschlagen.

Nachdem wir nun eine Bootstrapping-Methode und eine Evolutionsmethode vorgestellt haben, wollen wir aufschlüsseln, was du messen solltest, wobei wir uns darauf konzentrieren, was du als DBRE brauchst.

Instrumentierung der Anwendung

Deine Anwendung ist der erste Ort, an dem du beginnen solltest. Obwohl wir die meisten Dinge auf der Datenspeicherebene messen können, sollten die ersten Indikatoren für Probleme Veränderungen im Nutzer- und Anwendungsverhalten sein. Durch die Instrumentierung der Anwendung durch deine Techniker/innen und Application Performance Management-Lösungen (APM) wie New Relic und AppDynamics kannst du eine enorme Menge an Daten für alle Mitarbeiter/innen des Unternehmens erhalten:

  • Du solltest bereits alle Anfragen und Antworten auf Seiten oder API-Endpunkte messen und protokollieren.

  • Du solltest dies auch für alle externen Dienste tun, also auch für Datenbanken, Suchindizes und Caches.

  • Alle Aufträge oder unabhängigen Arbeitsabläufe, die ebenfalls überwacht werden sollten.

  • Jeder unabhängige, wiederverwendbare Code wie eine Methode oder Funktion, die mit Datenbanken, Caches und anderen Datenspeichern interagiert, sollte auf ähnliche Weise instrumentiert werden.

  • Überwache, wie viele Datenbankaufrufe von jedem Endpunkt, jeder Seite oder Funktion/Methode ausgeführt werden.

Die Verfolgung des Datenzugriffscodes (z. B. SQL-Aufrufe), der bei jeder Operation aufgerufen wird, ermöglicht einen schnellen Querverweis auf detailliertere Abfrageprotokolle innerhalb der Datenbank. Dies kann sich bei objektrelationalen Mapping-Systemen (ORMs), für die SQL dynamisch generiert wird, als schwierig erweisen.

SQL-Kommentare

Beim SQL-Tuning besteht eine große Herausforderung darin, das in der Datenbank ausgeführte SQL der spezifischen Stelle in der Codebasis zuzuordnen, von der es aufgerufen wird. In vielen Datenbank-Engines kannst du Kommentare zur Information hinzufügen. Diese Kommentare werden in den Datenbankabfrageprotokollen angezeigt. Dies ist ein guter Ort, um die Stelle in der Codebasis anzugeben.

Verteilte Rückverfolgung

Die Verfolgung der Leistung in allen Phasen von der Anwendung bis zum Datenspeicher ist entscheidend für die Optimierung von Problemen mit langen Latenzzeiten, die schwer zu erfassen sind. Systeme wie New Relic oder Zipkin (Open Source) ermöglichen verteilte Traces von den Aufrufen der Anwendung zu den externen Diensten, wie z. B. deinen Datenbanken. Ein vollständiger Transaktions-Trace von der Anwendung zum Datenspeicher sollte idealerweise das Timing für alle externen Service-Aufrufe enthalten, nicht nur für die Datenbankabfrage.

Die Rückverfolgung mit voller Transparenz bis hin zur Datenbank kann ein mächtiges Arsenal sein, um deine Softwareentwicklungsteams auszubilden und ihnen Autonomie und Selbstständigkeit zu vermitteln. Anstatt dass du ihnen sagst, worauf sie sich konzentrieren sollen, können sie sich die Informationen selbst beschaffen. Wie Aaron Morton vom Last Pickle in seinem Vortrag "Replacing Cassandra's Tracing with Zipkin" sagt:

Im Voraus zu wissen, welche Tools solche positiven kulturellen Veränderungen bewirken, ist im Grunde unmöglich, aber ich habe es mit Git und seiner Praxis der Pull Requests und stabilen Master-Branches gesehen, und ich habe es mit Grafana, Kibana und Zipkin gesehen.

Mehr darüber kannst du auf dem Blog von The Last Pickle lesen.

Es gibt viele Komponenten eines End-to-End-Gesprächs, die auftreten und für den DBRE von Interesse sein können. Dazu gehören u. a. die folgenden Punkte:

  • Herstellen einer Verbindung zu einer Datenbank oder einem Datenbank-Proxy

  • Warteschlange für eine Verbindung in einem Datenbank-Verbindungspool

  • Protokollierung einer Metrik oder eines Ereignisses an einen Warteschlangen- oder Nachrichtendienst

  • Erstellen einer Benutzer-ID von einem zentralisierten UUID-Dienst

  • Auswahl eines Shards anhand einer Variable (z. B. der Benutzer-ID)

  • Suchen, Ungültigmachen oder Zwischenspeichern auf einer Cache-Ebene

  • Komprimieren oder Verschlüsseln von Daten auf der Anwendungsebene

  • Abfrage einer Suchebene

Wenn für eine Transaktion ein Leistungs-"Budget" gilt und die Latenzanforderungen bekannt sind, haben die für die einzelnen Komponenten verantwortlichen Mitarbeiter einen Anreiz, im Team zu arbeiten, um die teuersten Aspekte zu ermitteln und die entsprechenden Investitionen und Kompromisse einzugehen, um dieses Ziel zu erreichen.

Ereignisse und Protokolle

Es versteht sich von selbst, dass alle Anwendungsprotokolle gesammelt und gespeichert werden sollten. Dazu gehören auch Stack Traces. Außerdem gibt es zahlreiche Ereignisse, die auftreten und bei OpViz registriert werden sollten, z. B:

  • Code-Einsätze

  • Bereitstellungszeit

  • Bereitstellungsfehler

Die Anwendungsüberwachung ist ein wichtiger erster Schritt, der einen realistischen Blick auf das Verhalten aus der Nutzerperspektive ermöglicht und direkt mit den Latenz-SLOs zusammenhängt. Dies sind die Symptome, die Hinweise auf Fehler und Beeinträchtigungen in der Umgebung geben. Betrachten wir nun die unterstützenden Daten, die bei der Ursachenanalyse und Bereitstellung helfen können: die Hostdaten.

Instrumentierung des Servers oder der Instanz

Als Nächstes folgt der einzelne Host, real oder virtuell, auf dem sich die Datenbankinstanz befindet. Hier erhalten wir alle Daten über das Betriebssystem und die physischen Ressourcen, die für den Betrieb unserer Datenbanken verwendet werden. Auch wenn diese Daten nicht spezifisch anwendungsbezogen sind, sind sie wertvoll, wenn du Symptome wie Latenz oder Fehler in der Anwendungsebene feststellst.

Wenn du diese Daten verwendest, um die Ursachen für Anwendungsanomalien zu ermitteln, ist es das Ziel, Ressourcen zu finden, die über oder unterausgelastet sind, die gesättigt sind oder die Fehler auslösen. (USE, wie Brendan Gregg in seiner Methodik definiert.) Diese Daten sind auch für die Kapazitätsplanung für Wachstum und Leistungsoptimierung entscheidend. Wenn du einen Engpass oder eine Einschränkung erkennst, kannst du bei deinen Optimierungsbemühungen Prioritäten setzen, um den Wert zu maximieren.

Verteilte Systeme Aggregation

Denke daran, dass die Daten einzelner Hosts nicht besonders nützlich sind, außer um anzuzeigen, dass ein Host ungesund ist und aus der Herde entfernt werden sollte. Betrachte deine Auslastung, Sättigung und Fehler vielmehr aus einer aggregierten Perspektive für den Pool von Hosts, die dieselbe Funktion ausführen. Mit anderen Worten: Wenn du 20 Cassandra-Hosts hast, interessiert dich vor allem die Gesamtauslastung des Pools, die Anzahl der Warteschleifen (Sättigung) und alle auftretenden Fehler. Wenn Fehler nur bei einem Host auftreten, ist es an der Zeit, diesen aus dem Ring zu entfernen und durch einen neuen Host zu ersetzen.

Auf einem Linux-System sind die folgenden ein guter Ausgangspunkt für Ressourcen zur Überwachung in einer Linux-Umgebung:

  • CPU

  • Speicher

  • Netzwerk-Schnittstellen

  • Speicherung I/O

  • Speicherkapazität

  • Speicher-Controller

  • Netzwerk-Controller

  • CPU-Verbindung

  • Speicherzusammenschaltung

  • Zusammenschaltung der Speicherung

Dein Betriebssystem verstehen

Wir können gar nicht genug betonen, wie wichtig es ist, sich mit den Betriebseigenschaften deines Betriebssystems zu beschäftigen. Obwohl viele Datenbankspezialisten dies den Systemadministratoren überlassen, ist der Zusammenhang zwischen Datenbankleistung und Betriebssystem einfach zu eng, als dass man sich nicht damit beschäftigen sollte. Ein perfektes Beispiel dafür ist, dass Linux den gesamten Speicher mit Page Cache füllt, so dass die Anzeige "Freier Speicher" zur Überwachung der Speichernutzung praktisch nutzlos ist. Pagescans pro Sekunde sind in diesem Fall eine viel nützlichere Kennzahl, was ohne ein tieferes Verständnis der Linux-Speicherverwaltung nicht offensichtlich ist.

Neben der Überwachung der Hardwareressourcen gibt es auch bei der Betriebssystemsoftware einige Punkte zu beachten:

  • Kernel Mutex

  • Benutzer-Mutex

  • Aufgabe Kapazität

  • Datei-Deskriptoren

Wenn das für dich neu ist, empfehlen wir dir, Brendan Greggs USE-Seite für Linux zu besuchen, denn sie ist unglaublich detailliert, wenn es darum geht, wie man diese Daten überwacht. Es ist offensichtlich, dass er viel Zeit und Mühe in die Daten investiert hat, die er präsentiert.

Ereignisse und Protokolle

Zusätzlich zu den Metriken solltest du alle Logs an ein geeignetes System zur Ereignisverarbeitung wie RSyslog oder Logstash senden. Dazu gehören Kernel-, Cron-, Authentifizierungs-, Mail- und allgemeine Nachrichtenprotokolle sowie prozess- oder anwendungsspezifische Protokolle, wie z. B. MySQL oder nginx.

Deine Konfigurationsmanagement- und Bereitstellungsprozesse sollten auch kritische Ereignisse an deinen OpViz-Stack melden. Hier ist ein guter Startpunkt:

  • Ein Host wird in unseren außer Betrieb genommen

  • Änderungen der Konfiguration

  • Host-Neustarts

  • Der Dienst startet neu

  • Host stürzt ab

  • Service-Abstürze

Wenn du das Vorangegangene in deinen OpViz-Stack einbauen kannst, bist du bestens gerüstet, um zu verstehen, was auf der Host- und Betriebssystemebene des Stacks vor sich geht. Schauen wir uns nun die Datenbanken selbst an.

Instrumentierung des Datenspeichers

Was überwachen und verfolgen wir in unseren Datenbanken, und warum? Einiges davon hängt von der Art des Datenspeichers ab. Wir konzentrieren uns hier auf Bereiche, die allgemein genug sind, um universell zu sein, aber spezifisch genug, um dir zu helfen, deine eigenen Datenbanken zu verfolgen. Wir können dies in vier Bereiche unterteilen:

  • Datenspeicher-Verbindungsschicht

  • Interne Datenbank-Sichtbarkeit

  • Datenbank-Objekte

  • Datenbankaufrufe/-abfragen

Jede dieser Schichten erhält einen eigenen Abschnitt, beginnend mit der Datenspeicher-Verbindungsschicht.

Datenspeicher Verbindungsschicht

Wir haben besprochen, wie wichtig es ist, die Zeit, die für die Verbindung zum Backend-Datenspeicher benötigt wird, als Teil der gesamten Transaktion zu verfolgen. Ein Tracing-System sollte auch in der Lage sein, die Zeit für die Kommunikation mit einem Proxy und die Zeit vom Proxy zum Backend zu erfassen. Du kannst dies über tcpdump und Tshark/Wireshark für Ad-hoc-Samples aufzeichnen, wenn etwas wie Zipkin nicht verfügbar ist. Du kannst dies für gelegentliche Stichproben automatisieren oder es ad hoc durchführen.

Wenn du Latenzzeiten und/oder Fehler zwischen der Anwendung und der Datenbankverbindung feststellst, benötigst du zusätzliche Metriken, um die Ursachen zu ermitteln. Nehmen wir die bereits erwähnte USE-Methode, die wir empfohlen haben, und sehen wir uns an, welche anderen Metriken uns helfen können.

Inanspruchnahme

Datenbanken können nur eine begrenzte Anzahl von Verbindungen unterstützen. Die maximale Anzahl der Verbindungen ist an mehreren Stellen begrenzt. Die Datenbankkonfigurationsparameter weisen die Datenbank an, nur eine bestimmte Anzahl von Verbindungen zuzulassen und setzen damit eine künstliche Obergrenze, um die Überlastung des Hosts zu minimieren. Es ist wichtig, diese Obergrenze und die tatsächliche Anzahl der Verbindungen zu überwachen, denn sie kann durch eine Standardkonfiguration willkürlich niedrig angesetzt sein.

Verbindungen öffnen auch Ressourcen auf der Ebene des Betriebssystems. PostgreSQL verwendet zum Beispiel einen Unix-Prozess pro Verbindung. MySQL, Cassandra und MongoDB verwenden einen Thread pro Verbindung. Sie alle verwenden Speicher und Dateideskriptoren. Es gibt also mehrere Stellen, die wir uns ansehen sollten, um das Verbindungsverhalten zu verstehen:

  • Obergrenze für Verbindungen und Anzahl der Verbindungen

  • Verbindungszustände (funktionierend, schlafend, abgebrochen, und andere)

  • Kernel-Level Open file utilization

  • Maximale Prozessauslastung auf Kernel-Ebene

  • Arbeitsspeicherauslastung

  • Thread-Pool-Metriken wie der MySQL-Tabellencache oder die MongoDB-Thread-Pool-Auslastung

  • Auslastung des Netzwerkdurchsatzes

Dies sollte dir Aufschluss darüber geben, ob du irgendwo in der Verbindungsschicht einen Kapazitäts- oder Auslastungsengpass hast. Wenn du eine 100%ige Auslastung siehst und die Sättigung ebenfalls hoch ist, ist das ein guter Indikator. Eine niedrige Auslastung bei gleichzeitiger Sättigung ist aber auch ein Indikator für einen Engpass irgendwo. Eine hohe, aber nicht vollständige Auslastung der Ressourcen wirkt sich oft auch auf die Latenz aus und könnte ebenfalls eine Ursache für die Latenz sein.

Sättigung

Die Sättigung ist oft am nützlichsten, wenn sie mit der Auslastung gepaart ist. Wenn du viele Warteschleifen auf die Ressourcen von siehst, die auch zu 100 % ausgelastet sind, hast du ein klares Kapazitätsproblem. Wenn du jedoch Wartezeiten/Sättigung ohne volle Auslastung feststellst, kann es sein, dass es an anderer Stelle einen Engpass gibt, der den Stack Up verursacht. Die Sättigung kann an diesen Wendepunkten gemessen werden:

  • Rückstand bei TCP-Verbindungen

  • Datenbankspezifische Verbindungswarteschlangen, wie z.B. MySQL back_log

  • Timeout-Fehler bei der Verbindung

  • Warten auf Threads in den Verbindungspools

  • Speicherauslagerung

  • Datenbankprozesse, die gesperrt sind

Die Länge der Warteschlange und die Wartezeiten sind entscheidend für das Verständnis der Sättigung. Jedes Mal, wenn du Verbindungen oder Prozesse findest, die warten, ist das ein Indikator für einen potenziellen Engpass.

Fehler

Anhand von Auslastung und Sättigung kannst du feststellen, ob Kapazitätsbeschränkungen und Engpässe die Latenz deiner Datenbankverbindungsschicht beeinträchtigen. Das sind wichtige Informationen, um zu entscheiden, ob du die Ressourcen erhöhen, künstliche Konfigurationsbeschränkungen beseitigen oder die Architektur ändern musst. Auch Fehler sollten überwacht und zur Beseitigung oder Identifizierung von Fehlern und/oder Konfigurationsproblemen genutzt werden. Fehler können wie folgt erfasst werden:

  • Die Datenbankprotokolle liefern Fehlercodes, wenn Fehler auf Datenbankebene auftreten. Manchmal gibt es Konfigurationen mit verschiedenen Ausführlichkeitsgraden. Achte darauf, dass die Protokollierung ausführlich genug ist, um Verbindungsfehler zu erkennen, aber achte auf den Overhead, vor allem, wenn deine Protokolle Speicher- und IO-Ressourcen mit deiner Datenbank teilen.

  • Anwendungs- und Proxy-Logs bieten ebenfalls zahlreiche Fehlerquellen.

  • Die im vorherigen Abschnitt beschriebenen Host-Fehler sollten auch hier verwendet werden.

Zu den Fehlern gehören Netzwerkfehler, Verbindungs-Timeouts, Authentifizierungsfehler, Verbindungsabbrüche und vieles mehr. Diese können auf so unterschiedliche Probleme wie beschädigte Tabellen, Abhängigkeit von DNS, Deadlocks, Authentifizierungsänderungen und so weiter hinweisen.

Durch die Verwendung von Latenz-/Fehlermetriken, Tracing und geeigneten Telemetriedaten zu Auslastung, Sättigung und spezifischen Fehlerzuständen solltest du die Informationen haben, die du brauchst, um degradierte und defekte Zustände auf der Datenbankverbindungsebene zu identifizieren. Als Nächstes werden wir uns ansehen, was innerhalb der Verbindungen zu messen ist.

Interne Datenbank-Sichtbarkeit

Wenn wir einen Blick in die Datenbank werfen, stellen wir fest, dass die Anzahl der beweglichen Teile, die Anzahl der Metriken und die Gesamtkomplexität erheblich gestiegen sind. Mit anderen Worten: Hier fangen die Dinge an, richtig ernst zu werden! Noch einmal: Behalten wir USE im Hinterkopf. Unser Ziel ist es, Engpässe zu verstehen, die sich auf die Latenz auswirken, die Anfragen einschränken oder Fehler verursachen können.

Es ist wichtig, dies aus der Perspektive eines einzelnen Hosts und als Aggregat nach Rolle zu betrachten. Einige Datenbanken, wie MySQL, PostgreSQL, ElasticSearch und MongoDB, haben Master- und Replikat-Rollen. Cassandra und Riak haben keine spezifischen Rollen, aber sie sind oft nach Regionen oder Zonen verteilt . Auch das ist wichtig, um sie zu aggregieren.

Durchsatz- und Latenzmetriken

Wie viele und welche Art von Operationen finden in den Datenspeichern statt? Diese Daten geben einen sehr guten Überblick über die Datenbankaktivitäten. Wenn SWEs neue Funktionen einführen, werden sich diese Arbeitslasten verschieben und gute Indikatoren dafür liefern, wie sich die Arbeitslast verschiebt. Einige Beispiele für Kennzahlen, die gesammelt werden sollten, um die sich verändernde Arbeitslast zu verstehen, sind die folgenden:

  • Liest

  • Schreibt

    • Einsätze

    • Updates

    • Löscht

  • Andere Operationen

    • Verpflichtet

    • Rollbacks

    • DDL-Anweisungen

    • Andere administrative Aufgaben

Wenn wir hier von Latenz sprechen, meinen wir nur die Gesamtheit, also Durchschnittswerte. Wir werden die granulare und informativere Abfrageüberwachung weiter unten in diesem Abschnitt besprechen. Bei dieser Art von Daten gibt es also keine Ausreißer, sondern nur sehr grundlegende Informationen über die Auslastung.

Commits, Redo und Journaling

Obwohl die spezifischen Implementierungen vom jeweiligen Datenspeicher abhängen, gibt es fast immer eine Reihe von E/A-Operationen, die am Flushing der Daten auf die Festplatte beteiligt sind. In der InnoDB-Speicher-Engine von MySQL und in PostgreSQL werden Schreibvorgänge im Pufferpool (Speicher) geändert und in einem Redo-Log (oder Write-Ahead-Log in PostgreSQL) aufgezeichnet. Hintergrundprozesse übertragen diese Daten dann auf die Festplatte und halten Checkpoints für die Wiederherstellung bereit. In Cassandra werden die Daten in einem Memtable (Speicher) gespeichert, an den ein Commit-Log angehängt wird. Memtables werden in regelmäßigen Abständen in eine SSTable gespült. SSTables werden ebenfalls regelmäßig komprimiert. Im Folgenden findest du einige Metriken, die du überwachen kannst:

  • Schmutzige Puffer (MySQL)

  • Prüfpunkt Alter (MySQL)

  • Anstehende und abgeschlossene Verdichtungsaufgaben (Cassandra)

  • Verfolgte schmutzige Bytes (MongoDB)

  • (Un)geänderte Seiten werden entfernt (MongoDB)

  • log_checkpoints Konfiguration (PostgreSQL)

  • pg_stat_bgwriter view (PostgreSQL)

Alle Checkpointing-, Flushing- und Verdichtungsoperationen haben erhebliche Auswirkungen auf die Leistung der Datenbank. Manchmal ist die Auswirkung eine erhöhte E/A, und manchmal kann es sein, dass alle Schreibvorgänge gestoppt werden, während eine größere Operation durchgeführt wird. Die Erfassung von Metriken ermöglicht es dir, bestimmte Konfigurationen so einzustellen, dass die Auswirkungen solcher Operationen minimiert werden. Wenn wir also in diesem Fall feststellen, dass die Latenzzeit ansteigt und die Metriken für das Flushing eine übermäßige Hintergrundaktivität anzeigen, können wir die mit diesen Prozessen verbundenen Vorgänge optimieren.

Replikationsstatus

Replikation ist das Kopieren von Daten über mehrere Knoten hinweg, so dass die Daten auf einem Knoten identisch einem anderen sind. Sie ist ein Eckpfeiler der Verfügbarkeit und Leseskalierung sowie ein Teil der Disaster Recovery und der Datensicherheit. Es gibt jedoch drei mögliche Replikationszustände, die nicht gesund sind und zu großen Problemen führen können, wenn sie nicht überwacht und abgefangen werden. Wir besprechen die Replikation im Detail in Kapitel 10.

Die Replikationslatenz ist der erste der Fehlerzustände. Manchmal kann sich die Anwendung von Änderungen auf andere Knoten verlangsamen. Das kann an einer Überlastung des Netzwerks, an einer Single-Thread-Anwendung, die nicht mithalten kann, oder an einer Reihe anderer Gründe liegen. Gelegentlich kommt die Replikation in Spitzenzeiten nicht hinterher, so dass die Daten auf den Replikaten schon Stunden alt sind. Das ist gefährlich, weil veraltete Daten ausgeliefert werden können, und wenn du dieses Replikat als Failover verwendest, kannst du Daten verlieren.

Die meisten Datenbanksysteme verfügen über leicht nachvollziehbare Replikationslatenz-Metriken; du kannst die Differenz zwischen dem Zeitstempel auf dem Master und dem Zeitstempel auf dem Replikat sehen. In Systemen wie Cassandra, mit eventuell konsistenten Modellen, suchst du nach Rückständen von Operationen, die zur Synchronisierung von Replikaten nach der Nichtverfügbarkeit verwendet werden. In Cassandra sind das zum Beispiel Hinted Handoffs.

Unterbrochene Replikation ist der zweite der Fehlerzustände. In diesem Fall brechen die Prozesse, die zur Aufrechterhaltung der Datenreplikation erforderlich sind, aufgrund einer beliebigen Anzahl von Fehlern einfach ab. Die Lösung erfordert eine schnelle Reaktion, die durch eine angemessene Überwachung erleichtert wird, gefolgt von der Behebung der Fehlerursache und der Wiederaufnahme der Replikation. In diesem Fall kannst du den Status der Replikations-Threads überwachen.

Der letzte Fehlerzustand ist der heimtückischste: Replikationsdrift. In diesem Fall sind die Daten nicht mehr synchronisiert, wodurch die Replikation nutzlos und potenziell gefährlich wird. Die Erkennung von Replikationsdrift bei großen Datenmengen kann eine Herausforderung sein und hängt von den Arbeitslasten und der Art der Daten ab, die du speicherst.

Wenn deine Daten zum Beispiel relativ unveränderlich sind und Einfüge-/Lesevorgänge die Regel sind, kannst du Prüfsummen über Datenbereiche in den Replikaten laufen lassen und dann vergleichen, ob sie identisch sind. Du kannst dies in einem rollierenden Verfahren hinter der Replikation tun, was eine einfache Sicherheitsprüfung auf Kosten einer zusätzlichen CPU-Auslastung auf den Datenbankhosts ermöglicht. Wenn du jedoch viele Mutationen durchführst, ist dies eine größere Herausforderung, weil du entweder wiederholt Prüfsummen über bereits überprüfte Daten laufen lassen oder nur gelegentlich Stichproben machen musst.

Speicher-Strukturen

Datenspeicher unterhalten zahlreiche Speicherstrukturen in ihrem regulären Betrieb. Eine der häufigsten allgegenwärtigen Strukturen in Datenbanken ist ein Daten-Cache. Auch wenn er viele Namen hat, besteht sein Ziel darin, Daten, auf die häufig zugegriffen wird, im Speicher und nicht auf der Festplatte zu halten. Es gibt noch weitere solche Caches, z. B. Caches für geparstes SQL, Verbindungs-Caches, Abfrageergebnis-Caches und viele mehr.

Die typischen Metriken, die wir bei der Überwachung dieser Strukturen verwenden, sind folgende:

Inanspruchnahme

Die Gesamtmenge des zugewiesenen Platzes, den im Laufe der Zeit nutzt.

Churn

Die Häufigkeit, mit der zwischengespeicherte Objekte entfernt werden, um Platz für andere Objekte zu schaffen oder weil die zugrunde liegenden Daten ungültig geworden sind.

Trefferquoten

Die Häufigkeit, mit der zwischengespeicherte Daten eher genutzt werden als nicht zwischengespeicherte Daten. Dies kann bei Übungen zur Leistungsoptimierung helfen.

Gleichzeitigkeit

Oft haben diese Strukturen ihre eigenen Serialisierungsmethoden, wie z.B. Mutexe, die zu Engpässen werden können. Das Verständnis der Sättigung dieser Komponenten kann auch bei der Optimierung helfen.

Einige Systeme wie Cassandra verwenden Java Virtual Machines (JVMs) für die Verwaltung des Speichers, wodurch sich ganz neue Bereiche ergeben, die überwacht werden müssen. Die Speicherbereinigung und die Nutzung der verschiedenen Objekt-Heap-Spaces sind in solchen Umgebungen ebenfalls entscheidend.

Sperren und Gleichzeitigkeit

Vor allem relationale Datenbanken verwenden Sperren, um den gleichzeitigen Zugriff zwischen Sitzungen zu gewährleisten. Durch Sperren können Mutationen und Lesevorgänge erfolgen, während gleichzeitig sichergestellt wird, dass keine Änderungen durch andere Prozesse vorgenommen werden können. Obwohl dies unglaublich nützlich ist, kann es zu Latenzproblemen führen, wenn sich Prozesse stapeln und darauf warten, dass sie an die Reihe kommen. In einigen Fällen können Prozesse aufgrund von Deadlocks ins Stocken geraten, für die es keine andere Lösung gibt, als die eingerichteten Sperren wieder aufzuheben. Die Einzelheiten der Implementierung von Sperren werden in Kapitel 11 erläutert.

Die Überwachung von Sperren umfasst die Überwachung der Zeit, die auf Sperren im Datenspeicher gewartet wird. Längere Warteschlangen können auf Anwendungs- und Gleichzeitigkeitsprobleme oder zugrundeliegende Probleme hinweisen, die sich auf die Latenzzeit auswirken, da Sitzungen, die Sperren halten, länger brauchen, um abgeschlossen zu werden. Die Überwachung von Rollbacks und Deadlocks ist ebenfalls wichtig, da dies ein weiterer Indikator dafür ist, dass Anwendungen Sperren nicht sauber freigeben, was dazu führt, dass wartende Sitzungen einen Timeout und einen Rollback verursachen. Rollbacks können Teil einer normalen, gut funktionierenden Transaktion sein, aber sie sind oft ein Indikator dafür, dass eine zugrunde liegende Aktion die Transaktionen beeinträchtigt.

Wie bereits im Abschnitt über die Speicherstrukturen erwähnt, gibt es auch zahlreiche Punkte in der Datenbank, die als Synchronisationsprimitive dienen, um Gleichzeitigkeit sicher zu verwalten. Dabei handelt es sich in der Regel entweder um Mutexe oder Semaphoren. Ein Mutex (Mutually Exclusive Lock) ist ein Sperrmechanismus, der verwendet wird, um den Zugriff auf eine Ressource wie einen Cache-Eintrag zu synchronisieren. Nur eine Aufgabe kann die Mutex erwerben. Das bedeutet, dass Mutexe mit Eigentumsrechten verbunden sind und nur der Eigentümer die Sperre (Mutex) freigeben kann. Das schützt vor Korruption.

Ein Semaphor begrenzt die Anzahl der gleichzeitigen Nutzer einer gemeinsam genutzten Ressource bis zu einer maximalen Anzahl. Threads können den Zugriff auf die Ressource anfordern (Dekrementierung der Semaphore) und signalisieren, dass sie die Nutzung der Ressource beendet haben (Inkrementierung der Semaphore). Beispiele für die Verwendung von Mutexen/Semaphoren zur Überwachung der InnoDB-Speicher-Engine von MySQL sind in Tabelle 4-1 aufgeführt.

Tabelle 4-1. Metriken zur InnoDB-Semaphore-Aktivität
Name Beschreibung
Mutex Os Waits (Delta) Die Anzahl der InnoDB Semaphore/Mutex-Wartezeiten, die an das Betriebssystem übergeben wurden.
Mutex-Runden (Delta) Die Anzahl der InnoDB Semaphore/Mutex-Runden für das interne Sync-Array.
Mutex Spin Waits (Delta) Die Anzahl der InnoDB Semaphore/Mutex Spin-Wartezeiten für das interne Sync-Array.
Os Reservierung zählen (Delta) Die Anzahl der Male, die eine InnoDB Semaphore/Mutex-Wartezeit zum internen Sync-Array hinzugefügt wurde.
Os Signalanzahl (Delta) Die Anzahl der Male, die ein InnoDB-Thread über das interne Sync-Array signalisiert wurde.
Rw Excl Os Waits (Delta) Die Anzahl der exklusiven (Schreib-)Semaphore-Wartezeiten, die InnoDB an das Betriebssystem weitergibt.
Rw Excl Runden (Delta) Die Anzahl der exklusiven (schreibenden) Semaphore-Runden innerhalb des InnoDB-Sync-Arrays.
Rw Excl Spins (Delta) Die Anzahl der exklusiven (schreibenden) Semaphore-Spin-Wartezeiten innerhalb des InnoDB-Sync-Arrays.
Rw Shared Os Waits (Delta) Die Anzahl der gemeinsamen (Lese-)Semaphore-Wartezeiten, die InnoDB an das Betriebssystem weitergibt.
RW Geteilte Runden (Delta) Die Anzahl der gemeinsamen (Lese-)Semaphoren-Runden innerhalb des InnoDB-Sync-Arrays.
RW Geteilte Spins (Delta) Die Anzahl der gemeinsamen (Lese-)Semaphoren-Spin-Waits innerhalb des InnoDB-Sync-Arrays.
Spins pro Wartezeit Mutex (Delta) Das Verhältnis von InnoDB-Semaphore/Mutex-Spin-Runden zu Mutex-Spin-Waits für das interne Sync-Array.
Spins pro Wartezeit RW Excl (Delta) Das Verhältnis von InnoDB-exklusiven (Schreib-)Semaphore/Mutex-Spin-Runden zu Spin-Waits innerhalb des internen Sync-Arrays.
Spins pro Wartezeit RW geteilt (Delta) Das Verhältnis von InnoDB shared (read) semaphore/mutex spin rounds zu spin waits innerhalb des internen sync array.

Steigende Werte können darauf hinweisen, dass deine Datenspeicher in bestimmten Bereichen der Codebasis an die Grenzen der Gleichzeitigkeit stoßen. Du kannst dieses Problem durch die Einstellung von Konfigurationen und/oder durch Skalierung lösen, um die Gleichzeitigkeit auf einem Datenspeicher aufrechtzuerhalten und die Anforderungen des Datenverkehrs zu erfüllen.

Sperren und Gleichzeitigkeit können selbst die leistungsfähigsten Abfragen zunichte machen, sobald du einen Wendepunkt bei der Skalierung erreichst. Indem du diese Metriken bei Lasttests und in Produktionsumgebungen verfolgst und überwachst, kannst du die Grenzen deiner Datenbanksoftware erkennen und herausfinden, wie deine eigenen Anwendungen optimiert werden müssen, um für eine große Anzahl gleichzeitiger Nutzer skalieren zu können.

Datenbank-Objekte

Es ist wichtig zu verstehen, wie deine Datenbank aussieht und wie sie gespeichert wird. Auf der einfachsten Ebene geht es darum, zu verstehen, wie viel Speicherung jedes Datenbankobjekt und die dazugehörigen Schlüssel/Indizes benötigen. Genau wie bei der Speicherung in einem Dateisystem ist das Verständnis der Wachstumsrate und der Zeit bis zum Erreichen der Obergrenze genauso wichtig, wenn nicht sogar wichtiger als die aktuelle Speichernutzung.

Neben dem Verständnis der Speicherung und des Wachstums ist es hilfreich, die Verteilung kritischer Daten zu überwachen. So ist es zum Beispiel hilfreich, die Ober- und Untergrenzen, den Mittelwert und die Kardinalität der Daten zu kennen, um die Index- und Scanleistung zu verstehen. Dies ist besonders wichtig für ganzzahlige Datentypen und zeichenbasierte Datentypen mit geringer Kardinalität. Wenn du diese Daten zur Hand hast, können du und deine SWEs Optimierungen bei Datentypen und Indizierung erkennen.

Wenn du deinen Datensatz mit Hilfe von Schlüsselbereichen oder Listen aufgeteilt hast, kann ein Verständnis der Verteilung auf die Shards dazu beitragen, dass du die Leistung auf jedem Knoten maximierst. Bei diesen Sharding-Methoden kann es zu Hot Spots kommen, da es sich nicht um gleichmäßige Verteilungen nach einem Hash- oder Modulus-Ansatz handelt. Wenn du dies erkennst, können du und dein Team feststellen, ob du deine Sharding-Modelle neu ausbalancieren oder neu ausrichten musst.

Datenbankabfragen

Je nach Datenbanksystem, mit dem du arbeitest, kann der tatsächliche Datenzugriff und die Datenmanipulation stark instrumentiert sein oder überhaupt nicht. Wenn du versuchst, die Datenflut, die bei der Protokollierung von Abfragen in einem ausgelasteten System entsteht, zu nutzen, kann das zu kritischen Latenz- und Verfügbarkeitsproblemen für dein System und deine Nutzer führen. Dennoch gibt es keine wertvolleren Daten als diese. Einige Lösungen, wie z.B. Vivid Cortex und Circonus, haben sich auf TCP- und Drahtprotokolle konzentriert, um die benötigten Daten zu erhalten, was die Auswirkungen der Abfrageprotokollierung auf die Leistung drastisch reduziert. Andere Methoden beinhalten Stichproben auf einem weniger belasteten Replikat, schalten die Protokollierung nur für bestimmte Zeiträume ein oder protokollieren nur Anweisungen, die langsam ausgeführt werden.

Unabhängig davon willst du so viel wie möglich über die Leistung und Auslastung deiner Datenbankaktivitäten speichern. Dazu gehören der CPU- und IO-Verbrauch, die Anzahl der gelesenen oder geschriebenen Zeilen, die detaillierten Ausführungs- und Wartezeiten sowie die Ausführungszahlen. Das Verständnis der Optimierungspfade, der verwendeten Indizes und der Statistiken über das Zusammenführen, Sortieren und Aggregieren ist ebenfalls entscheidend für die Optimierung.

Datenbank-Asserts und Ereignisse

Datenbank- und Client-Logs sind eine ergiebige Informationsquelle, insbesondere für Asserts und Fehler. Diese Protokolle können dir wichtige Daten liefern, die auf andere Weise nicht überwacht werden können, wie zum Beispiel die folgenden:

  • Verbindungsversuche und -misserfolge

  • Warnungen und Fehler bei Korruption

  • Neustarts der Datenbank

  • Änderungen der Konfiguration

  • Deadlocks

  • Core Dumps und Stack Traces

Du kannst einige dieser Daten zusammenfassen und an deine Kennzahlensysteme weiterleiten. Andere solltest du als Ereignisse behandeln, die du nachverfolgen und für Korrelationen nutzen kannst.

Einpacken

Nun, nach all dem brauchen wir alle eine Pause! Du hast dieses Kapitel mit einem soliden Verständnis für die Bedeutung der betrieblichen Sichtbarkeit, für den Start eines OpViz-Programms und für den Aufbau und die Weiterentwicklung einer OpViz-Architektur abgeschlossen. Du kannst nie genug Informationen über die Systeme haben, die du aufbaust und betreibst. Du kannst auch schnell die Systeme finden, die zur Beobachtung der Dienste gebaut wurden, die zu einem großen Teil deiner betrieblichen Aufgaben geworden sind! Sie verdienen genau so viel Aufmerksamkeit wie jede andere Komponente der Infrastruktur.

Get Datenbank-Zuverlässigkeitstechnik now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.