Wartung
Überblick
Ein etcd-Cluster muss regelmäßig gewartet werden, um zuverlässig zu bleiben. Je nach Anforderungen der etcd-Anwendung lässt sich diese Wartung gewöhnlich automatisieren und ohne Ausfallzeiten oder erhebliche Leistungseinbußen durchführen.
Alle Wartungsaufgaben in etcd dienen der Verwaltung der Speicherressourcen, die der etcd-Schlüsselraum belegt. Speicherplatzkontingente sichern gegen eine unzureichende Begrenzung der Schlüsselraumgröße ab: Wird der Speicherplatz eines etcd-Mitglieds knapp, löst ein Kontingent clusterweite Alarme aus, die das System in einen Wartungsmodus mit eingeschränktem Funktionsumfang versetzen. Damit weiterhin Platz für Schreibzugriffe auf den Schlüsselraum vorhanden ist, muss dessen Historie kompaktiert werden. Der Speicherplatz selbst kann durch Defragmentierung der etcd-Mitglieder zurückgewonnen werden. Regelmäßige Snapshot-Backups des Zustands eines etcd-Mitglieds ermöglichen schließlich die Wiederherstellung nach unbeabsichtigtem logischem Datenverlust oder nach Datenbeschädigungen durch Bedienfehler.
Aufbewahrung des Raft-Logs
etcd --snapshot-count legt fest, wie viele angewendete Raft-Einträge vor der Kompaktierung im Arbeitsspeicher gehalten werden. Sobald --snapshot-count erreicht ist, speichert der Server zunächst die Snapshot-Daten dauerhaft auf dem Datenträger und entfernt anschließend alte Einträge. Fordert ein langsamer Follower Logs vor einem kompaktierten Index an, sendet der Leader den Snapshot und zwingt den Follower damit, seinen Zustand zu überschreiben.
Ein höherer Wert für --snapshot-count hält bis zum Snapshot mehr Raft-Einträge im Arbeitsspeicher und verursacht damit eine wiederkehrend höhere Speichernutzung
. Da der Leader die neuesten Raft-Einträge länger aufbewahrt, hat ein langsamer Follower mehr Zeit, vor dem nächsten Snapshot des Leaders aufzuschließen. --snapshot-count stellt somit einen Kompromiss zwischen höherem Speicherbedarf und besserer Verfügbarkeit langsamer Follower dar.
In v3.2 wurde der Standardwert von --snapshot-count von 10,000 auf 100,000 geändert
. In v3.7.0 beträgt der Standardwert 10,000.
Werte von --snapshot-count über 100,000 können den Schreibdurchsatz beeinträchtigen. Eine größere Anzahl von Objekten im Arbeitsspeicher kann die Markierungsphase des Go-GC, runtime.scanobject
, verlangsamen; eine seltene Speicherfreigabe verlangsamt außerdem die Speicherzuweisung. Die Leistung hängt von Arbeitslast und Systemumgebung ab. Generell beeinträchtigt eine zu häufige Kompaktierung jedoch Clusterverfügbarkeit und Schreibdurchsatz. Eine zu seltene Kompaktierung ist ebenfalls schädlich, da sie den Garbage Collector von Go zu stark belastet. Weitere Untersuchungsergebnisse bietet Leistungsaspekte von etcd und Raft verstehen
.
Kompaktierung der Historie: Schlüssel-Wert-Datenbank der v3-API
Da etcd eine genaue Historie seines Schlüsselraums führt, sollte diese regelmäßig kompaktiert werden, um Leistungseinbußen und letztlich eine Erschöpfung des Speicherplatzes zu vermeiden. Die Kompaktierung der Schlüsselraumhistorie entfernt alle Informationen zu Schlüsseln, die vor einer bestimmten Revision des Schlüsselraums ersetzt wurden. Der von diesen Schlüsseln belegte Platz steht danach für weitere Schreibzugriffe auf den Schlüsselraum zur Verfügung.
Der Schlüsselraum lässt sich automatisch mit der zeitfensterbasierten Aufbewahrungsrichtlinie von etcd oder manuell mit etcdctl kompaktieren. etcdctl ermöglicht eine genaue Steuerung der Kompaktierung; die automatische Kompaktierung eignet sich für Anwendungen, die die Schlüsselhistorie nur für einen bestimmten Zeitraum benötigen.
Eine mit etcdctl ausgelöste Kompaktierung funktioniert wie folgt:
Revisionen vor der Kompaktierungsrevision sind danach nicht mehr zugänglich:
Automatische Kompaktierung
etcd lässt sich mit den Optionen --auto-compaction-mode und --auto-compaction-retention so konfigurieren, dass es den Schlüsselraum automatisch kompaktiert. Es gibt zwei Kompaktierungsmodi: periodic (Standard) und revision.
Periodische Kompaktierung
Die periodische Kompaktierung bewahrt ein zeitbasiertes Fenster der Schlüsselraumhistorie auf:
Der Aufbewahrungswert legt fest, wie viel Historie erhalten bleibt. Ein Datensatz wird erst ungefähr diese Zeitspanne nach seiner Erstellung kompaktiert. Dadurch können langsame Watcher innerhalb des Aufbewahrungsfensters noch aufschließen.
Ist die Aufbewahrungsdauer größer als 1 Stunde, kompaktiert etcd stündlich und behält dabei das vollständige Aufbewahrungsfenster bei. Beträgt die Aufbewahrungsdauer 1 Stunde oder weniger, erfolgt die Kompaktierung im Abstand dieser Dauer.
Bei --auto-compaction-retention=10h wartet etcd beispielsweise 10 Stunden bis zur ersten Kompaktierung und kompaktiert danach stündlich:
Die empfohlenen Werte hängen vom Anwendungsfall ab:
- Häufige Aktualisierungen derselben Schlüssel: ein kurzer Zeitraum wie
1hoder30m - Seltene Aktualisierungen: ein längerer Zeitraum wie
24h,48hoder72h - Allgemeiner Standardwert:
10h
Revisionsbasierte Kompaktierung
Die revisionsbasierte Kompaktierung bewahrt eine feste Anzahl von Revisionen auf:
etcd prüft alle 5 Minuten und kompaktiert bei "latest revision" - 1000. Ist die neueste Revision beispielsweise 30000, erfolgt die Kompaktierung bei Revision 29000.
Defragmentierung
Nach der Kompaktierung des Schlüsselraums kann die Backend-Datenbank intern fragmentiert sein. Interne Fragmentierung bezeichnet Platz, den das Backend wiederverwenden kann, der aber weiterhin Speicherplatz belegt. Beim Kompaktieren alter Revisionen entstehen Lücken in der Backend-Datenbank, wodurch etcd intern fragmentiert wird. Fragmentierter Platz steht etcd zur Verfügung, dem Dateisystem des Hosts jedoch nicht. Das Löschen von Anwendungsdaten gibt also keinen Speicherplatz auf dem Datenträger frei.
Die Defragmentierung gibt diesen Speicherplatz an das Dateisystem zurück. Sie wird für jedes Mitglied einzeln ausgelöst, um clusterweite Latenzspitzen vermeiden zu können.
Ein etcd-Mitglied mit dem Befehl etcdctl defrag defragmentieren:
Die Defragmentierung eines laufenden Mitglieds blockiert während des Neuaufbaus seines Zustands alle Lese- und Schreibzugriffe auf Daten.
Eine Defragmentierungsanfrage wird nicht im Cluster repliziert, sondern nur auf dem lokalen Knoten ausgeführt. Alle Mitglieder mit der Option --endpoints angeben oder mit --cluster alle Clustermitglieder automatisch ermitteln lassen.
Defragmentierung für alle Endpunkte des Clusters ausführen, zu dem der Standardendpunkt gehört:
Um ein etcd-Datenverzeichnis direkt zu defragmentieren, während etcd nicht läuft, folgenden Befehl verwenden:
Speicherplatzkontingent
Das Speicherplatzkontingent in etcd stellt einen zuverlässigen Clusterbetrieb sicher. Ohne ein solches Kontingent kann etcd bei einem übermäßig großen Schlüsselraum an Leistung verlieren oder schlicht den gesamten Speicherplatz aufbrauchen, was zu unvorhersehbarem Clusterverhalten führt. Überschreitet die Backend-Datenbank des Schlüsselraums eines beliebigen Mitglieds das Kontingent, löst etcd einen clusterweiten Alarm aus. Dieser versetzt den Cluster in einen Wartungsmodus, der nur das Lesen und Löschen von Schlüsseln erlaubt. Erst nachdem genügend Platz im Schlüsselraum freigegeben, die Backend-Datenbank defragmentiert und der Kontingentalarm aufgehoben wurde, kann der Cluster den normalen Betrieb wieder aufnehmen.
Standardmäßig verwendet etcd ein konservatives Speicherplatzkontingent, das für die meisten Anwendungen geeignet ist. Es lässt sich jedoch auf der Befehlszeile in Bytes konfigurieren:
Das Kontingent lässt sich mit einer Schleife ausschöpfen:
Durch das Entfernen überflüssiger Daten aus dem Schlüsselraum und die Defragmentierung der Backend-Datenbank liegt der Cluster wieder innerhalb des Kontingents:
Die Metrik etcd_mvcc_db_total_size_in_use_in_bytes zeigt die tatsächliche Datenbankbelegung nach einer Kompaktierung der Historie. etcd_debugging_mvcc_db_total_size_in_bytes zeigt dagegen die Datenbankgröße einschließlich freien Platzes, der noch auf Defragmentierung wartet. Letztere steigt nur, wenn Erstere nahe an ihr liegt. Nähern sich beide Metriken dem Kontingent, ist daher eine Kompaktierung der Historie erforderlich, um das Auslösen des Speicherplatzkontingents zu vermeiden.
Ab v3.4 heißt etcd_debugging_mvcc_db_total_size_in_bytes nun etcd_mvcc_db_total_size_in_bytes.
Eine Put/Txn/LeaseGrant-Anfrage kann den Fehler ErrGRPCNoSpace zurückgeben, obwohl der Schreibzugriff im Backend erfolgreich ist. etcd prüft das Speicherplatzkontingent sowohl auf der API-Schicht als auch auf der internen Apply-Schicht. Die Apply-Schicht löst lediglich den Alarm NOSPACE aus, ohne die weitere Ausführung der Transaktion zu blockieren.
Snapshot-Backup
Regelmäßige Snapshots des etcd-Clusters dienen als dauerhaftes Backup des etcd-Schlüsselraums. Durch regelmäßige Snapshots der Backend-Datenbank eines etcd-Mitglieds lässt sich ein etcd-Cluster auf einen Zeitpunkt mit einem nachweislich intakten Zustand zurücksetzen.
Ein Snapshot wird mit etcdctl erstellt: