Große Datenmengen lokal via rsync kopieren

Folgende Ausgangssituation: Aufgrund warum auch immer muss eine große Datenmenge von einem Verzeichnis in ein anderes kopiert werden. Rahmenbedingung: Die Daten sollen so lange wie möglich weiterhin zugreifbar sein. Die Lösung: Kopie via rsync. Denn rsync überträgt ab dem zweiten Lauf nur noch die Änderungen an den Daten. Das macht man so lange bis es kaum noch Änderungen gibt. Danach stoppt man die Dienste, ein letzter rsync Lauf, Austausch der Verzeichnisnamen, Dienste wieder starten und fertig.

GroupWise POA via rsync kopieren

Ein sehr großes POA eines GroupWise Systems muss an einen anderen Ort kopiert werden. Der konkrete Auslöser in diesem Fall: Das darunter liegende NSS-Dateisystem soll von 32 nach 64 Bit migriert werden. Rahmenbedingung: Der Emailserver soll nur so kurz wie irgendwie möglich unterbrochen werden. Die Lösung: Kopie via rsync. Denn rsync überträgt ab dem zweiten Lauf nur noch die Änderungen an den Daten. Das macht man so lange bis es kaum noch Änderungen gibt. Danach stoppt man die GroupWise Dienste, ein letzter rsync Lauf, Austausch der Verzeichnisnamen, Dienste wieder starten und fertig.

Ok, die Ausgangsbasis mag eine andere sein. Aber unterm Strich liest sich das eine gleich wie das andere, oder? Zusammengefasst soll eine große Datenmenge lokal in ein anderes Verzeichnis verschoben werden. Bei näherer Betrachtung dieser Daten fallen mir zwei Dinge auf: Es handelt sich um mehrere Terabyte und diese sind in sehr, sehr vielen kleinen Dateien gespeichert. Also all das was man braucht wenn man schnell fertig sein will -Ironie Ende-. Nein, ernsthaft. Das ist gar nicht gut. Das klingt nach sehr, sehr langer Laufzeit.

Warum rsync und kein einfacher cp ist ja bereits durch. Mein Problem ist so lange bekomme ich keine Downtime genehmigt. Also rsync gestartet. Der läuft auch rasch an und macht sich ans Werk. Die zu kopierende Dateiliste wird erstellt, das dauert halt etwas. Aber dann geht die Kopiererei auch schon los. Die ersten Megabyte und auch ziemlich rasch die ersten Gigabyte erscheinen im Ziellaufwerk. Apropos rsync: Die Geschwindigkeit die rsync lokal erreichen kann ist limitiert durch die Geschwindigkeit der verfügbaren Platten. Eine VM mit einem All-Flash-Array im Hintergrund. Ok, das rennt. Sollte man meinen. Denn irgendwie tut der rsync gerade nichts mehr: Die Meldungen bleiben stehen, es werden kaum noch Daten kopiert. Das ist alles so langsam und träge. Ein Blick in top: rsync will Unmengen an RAM, macht CPU Last ohne Ende während der Disk-IO gegen 0 geht. An der Stelle habe ich auch schon mal erlebt, dass der Verfügbare RAM durchaus ausgehen kann sofern hier nur wenig Reserven da sind. Ein Blick ins dmesg verrät einem sofort ob der gefürchtete OOM-Killer unterwegs war…

Aber was kann man tun? Die erste Suche war ohne Ergebnis. Die Geschwindigkeit richtet sich nach dem lokalen Plattendurchsatz. Das passt aber hier nicht ganz ins Bild. Also mal die zu kopierenden Daten betrachtet. Der allergrößte Brocken liegt bei GroupWise im Ordner offiles. Direkt unterhalb von diesem gibt es 256 weitere Unterordner in denen dann die eigentlichen Daten liegen. Die Terabyte an Daten liegen also größtenteils in 256 Ordner verteilt die jeweils nur wenige Gigabyte groß sind. Na damit lässt sich doch was anfangen. Also was kann man tun?

GNU parallel

GNU parallel

Im Sinne von „teile und herrsche“ (https://de.wikipedia.org/wiki/Teile-und-herrsche-Verfahren) kann man unlösbare Probleme lösen indem man sie in kleinere Teilprobleme zerlegt. Die Lösung dieser Unterschritte ergibt in Summe die Gesamtlösung.

In diesem Falle lässt sich der offiles Ordner in seine 256 „Einzelteile“ zerlegen. Jeder dieser Ordner ist überschaubar bzgl. der Größe und die Anzahl der Dateien. Und damit es schneller geht werden diese Einzelteile anstatt allesamt einer nach dem anderen parallel abgearbeitet. Ich habe mich auf gleichzeitig 8 Verzeichnisse festgelegt: Das hat die Hardware super weggesteckt und sogar keiner der GroupWise Anwender hat sich beklagt, dass die Performance während eines Kopiervorgangs schlechter geworden wäre. Hier heißt es ggf. erstmals ausprobieren und sachte heranzutasten was ein geeigneter Wert für gleichzeitige Kopiervorgänge wäre.

Mit etwas geschickter bash Programmierung wäre es kein Thema die parallelen Jobs selbst zu verwalten. Aber wozu? Mit „parallel“ aus den GNU Tools gibt es ein praktisches Werkzeug welches einem genau diese Arbeit abnimmt. Leider fehlt es vielen Linux Distributionen in den verfügbaren Paketen. Jedoch ist es aus den Quellen rasch übersetzt. Diese, sowie eine ausführliche Anleitung, finden sich auf der Homepage des GNU Projektes: https://www.gnu.org/software/parallel/.

 

Meine Lösung

Meine Lösung ist ein kurzes bash Skript welches im Kopf die beiden NSS Verzeichnisse als Quell- und Zielverzeichnis gelistet haben. Im Quellverzeichnis wird zunächst nach sämtlichen offiles Ordnern gesucht – ich habe hier Server stehen auf denen mehr als nur ein POA installiert sind. Im nächsten Schritt wird alles außer den offiles kopiert. Im folgenden Schritt werden anschließend alle offiles Unterordner via parallel aufgerufenen rsync Befehlen kopiert.

Bisher habe ich die Kopieraktion abgebrochen da nichts mehr vorwärts ging. Jetzt war der Erstsync innerhalb eines Tages fertig, die folgenden Läufe brauchten nur wenige Stunden. Vor der eigentlichen Umstellung wurde gerade nochmals eine knappe Stunde für den sync benötigt. Das passt, die Stunde Downtime im GroupWise bekomme ich im Rahmen der üblichen Wartungsfenster locker den Kunden gegenüber argumentiert.

NSS Kenner mögen jetzt fragen was mit den Trustees ist. Eine übliche GroupWise Installation legt keine Trustess an, somit gäbe es auch keine zu kopieren. Und falls doch: Ein nss /help zeigt den aktuellen Status und mittels nss /ListXaatrNWmetadata lässt sich eine xml-Datei aktivieren in der sämtliche Trustess gelistet sind. Diese Datei wird von rsync, sofern vorhanden, einfach mitkopiert. So können die Trustess auf dem Ziellaufwerk übernommen werden. Im Novell / MicroFocus / NetIQ NSS Migration Guide ist diese Variante mit rsync ausführlich beschrieben: https://www.novell.com/documentation/open-enterprise-server-2018/stor_nss_lx/data/t42v5hiqjnzn.html#t42v6m36om8w. Ich habe diesen Ansatz lediglich parallelisiert.

Und hier nun das von mir verwendete Hilfsskript. NSS Trustees werden zumindest erwähnt – ich habe halt wie bereits gesagt bei GroupWise keine im Einsatz. Somit sind die Trustee Blöcke rein informativer Natur.

#!/bin/bash

#
# Ein GroupWise NSS rsync Skript ;-) Mal kucken ob es damit besser läuft...
#

#
# 2019-12-13, Gehirn-Mag.Net: Init... (ob der Wochentag was aussagen soll?)
#

# sehr frei nach: https://www.novell.com/documentation/open-enterprise-server-2018/stor_nss_lx/data/t42v5hiqjnzn.html#t42v6m36om8w


# Source und Dest - wichtig der / am Ende!
SDIR=/media/nss/GROUPWISE/
DDIR=/media/nss/GROUPWISE64/
THREADS=8
#DRYRUN=--dry-run
LDIR=/tmp/gwrsync
START="$(date)"


# Logdir vorbereiten, alte Logs löschen
mkdir -pv $LDIR
find $LDIR -type f | xargs -n 50 rm -v

# NSS zumindest mal Trustee Status ausgeben
echo "nss /ListXattrNWmetadata <-- Sollte an sein ;-)"
nss /help | grep -A1 Xattr

# offiles Ordner suchen
cd $SDIR
find . -maxdepth 2 -type d -name "offiles" | cut -d/ -f2- > /tmp/gwrsync.exclude

# Alles außer offiles
rsync                                                       \\
   $DRYRUN                                                  \\
   -vv -r -h -lXHtS --stats --delete                        \\
   --exclude-from /tmp/gwrsync.exclude                      \\
   --exclude ._NETWARE/                                     \\
   --exclude '~DFSINFO.8-P'                                 \\
   --log-file=${LDIR}/wo-offiles.log                        \\
   $SDIR $DDIR

# Offiles
echo "--------------------------------------------------------------------"
echo "OFFILES"
while read FOLDER; do
   echo $FOLDER
   PO=$(echo $FOLDER | rev | cut -d'/' -f2 | rev)
   find ${SDIR}${FOLDER} -mindepth 1 -maxdepth 1 -type d |  \\
      parallel -j${THREADS}                                 \\
      rsync $DRYRUN -vv -r -h -lXHtS --stats --delete       \\
      --log-file=${LDIR}/{#}-{%}-${PO}-{/}.log              \\
      {} ${DDIR}${FOLDER}
done < <(cat /tmp/gwrsync.exclude)

# Trustees kopieren - ich hab halt keine ;-)

# Hinweis auf NSS wieder an ;-)
echo -e "\\n\\nnss ListXattrNWmetadata ggf. noch deaktivieren ;-)"
echo $START
date
exit

 

Warum das Ganze?

Der Auslöser war die schlichte Tatsache, dass auf dem GroupWise Server als Dateisystem für die Daten NSS verwendet wird – in der 32 Bit Version. Jetzt gibt es keine direkte Migrationsmöglichkeit von NSS 32 auf 64 Bit. Der offizielle Weg von MircoFocus sieht vor, dass man die Daten entsprechend kopiert. Das kann das NSS Migrationstool machen oder man kopiert mit Linux Bordmitteln. Ich habe mich für die Linux-Variante entscheiden. Und da mir das zu lange dauerte via parallel nachgeholfen.

Letztendlich zeigt diese Lösung, dass man sicherlich nicht alle, aber einige Kopierjobs parallel abgearbeitet deutlich beschleunigen kann. Im Falle GroupWise gibt es einige Verzeichnisse und noch ein paar mehr Dateien. Und es gibt den offiles Ordner. Dieser Ansatz lässt sich auf viele andere, große Kopierjobs, erfolgreich übertragen.