Python-Multiprocessing mit Queue vs ZeroMQ IPC

10

Ich bin damit beschäftigt, eine Python-Anwendung mit ZeroMQ zu schreiben und eine Variation des Majordomo-Musters zu implementieren, wie im ZGuide beschrieben .

Ich habe einen Makler als Vermittler zwischen einer Reihe von Arbeitern und Kunden. Ich möchte für jede eingehende Anfrage eine umfangreiche Protokollierung durchführen, aber ich möchte nicht, dass der Broker Zeit damit verschwendet. Der Broker sollte diese Protokollierungsanforderung an etwas anderes übergeben.

Ich habe mir zwei Möglichkeiten ausgedacht:

  1. Erstellen Sie Worker, die nur für die Protokollierung vorgesehen sind, und verwenden Sie den ZeroMQ IPC-Transport
  2. Verwenden Sie Multiprocessing mit einer Warteschlange

Ich bin mir nicht sicher, welches besser oder schneller ist. Mit der ersten Option kann ich die aktuellen Worker-Basisklassen verwenden, die ich bereits für normale Worker verwende. Die zweite Option scheint jedoch schneller zu implementieren zu sein.

Ich hätte gerne Ratschläge oder Kommentare zu den oben genannten oder möglicherweise eine andere Lösung.

Imraan
quelle

Antworten:

4

Ich mag den Ansatz, Standardwerkzeuge wie das von Jonathan vorgeschlagene zu verwenden. Sie haben nicht erwähnt, an welchem ​​Betriebssystem Sie arbeiten, aber eine andere Alternative, die diesem Geist folgt, könnte darin bestehen, das Standard-Protokollierungsmodul von Python zusammen mit logging.handlers.SysLogHandlerdem Protokollierungsdienst zu verwenden und die Protokollierungsnachrichten an den rsyslog- Dienst zu senden (verfügbar unter Linux / Unix, aber ich Ich denke, es gibt auch eine Windows-Option , aber ich habe diese nie verwendet.

Im Wesentlichen implementiert das gesamte System dasselbe, an das Sie denken. Ihr lokaler Prozess stellt eine Protokollnachricht in die Warteschlange, die von einer anderen Person verarbeitet werden soll. In diesem Fall ist jemand anderes ( rsyslog) ein bekannter, bewährter Dienst, der über viele integrierte Funktionen und Flexibilität verfügt.

Ein weiterer Vorteil dieses Ansatzes besteht darin, dass sich Ihr Produkt viel besser in andere Sysadmin-Tools integrieren lässt, die auf Syslog basieren. Und Sie müssten nicht einmal Code schreiben, um diese Option zu erhalten.

DXM
quelle
1
+1 für einen Vorschlag, der eine Neuerfindung des Rades vermeidet. Es würde mir nichts ausmachen, ein so entworfenes System zu erben. Es erledigt die Arbeit gut und bietet dennoch viele Freiheitsgrade für zukünftige Änderungen.
Evadeflow
2

Möglicherweise möchten Sie eine dritte Möglichkeit für die Implementierung der Remote-Protokollierung in Betracht ziehen. Wenn Sie das Standard-Python-Protokollierungsmodul verwenden, können Sie die logging.QueueHandlerKlasse in Ihren Workern, Clients und Brokern sowie die logging.QueueListenerKlasse in Ihrem Remote-Protokollierungsprozess verwenden.

Anstatt das normale Python multiprocessing.Queueals Transportmittel zwischen Ihren Anwendungsprozessen und Ihrem Protokollierungsprozess zu verwenden, implementieren Sie Ihre eigene QueueErsatzklasse mithilfe von ZeroMQ mit Ententypisierung, damit Ihre Klasse ein Ersatz für das Standard-Python ist Queue. Auf diese Weise kann Ihre Anwendung in jeder Umgebung unverändert von einem einzelnen Multi-Core-Computer über verteilte Rechenzentren ausgeführt werden.

Um es zusammenzufassen, verwenden Sie einen Standard-Python-Logger mit einem QueueHandlerin all Ihren Mitarbeitern, Kunden und Brokern und erstellen Sie einen unabhängigen Prozess basierend auf QueueListenerund den Python- loggingHandlern Ihrer Wahl, um das schwere Heben der Protokollierung zu bewältigen.

Jonathan
quelle
Ich benutze Python 2.7. Ich glaube, dass die QueueHandler-Klasse nur in Python 3.2 verfügbar ist.
Imraan
Es wäre sehr einfach, den Code aus Python 3 zu übernehmen und direkt als Teil Ihrer App zu verwenden.
Jonathan
Ich werde das versuchen und Sie wissen lassen, ob es funktioniert
Imraan
0

Hierbei handelt es sich um radikal unterschiedliche Ansätze mit jeweils eigenen Vor- und Nachteilen, die Sie höchstwahrscheinlich in einem späteren Entwicklungsstadium feststellen werden:

Ich habe mir zwei Möglichkeiten ausgedacht:

  1. Erstellen Sie Worker, die nur für die Protokollierung vorgesehen sind, und verwenden Sie den ZeroMQ IPC-Transport
  2. Verwenden Sie Multiprocessing mit einer Warteschlange

Eine Möglichkeit, die Sie versuchen können, besteht darin, einen zusätzlichen Protokollierungs-Worker wie in Ansatz 1 zu haben. Sie können Ihre Mitarbeiter in einem Memcache-Protokollierungscluster protokollieren lassen, und der Protokollierungs-Worker überwacht die aktuelle Ressourcenlast und bei Überschreitung eines bestimmten Ressourcenladeparameters den Der Worker meldet sich bei einem Gerät mit eingeschränktem IOP (z. B. Festplatte) an.

Ich mag auch Jonathans Ansatz mit der Einschränkung, dass auch ich meistens Python 2.x verwende und dass Sie wahrscheinlich Ihr eigenes Protokollierungs-Backend einrichten müssten, um den Leistungsumfang wirklich zu verbessern.

Korrigieren Sie mich, wenn ich falsch liege, aber ich gehe davon aus, dass Sie eine wirklich datenintensive Aufgabe ausführen, wobei Speicher-IOPs Ihr Engpass sind.

Ein bequemer Weg wäre immer noch, den Broker die brokerageProtokollierung - in der beschriebenen Form - mit allen Nachteilen einer zentralen Brokerinstanz durchführen zu lassen. Wenn der Broker beispielsweise so stark nachgefragt wird, dass er nie mehr Luft zum Schreiben der zwischengespeicherten Protokolle in den Speicher bekommt, müssen Sie einen anderen Ansatz wählen.

Sie können letztendlich mit einem Modell ohne Makler enden. Das ist mit den Arbeitern, die ihre Arbeit untereinander verwalten. In einem einfachen Beispiel durch einen verteilten Round-Robin- Algorithmus.

Lorenz Lo Sauer
quelle