Solr TTL (Time to Live) & Ablauf von Dokumenten
Lernen Sie zwei Funktionen kennen, die sich auf das „Verfallen“ von Dokumenten beziehen und die einzeln oder in Kombination verwendet werden können.
Lucene & Solr 4.8 wurden letzte Woche veröffentlicht und Sie können Solr 4.8 vom Apache Spiegelnetzwerk herunterladen. Heute möchte ich Ihnen eine kleine, aber leistungsstarke Funktion vorstellen, an der ich für 4.8 gearbeitet habe: Document Expiration.
Die DocExpirationUpdateProcessorFactory
bietet zwei Funktionen in Bezug auf den „Verfall“ von Dokumenten, die einzeln oder in Kombination verwendet werden können:
- Regelmäßiges Löschen von Dokumenten aus dem Index auf der Grundlage eines Verfallsfeldes
- Berechnung von Verfallsfeldwerten für Dokumente anhand einer „time to live“ (TTL)
Abgelaufene Dokumente automatisch löschen
Der wichtigste Aspekt dieses Update-Prozessors ist die Fähigkeit, Dokumente auf der Grundlage der Werte in einem von Ihnen konfigurierten Feld „Ablaufdatum“ automatisch zu löschen. Diese automatische Löschung ist nicht Teil des normalen Lebenszyklus des Update-Prozessors – sie wird über einen von der Factory erstellten Hintergrund-Timer-Prozess-Thread ausgeführt.
Um diese automatische Löschfunktion zu nutzen, müssen Sie zwei Optionen in der Factory konfigurieren:
expirationFieldName
– Der Name des zu verwendenden VerfallsfeldesautoDeletePeriodSeconds
– Wie oft der Timer der Fabrik einen Löschvorgang auslösen soll, um die Dokumente zu entfernen
Mit der folgenden Konfiguration erstellt DocExpirationUpdateProcessorFactory
beispielsweise einen Timer-Thread, der alle 30 Sekunden aufwacht. Wenn der Timer ausgelöst wird, führt er den Befehl deleteByQuery
aus, um alle Dokumente mit einem Wert im Feld press_release_expiration_date
zu entfernen, der in der Vergangenheit liegt:
<processor class="solr.processor.DocExpirationUpdateProcessorFactory"> <int name="autoDeletePeriodSeconds">30</int> <str name="expirationFieldName">press_release_expiration_date</str> </processor>
Nach der Ausführung von deleteByQuery
wird auch ein Soft-Commit mit openSearcher=true
durchgeführt, damit die Suchergebnisse die abgelaufenen Dokumente nicht mehr anzeigen.
Während die grundlegende Logik von „Timer geht los, lösche Dokumente mit Ablaufdatum vor JETZT“ recht einfach und unkompliziert hinzuzufügen war, war ein wichtiger Aspekt, damit dies gut funktioniert, in einer verwandten Ausgabe(SOLR-5783), um sicherzustellen, dass openSearcher=true
nichts tut, wenn es nicht wirklich Änderungen im Index gibt. Das bedeutet, dass Sie autoDeletePeriodSeconds
auf sehr kleine Werte konfigurieren können und trotzdem sicher sein können, dass Ihre Suchcaches nicht alle paar Sekunden grundlos weggeblasen werden. Die openSearcher=true
Soft Commits wirken sich nur dann aus, wenn es wirklich Änderungen im Index gibt.
Berechnen Sie das Verfallsdatum aus der TTL
Die zweite Funktion, die von dieser Factory implementiert wird (und der Hauptgrund dafür, dass sie als UpdateProcessorFactory
) ist die Verwendung von „TTL“-Werten (Time To Live), die mit Dokumenten verknüpft sind, um automatisch einen Wert für das Verfallsdatum zu generieren, der in der expirationFieldName
wenn Dokumente indiziert werden.
Standardmäßig sucht DocExpirationUpdateProcessorFactory
bei Aktualisierungsanfragen nach einem _ttl_
Anfrageparameter sowie nach einem _ttl_
Feld in jedem Dokument, das in dieser Anfrage indiziert wird. Wenn beides vorhanden ist, werden sie als mathematische Datumsausdrücke relativ zu NOW
geparst und zum Auffüllen von expirationFieldName
verwendet. Die auf dem Feld _ttl_
pro Dokument basierenden Werte haben Vorrang vor dem Parameter _ttl_
pro Anfrage.
Sowohl die Anfrageparameter als auch die Feldnamen, die für die Angabe von TTL-Werten verwendet werden, können durch die Konfiguration von ttlParamName
& ttlFieldName
auf DocExpirationUpdateProcessorFactory
außer Kraft gesetzt werden. Sie können auch vollständig deaktiviert werden, indem Sie sie als null
konfigurieren. Es ist auch möglich, die TTL-Berechnungsfunktion zu verwenden, um Verfallsdaten für Dokumente zu generieren, ohne die automatische Löschfunktion zu verwenden, indem Sie die Option autoDeletePeriodSeconds
nicht konfigurieren (so dass der Timer nie läuft).
In der folgenden Konfiguration sucht die Factory zum Beispiel in jedem Dokument nach einem time_to_live
Feld und berechnet daraus einen Ablaufwert für das press_release_expiration_date
Feld. Es werden keine Anfrageparameter auf eine TTL-Überschreitung geprüft und es erfolgt keine automatische Löschung:
<processor class="solr.processor.DocExpirationUpdateProcessorFactory"> <str name="expirationFieldName">press_release_expiration_date</str> <null name="ttlParamName"/> <!-- ignore _ttl_ request param --> <str name="ttlFieldName">time_to_live</str> <!-- NOTE: autoDeletePeriodSeconds not specified, no automatic deletes --> </processor>
Diese Art der Konfiguration kann praktisch sein, wenn Sie Dokumente nur für Suchclients auf der Grundlage einer TTL pro Dokument logisch ausblenden möchten, indem Sie etwas wie: fq=-press_release_expiration_date:[* TO NOW/DAY]
, aber die Dokumente trotzdem für andere Suchclients im Index behalten wollen.
Ein ausführliches Beispiel
Lassen Sie uns ein vollständiges Beispiel für beide Funktionen durchgehen, indem wir die Datei Solr 4.8 Beispiel solrconfig.xml
um die folgende Update-Prozessorkette hinzuzufügen:
<updateRequestProcessorChain default="true"> <processor class="solr.TimestampUpdateProcessorFactory"> <str name="fieldName">timestamp_dt</str> </processor> <processor class="solr.processor.DocExpirationUpdateProcessorFactory"> <int name="autoDeletePeriodSeconds">30</int> <str name="ttlFieldName">time_to_live_s</str> <str name="expirationFieldName">expire_at_dt</str> </processor> <processor class="solr.FirstFieldValueUpdateProcessorFactory"> <str name="fieldName">expire_at_dt</str> </processor> <processor class="solr.LogUpdateProcessorFactory" /> <processor class="solr.RunUpdateProcessorFactory" /> </updateRequestProcessorChain>
Ein paar Dinge sollten Sie über diese Kette wissen:
- Sie enthält ein einfaches
TimestampUpdateProcessorFactory
damit man in den Abfrageergebnissen, die ich unten zeige, leicht erkennen kann, wann diese Dokumente indiziert wurden – aber das ist nicht notwendig, damitDocExpirationUpdateProcessorFactory
funktioniert. - Die Instanz
DocExpirationUpdateProcessorFactory
verwendet eineautoDeletePeriodSeconds
von 30 Sekunden und überschreibt diettlFieldName
– aber der_ttl_
Anfrageparameter ist immer noch aktiviert - A
FirstFieldValueUpdateProcessorFactory
aufexpire_at_dt
konfiguriert ist – das bedeutet, dass, wenn ein Dokument mit einem expliziten Wert im Feldexpire_at_dt
hinzugefügt wird, dieser Wert anstelle eines Wertes verwendet wird, der vonDocExpirationUpdateProcessorFactory
mit dem Abfrageparameter_ttl_
hinzugefügt werden könnte
Mit dieser Konfiguration können wir nun damit beginnen, einige Dokumente zu indizieren und einige Abfragen auszuführen.
Als erstes fügen wir 2 Dokumente hinzu – eines ohne TTL oder Ablaufdatum und eines mit einem TTL-Feld von 2 Minuten.
$ date -u && curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/collection1/update?commit=true' -d '[ { "id" : "live_forever" }, { "id" : "live_2_minutes_a", "time_to_live_s" : "+120SECONDS" } ]' Wed May 7 22:17:46 UTC 2014 {"responseHeader":{"status":0,"QTime":574}}
Ein paar Sekunden später indizieren wir 3 weitere Dokumente mit einem „Standard“-TTL-Anfrageparameter von 5 Minuten: Eines mit einem expliziten Verfallsdatum, das weit in der Zukunft liegt, ein weiteres Dokument mit einem 2-Minuten-TTL-Feld und das dritte, das den TTL-Anforderungsparameter nutzt.
$ date -u && curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/collection1/update?commit=true&_ttl_=%2B5MINUTES' -d '[ { "id" : "live_a_long_time", "expire_at_dt" : "3000-01-01T00:00:00Z" }, { "id" : "live_2_minutes_b", "time_to_live_s" : "+120SECONDS" }, { "id" : "use_default_ttl" } ]' Wed May 7 22:17:51 UTC 2014 {"responseHeader":{"status":0,"QTime":547}}
Ein paar Sekunden später führen wir eine Abfrage aus und sehen alle 5 Dokumente im Index. Wenn wir uns das Feld timestamp_dt
ansehen, können wir genau sehen, wann jedes Dokument hinzugefügt wurde, und wenn wir uns das Feld expire_at_dt
ansehen, können wir sehen, welche Dokumente ein Ablaufdatum haben – entweder explizit oder über eine TTL-Berechnung.
$ date -u && curl -X GET 'localhost:8983/solr/query?q=*:*' Wed May 7 22:17:57 UTC 2014 { "responseHeader":{ "status":0, "QTime":0, "params":{ "q":"*:*"}}, "response":{"numFound":5,"start":0,"docs":[ { "id":"live_forever", "timestamp_dt":"2014-05-07T22:17:46.685Z", "_version_":1467483230500290560}, { "id":"live_2_minutes_a", "time_to_live_s":"+120SECONDS", "timestamp_dt":"2014-05-07T22:17:46.685Z", "expire_at_dt":"2014-05-07T22:19:46.685Z", "_version_":1467483230503436288}, { "id":"live_a_long_time", "expire_at_dt":"3000-01-01T00:00:00Z", "timestamp_dt":"2014-05-07T22:17:51.276Z", "_version_":1467483235314302976}, { "id":"live_2_minutes_b", "time_to_live_s":"+120SECONDS", "timestamp_dt":"2014-05-07T22:17:51.276Z", "expire_at_dt":"2014-05-07T22:19:51.276Z", "_version_":1467483235318497280}, { "id":"use_default_ttl", "timestamp_dt":"2014-05-07T22:17:51.276Z", "expire_at_dt":"2014-05-07T22:22:51.276Z", "_version_":1467483235320594432}] }}
Jetzt warten wir etwas mehr als 2,5 Minuten und führen die Abfrage erneut aus. Diesmal erhalten wir nur 3 Ergebnisse, da die Dokumente mit einer TTL von 2 Minuten bereits gelöscht wurden, weil ihr Verfallsdatum erreicht wurde.
$ date -u && curl -X GET 'localhost:8983/solr/query?q=*:*' Wed May 7 22:20:30 UTC 2014 { "responseHeader":{ "status":0, "QTime":1, "params":{ "q":"*:*"}}, "response":{"numFound":3,"start":0,"docs":[ { "id":"live_forever", "timestamp_dt":"2014-05-07T22:17:46.685Z", "_version_":1467483230500290560}, { "id":"live_a_long_time", "expire_at_dt":"3000-01-01T00:00:00Z", "timestamp_dt":"2014-05-07T22:17:51.276Z", "_version_":1467483235314302976}, { "id":"use_default_ttl", "timestamp_dt":"2014-05-07T22:17:51.276Z", "expire_at_dt":"2014-05-07T22:22:51.276Z", "_version_":1467483235320594432}] }}
Nach weiteren 2,5 Minuten (ungefähr) führen wir die Abfrage erneut aus und sehen, dass ein weiteres Dokument (das Teil einer Aktualisierung mit der Standard-TTL von 5 Minuten war) nun ebenfalls gelöscht wurde.
$ date -u && curl -X GET 'localhost:8983/solr/query?q=*:*' Wed May 7 22:22:57 UTC 2014 { "responseHeader":{ "status":0, "QTime":0, "params":{ "q":"*:*"}}, "response":{"numFound":2,"start":0,"docs":[ { "id":"live_forever", "timestamp_dt":"2014-05-07T22:17:46.685Z", "_version_":1467483230500290560}, { "id":"live_a_long_time", "expire_at_dt":"3000-01-01T00:00:00Z", "timestamp_dt":"2014-05-07T22:17:51.276Z", "_version_":1467483235314302976}] }}
Von den 2 verbleibenden Dokumenten hat eines kein Verfallsdatum und das andere wird zu unseren Lebzeiten nicht ablaufen – aber solange der Solr-Server läuft, wird DocExpirationUpdateProcessorFactory
alle 30 Sekunden prüfen, ob etwas gelöscht werden muss.