7 Stimmen

Bestes Nebenläufigkeits-Framework für Datenübertragungen mit geringer Latenz und hoher Durchsatzrate auf einer einzelnen Maschine

Ich suche nach Ideen, wie ein Nebenläufigkeits-Framework für meine spezifische Architektur implementiert werden könnte, unter Verwendung von C#:

Ich habe mehrere Module/Container (implementiert als Klassen) erstellt, die alle individuell eine Verbindung zu einem Nachrichtenbus herstellen sollen. Jedes Modul produziert hauptsächlich oder konsumiert hauptsächlich, aber alle Module implementieren auch ein Anfrage/Antwort-Muster für die Kommunikation zwischen zwei bestimmten Modulen. Ich bin ganz neu in der Nebenläufigen und asynchronen Programmierung, möchte aber im Grunde genommen die gesamte Architektur nebeneinander laufen lassen, anstatt synchron. Ich würde mich sehr über Hinweise freuen, welche Technologie (TPL, ThreadPool, CTP, Open-Source-Bibliotheken usw.) für meinen spezifischen Anwendungsfall in Betracht gezogen werden sollte, basierend auf den folgenden Anforderungen:

  • Das gesamte System läuft nur auf einem lokalen Rechner (im Prozess, auch der Nachrichtenbus)
  • Mindestens ein Modul führt intensive E/A-Vorgänge durch (liest mehrere Millionen 16-Byte-Nachrichten pro Sekunde von einem physischen Laufwerk) und veröffentlicht während der gesamten Zeit mehrere 16-Byte-Chunks an eine blockierende Sammlung.
  • Ein anderes Modul konsumiert die Informationen aus der blockierenden Sammlung während der gesamten Zeit.
  • Der Einstiegspunkt ist der Produzent, der beginnt, Nachrichten zu versenden, und beendet den Vorgang, wenn der Produzent eine endliche Menge von 16-Byte-Nachrichten veröffentlicht hat.
  • Die einzige Kommunikation, die den Nachrichtenbus umgeht, ist die Veröffentlichung/von der blockierenden Sammlung aus zu konsumieren aus Gründen der Durchsatz- und Reaktionszeit. (Ich bin bereit, Vorschläge anzuhören, um den Nachrichtenbus loszuwerden, wenn dies möglich ist)
  • Andere Module führen Operationen wie Schreiben in eine SQL-Datenbank, Veröffentlichen an einen GUI-Server, Verbinden mit APIs, die mit externen Servern kommunizieren, durch. Solche Operationen laufen seltener/geregelt und könnten potenziell als Aufgaben ausgeführt werden, anstatt durchgehend einen ganzen Thread während des Betriebs des Systems zu nutzen.
  • Ich betreibe eine Maschine mit 64-Bit, Quad-Core und 16 GB Arbeitsspeicher, aber idealerweise möchte ich eine Lösung implementieren, die auch auf einer Dual-Core-Maschine laufen kann.

Basierend darauf, was ich verwalten möchte, auf welche Nebenläufigkeits-Implementierung würden Sie empfehlen, dass ich mich fokussieren sollte?

EDIT: Ich möchte betonen, dass das größte Problem, dem ich gegenüberstehe, ist, wie ich jedes Behälter/Modul bequem mit einem Thread/Aufgaben-Pool verknüpfen kann, so dass jedes Modul asynchron ausgeführt wird und dennoch eine vollständige Ein- und Aus-Kommunikation zwischen solchen Modulen bereitstellt. Ich mache mir nicht allzu große Sorgen darüber, ein einzelnes Produzenten-/Konsumentenmuster zu optimieren, bevor ich nicht das Verknüpfungsproblem aller Module mit einer nebeneinander laufenden Plattform gelöst habe, die die Anzahl der dynamisch beteiligten Aufgaben/Threads bewältigen kann.

2voto

Matt Punkte 6540

Ich habe n-act http://code.google.com/p/n-act/ gefunden, ein Actors-Framework für .Net, das ziemlich genau das umsetzt, wonach ich suche. Ich habe in meiner Frage beschrieben, dass ich nach Framework-Empfehlungen für das Gesamtbild suche und es scheint mir, dass ein Actor-Framework das löst, was ich brauche. Ich sage nicht, dass die n-act-Bibliothek das ist, was ich implementieren werde, aber es ist ein interessantes Beispiel dafür, wie man Schauspieler einrichten kann, die asynchron kommunizieren können und auf ihren eigenen Threads laufen können. Die Nachrichtenübermittlung unterstützt auch die neue C#5 async/await-Funktionalität.

Disruptor wurde oben erwähnt, ebenso wie die TPL und ein paar andere Ideen, und ich schätze die Beiträge sehr. Es hat mich tatsächlich zum Nachdenken gebracht und ich habe ziemlich viel Zeit damit verbracht zu verstehen, was jede Bibliothek/framework zu erreichen versucht und welche Probleme sie zu lösen versucht, also waren die Beiträge sehr fruchtbar.

Für meinen speziellen Fall glaube ich jedoch, dass das Actors-Framework genau das ist, was ich brauche, weil mein Hauptanliegen der Austausch von asynchronem Datenfluss ist. Leider sehe ich das Actor-Modell noch nicht in einer .Net-Technologie implementiert (bisher). TPL Dataflow sieht sehr vielversprechend aus, aber wie Weismat angemerkt hat, ist es noch nicht vollständig einsatzbereit.

Wenn sich herausstellt, dass N-Act nicht stabil oder verwendbar ist, werde ich nach einer benutzerdefinierten Implementierung durch die TPL suchen. Es wird sowieso Zeit, all das zu verstehen, was die TPL zu bieten hat, und bereits in der Entwurfsphase gleichzeitig zu denken, anstatt zu versuchen, synchrone Modelle in ein asynchrones Framework zu übertragen.

Zusammenfassend gesagt, war das "Actor-Modell" das, wonach ich gesucht habe.

1voto

Gabe Punkte 82268

Ich empfehle disruptor-net für eine Aufgabe wie diese, bei der Sie eine hohe Durchsatzleistung, geringe Latenzzeiten und einen gut definierten Datenfluss haben.

Wenn Sie bereit sind, etwas Leistung für die Thread-Verwaltung zu opfern, könnte TPL Dataflow für Sie funktionieren. Es macht einen guten Job bei der Verwendung von TPL für die Aufgabenplanung.

0voto

weismat Punkte 6931

Sie sollten sich auch Concurrency and Coordination_Runtime ansehen, wenn Sie nach einer auf Framework basierenden Lösung für nebenläufige Prozesse suchen. Ich denke, das könnte gut zu Ihren Designideen passen.
Ansonsten würde ich der Regel folgen, dass Threads verwendet werden sollten, wenn etwas über die gesamte Laufzeit Ihrer Anwendung hinweg ausgeführt wird, und Tasks für kurzzeitig laufende Prozesse.
Ich glaube, es ist wichtiger, dass die Verantwortlichkeiten für die Nebenläufigkeit klar definiert sind, sodass Sie das Framework später möglicherweise ändern können.
Wie üblich beim Schreiben von schnellem Code gibt es keine Faustregeln, sondern die Notwendigkeit, viel mit kleinen Stubs zu testen und die tatsächliche Leistung zu messen.

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