2 Stimmen

Nachrichten mit Threads effizient verarbeiten?

Ich brauche Hilfe bei der Gestaltung eines Nachrichtenverteilungssystems. Bislang habe ich 2 Prozesse, einen, der auf entfernte Clients wartet, um Nachrichten zu übermitteln, die dann in eine Datenbanktabelle geschrieben werden.

Ich habe dann einen zweiten Prozess, der liest aus dieser gleichen Tabelle alle [n] Sekunden, immer bis zu 100 Nachrichten in einem einzigen lesen, und wenn alle neuen Datensätze, Warteschlangen jeder auf seine eigenen ThreadPool ausgegeben backgorund Thread gesendet werden.

Wenn mehr Nachrichten als Threads verfügbar sind, stellt der ThreadPool alle Nachrichten, die über seine maximale Thread-Anzahl hinausgehen, in eine Warteschlange. Wenn keine Nachrichten vorliegen, geht er wieder in den Ruhezustand über und wartet auf das nächste Timer-Ereignis, das ihn für eine weitere Überprüfung der Datenbanktabelle aufweckt.

Das Problem ist, dass in einem Intervall sehr viele Nachrichten eintreffen können: Es wäre weitaus besser, sie in der Datenbank zu belassen, bis sie benötigt werden, als sie im Speicher in einer Warteschlange im ThreadPool zu speichern.

Mit anderen Worten, ich bin auf der Suche nach einer eleganten Art und Weise zu wissen, wann es ok ist, mehr Threads in der Warteschlange hinzuzufügen, anstatt einfach bis zum nächsten Timer-Intervall zu warten...

Eine Idee, die ich hatte, war zu zählen, wie viele Worker-Threads ich in der Warteschlange hatte (z. B. 500, gleich der maximalen Anzahl von Threads, die ich zuerst eingerichtet hatte), und sie zu zählen, wenn sie abgeschlossen sind. Wenn sie unter 1/2 fallen (z. B. 250), eine Db-Prüfung erneut auslösen. Wenn Datensätze gefunden werden, super, hole 100 auf einmal, bis die Db-Tabelle komplett gelesen ist oder die 500er Grenze wieder erreicht ist.

Mit anderen Worten, das Hauptaugenmerk beim Dequeuing liegt auf den Threads selbst, die sich kontinuierlich selbst starten, und nicht auf dem Timer (das Timer-Intervall dient nur als Mechanismus, um den Prozess neu zu starten, falls die Pipe austrocknet).

Hat jemand Ratschläge/Bemerkungen/Erfahrungen mit einem solchen System? Ist der Ansatz solide? Oder hat es gravierende Mängel?

1voto

AndrewS Punkte 3356

Ich habe festgestellt, dass die mit dem Threading verbundenen Overheads, wie z. B. das Kontext-Switching, die Verwendung von Threads schnell zu Lasten der Leistung gehen können. Auch, es sei denn, Ihre Threads verbringen eine Menge Zeit warten auf IO usw., gibt es keinen wirklichen Sinn in mehr Threads als Sie CPUs (oder Kerne) haben.

Wenn man also davon ausgeht, dass man tatsächlich Threads zur Verarbeitung der Daten benötigt, kann man vielleicht eine Handvoll Threads erstellen. Jeder Thread fragt die Datenbank ab, um ein Datenpaket zu holen (vielleicht auf 100 Zeilen gleichzeitig begrenzt) und verarbeitet es. Wenn die Verarbeitung abgeschlossen ist, versucht er, ein weiteres Datenpaket zu erhalten. Sie müssen den Datenzugriff synchronisieren (d. h. die zuletzt abgerufene Zeilen-ID synchronisieren) und benötigen einen Zeitgeber, falls die Threads alle verfügbaren Daten verarbeiten und dann schlafen. Bei diesem Ansatz wird davon ausgegangen, dass die Datenverarbeitung wesentlich länger dauert als der Datenbankzugriff.

Und vor allem: Sind Sie sicher, dass Sie überhaupt Fäden brauchen? Ich würde sagen, dass es am besten ist, es ohne Threads zum Laufen zu bringen und dann später zu optimieren, falls nötig. Das ist die wichtigste Lektion, die ich über Threads (auf die harte Tour) gelernt habe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X