Cassandra generiert Grabsteine, wenn Sie Daten löschen. Unter bestimmten Umständen können überschüssige Tombstones lange GC-Pausen, Latenz, Lesefehler oder Out-of-Heap-Fehler verursachen. Dieser Artikel enthält Ratschläge zur Verwaltung von Grabsteinen.
Inhaltsverzeichnis
Was ist ein Grabstein?
In Cassandra werden gelöschte Daten nicht sofort von der Festplatte gelöscht. Stattdessen schreibt Cassandra einen speziellen Wert, der als Tombstone bezeichnet wird, um anzuzeigen, dass Daten gelöscht wurden. Tombstones verhindern, dass gelöschte Daten während des Lesens zurückgegeben werden, und ermöglichen schließlich das Löschen der Daten durch Komprimierung.
Grabsteine sind Schreibvorgänge – sie durchlaufen den normalen Schreibpfad, belegen Speicherplatz auf der Festplatte und nutzen die Konsistenzmechanismen von Cassandra. Grabsteine können über Hinweise und Reparaturen im gesamten Cluster verbreitet werden. Wenn ein Cluster ordnungsgemäß verwaltet wird, wird sichergestellt, dass Daten auch dann gelöscht bleiben, wenn ein Knoten zum Zeitpunkt der delete nicht verfügbar ist.
Grabsteine werden von:
- DELETE-Anweisungen
- TTLs setzen
- Nullwerte einfügen
- Daten in Teile einer Sammlung einfügen.
Was ist der normale Lebenszyklus von Grabsteinen?
Grabsteine werden mit einem Zeitstempel geschrieben. Unter idealen Umständen werden Grabsteine (und die damit verbundenen Daten) während der Verdichtung nach Ablauf einer bestimmten Zeit gelöscht.
Die folgenden drei Kriterien müssen erfüllt sein, damit Grabsteine entfernt werden können:
- Die Grabsteine wurden vor mehr als gc_grace_seconds erstellt.
- Die Tabelle mit dem Grabstein ist an einer Verdichtung beteiligt.
- Alle sstables, die die relevanten Daten enthalten könnten, sind an der Verdichtung beteiligt.
Jede Tabelle hat eine Einstellung gc_grace_seconds. Standardmäßig ist dies auf 864000 festgelegt, was 10 Tagen entspricht. Ziel ist es, dem Cluster Zeit zu geben, um durch Reparaturen Konsistenz zu erreichen (und somit die Wiederherstellung gelöschter Daten zu verhindern).
Tombstones werden nur dann über eine Verdichtung gelöscht, wenn alle sstables, die die relevanten Daten enthalten könnten, an der Verdichtung beteiligt sind. Wenn zwischen dem Schreiben der Originaldaten und dem Löschen viel Zeit vergangen ist, wird dies weniger wahrscheinlich:
- Die größenstufige Verdichtungsstrategie komprimiert Sstables ähnlicher Größe zusammen. Daher ist es unwahrscheinlich, dass der Tombstone (in einem neuen, kleinen Sstable) mit den Daten (in einem alten, großen Sstable) komprimiert wird.
- Die nivellierte Verdichtungsstrategie ist in viele Ebenen unterteilt, die separat verdichtet werden. Der Tombstone wird in Level 0 geschrieben und jagt die Daten effektiv durch die Level – er sollte schließlich aufholen.
- Die Zeitfensterverdichtungsstrategie (oder die Datumsstufenverdichtungsstrategie) verdichtet den Tombstone niemals mit den Daten, wenn sie in verschiedene Zeitfenster geschrieben werden.
Wann verursachen Grabsteine Probleme?
Festplattennutzung
Wenn Daten gelöscht werden, wird der Speicherplatz mindestens für den in den Tabelleneinstellungen festgelegten gc_grace-Zeitraum nicht freigegeben. Dies kann zu Problemen führen, wenn sich ein Cluster schnell füllt.
Unter bestimmten Umständen wird der Speicherplatz niemals ohne manuellen Eingriff freigegeben.
Leseleistung
Wenn Lesevorgänge auf eine große Anzahl von Grabsteinen stoßen, können schwerwiegende Leistungsprobleme auftreten.
Performance-Probleme treten am ehesten bei den folgenden Abfragetypen auf:
- Abfragen, die alle Partitionen in einer Tabelle durchlaufen („select * from keyspace.tabelle“)
- Bereichsabfragen („select * from keyspace.tabelle WHERE value > x“ oder „WHERE value IN (value1, value2, …)“
- Jede Abfrage, die nur mit einer „ALLOW FILTERING“ -Klausel ausgeführt werden kann.
Diese Leistungsprobleme treten aufgrund des Verhaltens von Tombstones beim Lesen auf. In einer Bereichsabfrage verwendet Ihr Cassandra-Treiber normalerweise Paging, wodurch Knoten eine begrenzte Anzahl von Antworten gleichzeitig zurückgeben können. Wenn Cassandra-Tombstones beteiligt sind, muss der Knoten die Tombstones, auf die er gestoßen ist, im Speicher behalten und an den Koordinator zurückgeben, falls eines der anderen Replikate nicht weiß, dass die relevanten Daten gelöscht wurden. Die Grabsteine können nicht ausgelagert werden, da es wichtig ist, alle zurückzugeben, sodass Latenz und Speichernutzung proportional zur Anzahl der angetroffenen Grabsteine zunehmen.
Ob die Grabsteine gefunden werden, hängt davon ab, wie die Daten gespeichert und abgerufen werden. Wenn Cassandra beispielsweise zum Speichern von Daten in einer Warteschlange verwendet wird (was nicht empfohlen wird), können bei Abfragen Zehntausende von Tombstones auftreten, um einige Datenzeilen zurückzugeben.
Wie kann ich Tombstone-Probleme diagnostizieren?
Abfragen, die auf eine große Anzahl von Grabsteinen stoßen, werden in den Protokollen angezeigt. Standardmäßig generiert ein Lesevorgang mit mehr als tausend Grabsteinen eine Warnung:
WARN org.Apache.Cassandra.DB.ReadCommand Liest 0 Live-Zeilen und 87051 Tombstone-Zellen für die Abfrage SELECT * FROM example .tabelle
Standardmäßig schlägt die Abfrage bei mehr als 100.000 Grabsteinen mit einer TombstoneOverwhelmingException fehl.
Um zu überprüfen, ob Tombstone-Lesevorgänge Leistungsprobleme verursachen, überprüfen Sie, ob die Lesevorgänge mit einer Erhöhung der Leselatenz und der GC-Pausendauer korrelieren.
Wenn klar ist, dass Tombstones die Probleme sind, können die folgenden Techniken helfen, den Umfang des Problems einzugrenzen:
- Die Anzahl der Tombstones, die in einer bestimmten Abfrage zurückgegeben werden, kann ermittelt werden, indem die Abfrage in cqlsh mit aktivierter Ablaufverfolgung ausgeführt wird.
- Statistiken für die Anzahl der kürzlich in jeder Tabelle gefundenen Grabsteine sind in der Ausgabe von
nodetool cfstats
verfügbar. - Für Cluster in unserem Managed Service sind Statistiken für kürzlich gefundene Tombstones auf der Cluster-Seite in Metrikenlisten > Tabelleninfo verfügbar. Dazu gehören lebende Zellen pro Lesevorgang sowie durchschnittliche und maximale Grabsteine pro Lesevorgang, aufgeschlüsselt nach Knoten oder Tabelle für einen bestimmten Zeitraum.
- Detailliertere Informationen zu gespeicherten Grabsteinen finden Sie mit ic-tools.
Wie kann ich Tombstone-Probleme vermeiden?
Die folgenden Optionen können helfen:
- Vermeiden Sie Abfragen, die auf allen Partitionen in der Tabelle ausgeführt werden (z. B. Abfragen ohne WHERE-Klausel oder Abfragen, für die eine ALLOW-FILTERUNG erforderlich ist).
- Ändern Sie Bereichsabfragen, um die Abfrage gelöschter Daten zu vermeiden, oder arbeiten Sie mit einem engeren Datenbereich. Leistungsprobleme treten nur auf, wenn die Grabsteine gelesen werden, und skalieren mit der Anzahl der gelesenen Grabsteine.
- Entwerfen Sie das Datenmodell, um das Löschen großer Datenmengen zu vermeiden.
- Wenn Sie alle Daten in einer Tabelle löschen möchten, kürzen oder löschen Sie die Tabelle, um alle Daten zu entfernen, ohne Tombstones zu generieren.
- Verwenden Sie einen Standardwert für Time-to-live. Dies funktioniert nur dann effizient, wenn der Primärschlüssel Ihrer Daten zeitbasiert ist, Ihre Daten in chronologischer Reihenfolge geschrieben werden und die Daten zu einem bekannten Datum gelöscht werden. Legen Sie dazu eine Standard-TTL in den Optionen auf Tabellenebene fest und legen Sie eine zeitbasierte Verdichtungsstrategie fest (TimeWindowCompactionStrategy falls verfügbar, DateTieredCompactionStrategy andernfalls). Dadurch werden weiterhin Tombstones erstellt, aber ganze Sstables werden effizient gelöscht, sobald die TTL für alle ihre Inhalte abgelaufen ist.
Wie kann ich vorhandene Grabsteine entfernen?
In den meisten Fällen ist es am besten zu warten, bis sich der Grabstein normal verdichtet hat. Wenn dringende Probleme mit der Leistung oder der Festplattennutzung sofortigere Maßnahmen erfordern, gibt es zwei Nodetool-Befehle, mit denen Komprimierungen erzwungen werden können. Diese sollten als letzter Ausweg betrachtet werden – in einem gesunden Cluster mit einem gut gestalteten Datenmodell ist es nicht erforderlich, manuelle Komprimierungen durchzuführen.
Ausführen von nodetool compact
erzwingt eine Komprimierung aller sstables. Dies erfordert eine große Menge an freiem Speicherplatz. Keyspace- und Tabellenargumente sollten verwendet werden, um die Verdichtung auf die Tabellen zu beschränken, in denen Grabsteine ein Problem darstellen. In Tabellen, in denen eine größenstufige Verdichtungsstrategie verwendet wird, kann dieser Befehl zur Erstellung einer riesigen sstable führen, mit der niemals Peers komprimiert werden können; wenn das Flag –split-output
verfügbar ist, sollte es verwendet werden.
Der Befehl nodetool garbagecollect
ist ab Cassandra 3.10 verfügbar. Dieser Befehl führt eine Reihe kleinerer Komprimierungen aus, die auch überlappende sstables überprüfen. Es ist CPU-intensiver und zeitaufwändiger als nodetool compact
, benötigt aber weniger freien Speicherplatz.
Grabsteine werden nur entfernt, wenn gc_grace_seconds seit der Erstellung der Grabsteine verstrichen ist. Der beabsichtigte Zweck von gc_grace_seconds besteht darin, Zeit für Reparaturen bereitzustellen, um die Konsistenz des Clusters wiederherzustellen. Daher ist es gefährlich, gc_grace_seconds unter die Dauer des Hinweisübergabefensters zu reduzieren (standardmäßig 3 Stunden).
Reparaturen
Reparaturen können das Fallenlassen von Grabsteinen verzögern oder verhindern. Wenn eine vollständige oder inkrementelle Reparatur ausgeführt wird, werden die betroffenen Sstables als repariert markiert. Wenn sich Tombstones in nicht reparierten Sstables befinden und sich die schattierten Daten in reparierten Sstables befinden (oder umgekehrt), können die Daten nicht gelöscht werden, da die Sstables nicht zusammen komprimiert werden können.
Wenn Sie regelmäßig vollständige oder inkrementelle Reparaturen am Cluster durchführen, sollte dies kein allzu großes Problem darstellen, da Tombstones und Daten schließlich repariert werden. Wenn Sie jedoch eine Mischung aus reparierten und nicht reparierten Daten haben und nicht regelmäßig Reparaturen durchführen, kann dies zu einem Problem werden. mit sstablemetadata können Sie den reparierten Status Ihrer sstables überprüfen, um herauszufinden, ob dies geschieht. Wenn dies der Fall ist, kann es ratsam sein, alle sstables mit sstablerepairedset als nicht repariert sstablerepairedset , damit sie zusammen komprimiert werden können.
Bitte beachten Sie, dass Subrange-Reparaturen Daten nicht als repariert markieren.