Fehlerbehebung bei langsamen Elasticsearch-Abfragen für eine bessere Nutzererfahrung

Für alle, die Elasticsearch® als Suchmaschine verwenden, ist das Identifizieren und Beheben von Abfragen eine entscheidende Fähigkeit. Ob E-Commerce, Beobachtbarkeit oder arbeitsplatzorientierte Suchlösungen – ein langsames Elasticsearch beeinträchtigt die Erfahrung Ihrer Nutzer negativ.
Um langsame Elasticsearch-Abfragen zu identifizieren, können Sie das Slow Log verwenden, das die Abfrageausführung ab einem bestimmten Schwellenwert erfasst. Die korrekte Einstellung des Slow-Log-Schwellenwerts ist eine Herausforderung für sich. Beispielsweise kann eine Abfrage, die unter Volllast 500 Millisekunden dauert, akzeptabel sein, während dieselbe Abfrage unter geringer Last inakzeptabel sein könnte. Das Slow Log unterscheidet hier nicht und protokolliert alles, was über 500 Millisekunden liegt. Das Slow Log erfüllt seine Aufgabe sehr gut, sodass Sie je nach Schwellenwert unterschiedliche Granularitätsstufen erfassen können. Tracing hingegen kann alle Abfragen betrachten und identifizieren, wie viele Ihrer Abfragen innerhalb bestimmter Schwellenwerte liegen.
Monitoring der Anwendungsleistung (meist: APM) ist nicht mehr nur auf Ihre Anwendung beschränkt. Durch die Instrumentierung in Elasticsearch können wir Elasticsearch jetzt als vollwertigen Service hinzufügen, anstatt es als Abhängigkeit in Ihrem Anwendungs-Stack zu führen. Auf diese Weise erhalten wir eine differenziertere Sicht auf die Leistung, als es der Slow-Log bieten kann.
Für das folgende Beispiel ist unser Datenkorpus OpenWebText, das etwa 40 GB reinen Text und etwa 8 Millionen einzelne Dokumente bereitstellt, die lokal auf einem M1 Max Macbook mit 32 GB RAM ausgeführt werden.
Erste Schritte
Die Aktivierung des Tracing in Elasticsearch erfolgt über statische Einstellungen (konfiguriert in der elasticsearch.yml) sowie dynamische Einstellungen, die während der Laufzeit mithilfe eines PUT _cluster/settings -Befehls umgeschaltet werden können, wobei eine dieser dynamischen Einstellungen die Sampling-Rate ist. Einige Einstellungen, wie die Sampling-Rate, können während der Laufzeit umgeschaltet werden. In der elasticsearch.yml möchten wir Folgendes festlegen:
Gültig für Version 9.x
telemetry.agent.enabled: true
telemetry.agent.server_url: "url of the APM server"Gültig für Version 7.x und 8.x
tracing.apm.enabled: true
tracing.apm.agent.server_url: "url of the APM server"Der geheime Token (oder API-Schlüssel) muss im Elasticsearch-Keystore sein. Das Keystore-Tool sollte in /bin/elasticsearch-keystore verfügbar sein,<your elasticsearch install directory> wobei für Version 7.x und 8.x elasticsearch-keystore folgende Befehle verwendet werden:add tracing.apm.secret_token odertracing.apm.api_key.Für Version 9.x verwenden Sie bitte stattdessentelemetry.secret_token odertelemetry.api_key.Danach musst du Elasticsearch neu starten. Weitere Informationen zur Nachverfolgung finden Sie in unserem Nachverfolgungsdokument.
Sobald APM aktiv ist, können wir uns die APM-Ansicht in Kibana ansehen und feststellen, dass Elasticsearch verschiedene REST API-Endpoints automatisch erfasst. Hier konzentrieren wir uns hauptsächlich auf die POST /{index}/_search -Aufrufe und sehen, welche Erkenntnisse wir daraus gewinnen können.

Durch die Untersuchung einer einfachen Abfrage direkt im GET /{index}/_search -Feld sehen wir die folgende Waterfall-Aufschlüsselung. Diese enthält interne Spans, die tiefere Einblicke in die Vorgänge innerhalb von Elasticsearch bieten. Zudem sehen wir die Gesamtdauer dieser Suche (86 Millisekunden).

Die Metadaten, die die Abfrage begleiten, enthalten umfassende Informationen zum HTTP-Header, Nutzer-Agent, Standort des Elasticsearch-Nodes (Metadaten zum Cloudanbieter, Hostname, Container-Informationen), einige Systeminformationen sowie URL-Details. Mithilfe einiger grundlegender Transaktionsinformationen können wir ein Lens-Diagramm erstellen, das die durchschnittliche Transaktionsdauer darstellt und uns erkennen lässt, ob ein Aufwärts- oder Abwärtstrend vorliegt.
Unsere Suchanwendung
Es ist schön, keine Slow-Logs mehr verwenden zu müssen! Ich kann die Transaktionsdauer bestimmen und ermitteln, wie viele Suchanfragen unterhalb eines bestimmten Schwellenwerts beantwortet werden. Es gibt jedoch einen Nachteil – Elasticsearch erfasst die gesendete Abfrage nicht. Wir wissen also zwar, dass eine Abfrage lange gedauert hat, aber wir wissen nicht, um welche Abfrage es sich handelte.
Lassen Sie uns eine Beispiel-Suchanwendung instrumentieren. In diesem Fall verwenden wir eine einfache Flask-App mit zwei Routen, search_single und search_phrase, die eine match - und eine match_phrase -Abfrage in Elasticsearch darstellen. Wir könnten zum Beispiel die folgenden Abfragen verwenden:
{
"query": {
"match": {
"content": "support"
}
}
}
And
{
"query": {
"match_phrase": {
"content": "support protest"
}
}
}Der folgende Flask-Code implementiert die search_single -Route. Die search_phrase ist sehr ähnlich, verwendet jedoch match_phrase anstelle von match.
@app.route("/search_single", methods=["GET"])
def search_single():
query = request.args.get("q", "")
if not query.strip():
return jsonify({"error": "No search query provided"}), 400
try:
result = es.search(
index=ES_INDEX, query={"match": {"content": query}}
)
hits = result["hits"]["hits"]
response = []
for hit in hits:
response.append(
{
"score": hit["_score"],
"content": hit["_source"]["content"],
}
)
return jsonify(response)Nachdem all dies vorbereitet ist, kann ich nun curl -XGET "http://localhost:5000/search_single?q='microphone'" aufrufen, um nach dem Begriff microphone zu suchen.
Wir fügen unserer Anwendung zum Suchen hauptsächlich APM hinzu, um sie zu Observe, aber unsere APM-Agenten erfassen ausgehende Anfragen und reichern sie mit Metadaten an. In unserem Fall enthält span.db.statement die Elasticsearch-Abfrage. Und in diesem Fall unten hat jemand nach window gesucht.

Aus den Einzelteilen entsteht ein Ganzes
In meinem Flask-Service habe ich die Abfragegröße auf 5.000 festgelegt, was bedeutet, dass Elasticsearch mir bis zu 5.000 übereinstimmende Dokumente in einer einzigen JSON-Reaktion zurückgeben sollte. Das ist eine große Zahl, und ein Großteil der Zeit wird damit verbracht, diese Menge an Dokumenten von der Festplatte abzurufen. Nachdem ich die Ansicht auf die Top 100 Dokumente geändert habe, kann ich durch einen Vergleich schnell identifizieren, was in meinem Dashboard passiert ist.
Wenn man eine Transaktion in der APM-Ansicht betrachtet und die Labs-Funktion für den kritischen Pfad aktiviert, wird ein Overlay erstellt, das anzeigt, womit unsere Anwendung Zeit verbringt.

Danach habe ich ein Dashboard unter Verwendung der Felder transaction.duration.us, es_query_took, transaction.name erstellt. Allgemeine KQL-Filter enthalten service.name, processor.event: transaction, transaction.name: POST /{index}/_search.
Tipp am Rande: Gehen Sie zur Data view-Verwaltung > wählen Sie Ihre Data view aus, die die APM-Datenströme enthält > wählen Sie das Feld transaction.duration.us > und ändern Sie das Format in duration. Es wird nun automatisch in einem menschenlesbaren Ausgang anstelle von Mikrosekunden dargestellt.
Durch die Nutzung des Lens-Anmerkungs-Features können wir in der mittleren Lens sehen, dass die Änderung auf 100 Dokumente die durchschnittliche Suchtransaktion erheblich reduziert hat. Darüber hinaus sollten Sie sich die Gesamtzahl der Einträge in der oberen rechten Ecke ansehen. Da wir schneller suchen können, haben wir einen höheren Durchsatz! Ich mag Histogramme sehr, daher habe ich in der Mitte der oberen Zeile eines erstellt, bei dem ich die Transaktionsdauer auf der X-Achse und die Anzahl der Einträge auf der Y-Achse habe. Darüber hinaus liefert APM Metriken, sodass wir jederzeit ermitteln können, wie hoch die CPU-Auslastung in % ist, sowie Informationen zum JVM-Heap, zur Non-Heap-Nutzung, zur Anzahl der Threads und weitere nützliche Daten.

Fazit
In diesem Blogbeitrag habe ich Ihnen gezeigt, wie wichtig es ist, Elasticsearch als instrumentierte Anwendung zu nutzen und Engpässe wesentlich einfacher zu identifizieren. Außerdem können Sie die Transaktionsdauer als Metrik für die Anomalieerkennung verwenden, A/B-Tests für Ihre Anwendung durchführen und müssen sich nie wieder fragen, ob Elasticsearch sich schneller anfühlt, da Sie nun über Daten verfügen, um diese Frage zu beantworten. Darüber hinaus helfen Ihnen alle Metadaten, die von Nutzer-Agenten bis hin zu Abfragen erfasst werden, bei der Fehlerbehebung.
Die Dashboards und die Data view können hier importiert werden.
Warnung
Es gibt ein Problem mit der Dauer von Transaktionen innerhalb von Elasticsearch. Dies wurde behoben in der kommenden Version 8.9.1. Bis dahin verwenden die Transaktionen die falsche Uhrzeit, was die Gesamtdauer beeinträchtigt.
Die Entscheidung über die Veröffentlichung der in diesem Blogeintrag beschriebenen Leistungsmerkmale und Features sowie deren Zeitpunkt liegt allein bei Elastic. Es ist möglich, dass noch nicht verfügbare Leistungsmerkmale oder Features nicht rechtzeitig oder überhaupt nicht veröffentlicht werden.