Effizientes Suchen und Abrufen großer Datensätze in Elasticsearch

Für diesen Beitrag verwenden wir Hosted Elasticsearch auf Qbox.io . Sie können sich hier anmelden oder Ihren Cluster starten oder in der Kopfzeilennavigation auf “Erste Schritte” klicken. Wenn Sie Hilfe beim Einrichten benötigen, lesen Sie “Bereitstellen eines Qbox Elasticsearch-Clusters.”

Unser Ziel

Qbox bietet eine schlüsselfertige Lösung für Elasticsearch, Kibana und viele Elasticsearch Analyse- und Monitoring-Plugins. Ziel des Lernprogramms ist es, mit Qbox das Abrufen großer Datenblöcke mithilfe von Scan- und Bildlaufanforderungen zu demonstrieren. Wir haben Logstash in einem separaten Knoten / Computer eingerichtet, um Twitter-Streams zu erfassen, und verwenden die von Qbox bereitgestellte Elasticsearch, um die leistungsstarke Scan- und Scroll-API zu umgehen.

Unser ELK-Stack-Setup besteht aus drei Hauptkomponenten:

  • Elasticsearch: Es wird verwendet, um alle Anwendungs- und Überwachungsprotokolle zu speichern (bereitgestellt von Qbox).
  • Logstash: Die Serverkomponente, die eingehende Protokolle verarbeitet und an ES weiterleitet.
  • Kibana( optional): Eine Weboberfläche zum Suchen und Visualisieren von Protokollen (bereitgestellt von Qbox).

Voraussetzungen

Die Menge an CPU, RAM und Speicher, die Ihr Elasticsearch Server benötigt, hängt vom Volumen der Protokolle ab, die Sie erfassen möchten. Für dieses Tutorial verwenden wir eine von Qbox bereitgestellte Elasticsearch mit den folgenden Mindestspezifikationen:

  • Anbieter: AWS
  • Ausführung: 5.1.1
  • RAM: 1GB
  • CPU: vCPU1
  • Repliken: 0

Die oben genannten Spezifikationen können gemäß Ihren gewünschten Anforderungen geändert werden. Bitte wählen Sie die entsprechenden Namen, Versionen und Regionen für Ihre Anforderungen aus. Für dieses Beispiel haben wir Elasticsearch Version 5.1.1 verwendet, die aktuellste Version ist 5.3. Wir unterstützen alle Versionen von Elasticsearch auf Qbox. (Um mehr über die Hauptunterschiede zwischen 2 zu erfahren.x und 5.x, klicken Sie hier.)

Zusätzlich zu unserem Elasticsearch-Server benötigen wir einen separaten Logstash-Server, um eingehende Twitter-Streams von der Twitter-API zu verarbeiten und an Elasticsearch zu senden. Der Einfachheit halber und zu Testzwecken kann der Logstash-Server auch als Client-Server selbst fungieren. Die Endpunkt- und Transportadressen für unseren von Qbox bereitgestellten Elasticsearch-Cluster lauten wie folgt:

 häufig_1.png

Endpunkt: REST-API

https://ec18487808b6908009d3:[email protected]:32563

Authentifizierung

  • Benutzername = ec18487808b6908009d3
  • Passwort = efcec6a1e0

TRANSPORT (NATIVES JAVA)

eb843037.qb0x.com:30543

Hinweis: Stellen Sie sicher, dass Sie die IP-Adresse des Logstash-Servers aus dem Qbox Elasticsearch-Cluster auf die Whitelist setzen.

Logstash installieren

Öffentlichen Signaturschlüssel herunterladen und installieren:

wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Wir werden den Logstash version 2.4.x als kompatibel mit unserem Elasticsearch version 5.1.x verwenden. Auf die Elastic Community Product Support Matrix kann verwiesen werden, um Versionsprobleme zu beheben.

Fügen Sie die Repository-Definition zu Ihrer /etc/apt/sources hinzu.liste Datei:

echo "deb https://packages.elastic.co/logstash/2.4/debian stable main" | sudo tee -a /etc/apt/sources.list

Führen Sie sudo apt-get update aus und das Repository ist einsatzbereit. Sie können es installieren mit:

sudo apt-get update && sudo apt-get install logstash

Alternativ kann logstash tar auch von der Elastic Product Releases-Website heruntergeladen werden. Dann sind die Schritte zum Einrichten und Ausführen von Logstash ziemlich einfach:

  • Logstash herunterladen und entpacken
  • Bereiten Sie eine logstash.conf Konfigurationsdatei vor
  • Führen Sie bin/logstash -f logstash.conf -t aus, um die Konfiguration von logstash zu überprüfen.conf)
  • Ausführen bin/logstash -f logstash.conf

Configure Logstash (Twitter Stream)

Logstash-Konfigurationsdateien sind im JSON-Format und befinden sich in /etc/logstash/conf.d. Die Konfiguration besteht aus drei Abschnitten: Eingänge, Filter und Ausgänge.

Wir müssen autorisiert sein, Daten von Twitter über seine API zu übernehmen. Dieser Teil ist einfach:

  1. Melden Sie sich bei Ihrem Twitter-Konto an
  2. Gehen Sie zu https://dev.twitter.com/apps/
  3. Erstellen Sie eine neue Twitter-Anwendung (hier gebe ich Twitter-Qbox-Stream als Namen der App an).

 t1.png

Nachdem Sie die Twitter-Anwendung erfolgreich erstellt haben, erhalten Sie die folgenden Parameter in “Schlüssel und Zugriffstoken”:

  1. Verbraucherschlüssel (API-Schlüssel)
  2. Verbrauchergeheimnis (API-Geheimnis)
  3. Zugriffstoken
  4. Zugriffstokengeheimnis

 t2.png

Wir sind jetzt bereit, den Twitter-Datenpfad (Stream) von Twitter-Servern zu unserem Computer zu erstellen. Wir werden die obigen vier Parameter (Consumer key, consumer secret, access Token, access Token secret) verwenden, um die Twitter-Eingabe für Logstash zu konfigurieren.

Erstellen wir eine Konfigurationsdatei mit dem Namen 02-twitter-input.conf und richten unseren “Twitter” -Eingang ein:

sudo vi /etc/logstash/conf.d/02-twitter-input.conf

Fügen Sie die folgende Eingabekonfiguration ein:

input { twitter { consumer_key => "BCgpJwYPDjXXXXXX80JpU0" consumer_secret => "Eufyx0RxslO81jpRuXXXXXXXMlL8ysLpuHQRTb0Fvh2" keywords => oauth_token => "193562229-o0CgXXXXXXXX0e9OQOob3Ubo0lDj2v7g1ZR" oauth_token_secret => "xkb6I4JJmnvaKv4WXXXXXXXXS342TGO6y0bQE7U" }}

Speichern und beenden Sie die Datei 02-twitter-input.conf.

Dies gibt eine Twitter-Eingabe an, die Tweets mit den Schlüsselwörtern “mobile”, “java”, “android”, “elasticsearch”, “search” filtert und an die Logstash-Ausgabe übergibt. Speichern und beenden. Zuletzt erstellen wir eine Konfigurationsdatei namens 30-elasticsearch-output.conf:

sudo vi /etc/logstash/conf.d/30-elasticsearch-output.conf

Fügen Sie die folgende Ausgabekonfiguration ein:

output { elasticsearch { hosts => user => "ec18487808b6908009d3" password => "efcec6a1e0" index => "twitter-%{+YYYY.MM.dd}" document_type => "tweet" } stdout { codec => rubydebug }}

Speichern und beenden. Diese Ausgabe konfiguriert Logstash so, dass die Twitter-Protokolldaten in Elasticsearch, das unter https://eb843037.qb0x.com:30024/ ausgeführt wird, in einem nach Twitter benannten Index gespeichert werden.

Wenn Sie logstash tar oder zip heruntergeladen haben, können Sie einen Logstash erstellen.conf-Datei mit Eingabe, Filter und Ausgabe an einem Ort.

sudo vi LOGSTASH_HOME/logstash.conf

Fügen Sie die folgende Eingabe- und Ausgabekonfiguration in Logstash ein.conf

input { twitter { consumer_key => "BCgpJwYPDjXXXXXX80JpU0" consumer_secret => "Eufyx0RxslO81jpRuXXXXXXXMlL8ysLpuHQRTb0Fvh2" keywords => oauth_token => "193562229-o0CgXXXXXXXX0e9OQOob3Ubo0lDj2v7g1ZR" oauth_token_secret => "xkb6I4JJmnvaKv4WXXXXXXXXS342TGO6y0bQE7U" }}output { elasticsearch { hosts => user => "ec18487808b6908009d3" password => "efcec6a1e0" index => "twitter-%{+YYYY.MM.dd}" document_type => "tweet" } stdout { codec => rubydebug }}

Testen Sie Ihre Logstash-Konfiguration mit diesem Befehl:

sudo service logstash configtest

Es sollte Konfiguration OK anzeigen, wenn keine Syntaxfehler vorliegen. Versuchen Sie andernfalls, die Fehlerausgabe zu lesen, um festzustellen, was mit Ihrer Logstash-Konfiguration nicht stimmt.

Starten Sie Logstash neu und aktivieren Sie es, um unsere Konfigurationsänderungen in Kraft zu setzen:

sudo service logstash restartsudo update-rc.d logstash defaults 96 9

Wenn Sie logstash tar oder zip heruntergeladen haben, kann es mit folgendem Befehl ausgeführt werden

bin/logstash -f logstash.conf

Zahlreiche Antworten werden empfangen. Die Struktur des Dokuments ist wie folgt:

{ "text": "Learn how to automate anomaly detection on your #Elasticsearch #timeseries data with #MachineLearning:", "created_at": "2017-05-07T07:54:47.000Z", "source": "<a href="%5C">Twitter for iPhone</a>", "truncated": false, "language": "en", "mention": , "retweet_count": 0, "hashtag": , "location": { "lat": 33.686657, "lon": -117.674558 }, "place": { "id": "74a60733a8b5f7f9", "name": "elastic", "type": "city", "full_name": "San Francisco, CA", "street_address": null, "country": "United States", "country_code": "US", "url": "https://api.twitter.com/1.1/geo/id/74a60733a8b5f7f9.json" }, "link": , "user": { "id": 2873953509, "name": "Elastic", "screen_name": "elastic", "location": "SF, CA", "description": "The company behind the Elastic Stack (#elasticsearch, #kibana, Beats, #logstash), X-Pack, and Elastic Cloud" }}

Elasticsearch ermöglicht die Paginierung durch Hinzufügen eines size- und eines from-Parameters. Wenn Sie beispielsweise Ergebnisse in 5er-Stapeln ab der 3. Seite abrufen möchten (dh Ergebnisse 11-15 anzeigen), tun Sie Folgendes:

curl -XGET 'ES_HOST:ES_PORT/twitter/tweet/_search?size=5&from=10'

Es wird jedoch teurer, je weiter wir uns in der Ergebnisliste bewegen. Jedes Mal, wenn wir einen dieser Anrufe tätigen, führen wir den Suchvorgang erneut aus und zwingen Lucene, alle Ergebnisse neu zu bewerten, sie zu bewerten und dann die ersten 10 (oder 10000, wenn wir so weit kommen) zu verwerfen. Die einfachere Option ist die Scan- und Scroll-API. Die Idee ist, die eigentliche Abfrage einmal auszuführen und dann das Ergebnis irgendwo zwischenzuspeichern und uns ein “Zugriffstoken” zu geben, um sie wieder abzurufen. Dann rufen wir den Scroll-API-Endpunkt mit diesem Token auf, um die nächste Ergebnisseite zu erhalten.

Um das Scrollen zu verwenden, sollte die anfängliche Suchanforderung den Scroll-Parameter in der Abfragezeichenfolge angeben, der Elasticsearch mitteilt, wie lange der “Suchkontext” am Leben bleiben soll, z. B. ?blättern = 1 mt.

curl -XPOST 'ES_HOST:ES_PORT/twitter-*/tweet/_search?scroll=1m&pretty' -H 'Content-Type: application/json' -d '{ "size": 100, "query": { "match" : { "text" : "elasticsearch" } }}'

Das Ergebnis der obigen Anforderung enthält eine _scroll_id , die an die scroll API übergeben werden soll, um den nächsten Ergebnisblock abzurufen.

curl -XPOST 'ES_HOST:ES_PORT/_search/scroll?pretty' -H 'Content-Type: application/json' -d '{ "scroll" : "1m", "scroll_id" : "DXF1ZXJ5DKJ56hghFHFDJgBAAAAAAAArknJBJsbjYtZndUQlNsdDcwakFSDSSXSQ=="}'

Mit dem Parameter size können Sie die maximale Anzahl von Treffern konfigurieren, die mit jedem Ergebnisblock zurückgegeben werden sollen. Jeder Aufruf der Scroll-API gibt den nächsten Stapel von Ergebnissen zurück, bis keine Ergebnisse mehr zurückgegeben werden können, dh das Treffer-Array ist leer. Einige wichtige Punkte in Bezug auf die Scroll- und Scan-API sind folgende:

  • Die anfängliche Suchanforderung und jede nachfolgende Bildlaufanforderung geben eine neue _scroll_id zurück.
  • Wenn die Anforderung Aggregationen angibt, enthält nur die anfängliche Suchantwort die Aggregationsergebnisse.
  • Scroll-Anfragen haben Optimierungen, die sie schneller machen, wenn die Sortierreihenfolge _doc ist. Wenn Sie alle Dokumente unabhängig von der Reihenfolge durchlaufen möchten, ist dies die effizienteste Option:
curl -XGET 'ES_HOST:ES_PORT/_search?scroll=1m&pretty' -H 'Content-Type: application/json' -d '{ "sort": }'

Suchkontext

Der Scroll-Parameter teilt Elasticsearch mit, wie lange der Suchkontext am Leben bleiben soll. Sein Wert (z. B. 1m) muss nicht lang genug sein, um alle Daten zu verarbeiten, sondern muss nur lang genug sein, um den vorherigen Ergebnisblock zu verarbeiten. Jede Scroll-Anforderung legt eine neue Ablaufzeit fest.

Clear Scroll API

Suchkontext wird automatisch entfernt, wenn das Scroll-Timeout überschritten wurde. Das Offenhalten von Schriftrollen ist jedoch mit Kosten verbunden (siehe später im Abschnitt Leistung), daher sollten Schriftrollen explizit gelöscht werden, sobald der Bildlauf mithilfe der Clear-Scroll-API nicht mehr verwendet wird:

curl -XDELETE 'ES_HOST:ES_PORT/_search/scroll?pretty' -H 'Content-Type: application/json' -d '{ "scroll_id" : }'

Mehrere Scroll-IDs können als Array übergeben werden:

curl -XDELETE 'ES_HOST:ES_PORT/_search/scroll?pretty' -H 'Content-Type: application/json' -d '{ "scroll_id" : }'

Alle Suchkontexte können mit dem Parameter _all gelöscht werden:

curl -XDELETE 'ES_HOST:ES_PORT/_search/scroll/_all?pretty'

Sliced Scroll

Scroll-Abfragen, die viele Dokumente zurückgeben, können in mehrere Slices aufgeteilt werden, die unabhängig voneinander verwendet werden können:

 curl -XGET 'ES_HOST:ES_PORT/twitter-*/tweet/_search?scroll=1m&pretty' -H 'Content-Type: application/json' -d '{ "slice": { "id": 0, "max": 2 }, "query": { "match" : { "text" : "elasticsearch" } }}'
curl -XGET 'ES_HOST:ES_PORT/twitter-*/tweet/_search?scroll=1m&pretty' -H 'Content-Type: application/json' -d '{ "slice": { "id": 1, "max": 2 }, "query": { "match" : { "text" : "elasticsearch" } }}'

Das Ergebnis der ersten Anforderung gibt Dokumente zurück, die zum ersten Slice gehören (id: 0), und das Ergebnis der zweiten Anforderung gibt Dokumente zurück, die zum zweiten Slice gehören. Da die maximale Anzahl von Slices auf 2 festgelegt ist, entspricht die Vereinigung der Ergebnisse der beiden Anforderungen den Ergebnissen einer Bildlaufabfrage ohne Slicing.

Standardmäßig erfolgt die Aufteilung zuerst für die Shards und dann lokal für jeden Shard mithilfe des Felds _uid mit der folgenden Formel:

slice(doc) = floorMod(hashCode(doc._uid), max)

Überlegungen zur Leistung:

Scroll API : Der Hintergrundzusammenführungsprozess optimiert den Index, indem kleinere Segmente zusammengeführt werden, um neue größere Segmente zu erstellen. Dieser Vorgang wird während des Bildlaufs fortgesetzt, aber ein offener Suchkontext verhindert, dass die alten Segmente gelöscht werden, während sie noch verwendet werden. Auf diese Weise kann Elasticsearch die Ergebnisse der ersten Suchanfrage zurückgeben, unabhängig von späteren Änderungen an Dokumenten.

Ältere Segmente am Leben zu erhalten bedeutet, dass mehr Dateihandles benötigt werden. Stellen Sie sicher, dass Knoten so konfiguriert wurden, dass sie über ausreichend freie Dateihandles verfügen, und dass der API-Kontext kurz nach dem Datenabruf gelöscht wird.

Mit der nodes stats API können wir überprüfen, wie viele Suchkontexte geöffnet sind:

curl -XGET 'ES_HOST:ES_PORT/_nodes/stats/indices/search?pretty'

Es ist daher sehr wichtig, den Scroll-API-Kontext zu löschen, wie zuvor im Abschnitt Scroll-API löschen beschrieben.

Geschnittene Scroll-API : Wenn die Anzahl der Slices größer als die Anzahl der Shards ist, ist der Slice-Filter bei den ersten Aufrufen sehr langsam, hat eine Komplexität von O (N) und Speicherkosten von N Bits pro Slice, wobei N die Gesamtzahl der Dokumente im Shard ist. Nach einigen Aufrufen sollte der Filter zwischengespeichert werden und nachfolgende Aufrufe sollten schneller sein, aber Sie sollten die Anzahl der parallel ausgeführten Abfragen begrenzen, um die Speicherexplosion zu vermeiden.

Hinweis: Die maximal zulässige Anzahl von Slices pro Bildlauf ist auf 1024 begrenzt und kann mit der Indexeinstellung index.max_slices_per_scroll aktualisiert werden, um dieses Limit zu umgehen.

Um diese Kosten vollständig zu vermeiden, ist es möglich, das doc_values eines anderen Felds zum Schneiden zu verwenden, der Benutzer muss jedoch sicherstellen, dass das Feld die folgenden Eigenschaften aufweist:

  • Das Feld ist numerisch.
  • doc_values sind in diesem Feld aktiviert
  • Jedes Dokument sollte einen einzelnen Wert enthalten. Wenn ein Dokument mehrere Werte für das angegebene Feld enthält, wird der erste Wert verwendet.
  • Der Wert für jedes Dokument sollte einmal festgelegt werden, wenn das Dokument erstellt und nie aktualisiert wird. Dies stellt sicher, dass jede Scheibe deterministische Ergebnisse erhält.
  • Die Kardinalität des Feldes sollte hoch sein. Dadurch wird sichergestellt, dass jedes Slice ungefähr die gleiche Menge an Dokumenten erhält.

Das Feld “Datum” dient natürlich obigen Eigenschaften und kann somit zum Slicing verwendet werden:

curl -XGET 'ES_HOST:ES_PORT/twitter-*/tweet/_search?scroll=1m&pretty' -H 'Content-Type: application/json' -d '{ "slice": { "field": "date", "id": 0, "max": 10 }, "query": { "match" : { "text" : "elasticsearch" } }}'

Testen Sie Qbox Hosted Elasticsearch

Es ist einfach, einen standardmäßigen Hosted Elasticsearch-Cluster in einem unserer 47 Rackspace-, Softlayer- oder Amazon-Rechenzentren hochzufahren. Und Sie können jetzt Ihre eigenen AWS-Credits auf Qbox Private Hosted Elasticsearch bereitstellen.

Fragen? Schreiben Sie uns eine Nachricht, und wir werden Ihnen umgehend antworten.

Genießen Sie noch nicht die Vorteile einer gehosteten ELK-Stack Enterprise Search auf Qbox? Wir laden Sie ein, noch heute ein Konto zu erstellen und zu entdecken, wie einfach es ist, Ihre Elasticsearch-Umgebung in unserem Cloud-Hosting-Service zu verwalten und zu skalieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.