Frage

Dies wird eine schwierige Frage sein, aber ich werde es trotzdem versuchen: Unsere Aufgabe ist es, Microsoft Fast ESP mit Gigabyte von Daten zu füttern. Die endgültige Menge an indizierten Daten liegt irgendwo in der Nachbarschaft von 50-60 GB.

Fast hat eine .NET -API, aber Kernkomponenten sind in Python geschrieben (Verarbeitungspipelines zu Indexdokumenten). Die Herausforderung besteht darin, zuverlässig mit dem System zu kommunizieren und gleichzeitig Gigabyte von Daten zur Indexierung zu füttern.

Die Probleme, die mit schnellem hier auftreten, sind:

  1. Das System ist skurril, wenn es zu viele Daten gleichzeitig gefüttert wird, da es seine Daten wieder in der Lage sein möchte, in denen das System stundenlang nicht erreichbar bleibt. Inakzeptabel.

  2. Es ist keine Option, alle Daten zu starten und jeweils ein Element seriell zu füttern, da dies zu lange dauert (mehrere Tage).

  3. Wenn ein Element durch Fast nicht indiziert werden kann, muss der Client den Artikel erneut füttern. Damit dies funktioniert, soll das System eine Rückrufmethode aufrufen, um den Kunden über den Fehler zu informieren. Immer wenn das System ausmacht, kann der Fütterungsclient jedoch nicht auf das Timeout reagieren, da dieser Rückruf niemals aufgerufen wird. Daher hungert der Kunde. Die Daten sind in der Warteschlange, können aber nicht an das System weitergegeben werden. Die Warteschlange bricht zusammen. Daten gehen verloren. Du hast die Idee.

Anmerkungen:

  1. Das Füttern eines Artikels kann Sekunden lang für einen kleinen Artikel und bis zu 5-8 Stunden für einen einzigen großen Artikel dauern.
  2. Die indizierten Elemente sind sowohl binär als auch textbasiert.
  3. Das Ziel ist die volle Indexierung, "nur" 48-72h zu nehmen, dh es muss über das Wochenende passieren.
  4. Die schnellen Dokumentverarbeitungspipelines (Python -Code) haben hier jeweils rund 30 Stufen. Zu diesem Zeitpunkt gibt es insgesamt 27 Pipelines.

Zusammenfassend:

Die größte Herausforderung besteht darin, das System mit großer und kleiner Elemente mit genau der richtigen Geschwindigkeit zu füttern (nicht zu schnell, weil es möglicherweise einstürzen oder auf Speicherprobleme stößt; nicht zu langsam, weil dies gleichzeitig zu lang dauert), gleichzeitig auf parallel Art wie asynchron laufende Threads. Meiner Meinung nach muss es einen Algorithmus geben, der entscheidet, wann die Elemente und wie viele auf einmal füttern soll. Parallele Programmierung fällt mir in den Sinn.

Es könnte auch mehrere "Warteschlangen" geben, bei denen jede Warteschlange (Prozess) bestimmte Elemente gewidmet ist, die in einer Warteschlange geladen und dann nacheinander (in Arbeiter-Threads) gefüttert werden.

Ich bin neugierig, ob jemand jemals so etwas getan hat oder wie Sie ein solches Problem vornehmen würden.

EDIT: Auch hier möchte ich nicht schnell "reparieren" und seine inneren Arbeiten verbessern. Die Herausforderung besteht darin, es effektiv zu nutzen!

War es hilfreich?

Lösung

Es hört sich so an, als ob Sie mehr mit einer Reihe von Problemen arbeiten als ein bestimmtes Problem mit der C# -Fütterungsgeschwindigkeit.

Ein paar Fragen im Voraus - sollen diese 60 -GB -Daten jedes Wochenende verbraucht werden oder ist es eine erste Rückfüllung des Systems? Gibt es die Daten als Elemente im Dateisystem lokal zur ESP -Installation oder Elseware? Ist dies eine einzige interne ESP -Bereitstellung oder eine Lösung, die Sie an mehreren Stellen replizieren möchten? Einzelknoten installieren oder mehrere (oder besser gesagt ... wie viele - einzelne Knotenkappen sind 20 DocProcs)?

Die ESP -Leistung wird normalerweise durch die Anzahl der Dokumente begrenzt, die mehr als die Anzahl der Dateien gehandhabt werden sollen. Unter der Annahme, dass Ihre Daten zwischen der Größe von E -Mail -Größe 35K und Dateisystemgröße 350K -Daten liegen, entspricht Sie 60 GB zwischen 180.000 Dokumenten und 1,8 -mil -Dokumenten. Um diese über 48 Stunden zu füttern, müssen Sie zwischen 3750 und 37500 Dokumente pro Stunde füttern. Kein sehr hohes Ziel für moderne Hardware (wenn Sie dies auf einer VM installiert haben ... nun ... alle Wetten sind ausgeschaltet, es wäre besser dran auf einem Laptop).

Für die Fütterung haben Sie die Wahl zwischen einer schnelleren Codierung und mehr Kontrolle, wenn Sie entweder die Stapel gefüttert oder das Dokumentfeeder -Framework in der API verwenden, die einen Großteil der Chargenlogik abstrahiert. Wenn Sie nur 37,5.000 Dokumente/HR wählen, speichern Sie den Overhead und verwenden Sie nur DocumentFeeder - obwohl Sie sich in seinen Konfigurationsparamien vorstellen können. Mit dem Dokumentfutterleiter können Sie Ihre Inhalte pro Dokument behandeln, anstatt die Stapel selbst zu erstellen. Dies ermöglicht auch ein gewisses Maß für die automatische Wiederholung auf der Basis von Konfiguration. Das allgemeine Ziel sollte für einen maximalen Inhalt von 50 MB pro Stapel oder 100 Dokumente erfolgen, je nachdem, was zuerst eintritt. Größere Dokumente sollten in kleineren Chargen gesendet werden ... Wenn Sie also eine 50 -MB -Datei haben, sollte sie idealerweise von selbst gesendet werden usw. Sie würden tatsächlich die Kontrolle über die von Dokumentfuttermittel gebildeten Stapel verlieren ... also die Logik dort dort ist ein bisschen eine beste Anstrengung Ihres Codes.

Verwenden Sie die Rückrufe, um zu überwachen, wie gut der Inhalt in das System geschafft. Setzen Sie Grenzen für die Fütterung, für die Sie die endgültigen Rückrufe noch nicht erhalten haben. Das Ziel sollte sein, dass X -Stapel zu einem bestimmten Zeitpunkt eingereicht werden, um an beiden Grenzwerten zu pausieren. X sollte ungefähr 20 + # Dokumentverarbeiter sein, y sollte sich in der Fläche von 500-1000 MB befinden. Mit Dokumentfutterleiter ist es nur ein Pass/Ausfall pro Dokument, mit dem herkömmlichen System, das detaillierter ist. Warten Sie nur auf den "gesicherten" Rückruf ... der Ihnen sagt, dass er verarbeitet und indiziert wird ... Warten darauf, dass er durchsuchbar ist, ist sinnlos.

Setzen Sie einige Grenzen für Ihren Inhalt ... Im Allgemeinen wird ESP mit sehr großen Dateien zusammenbrechen, es gibt eine harte Begrenzung von 2 GB, da es sich immer noch um 32 -Bit -Procs handelt, aber in Wirklichkeit sollte etwas mehr als 50 MB nur die Metadaten eingefügt haben. Auch ... auch ... Vermeiden Sie das Füttern von Protokolldaten, sie zerkleinern die internen Strukturen und töten Perfs ab, wenn nicht. In der Pipeline können Dinge erledigt werden, um das zu ändern, was durchsucht werden kann, um die Schmerzen einiger Protokolldaten zu erleichtern.

Sie müssen auch sicherstellen, dass Ihr Index so gut konfiguriert ist. Es ist schwer, sich auf die Details zu befassen, ohne mehr über den Einsatz zu wissen. Die Pipeline-Konfiguration kann auch einen großen Einfluss haben ... kein Dokument sollte jemals 5-8 Stunden dauern. Stellen Sie sicher, dass Sie alle SearchExport- oder HTMLEXport -Stufen mit benutzerdefinierten Instanzen durch ein vernünftiges Timeout (30-60 Sek.) Ersetzen - Standardeinstellung ist keine Auszeit.

Letzter Punkt ... Die Wahrscheinlichkeit besteht darin, dass die Pipeline, egal wie Ihre Fütterung konfiguriert ist, in einigen Dokumenten fehlerhaft wird. Sie müssen bereit sein, das entweder zu akzeptieren oder nur die Metadaten zu befriedigen (es gibt andere Optionen, aber hier außerhalb des Rahmens).

viel Glück.

Andere Tipps

Zunächst sollten Sie die Aufgaben für ein solches Problem verwenden.
Sie können mit Synchronisation, Async, im Thread-Pool usw. und viel billigerer Speicher als Modelle mit Thread-Sperrung gestartet werden.

Ich denke, die Task.continueWith passt perfekt zu Ihrem Problem.

Der Algorithmus sieht aus wie:

  1. Sammeln Sie eine Warteschlange mit Daten, die Sie veröffentlichen müssen.
  2. Starten Sie eine Aufgabe (oder Aufgaben, wenn Sie riskant sind :) Das nimmt das schwerere Objekt aus der Warteschlange (und das kleinste Objekt von der anderen Seite) und starten Sie es hoch.
  3. Erstellen Sie eine Methode für das Ende des Hochladens, die eine neue Aufgabe für das neue Warteschlangenelement startet.
  4. Sie können Stornierungsstoken für die Zeitüberschreitungen verwenden.
  5. Jedes Mal, wenn Sie definieren können, welches Element das System Fehler erhalten.

Können Sie einfach einen Masseneinsatz direkt in der Datenbank verwenden? Wenn nicht, schlage ich vor, dass Sie mit dem Anbieter des Drittanbieters zusammenarbeiten, damit Sie gemeinsam eine funktionsfähige Lösung formulieren können.

Die Datenbank, wie Sie beschrieben haben, ist unbrauchbar. Sie könnten einige Arbeiten finden, aber Sie werden in Zukunft ähnliche große Probleme treffen. ~ 10 GB einen Tag dauern, um zu transferieren, und zufällige Reindexing klingt absurd.

Mein Rat wäre, entweder zu fordern, dass Ihr Anbieter die Datenbank in einem verwendbaren Zustand erhält (die Fehler beheben), oder dass er Ihnen einen Datenextrakt liefert und Sie Ihre eigene Datenbank erstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top