parallel rsync

parallel rsync

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.

Kein NXDOMAIN heute: dig vs. FORMERR

Kein NXDOMAIN heute: dig vs. FORMERR

Die gängigen zwei Gründe für einen NXDOMAIN bei einer DNS-Anfrage sind: Vertippt und vergessen. Bei vertippt ist es egal ob dies auf der Client Seite oder in der Zonendatei passiert ist: Vertippt bleibt vertippt. Und vergessen kennt jeder: Es hätte schon längst in der Zonendatei drin stehen sollen. Hätte. Nur was ist wenn man wie beim NXDOMAIN kein Ergebnis bekommt und stattdessen als Status FORMERR?

Ich hatte es bereits neulich schon einmal von einem DNS Problem: "lame server" oder viel Spaß mit DNS. Hier verweigerte ein Server die Antwort obwohl er diese liefern müsste. Nur warum hat er dies getan? Was wäre wenn die Zonendatei und die Konfiguration korrekt wären? Was wäre wenn dieser eine Nameserver anstatt NXDOMAIN dann doch tatsächlich einen FORMERR zurück liefert? Und sogar bei Einträgen die es gibt der FORMERR kommt? Was wäre wenn das Dein DNS-Server wäre und Du jetzt nach der Ursache suchen müsstest?

Da kann man allerdings noch einen oben drauf setzen: Das ist kein generelles Problem, bei vielen funktioniert alles wunderbar. Und auch einschlägige Testtools welche man auf diversen Internetseiten findet liefern das korrekte Ergebnis zurück. Also gut, los geht es. Schauen wir uns das doch nochmals genauer an.

Was wissen wir bereits? Grundsätzlich funktioniert der DNS-Server. Der Fehler ist reproduzierbar und er ist selektiv. Das heißt bei den Personen wo dieses Problem auftritt, tritt es bei jeder DNS-Anfrage auf. Für alle anderen ist alles in bester Ordnung. Somit gibt es zwei Gruppen: Die wo es funktioniert und diejenigen wo es nicht funktioniert. Es gilt also den Unterschied zu suchen. Da für beide Gruppen der Server der gleiche ist muss die Ursache auf dem Client liegen. Irgendwas muss bei der vermeintlich gleichen Frage an den Server unterschiedlich sein. Also fangen wir mal an der Stelle an und betrachten die Frage an den Server genauer.

Zurück an die Konsole

Also gut, es geht darum zu finden was auf Client Seite passiert ist. Somit starte ich mein Werkzeug der Wahl: dig. Schauen wir uns doch mal an was hier zurück kommt:

steffen@gmn:~$ dig <domain>.com @ns1.<domain>.com

; <<>> DiG 9.16.1-Ubuntu <<>> <domain>.com @ns1.<domain>.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: FORMERR, id: 27153
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 247f6f7828e8660c (echoed)
;; QUESTION SECTION:
;<domain>.com. IN A

;; Query time: 204 msec
;; SERVER: 1.2.3.4#53(1.2.3.4)
;; WHEN: Di Jun 16 21:36:49 CEST 2020
;; MSG SIZE rcvd: 55

Grün markiert ist mein eingegebenes Kommando. Rot der FORMERR. Das wissen wir bereits. Aber halt, in der blau markierten Zeile mit Cookie: Da steht echoed in der Klammer, jedoch sollte hier good stehen. Also nochmals die gleiche Anfrage gestellt, dieses mal jedoch mit der zusätzlichen Option +noedns:

steffen@lka:~$ dig <domain>.com @ns1.<domain>.com +noedns

; <<>> DiG 9.16.1-Ubuntu <<>> <domain>.com @ns1.<domain>.com +noedns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23374
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;<domain>.com. IN A

;; ANSWER SECTION:
<domain>.com. 3600 IN CNAME sub.<domain>.com.

;; Query time: 204 msec
;; SERVER: 1.2.3.4#53(1.2.3.4)
;; WHEN: Di Jun 16 21:36:57 CEST 2020
;; MSG SIZE rcvd: 57

Und siehe an, das hat funktioniert. Dabei wäre es egal ob ich als Option +noedns wie gezeigt oder +nocookie verwendet hätte. Beide Optionen liefern wieder die gewohnten Ergebnisse zurück. Gesucht, gefunden: Der DNS-Server hat ein Problem mit EDNS.

Und nun?

Naja, was kann man tun? Bei mir hier im Netz läuft ein lokaler bind Server fürs DNS Caching. Gemäß Doku kann man hier sagen, dass immer dann wenn er den betroffenen Server kontaktiert werden soll EDNS abschaltet wird:

server <IP address or prefix> { edns no; };

Der Link dazu: https://kb.isc.org/docs/aa-01219. Aber mal ehrlich: Will ich das tun? Nein, dass will ich nicht. Warum sollte ich die Probleme eines Dritten bei mir im DNS Resolver lösen? Hier liegt ja offensichtlich ein Fehler vor der klar wird wenn man z.B. ins RFC 6891, Absatz 6.1.2 schaut:

Any OPTION-CODE values not understood by a responder or requestor MUST be ignored.

Der Link zum RFC: https://tools.ietf.org/html/rfc6891#section-6.1.2. "Must be ignored"... Und was bekomme ich? FORMERR. Also alles andere als ignoriert. Soso...

Nein, dann soll doch lieber der DNS-Server Betreiber die passenden Updates einspielen damit EDNS bzw. die Cookies richtig funktionieren. Ich bin garantiert nicht der einzige mit dem Problem und ich werde es auch sicherlich nicht bleiben. EDNS ist nun mal wichtig für die kommenden DNS Erweiterungen.

Weitere Details zu den DNS Cookies sowie zu EDNS gefällig? Ein sehr guter Ausgangspunkt finde ich ist der DNS Flag Day von 2019: https://dnsflagday.net/2019/. Ebenso interessant dazu ist der ISC EDNS Compliance Test: https://ednscomp.isc.org/. Auch hier finden sich viele praktische Infos rund um das Thema EDNS. Und besonders Schick, deswegen heißt das Ding ja "Konformitätstest": Hier kann man den betroffenen Server testen lassen und bekommt einen ausführlichen Bericht mit vielen weiteren Detailinformationen. Neben dem bereits genannten RFC ist auch dieses hier interessant welches die Cookies nochmals erklärt: https://tools.ietf.org/html/rfc7873#section-2.1.