Vorwort: wieso ein Blog zu PHP, Solr und Lucene?

Wieso ein Blog zu PHP, Solr und Lucene?
Gegenstand und Ausgangspunkt all unserer Aktivitäten auf diesem Gebiet war ein Projekt um ein Nachrichtenportal und die Aufgabe, Recherchen und Analysen im Nachrichtenbestand von über 10 Million News performant zu handeln. Die MySQL Volltextsuche kam da schnell an Ihre grenzen, Oracle war keine Alternative.
Es reifte also die Frage, wie können andere (etwa die Internetsuchmaschiene google) immense Datenmengen spielend handeln?
Wir lösten den MySQL volltext mit Lucene ab. Der Performancegewinn war dramatisch. Suchen im Datenbestand, die vorher über 10 Sekunden dauerten, brauchen mittels Lucene und Solr nur selten mehr als 20ms!
Eine neue Welt tat sich auf, die es zu erobern galt und schnell fiel auf, dass deutschsprachige Seiten zum Thema Mangelware sind. Dies soll sich mit diesem Blog ein wenig ändern.

Sie haben Fragen zu Solr/Lucene/PHP? Schreiben sie uns einen Kommentar!

Freitag, 28. September 2012

Realtime Suche vs. Performance

Unser Datenbestand unterliegt dauernden Änderungen. In der Ausprägung, dass täglich mehrere tausend Dokumente hinzu kommen. Das ist für Solr per se kein Problem. Unser Ziel ist jedoch, dass neue Dokumente quasi zeitgleich auch in Solr gefunden werden. Das heißt: permanentes Hinzufügen neuer Dokumente. Bei uns passiert das als Dienst alle 10 Sekunden.
Alle 10 Sekunden führen wir ein Dataimport durch, mit dem Parameter commit=true (oder autocommit) und optimize=false,  Commit ist wichtig, damit die Daten auffindbar sind. Optimize ist wichtig, damit die Suche performant ist. Und genau hier hängt das Problem.

Beim Import von Daten aus einer relationalen Datenbank (bspw. MySQL) stehen uns 2 Import-Modi zur Verfügung: full-import oder delta-import. Der full Import mit Option clean=false macht letztlich das, was der Delta Import macht.
In beiden Fällen können die Anwender während eines laufenden Imports weiter suchen. Ist der Import abgeschlossen startet Solr eine neue Instanz des Such-handlers (bspw. /select) und schwenkt den alten, aktiven Such-handler auf den Neuen. Ab diesem Zeitpunkt sind die neuen Nachrichten auffindbar.
Führt man nun alle paar Sekunden ein Update aus, so sind die Dokumente "gefühlt" in nahe Echtzeit auffindbar. Near Relatime Search heißt das zugehörige Buzzword.
Dieser Wechsel der Search Handler hat einen Vorteil: Solr ist auch während eines Update verfügbar. Allerdings auch 2 deutliche Nachteile:
  1. ein neuer Searchhandler verliert die kostbar gesammelten Caching Informationen seines Vorgängers. Um das zu verhindern, gibt es automatisches Warmup eines Caches, dass man in der solrconfig.xml für jeden Cach-Typ definieren kann:
        <filterCache class="solr.FastLRUCache"
                     size="16384"
                     initialSize="4096"
                     autowarmCount="512"/>

    autowarmCount definiert dabei, wie viele Einträge vom alten Cache übernommen werden sollen. Solr fürt dabei intern offensichtlich die entsprechende Querys aus. Hohe Werte >4096 können bei einem großen Index dazu führen, dass das auto-warming eine halbe Minute oder länger dauert, was selten eine Option ist, bei "Near Relatime". Die Alternative ist, diesen Cache klein zu halten, wobei dann gecachte Einträge nicht über einen längeren Zeitraum an neue Searchhandler vererbt werden können.
  2. Ein Update defragmentiert den Suchindex. Dieser besteht im Dateisystem aus mehreren Dateien. Durch ein Optimize werden diese Dateien gemäß der Konfiguration zusammengefasst mit teils erheblichem Performancegewinn. Ein facetted Search über 8 Millionen Dokumente dauert im Beispiel ca. 20-40 Sekunden. Nach einem Optimize benötigt die gleiche Abfrage keine 5 Sekunden. Der Knackpunkt: ein Optimize bei einem so großen Datenbestand benötigt auf einem virtuellen Server gut 1 1/2 Stunden. Aber selbst auf gut bestückter Hardware vergehen 20 Minuten. Es ist daher keine Alternative, jeden Import mit der Option optimize=true zu starten. Aus ein paar Sekunden Importzeit werden Minuten, bis die neuen Daten auffindbar sind. Eine Möglichkeit ist in der Datei solrconfig.xml die Option <mergeFactor>3</mergeFactor> auf einen kleineren Wert zu setzen. Standard ist 10. Bis zu einem Wert von 3 konnten wir nachhaltig einen Performancegewinn verbuchen. Trotz Update und ohne Optimize zwischendurch benötigt der o.g. facetted Search nun ca. 10 Sekunden, statt vorher 20-40 Sekunden. Für den Anwender ein akzeptables Resultat aufgrund der Datenmenge.
    Ein Optimize des Index realisieren wir nun nur noch 1x täglich, nachts.
Zusammenfassend: "Near Relatime" ist möglich, jedoch mit einigen Kosten hinsichtlich der Performance verbunden, die man sicher im Einzelfall abwägen muss.

Keine Kommentare:

Kommentar veröffentlichen