Wie funktioniert das DateRangeField von Solr?

Techniken zur Optimierung der Leistung des DateRangeFields für Datumsbereichsabfragen in Apache Solr.

Solr’s DateRangeFeld

Ich muss David Smiley hier als Co-Autor nennen. Erstens ist er größtenteils für die räumliche Funktionalität verantwortlich und zweitens war er sehr großzügig, mir einige Details zu erklären. Für Fehler bin natürlich ich verantwortlich. Solr verfügt schon seit einiger Zeit über ein neues DateRangeField (siehe SOLR-6103). DateRangeFields basieren auf der Magie von Solr Spatial und ermöglichen einige sehr interessante Arten der Arbeit mit Daten. Hier sind ein paar Referenzen, die Ihnen den Einstieg erleichtern. Arbeiten mit Datumsangaben, Solr Reference Guide Spatial for Time Durations.

Über das DateRangeField:

  • Es handelt sich um einen fieldType, der einen Datumsbereich indiziert, d.h. ein Anfangs- und Enddatum in einem einzigen Feld
  • Sie wird genau wie eine typische Bereichsabfrage verwendet
  • Der Abfrageparser ist etwas nachsichtiger bei der Angabe der Wertebereiche. Anders als das typische Datumsformat in Apache Solr unterstützt er freundlichere Datumsangaben. Das heißt, Sie können Abfragen formulieren wie q=field:[2000-11-01 TO 2014-12-01] oder q=field:2000-11
  • Es unterstützt die Indizierung einer date range in einem einzelnen Feld. Zum Beispiel könnte ein Feld in einem Dokument in SolrJ als solrInputDocument.addField(„dateRange“, „[2000 TO 2014-05-21]“) oder in einem XML-Format wie folgt hinzugefügt werden <field name="dateRange">[2000 TO 2014-05-21]</field>
  • Es unterstützt mehrwertige Datumsbereiche. Das war mit Apache Solr schon immer schwierig zu bewerkstelligen. Um einen Bereich zu indizieren, brauchte man zwei Felder, beispielsweise „date_s“ und „date_e“. Es war einfach, eine Abfrage durchzuführen, die Dokumente über einen bestimmten Zeitraum hinweg fand, etwa so wie q=date_e:[* TO target] AND date_s:[target TO *]. Das funktionierte gut, wenn das Dokument nur einen Bereich hatte, aber wenn zwei oder mehr Bereiche notwendig waren, fiel dieser Ansatz ins Wasser, denn wenn date_s und date_e multiValued=“true“ haben, würde die obige Abfrage das Dokument finden, wenn irgendein Eintrag in date_s < als Zieldatum und irgendein date_e als Zieldatum war. >.

Kleiner Tadel: Ich finde es wirklich gut, dass Solr vollständige Datumsangaben im UTC-Datumsformat verlangt, aber ich gebe zu, dass es manchmal etwas umständlich ist. Die Möglichkeit, partielle Datumsangaben zu machen, ist ziemlich cool. DateRangeField drückt einige der Konzepte, die wir oft mit Datumsangaben in Dokumenten unterstützen müssen, natürlicher aus. Zum Beispiel: „Dieses Dokument ist gültig von A bis B, C bis D und M bis N“. Es gibt noch andere sehr interessante Dinge, die mit diesem „räumlichen“ Zeug gemacht werden können, siehe: Hossman’s Spatial für Nicht-Raumbezogene. Genug der Einführung. Im Referenzhandbuch finden Sie den Kommentar „Ziehen Sie die Verwendung dieses [DateRangeField] in Betracht, auch wenn es sich nur um Datumsinstanzen handelt, insbesondere wenn die Abfragen typischerweise auf die Grenzen von UTC-Jahr/Monat/Tag/Stunde usw. fallen.“ Die Folgefrage lautet: „Und, wie funktioniert es?“ Vor kurzem musste ich versuchen, diese Frage zu beantworten und stellte fest, dass ich keine Referenzen hatte, also machte ich mich daran, welche zu erstellen. Das Ergebnis ist dieser Blog.

Die Methodik:

Bei diesem Test gibt es einige Dinge zu beachten.

  • Bei diesem Test werden die ausgefallenen Bereichsfunktionen nicht verwendet. Es gibt einige Probleme, die viel einfacher sind, wenn Sie einen Bereich indizieren können, aber dieser Test ist dazu gedacht, die „nur für Datumsinstanzen“ aus dem obigen Zitat zu vergleichen. Es ist also ein Vergleich zwischen Äpfeln und Birnen. Es soll helfen, die Folgen der Verwendung von DateRangeField als direkten Ersatz für TrieDate (mit oder ohne DocValues) zu bewerten.
  • David hat eine Reihe von Verbesserungen im Sinn, die einige dieser Messungen verändern werden, insbesondere den notwendigen JVM-Heap. Diese werden wahrscheinlich keine Neuindizierung erfordern.
  • Das Setup hat 25 Millionen Dokumente im Index. Es wird eine Reihe von 1.000 verschiedenen Abfragen an den Server gesendet und die Ergebnisse werden ausgewertet. Die Messungen werden erst vorgenommen, nachdem 100 Aufwärmabfragen ausgeführt wurden. Jede Gruppe von 1.000 Abfragen entspricht einem der folgenden Muster:
    • q=field:date. Diese werden aus den Ergebnissen entfernt, da sie uninteressant sind. Die Reaktionszeiten liegen alle nahe 0 Millisekunden nach dem Aufwärmen.
    • einfache q=field:[date1 TO date2]. Diese sind nicht in der Grafik enthalten, da sie nicht interessant sind. Sie werden alle zu schnell befriedigt, um von Bedeutung zu sein.
    • Intervallfacetten, facet=true&...facet.range.start=date1&facet.range.end=date2&facet.range.gap=+1DAY (or MINUTE or..).
    • 1-5 facet.query Klauseln, bei denen q=*:*
    • Die Einrichtung ist nicht SolrCloud, da dies keinen Einfluss auf die Ergebnisse haben sollte.
  • Die Abfragen wurden mit 1, 10, 20 und 50 Threads ausgeführt, um zu sehen, ob es zu Unregelmäßigkeiten kommt, wenn die Solr-Instanzen wirklich ausgelastet sind. Das war nicht der Fall. Die Ergebnisse ergaben im Wesentlichen die gleichen Graphen, so dass die Grafik unten für die 10-Thread-Version steht.
  • Der DateRangeType wurde verglichen mit:
    • TrieDate, indexed=“true“ docValues=“false“ (TrieDate für den Rest dieses Dokuments)
    • TrieDate, indexed=“true“ docValues=“true“ (DocValues im Rest des Dokuments)
  • Ich hatte drei Kerne, einen für jeden Typ. Jeder Kern hatte identische Dokumente mit sehr einfachen Dokumenten, im Wesentlichen das ID-Feld und das dateRange-Feld (auch das Feld _version_ war definiert). Für jeden Test
    • Nur der zu testende Kern war aktiv, die beiden anderen wurden nicht geladen (ein Trick mit core.properties, wenn Sie es wissen müssen)
    • Am Ende eines jeden Tests habe ich den Speicherverbrauch gemessen, aber die Skala ist zu klein, um eindeutige Schlussfolgerungen zu ziehen. Was ich berichten _kann_, ist, dass DateRangeType zu diesem Zeitpunkt keine großen Unterschiede aufweist. Abgesehen davon, lesen Sie bitte die filterCache-Kommentare in Davids Kommentar weiter unten.
    • Die Statistiken wurden auf einem externen Client gesammelt, auf dem die QT-Zeiten aufgezeichnet wurden.

Ergebnisse

  • Wie das Diagramm etwas später zeigt, übertraf DateRangeField sowohl TrieDate als auch DocValues im Allgemeinen.
  • Die Anzahl der Threads machte nur einen geringen Unterschied in der relativen Leistung von DateRangeField .vs. den beiden anderen. Natürlich erhöht sich die absolute Antwortzeit, wenn genügend Threads gleichzeitig ausgeführt werden, so dass die CPU gesättigt wird.
  • DateRangeFields haben im Vergleich zu TrieDate-Feldern und TrieDate+DocValues eine ziemlich konstante Verbesserung.
  • Die Option facet.range.method=dv war bei diesen Tests nicht aktiviert. Bei einer geringen Anzahl von Treffern kann die Angabe dieses Wertes die Leistung deutlich verbessern, aber dieser spezielle Test verwendet eine minimale Bucket-Größe von 1M, was empirisch gesehen jenseits der Anzahl von Treffern liegt, bei denen die Angabe dieses Parameters von Vorteil ist. Ich werde versuchen, in Zukunft einen weiteren Blog mit einer geringeren Anzahl von Treffern zu verfassen.

Der Graph

Diese benötigen eine kleine Erklärung. Wichtige Hinweise.

  • Die Intervall- und Abfragefacetten beziehen sich auf die gesamten 25 Millionen Dokumente. Dies sind die Punkte ganz rechts im Diagramm. Sie zeigen, dass der Unterschied zwischen den Intervall- und Abfrage-Facetten in Bezug auf die Abfragezeit nicht sehr groß ist.
  • Die übrigen Markierungen (0-24 auf der X-Achse) sind die Leistung bei Treffern von so vielen Millionen Dokumenten für die Bereiche Tag, Minute und Millisekunde. Ein Wert von 10 auf der X-Achse ist also die Spalte für Ergebnismengen von 10M Dokumenten für TrieDate und TrieDate+DocValues.
  • Die wenigen Werte über 1 (100%) sind Fälle, in denen DateRangeFields als etwas langsamer gemessen wurde. Dies kann ein Test-Artefakt sein.
  • Die Y-Achse zeigt den prozentualen Anteil der Zeit an, den die DateRange-Felder im Vergleich zu TrieDate (grüne Xs) und TrieDate+DocValues (rote Xs) benötigen.

Hübscher Graph

Index und Speichergröße

Die Skala ist zu klein, um über Index- und Speicherunterschiede zu berichten. Bei dieser Größe (25 Mio. Datumsfelder) war der Unterschied zwischen dem reinen Index und docValues sowohl bei der Speicher- als auch bei der Festplattengröße (ohne DateRangeField) so gering, dass er im Rauschen unterging. Auch wenn ich es mir angesehen habe, ist es bestenfalls irreführend, einen Unterschied von z.B. 1% zu melden. Siehe Davids Kommentare weiter unten. Wir wissen, dass DocValues die Größe des Index auf der Festplatte erhöht und den benötigten JVM-Speicher um ungefähr die Größe der *.dvd Dateien auf der Festplatte verringert.

David Smileys Bereicherung

Nochmals vielen Dank an David für seine Tutorials. Hier sind einige Dinge, die Sie beachten sollten:

  • Die Erwartung ist, dass DateRangeField schneller als TrieDateField für Bereiche sein sollte, die auf Sekundeneinheiten oder gröbere Einheiten ausgerichtet sind; aber vielleicht nicht gröber als hundert Jahre auseinander.
  • Wenn Sie also Bereichsabfragen von einer zufälligen Millisekunde zu einer anderen erwarten, sollten Sie weiterhin TrieDate verwenden; andernfalls ziehen Sie DateRangeField in Betracht.
  • [Ich muss noch einmal betonen, dass DateRangeField für Abfragetypen verwendet werden kann , die in diesem Test nicht getestet wurden. Es gibt einfach Probleme, die viel einfacher sind als die Verwendung von DateRangeField. Diese Übung diente lediglich dazu, DateRangeField mit den anderen Varianten zu vergleichen.
  • TrieDate+DocValues verwendet den filterCache überhaupt nicht, während TrieDate-only und DateRangeField ihn verwenden. Derzeit gibt es keine Möglichkeit, DateFangeField anzuweisen, filterCache nicht zu verwenden. Eine der zukünftigen Verbesserungen besteht darin, facet.range mit DateRangeField zu aktivieren, um die Low-Level-Facettenimplementierung gemeinsam mit der räumlichen Heatmap-Facettierung zu verwenden, was dazu führen würde, dass DateRangeField den filterCache nicht verwendet.
    • [Wenn Sie mehr Details dazu wissen möchten, fragen Sie David, er ist der Assistent. Ich möchte noch hinzufügen, dass die Heatmap sehr cool ist. Ich habe einmal gesehen, wie jemand dies innerhalb von 2 Stunden in seine Anwendung eingebaut hat (kein DateRangeField, nur eine Heatmap). Zugegeben, die Anzeige im Browser war ein Stück Code von der Stange.
  • Eine weitere erwähnenswerte Sache auf dem Radar ist die Einführung von „PointValues“ (früher bekannt als DimensionalValues) in Lucene 6. Es würde sich wie ein viel schnelleres TrieDateField (ohne DocValues) stapeln
  • Diskussionen über die Speichernutzung oder die Echtzeitsuche beziehen sich meist nur auf facet.range. Für eine einfache Bereichsabfrage gilt die DV nicht einmal und es gibt keine Speicheranforderungen/-beschränkungen.

Schlussbemerkungen

Wie immer können Sie bei der Verwendung von DateRangeFields unterschiedliche Erfahrungen machen.

  • Für die Echtzeitsuche werden docValues sowohl für TrieDate-only als auch für DateRangeFields bevorzugt, obwohl sich das in Zukunft ändern kann.
  • Je mehr Arbeit hier geleistet wird, desto mehr Funktionen werden in den Speicher des Betriebssystems verlagert, so dass die JVM-Nutzung durch DateRangeField reduziert wird.
  • Wenn Ihr Problem den erweiterten Möglichkeiten von DateRangeField besser entspricht, sollten Sie es vorzugsweise verwenden. Die Leistung wird nicht darunter leiden (zumindest gemessen an diesen Tests), aber Sie zahlen einen Preis für den Speicherplatz im Vergleich zu TrieDate+DocValues
  • Für diese Übung habe ich den filterCache ausgeschaltet. Dies ist wahrscheinlich eine genauere Simulation von NRT-Setups, aber in einem relativ statischen Index muss DateRangeField mit dem fiterCache in Ihrer spezifischen Situation bewertet werden, um die Konsequenzen zu bestimmen.

Über-Analyse

Ursprünglich wollte ich die Speichernutzung, den Festplattenplatz usw. vergleichen. Man neigt dazu, aus einem begrenzten Test Informationen herauszuziehen, die einfach nicht vorhanden sind. Nachdem ich pflichtbewusst viele dieser Informationen gesammelt hatte, wurde mir klar, dass es nicht genug Informationen gab, um daraus irgendwelche Verallgemeinerungen abzuleiten. Alles, was ich auf der Grundlage dieser Daten sagen könnte, abgesehen von dem, was David angegeben hat und von dem ich weiß, dass es wahr ist (z.B. dass docValues die Indexgröße auf der Festplatte erhöhen, aber den JVM-Speicher reduzieren), wäre nicht besonders relevant…

Wie immer bitten wir Sie, Ihre Kommentare zu posten, insbesondere Mr. Smiley!


Dieser Beitrag wurde ursprünglich am 13. Februar 2016 veröffentlicht.

You Might Also Like

Vom Suchunternehmen zum praktischen KI-Pionier: Unsere Vision für 2025 und darüber hinaus

CEO Mike Sinoway gibt Einblicke in die Zukunft der KI und stellt...

Read More

Wenn KI schief geht: Fehlschläge in der realen Welt und wie man sie vermeidet

Lassen Sie nicht zu, dass Ihr KI-Chatbot einen 50.000 Dollar teuren Tahoe...

Read More

Lucidworks Kernpakete: Branchenoptimierte KI-Such- und Personalisierungslösungen

Entdecken Sie unsere umfassenden Core Packages, die Analytics Studio, Commerce Studio und...

Read More

Quick Links