Cassandra NetWorker
EMC NetWorker ist eine häufig verwendete Backuplösung, welche von verschiedenen Unternehmen eingesetzt wird, um ihre Backup- und Recovery-Strategien umzusetzen. Die Software unterstützt durch seine eigenen Module für Datenbanken und Anwendungen (NMDA) die automatisierte Sicherung und Wiederherstellung einer Vielzahl von Softwaresystemen. Hierzu gehören Datenbankensysteme wie Oracle oder MySQL. Bei Software- und Datenbanksystemen, welche nicht unterstützt werden, muss auf individuell für die Zielsysteme angepasste Filesystem-Sicherungen zurückgegriffen werden. Ein Beispiel hierfür ist die Sicherung der Daten eines Apache Cassandra Clusters.
Apache Cassandra ist ein NoSQL-Datenbanksystem, welches sich unter anderem durch seinen Fokus auf Skalierbarkeit und Hochverfügbarkeit positioniert. Bei einem hochverfügbaren System wie diesem beeinflussen selbst Ausfälle von einzelnen Knoten innerhalb eines Clusters nicht die Bereitstellung der Daten. Trotz Hochverfügbarkeit der Daten im Cluster muss z.B. zur Absicherung gegen logische Fehler aber trotzdem eine traditionelle Sicherung der Daten vorgenommen werden.
Daten innerhalb von Apache Cassandra werden in einem bestimmten System zusammengefasst. Das äußerste Element hierbei ist ein Keyspace. Dies ist vergleichbar mit einer Database aus einem relationalen Datenbanksystem, welches als äußeres Konstrukt zum Speichern der Daten dient. Innerhalb eines Keyspaces werden Tables angelegt, welche als Tabellen zu verstehen sind. Die Daten, welche hier hinzugefügt oder verändert werden, durchlaufen beim Speichern mehrere Stadien. Besonders relevant zur Sicherung sind hierbei die unveränderlichen SSTable-Dateien. In dieser Form werden die Daten einer Tabelle letztendlich auf dem Festplattenspeicher geschrieben.
Apache Cassandra bietet von sich aus sehr grundlegende Funktionalitäten, um eine konsistente Sicherung herzustellen. Dabei werden auf einem Knoten per Kommandozeile lokal Hardlinks von spezifizierten SSTable-Dateien erstellt. Weitere Tätigkeiten, wie die Verwaltung der Sicherungen und deren Verschiebung außerhalb des Clusters, bleiben jedoch in den Händen des Administrators. In diesem Blogartikel wird beschrieben, inwiefern die von EMC NetWorker bereitgestellten Funktionen genutzt werden können, um die SSTable-Dateien zu sichern und wiederherzustellen.
Grundlage: Sichern mit Apache Cassandra
Apache Cassandra bietet zwei Möglichkeiten an, um Sicherungen der SSTable-Dateien anzulegen: ‚Snapshots' und ‚Incremental Backups'. Für eine Sicherung mit NetWorker konzentrieren wir uns auf Snapshots, da diese einen konsistenten Zustand einer Tabelle zu einem Zeitpunkt erzeugen.
Um verstehen zu können, wie das funktioniert, muss erklärt werden, wie und wo die SSTable-Dateien auf einer Node abgespeichert sind.
Hierzu wird innerhalb der cassandra.yaml, der Konfigurationsdatei von Cassandra, ein Data Directory definiert. Standardmäßig wird das Data Directory unter $CASSANDRA_HOME/data/data angelegt. Innerhalb dieses Verzeichnisses besteht eine Verzeichnisstruktur, welche sich wie folgt zusammensetzt:
keyspace-name/table-name/
Innerhalb des Ordners einer spezifischen Tabelle befinden sich die zugehörigen SSTable-Dateien, in denen die Dateninhalte der Tabellen abgelegt werden. Diese bilden das Ziel unseres Backups.
Durch einen Snapshot werden Hardlinks im Linux-Filesystem auf alle bestehenden SSTable-Dateien einer ausgewählten Tabelle erzeugt. Diese werden dann in einem separaten Unterordner abgelegt. Grundlegend wird ein Snapshot mit dem Befehl ‚nodetool snapshot' durchgeführt. Alle Snapshots einer spezifischen Table werden in dem Unterverzeichnis
keyspace-name/table-name/snapshots/
abgelegt. Hier wird für jeden Snapshot ein weiteres Unterverzeichnis mit dem definierten Namen des Snapshots erstellt. Ist kein Name angegeben, wird standardmäßig ein UNIX-Zeitstempel zum Zeitpunkt des jeweiligen Snapshots verwendet.
Zusätzlich zu den Hardlinks der SSTable-Dateien befindet sich im Verzeichnis eine Datei namens ‚schema.cql'. Mit dieser kann das Schema der Table zum Zeitpunkt des Snapshots wiederhergestellt werden.
Um die Daten des Snapshots physikalisch von den Daten im Cluster zu trennen, ist eine Sicherung der Snapshots mit einer Backup-Software wie NetWorker denkbar. Ein Problem stellt jedoch die Auswahl der zu sichernden Dateien dar. Ein Backup muss neu hinzugefügte Keyspaces und Tables berücksichtigen, jedoch nur die SSTable-Dateien eines Snapshots sichern. Dies lässt sich mittels einer Vorauswahl über Skripte ermöglichen.
Aufbau: Angepasste Backup-Durchläufe für NetWorker mit Skripten
EMC NetWorker unterstützt die Verwendung von Skripten, welche automatisiert vor, während oder nach einem Backup ausgeführt werden. Mithilfe dieser Skripte ist es möglich, auf Basis von Cassandra-Snapshots konsistente Backups der Snapshots von spezifischen Tables oder des gesamten Keyspaces im NetWorker zu erstellen.
Hierfür lassen sich drei individuelle Skripte erstellen: Ein Pre-command Skript, ein Backup Skript, und ein Post-command Skript. Diese Skripte müssen sich jeweils auf dem zu sichernden Node befinden und im NetWorker für den jeweiligen Client ausgewählt werden, damit sie bei einer Sicherung verwendet werden.
Pre-command Skript
#!/bin/bash snapname=Snapshot keyspacename=ami_test01 nsr_logfile=/nsr/logs/cassandra_pre.log date >> "$nsr_logfile" echo "Attempting to run pre-backup script for Apache Cassandra" >> "$nsr_logfile" #Erstellung eines Snapshots /opt/cassandra/apache-cassandra-3.11.4/bin/nodetool -u cassandra -pw cassandra snapshot -t $snapname $keyspacename ret_createsnapshot_command=$? echo "Generating snapshot "$snapname" for Keyspace "$keyspacename": "$ret_createsnapshot_command >> "$nsr_logfile" #Status des Pre-Script if [ $ret_createsnapshot_command != 0 ] then echo "Error" >> "$nsr_logfile" echo "Cancelling backup" >> "$nsr_logfile" exit 1 else echo "Success" >> "$nsr_logfile" fi
Mit diesem Pre-Skript wird vor der Durchführung des Backups auf dem ausgewählten Node ein Snapshot eines spezifizierten Keyspace erstellt. Dem Snapshot wird ein spezifischer Name – hier ‚Snapshot' – gegeben, damit dieser im nachfolgenden Backup-Skript ermittelt und verwendet werden kann. Dieser Name ist case-sensitive und darf nicht identisch mit anderen, bestehenden Snapshots oder Verzeichnisnamen innerhalb der Data Directory sein.
Zusätzlich wird überprüft, ob bei der Erstellung des Snapshots Fehler auftraten. Dies kommt z.B. vor, wenn ein Snapshot mit einem identischen Namen bereits existiert. Ist dies der Fall, wird der Backup-Prozess abgebrochen, damit kein fehlerhafter oder potenziell veralteter Snapshot gesichert wird.
Backup Skript
#!/bin/bash nsr_pool=otc-data datadir=/opt/cassandra/data/data/ nsr_logfile=/nsr/logs/cassandra_save.log filelist=/nsr/logs/savefilelist.txt snapname=Snapshot NSR_CLIENT=`hostname` CASSANDRA_ID=Testumgebung date >> "$nsr_logfile" echo "Attempting to backup the files of the created Snapshot "$snapname >> "$nsr_logfile" # Erstellung der Dateiliste /usr/bin/find $datadir -path "*"\/$snapname\/"*" -print > $filelist # Dateiliste wird als Input für den save-Befehl verwendet /usr/sbin/save -b $nsr_pool -I $filelist -N "CASSANDRA:"$NSR_CLIENT":"$CASSANDRA_ID ret_save_command=$? echo "Execute save command: "$ret_save_command >> "$nsr_logfile" # Dateiliste wird nach Verwendung wieder entfernt rm $filelist ret_filelist_delete=$? echo "Remove filelist: "$ret_filelist_delete >> "$nsr_logfile" if [ $ret_save_command != 0 ] || [ $ret_filelist_delete != 0 ] then echo "Error" >> "$nsr_logfile" exit 1 else echo "Success" >> "$nsr_logfile" fi
Durch das Backup-Skript wird der Ablauf und Inhalt der NetWorker-Sicherung auf dem Node gesteuert. Vor der eigentlichen Sicherung wird eine Dateiliste erstellt, die sämtliche Dateien beinhaltet, welche sich in dem Verzeichnis des zuvor erstellten Snapshots befinden und gesichert werden sollen. Hierbei wird der Snapshot-Name als identifizierende Eigenschaft verwendet. Daher ist die Verwendung eines eindeutigen Namens wichtig, damit keine irrelevanten Verzeichnisse zusätzlich gesichert werden.
Nur die Dateien innerhalb dieser Liste werden anschließend bei der Sicherung berücksichtigt. Nach der Sicherung wird diese Dateiliste wieder vom Zielsystem entfernt.
Post-command Skript
#!/bin/bash snapname=Snapshot keyspacename=ami_test01 nsr_logfile=/nsr/logs/cassandra_post.log date >> "$nsr_logfile" echo "Attempting to run post-backup script for Apache Cassandra" >> "$nsr_logfile" # Löschen der generierten Snapshots /opt/cassandra/apache-cassandra-3.11.4/bin/nodetool -u cassandra -pw cassandra clearsnapshot -t $snapname $keyspacename ret_clearsnapshot_command=$? echo "Removing snapshot "$snapname" for Keyspace "$keyspacename": "$ret_clearsnapshot_command >> "$nsr_logfile" #Status des Post-Script if [ $ret_clearsnapshot_command != 0 ] then echo "Error" >> "$nsr_logfile" echo "Cancelling Backup" >> "$nsr_logfile" exit 1 else echo "Success" >> "$nsr_logfile" fi
Das Post-Skript dient dazu, nach der NetWorker-Sicherung den für das Backup erstellten Snapshot wieder zu entfernen. Wird dies nicht durchgeführt, kommt es bei der nächsten Sicherung zu Problemen, wenn die Dateien des Snapshots nicht manuell entfernt werden.
Während mit diesen Skripten der konsistente Zustand eines Nodes gesichert werden kann, wird für eine konsistente Sicherung der gesamten Daten eines Clusters eine solche Sicherung für jede Instanz des Clusters benötigt. Werden mithilfe von diesen Skripten – je nach Replikationsfaktor und weiteren Konfigurationen – mehrere oder alle Nodes eines Clusters gesichert, lässt sich hierdurch ein konsistentes Backup der ausgewählten Daten zu einem Zeitpunkt innerhalb des Clusters erstellen.
Restore der Daten via Skript
Wo gesichert wird, muss auch wiederhergestellt werden. Grundsätzlich besteht bei Apache Cassandra die Möglichkeit, den ‚sstableloader' zu verwenden, um die Inhalte von externen Dateien in die SSTable-Dateien eines Clusters einzuführen. Damit dies erfolgreich durchgeführt wird, müssen sich die externen Dateien jedoch in einer bestimmten Verzeichnisstruktur – ähnlich wie die der Verzeichnisstruktur des Data Directory – befinden. Der ‚sstableloader' bezieht sich auf die beiden überliegenden Verzeichnisnamen, um den Keyspace und die Table, in denen die Daten eingefügt werden sollen, zu ermitteln.
#!/bin/bash datadir=/home/ami/recoverscripttest savesetid=$1 logfile=/tmp/cas_recover.log date >> $logfile #Wiederherstellung des Snapshots mittels savesetID echo "Restoring saveset $savesetid in directory $datadir" >> $logfile /bin/recover -S $savesetid -d $datadir -I '/opt/cassandra/data/data/' rec_ret=$? #Test ob Wiederherstellung ohne Fehler geschehen ist if [ $rec_ret != 0 ] then echo "Error during saveset restore" >> $logfile echo "Cancelling further restore operations" >> $logfile exit 1 else echo "Restore successful" >> $logfile fi #Verschieben der Dateien als Vorbereitung fuer sstableloader for i in `find $datadir -name schema.cql -exec dirname {} \;` do mv $i/*.* $i/../../. ret=$? echo "Moving files from "$i/*.*" to "$i/../../." ended with code "$ret >> $logfile done #Wiederherstellung der Daten aus sstable-Dateien mittels sstableloader for i in `find $datadir -name schema.cql -exec dirname {} \;` do echo "Restoring sstable-files in $i with sstableloader" >> $logfile /opt/cassandra/apache-cassandra-3.11.4/bin/sstableloader -u cassandra -pw cassandra --nodes 192.168.130.28,192.168.130.196,192.168.130.197 $i >> $logfile done echo "Restoring with sstableloader completed" >> $logfile #Entfernen der nicht mehr noetigen Snapshot-Dateien echo "Removing restored directory under $datadir" >> $logfile rm -r $datadir rm_ret=$? echo "Removing files ended with code $rm_ret" >> $logfile
Durch dieses Skript lassen sich die Daten einer Sicherung wieder in das Cassandra Cluster einfügen. Die Auswahl der wiederherzustellenden Sicherung findet über die Saveset-ID der jeweiligen NetWorker-Sicherung statt. Mithilfe des durch NetWorker bereitgestellten ‚recover'-Befehls werden die Daten in einem spezifizierten Verzeichnis wiederhergestellt. Hierbei wird auch die überliegende Verzeichnisstruktur rekonstruiert. Durch das Skript werden die SSTable-Dateien in jene Verzeichnisse verschoben, welche die Wiederherstellung durch den sstableloader in die korrekten Keyspaces und Tables ermöglicht. Anschließend werden mittels des sstableloader-Befehls die Daten wieder in das Cassandra Cluster eingeführt. Die Dateien der Sicherung werden anschließend wieder entfernt, da sie nicht mehr benötigt werden, sobald die Daten in das Cluster eingeführt wurden.
Fazit
Mit der Verwendung der Backup-Skripte lassen sich mit NetWorker konsistente Backups eines Cassandra Clusters erstellen. Damit muss für Cassandra-Datenbanken keine eigene Lösung entwickelt werden, um die Daten zu sichern und wiederherzustellen. Ein möglicher Nachteil bilden potenzielle Probleme, wenn beispielsweise Snapshots manuell erstellt werden, welche den Namen des automatisch generierten Snapshots teilen. Ein weiterer Nachteil ist, dass das hier dargestellte Restore-Skript nur eine einzelne Sicherung vollständig wieder in das Cluster einführt. Um einen Stand eines Clusters wieder einzuführen, muss je nach Konfiguration für jede gesicherte Instanz das Skript einmal ausgeführt werden. Für den Fall, dass nur individuelle Keyspaces oder Tabellen wiederhergestellt werden sollen, muss zudem manuell agiert werden, da dieses Restore-Skript alle SSTable-Dateien wiederherstellt.
Sie haben Interesse an einer Weiterbildung oder Fragen zum Thema Cassandra? Sprechen Sie uns an oder besuchen Sie einen unserer Kurse aus unserem Seminarshop:
Zu unseren Seminaren
Bei Updates im Blog, informieren wir per E-Mail.
Kommentare