Ich werde ein wenig darauf eingehen, wie wir uns für die Umsetzung entschieden haben Lucene.Net hier auf Stack Overflow und einige Lektionen, die ich auf diesem Weg gelernt habe:
Wo soll ich den Index platzieren? Ich habe gesehen, dass empfohlen wird, ihn auf den Webserver zu legen, aber das scheint bei einer großen Anzahl von Webservern verschwenderisch zu sein. Wäre eine Zentralisierung hier nicht besser?
- Das hängt von Ihren Zielen ab, wir hatten eine stark eine unzureichend ausgelastete Webebene (~10% CPU) und eine überlastete Datenbank, die eine Volltextsuche durchführt (ca. 60% CPU, wir wollten es weniger). Das Laden desselben Indexes auf jede Web-Tier können wir diese Maschinen nutzen und haben eine tonnenweise Redundanz Wir können immer noch 9 von 10 Webservern ausfallen lassen und das Stack Exchange-Netzwerk aufrechterhalten, wenn es nötig ist. Die Kehrseite der Medaille ist, dass es für uns sehr IO-intensiv ist und der Web-Tier nicht mit diesem Ziel gekauft wurde (das ist bei den meisten Unternehmen der Fall). Obwohl es gut funktioniert, werden wir unseren Web-Tier auf SSDs aufrüsten und einige andere Bits implementieren, die in der .Net-Portierung ausgelassen wurden, um diesen Hardwaremangel zu kompensieren (
NIOFSDirectory
zum Beispiel).
- Der andere Nachteil, wenn wir alle unsere Datenbanken indizieren
n
Zeiten für die Webebene, aber zum Glück haben wir keine Probleme mit der Netzwerkbandbreite und der SQL-Server, der die Ergebnisse zwischenspeichert, macht dies jedes Mal zu einem sehr schnellen Delta-Indizierungsvorgang. Bei einer großen Anzahl von Webservern kann dies allein schon diese Option ausschließen.
Wenn der Index zentralisiert ist, wie würde ich ihn dann abfragen, wenn er sich nur im Dateisystem befindet? Muss ich ihn tatsächlich auf eine Netzwerkfreigabe legen, die alle Webserver sehen können?
- Sie können es auf einer Dateifreigabe auf beide Arten abfragen, stellen Sie nur sicher, dass jeweils nur eine Indizierung stattfindet (
write.lock
Der Verzeichnissperrmechanismus stellt dies sicher, und es kommt zu Fehlern, wenn Sie mehrere IndexWriter auf einmal ausprobieren).
- Denken Sie daran, meine Notizen oben, das ist IO-intensiv, wenn eine Menge von Lesern herumfliegen, so dass Sie brauchen reichlich Bandbreite zu Ihrem Speicher, kurz von mindestens iSCSI oder ein Glasfaser-SAN, würde ich vorsichtig sein, dieser Ansatz auf einem hohen Verkehr (Hunderttausende von Suchanfragen pro Tag) zu verwenden.
- Eine weitere Überlegung ist, wie Sie Ihre Webserver (oder die abfragende Ebene) aktualisieren/benachrichtigen. Wenn Sie einen Indizierungsdurchlauf beenden, müssen Sie Ihre
IndexReader
s, um den aktualisierten Index mit neuen Dokumenten zu erhalten. Wir verwenden eine Redis-Nachrichtenkanal um alle Beteiligten zu benachrichtigen, dass der Index aktualisiert wurde... jeder Nachrichtenmechanismus würde hier funktionieren.
Gibt es bereits existierende Tools, die einen Lucene-Index nach einem Zeitplan inkrementell auffüllen, indem sie die Daten aus einer SQL Server-Datenbank abrufen? Wäre ich besser dran, wenn ich meinen eigenen Dienst hier einrichten würde?
- Leider gibt es keine, von denen ich wüsste, aber ich kann Ihnen mitteilen, wie ich an diese Sache herangegangen bin.
- Bei der Indizierung einer bestimmten Tabelle (vergleichbar mit einem Dokument in Lucene) haben wir eine Zeilenversion zu diesem Tisch. Beim Indizieren wählen wir anhand der letzten Zeilenversion (a Zeitstempel Datentyp, zurückgezogen als bigint ). Ich habe mich dafür entschieden, das Datum des letzten Index und die letzte indizierte Zeilenversion in einer einfachen .txt-Datei im Dateisystem zu speichern, und zwar aus einem Grund: Alles andere in Lucene wird dort gespeichert. Das bedeutet, wenn es jemals ein großes Problem gibt, können Sie einfach den Ordner mit dem Index löschen und der nächste Indizierungsdurchgang wird sich erholen und einen vollständig aktuellen Index haben, fügen Sie einfach etwas Code hinzu, um damit umzugehen, dass nichts da ist, was "alles indizieren" bedeutet.
Wenn ich den Index abfragen, sollte ich suchen, um nur zurückziehen ein Bündel von Datensatz-IDs, die ich dann zurück zu der DB für den tatsächlichen Datensatz gehen, oder sollte ich zielen auf alles, was ich für die Suche direkt aus dem Index benötigen?
- Diese vraiment hängt von Ihren Daten ab, für uns ist es nicht wirklich machbar, alles im Index zu speichern (und es wird auch nicht empfohlen). Ich schlage vor, dass Sie die Felder für Ihre Suchergebnisse im Index speichern, und damit meine ich, was Sie brauchen, um Gegenwart Ihre Suchergebnisse in einer Liste, bevor der Nutzer auf die vollständige [hier einfügen] Seite klickt.
- Eine weitere Überlegung ist, wie häufig sich Ihre Daten ändern. Wenn sich viele Felder, die Sie nicht Wenn sich die Felder, nach denen Sie suchen, schnell ändern, müssen Sie diese Zeilen (Dokumente) neu indizieren, um Ihren Index zu aktualisieren, und zwar nicht nur, wenn sich das Feld, nach dem Sie suchen, ändert.
Ist es sinnvoll, so etwas wie Solr in dieser Geschmacksumgebung zu implementieren? Wenn ja, würde ich ihm wahrscheinlich eine eigene *nix-VM geben und es innerhalb von Tomcat auf dieser ausführen. Aber ich bin mir nicht sicher, was mir Solr in diesem Fall bringen würde.
- Sicherlich, es ist die zentrale Suche, von der Sie sprechen (bei einer großen Anzahl von Suchvorgängen können Sie mit einer VM-Einrichtung wieder an eine Grenze stoßen, behalten Sie dies im Auge). Wir haben das nicht gemacht, weil es eine Menge (unserer Meinung nach) ungerechtfertigter Komplexität in unseren Technologie-Stack und den Build-Prozess gebracht hat, aber für eine größere Anzahl von Webservern macht es viel mehr Sinn.
- Was bekommen Sie dafür? In erster Linie Leistung und einen oder mehrere dedizierte Indexierungsserver. Anstelle von
n
Servern, die eine Netzwerkfreigabe crawlen (und ebenfalls um IO konkurrieren), können sie einen einzelnen Server treffen, der nur befasst sich mit Anfragen und Ergebnissen über das Netzwerk, nicht mit dem Crawlen des Index, bei dem viel mehr Daten hin- und hergehen... dies würde lokal auf dem/den Solr-Server(n) erfolgen. Außerdem wird Ihr SQL-Server nicht so stark belastet, da weniger Server indizieren.
- Was es nicht kaufen Sie ist so viel Redundanz, aber es liegt an Ihnen, wie wichtig dies ist. Wenn Sie mit einer verschlechterten Suche oder ohne sie auskommen, sollte Ihre Anwendung dies einfach übernehmen. Wenn Sie kann nicht , dann kann ein Backup-Solr-Server oder mehr auch eine gültige Lösung sein... und es ist möglich, einen weiteren Software-Stack zu pflegen.