Kleine Tricks mit Elasticsearch

Eine kurze Anmerkung, eher für mich, über kleine Tricks zur Datenwiederherstellung in Elasticsearch. Wie man den roten Index repariert, wenn keine Sicherung vorhanden ist, was zu tun ist, wenn ich die Dokumente gelöscht habe und keine Kopie mehr vorhanden ist - leider schweigen sie in der offiziellen Dokumentation über diese Funktionen.

Backups




Als erstes müssen Sie Sicherungen wichtiger Daten einrichten. Wie dies gemacht wird, ist in der offiziellen Dokumentation beschrieben .

Alles in allem nichts kompliziertes. Erstellen Sie in der einfachsten Version einen Ball auf einem anderen Server und hängen Sie ihn auf bequeme Weise an alle elastischen Knoten an (nfs, smbfs, was auch immer). Verwenden Sie als Nächstes cron, Ihre Anwendung oder etwas anderes, um Anforderungen für regelmäßige Snapshots zu senden.

Der erste Schnappschuss ist lang, die folgenden enthalten nur das Delta zwischen den Zuständen des Index. Beachten Sie, dass das Delta sehr groß ist, wenn Sie regelmäßig ein Forcemerge durchführen. Dementsprechend ist die Zeit, die zum Erstellen eines Snapshots benötigt wird, wie beim ersten Mal.

Was zu beachten ist:

  • Überprüfen Sie den Status von Sicherungen, z. B. mit _cat: curl localhost:9200/_cat/snapshots/ yourbackuprepo / . Teilweise oder fehlgeschlagene Schnappschüsse sind nicht dein Bruder.
  • Ab ES 6.x ist das Gummiband auf Anfrage sehr anspruchsvoll. Wenn Sie sie manuell ausführen (nicht über die API), überprüfen Sie, ob Sie Content-Type: application/json haben. Andernfalls werden alle Ihre Anforderungen einfach abgebrochen und die Sicherung findet nicht statt
  • Snapshot kann nicht in einem offenen Index wiederhergestellt werden. Es muss zuerst geschlossen oder entfernt werden. Sie können den Snapshot jedoch nebeneinander mit rename_pattern, rename_replacement wiederherstellen ( siehe Beispiel im Dock ). Wenn ein Snapshot wiederhergestellt wird, werden auch seine Einstellungen wiederhergestellt, einschließlich Aliase, Anzahl der Replikate usw. Wenn Sie dies nicht benötigen, fügen Sie index_settings ( ein Beispiel finden Sie im Dock ) mit den erforderlichen Änderungen an der Wiederherstellungsanforderung hinzu.
  • Repos (Ball) mit Snapshots können mit mehr als einem Cluster verbunden werden und Snapshots von jedem Cluster in einem anderen wiederherstellen. Die Hauptsache ist, dass die elastischen Versionen kompatibel sind.

Schauen Sie sich im Allgemeinen die Dokumentation an, dort wird dieses Thema mehr oder weniger offengelegt.

Elasticdump




Ein kleines Dienstprogramm auf nodejs, mit dem Sie Daten von einem Index in einen anderen Index, Cluster, Datei oder Standard kopieren können.

Übrigens kann die Ausgabe in eine Datei oder ein Standardout als alternative Sicherungsmethode verwendet werden - die Ausgabe ist ein regulär gültiger JSON (so etwas wie SQL Dump), der nach Belieben wiederverwendet werden kann. Beispielsweise können Sie die Ausgabe in eine Pipe einfügen, in der Ihr Skript die Daten irgendwie transformiert und an ein anderes Repository wie Clickhouse sendet. Die einfachsten js-Konvertierungen können direkt durch elasticdump selbst durchgeführt werden, es gibt eine entsprechende Schlüsseltransformation. Im Allgemeinen ein Flug der Phantasie.

Von den Fallstricken:

  • Als Sicherungsmethode ist es viel langsamer als Snapshots. Außerdem wird die Sicherung im Laufe der Zeit erweitert, sodass das Ergebnis eines häufig wechselnden Index möglicherweise inkonsistent ist. Denken Sie daran.
  • Verwenden Sie keine NodeJs aus dem Debian-Repository. Es gibt eine zu alte Version, die sich negativ auf die Stabilität der Tools auswirkt.
  • Die Stabilität kann variieren, insbesondere wenn eine der Parteien überlastet ist. Versuchen Sie nicht, von einem Server auf einen anderen zu sichern, indem Sie das Tool auf dem Büromaschinen ausführen. Der gesamte Datenverkehr fließt durch diesen.
  • Abb. Zuordnungen kopieren. Wenn Sie dort etwas Kompliziertes haben, erstellen Sie den Index manuell und füllen Sie erst dann die Daten hinein.
  • Manchmal ist es sinnvoll, die Größe des Blocks zu ändern (Parameter --limit). Diese Option wirkt sich direkt auf die Kopiergeschwindigkeit aus.

Um eine große Anzahl von Indizes gleichzeitig zusammenzuführen, gibt es einen Multielasticdump mit einem vereinfachten Satz von Optionen, aber alle Indizes werden parallel zusammengeführt.

Hinweis! Der Autor des Dienstprogramms sagte, dass er keine Zeit mehr für die Unterstützung hat, daher sucht das Programm nach einem neuen Betreuer .

Aus persönlicher Erfahrung: nützlicher Nutzen, mehr als einmal gerettet. Geschwindigkeit und Stabilität sind so lala, ich hätte gerne einen angemessenen Ersatz, aber bisher ist nichts am Horizont.

Checkindex


Also nähern wir uns der dunklen Seite. Situation: Der Index ist rot geworden. In den Protokollen - etwas ist schief gelaufen, die Prüfung stimmt nicht mit dem Betrag überein, Sie haben wahrscheinlich einen Speicher oder eine Festplatte:

org.apache.lucene.index.CorruptIndexException: checksum failed (hardware problem?)

Natürlich passiert dies bei Mutteradministratoren nie, da sie über Top-End-Hardware mit dreifacher Replikation, SuperECC-Speicher mit Korrektur aller Fehlerstufen im laufenden Betrieb und im Allgemeinen jede Sekunde konfigurierte Snapshots verfügen.

Aber die Realität fordert leider manchmal solche Optionen auf, wenn die Sicherung relativ lang war (wenn Sie Gigabyte pro Stunde indiziert haben, ist die Sicherung vor 2 Stunden zu alt?). Es gibt keinen Ort zum Wiederherstellen der Daten, die Replikation hatte keine Zeit und ähnliches.

Natürlich, wenn es einen Schnappschuss, ein Backup oder ähnliches gibt. - Ausgezeichnet, ausrollen und keine Sorgen machen. Und wenn nicht? Glücklicherweise können zumindest einige der Daten noch gespeichert werden.

Schließen Sie zunächst den Index und / oder schalten Sie das Gummiband aus und erstellen Sie eine Sicherungskopie des ausgefallenen Shards.

Lucene (das heißt, es funktioniert als Backend in der Elasticsearch) hat eine wunderbare CheckIndex-Methode. Wir müssen es nur über eine zerbrochene Scherbe beschwören. Lucene überprüft alle Segmente und entfernt die beschädigten. Ja, Daten gehen verloren, aber zumindest nicht alles. Obwohl es so viel Glück gibt.

Es gibt mindestens zwei Möglichkeiten.

Methode 1: Direkt vor Ort


Ein so einfaches Skript wird uns helfen.

 #!/bin/bash pushd /usr/share/elasticsearch/lib java -cp lucene-core*.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex "$@" popd 

Wenn wir es ohne Parameter aufrufen, erhalten wir ungefähr Folgendes:

 ERROR: index path not specified Usage: java org.apache.lucene.index.CheckIndex pathToIndex [-exorcise] [-crossCheckTermVectors] [-segment X] [-segment Y] [-dir-impl X] -exorcise: actually write a new segments_N file, removing any problematic segments -fast: just verify file checksums, omitting logical integrity checks -crossCheckTermVectors: verifies that term vectors match postings; THIS IS VERY SLOW! -codec X: when exorcising, codec to write the new segments_N file with -verbose: print additional details -segment X: only check the specified segments. This can be specified multiple times, to check more than one segment, eg '-segment _2 -segment _a'. You can't use this with the -exorcise option -dir-impl X: use a specific FSDirectory implementation. If no package is specified the org.apache.lucene.store package will be used. **WARNING**: -exorcise *LOSES DATA*. This should only be used on an emergency basis as it will cause documents (perhaps many) to be permanently removed from the index. Always make a backup copy of your index before running this! Do not run this tool on an index that is actively being written to. You have been warned! Run without -exorcise, this tool will open the index, report version information and report any exceptions it hits and what action it would take if -exorcise were specified. With -exorcise, this tool will remove any segments that have issues and write a new segments_N file. This means all documents contained in the affected segments will be removed. This tool exits with exit code 1 if the index cannot be opened or has any corruption, else 0. 

Tatsächlich können wir entweder einfach den Indextest ausführen oder CheckIndex dazu bringen, ihn zu „reparieren“ und alles zu entfernen, was beschädigt ist.

Der Lucene-Index lebt ungefähr auf die gleiche Weise: / var / lib / elasticsearch / node / 0 / indices / str4ngEHashVa1uE / 0 / index /, wobei 0 und 0 die Knotennummer auf dem Server und die Nummer des Shards auf dem Knoten sind. Der beängstigende Wert zwischen ihnen - der interne Name des Index - kann aus der Ausgabe von curl localhost ermittelt werden: 9200 / _cat / indizes.

Normalerweise mache ich eine Kopie in ein anderes Verzeichnis und repariere sie vor Ort. Dann starte ich elasticsearch neu. In der Regel wird alles abgeholt, wenn auch mit Datenverlust. Manchmal möchte der Index aufgrund der * beschädigten * Dateien im Shards-Ordner immer noch nicht gelesen werden. Bewahren Sie sie für eine Weile an einem sicheren Ort auf.

Methode 2: Luke



(Bild aus dem Internet)

Es gibt ein großartiges Dienstprogramm für die Arbeit mit Lucene namens Luke .

Hier ist es noch einfacher. Finden Sie die Lucene-Version aus Ihrer Elasticsearch heraus:

 $ curl localhost:9200 { "name" : "node00", "cluster_name" : "main", "cluster_uuid" : "UCbEivvLTcyWSQElOipgTQ", "version" : { "number" : "6.2.4", "build_hash" : "ccec39f", "build_date" : "2018-04-12T20:37:28.497551Z", "build_snapshot" : false, "lucene_version" : "7.2.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } 

Nimm die gleiche Version von Luke. Wir öffnen darin einen Index (Kopie natürlich) mit einer Morgendämmerung. Öffnen Sie den IndexReader nicht (wenn Sie einen beschädigten Index öffnen) . Klicken Sie anschließend auf Extras / Index prüfen. Zuerst empfehle ich, trocken zu laufen und erst dann im Reparaturmodus. Weitere Aktionen sind ähnlich - kopieren Sie das Gummiband zurück, starten Sie den Index neu / öffnen Sie ihn.

Gelöschte Dokumente wiederherstellen


Situation: Sie haben eine destruktive Abfrage durchgeführt, bei der viele / alle benötigten Daten gelöscht wurden. Und nirgends zu restaurieren oder sehr teuer. Nun, SSZB natürlich, dass es keine Backups gibt, aber das passiert auch.

Leider oder zum Glück entfernt Lucene nie etwas direkt. Die Philosophie ist näher an CoW, sodass gelöschte Daten nicht tatsächlich gelöscht, sondern nur als gelöscht markiert werden. Das Löschen selbst erfolgt während der Indexoptimierung - Live-Daten von Segmenten werden in neu erstellte Segmente kopiert, alte Segmente werden einfach gelöscht. Obwohl der Status des gelöschten Index nicht 0 ist, besteht im Allgemeinen die Möglichkeit, ihn zu löschen.

 $ curl localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open data.0 R0fgvfPnTUaoI2KKyQsgdg 5 1 7238685 1291566 45.1gb 22.6gb 

Nach dem Auftauchen gibt es keine Chance.

Schließen Sie also zunächst den Index, stoppen Sie das Gummiband und kopieren Sie den Index (die Dateien) an einen sicheren Ort.

Es ist nicht möglich, ein einzelnes gelöschtes Dokument herauszuziehen. Sie können nur alle gelöschten Dokumente im angegebenen Segment wiederherstellen.

Für Versionen Lucene unter 4 ist alles sehr einfach. Die Lucene-API verfügt über eine Funktion namens undeleteAll. Sie können sie direkt von Luke aus dem vorherigen Absatz anrufen.

Für neuere Versionen wurde leider die Funktionalität eingeschränkt. Aber es gibt immer noch einen Weg. Informationen zu Live-Dokumenten werden in * .liv-Dateien gespeichert. Durch einfaches Entfernen wird der Index jedoch unlesbar. Die Datei segment_N muss korrigiert werden, damit ihre Existenz vollständig vergessen wird.

Öffnen Sie die Datei segment_N (N ist eine Ganzzahl) in Ihrem bevorzugten Hex-Editor. Die offizielle Dokumentation hilft uns bei der Navigation:
 segments_N: Header, LuceneVersion, Version, NameCounter, SegCount, MinSegmentLuceneVersion, <SegName, SegID, SegCodec, DelGen, DeletionCount, FieldInfosGen, DocValuesGen, UpdatesFiles>SegCount, CommitUserData, Footer 

Von all dem benötigen wir die Werte von DelGen (Int64) und DeletionCount (Int32). Die erste muss gleich -1 und die zweite 0 sein.



Es ist nicht schwer, sie zu finden, sie befinden sich direkt hinter SegCodec, einer sehr auffälligen Zeichenfolge wie Lucene62. In diesem Screenshot sehen Sie, dass DelGen den Wert 3 und DeletionCount - 184614 hat. Ersetzen Sie den ersten durch 0xFFFFFFFFFFFFFFFF und den zweiten durch 0x00000000. Wiederholen Sie diesen Vorgang für alle erforderlichen Segmente.

Der feste Index möchte jedoch nicht geladen werden, da ein Prüfsummenfehler vorliegt. Hier ist es noch einfacher. Nehmen Sie Luke und laden Sie den Index mit dem deaktivierten IndexReader, Tools / Check Index. Wir machen einen Testlauf und stellen sofort fest, dass segment_N beschädigt ist. Eine solche und eine solche Prüfung wird erwartet, aber eine solche und eine solche wird empfangen.

 Caused by: org.apache.lucene.index.CorruptIndexException: checksum failed (hardware problem?) : expected=51fbdb5c actual=6e964d17 

Unsinn! Wir nehmen die erwartete Prüfsumme und geben sie in die letzten 4 Bytes der Datei ein.



Speichern. Wir führen CheckIndex erneut aus, um sicherzustellen, dass alles in Ordnung ist und der Index geladen wird.

Et voilà!

Source: https://habr.com/ru/post/de416955/


All Articles