Effiziente Datenverwaltung mit dem Elasticsearch _bulk API-Befehl
Verwenden Sie die Elasticsearch _bulk API korrekt mit NDJSON-Beispielen, Antwortprüfungen, Batch-Größenanpassung und sicherer Wiederholungsanleitung.
Effiziente Datenverwaltung mit dem Elasticsearch _bulk API-Befehl
Die Elasticsearch _bulk API ist das richtige Werkzeug, wenn Ihre App viele Dokumente indizieren, aktualisieren oder löschen muss, ohne für jedes Dokument eine eigene HTTP-Anfrage zu senden. Die Hürde liegt im Anfragekörper: Es handelt sich um zeilengetrenntes JSON (NDJSON), nicht um ein hübsch formatiertes JSON-Array.
Verwenden Sie _bulk beim Laden von Logs, Synchronisieren von Datensätzen aus einer anderen Datenbank oder beim Anwenden einer Batch-Bereinigung von Löschvorgängen. Sie müssen dennoch jedes Element in der Antwort überprüfen, da ein einzelner Vorgang fehlschlagen kann, während die gesamte HTTP-Anfrage erfolgreich ist.
Verstehen der _bulk API-Struktur
Die _bulk API akzeptiert zeilengetrenntes JSON, üblicherweise als NDJSON bezeichnet. Jede Aktion wird in einer Zeile definiert. Aktionen, die einen Dokumentkörper benötigen, verwenden die nächste Zeile als Quelle oder Aktualisierungspayload. Die letzte Zeile muss ebenfalls mit einem Zeilenumbruch enden.
Schlüsselkomponenten einer _bulk-Anfrage:
- Aktions- und Metadatenzeile: Diese Zeile gibt den Operationstyp (
index,create,updateoderdelete), den Zielindex und optional die Dokument-ID an. Dokumenttypen werden in modernen Elasticsearch-APIs nicht verwendet. - Quellzeile: Diese Zeile enthält das eigentliche JSON-Dokument, das indiziert oder aktualisiert werden soll. Diese Zeile wird bei
delete-Operationen weggelassen. - Zeilenumbruch-Trennzeichen: Jedes Aktions-/Metadatenpaar und die dazugehörige Quelle (falls zutreffend) müssen durch ein Zeilenumbruchzeichen (
\n) getrennt sein. Der gesamte Anfragekörper sollte mit einem Zeilenumbruchzeichen enden.
Beispielstruktur:
{ "index": { "_index": "my-index", "_id": "1" } }
{ "field1": "value1" }
{ "delete": { "_index": "my-index", "_id": "2" } }
Oder für eine Löschoperation:
curl -sS -H 'Content-Type: application/x-ndjson' \
-X POST 'http://localhost:9200/_bulk' \
--data-binary @bulk.ndjson
Durchführen gängiger Operationen mit _bulk
Die _bulk API ist vielseitig und kann eine Mischung von Operationen in einer einzigen Anfrage verarbeiten. Hier liegt ihre wahre Stärke, da sie komplexe Datenmanipulationen in einem einzigen Roundtrip ermöglicht.
Indizieren mehrerer Dokumente
Zum Indizieren mehrerer Dokumente verwenden Sie die Aktion index. Wenn ein Dokument mit der angegebenen ID bereits existiert, überschreibt index es. Wenn Sie sicherstellen möchten, dass ein Dokument nur indiziert wird, wenn es noch nicht existiert, verwenden Sie stattdessen die Aktion create.
Beispiel: Indizieren zweier neuer Dokumente.
{ "index": { "_index": "my-index", "_id": "1" } }
{ "field1": "value1", "field2": "value2" }
{ "index": { "_index": "my-index", "_id": "2" } }
{ "field1": "another_value", "field2": "different_value" }
Aktualisieren von Dokumenten
Das Aktualisieren von Dokumenten kann mit der Aktion update erfolgen. Sie geben die zu aktualisierende Dokument-ID an und liefern ein partielles Dokument mit den Feldern, die Sie ändern möchten. Wenn Sie ein Skript zum Aktualisieren verwenden möchten, können Sie dies innerhalb der update-Aktion tun.
Beispiel: Aktualisieren eines Feldes in einem vorhandenen Dokument.
{ "update": { "_index": "my-index", "_id": "1" } }
{ "doc": { "field1": "updated_value" } }
Löschen von Dokumenten
Zum Löschen von Dokumenten verwenden Sie die Aktion delete und geben _index und _id des zu entfernenden Dokuments an. Für Löschoperationen ist kein Quelldokument erforderlich.
Beispiel: Löschen eines Dokuments.
{ "delete": { "_index": "my-index", "_id": "2" } }
Kombinieren von Operationen
Die wahre Effizienz ergibt sich aus der Mischung dieser Operationen. Sie können neue Dokumente indizieren, vorhandene aktualisieren und andere in derselben _bulk-Anfrage löschen.
Beispiel: Indizieren, Aktualisieren und Löschen in einer Anfrage.
{ "index": { "_index": "my-index", "_id": "3" } }
{ "field1": "new_document_field", "field2": "new_document_value" }
{ "update": { "_index": "my-index", "_id": "1" } }
{ "doc": { "field1": "further_updated_value" } }
{ "delete": { "_index": "my-index", "_id": "2" } }
Antwortbehandlung
Die _bulk API gibt eine JSON-Antwort zurück, die das Ergebnis jeder einzelnen Operation detailliert beschreibt. Es ist entscheidend, diese Antwort zu parsen, um zu überprüfen, ob alle Operationen erfolgreich waren, und um etwaige Fehler zu identifizieren.
Die Antwort enthält ein items-Array, in dem jedes Element einer der Operationen in Ihrer Anfrage in derselben Reihenfolge entspricht. Jedes Element enthält die Operation index, create, update oder delete zusammen mit ihrem Status (z. B. created, updated, deleted, noop) und anderen relevanten Metadaten.
Beispiel-Antwortauszug:
{
"took": 150,
"errors": false,
"items": [
{
"index": {
"_index": "my-index",
"_id": "3",
"version": 1,
"result": "created",
"_shards": {"total": 2, "successful": 1, "failed": 0},
"_seq_no": 0,
"_primary_term": 1
}
},
{
"update": {
"_index": "my-index",
"_id": "1",
"version": 2,
"result": "updated",
"_shards": {"total": 2, "successful": 1, "failed": 0},
"_seq_no": 1,
"_primary_term": 1
}
},
{
"delete": {
"_index": "my-index",
"_id": "2",
"version": 2,
"result": "deleted",
"_shards": {"total": 2, "successful": 1, "failed": 0},
"_seq_no": 2,
"_primary_term": 1
}
}
]
}
Wenn eine Operation fehlschlägt, wird das errors-Feld auf oberster Ebene in der Antwort true sein, und das einzelne Element für die fehlgeschlagene Operation enthält ein error-Objekt, das das Problem detailliert beschreibt.
Best Practices und Tipps
- Batch-Größe: Sehr große Batches können den Client-Speicher, koordinierende Knoten und Datenknoten belasten. Beginnen Sie mit moderaten Payloads, messen Sie Durchsatz und Ablehnungsraten und passen Sie sie dann an Ihren Cluster und die Dokumentgröße an.
- Fehlerbehandlung: Parsen Sie die Antwort immer auf Fehler. Implementieren Sie bei Bedarf eine Wiederholungslogik für vorübergehende Fehler.
- Zeilenumbruch-Trennzeichen: Stellen Sie sicher, dass Zeilenumbruchzeichen (
\n) korrekt zwischen den einzelnen JSON-Objekten verwendet werden. Falsche Formatierung ist eine häufige Ursache für Fehler bei der_bulkAPI. - Parallelisierung: Für sehr hohe Erfassungsraten sollten Sie mehrere
_bulk-Anfragen parallel senden, aber achten Sie auf die Kapazität Ihres Clusters. createvs.index: Verwenden Siecreate, wenn die Operation fehlschlagen soll, falls die ID bereits existiert. Verwenden Sieindex, wenn das Ersetzen eines vorhandenen Dokuments akzeptabel ist.- API-Clients: Die meisten Elasticsearch-Clientbibliotheken bieten praktische Methoden zum Erstellen und Ausführen von
_bulk-Anfragen, die einen Teil der manuellen Formatierung abstrahieren.
Praktische Erkenntnisse
Die _bulk API ist schnell, weil sie den Anfrage-Overhead reduziert, aber sie ist nur sicher, wenn Ihr Client die Antwort als Liste einzelner Ergebnisse behandelt. Senden Sie gültiges NDJSON mit Content-Type: application/x-ndjson, halten Sie die Batches in einer Größe, die Ihr Cluster aufnehmen kann, und wiederholen Sie nur die Operationen, die aus vorübergehenden Gründen fehlgeschlagen sind.