Was ist der beste IPC-Mechanismus für mittelgroße Daten in Perl?

7

Ich arbeite an der Entwicklung einer mehrstufigen App in Perl und ich frage mich, welche Vor- und Nachteile die verschiedenen IPC-Mechanismen haben, die mir zur Verfügung stehen. Ich versuche, mittelgroße Daten zu verarbeiten, normalerweise ein paar Dutzend Kilobyte, aber bis zu ein paar Megabyte, und die Last ist ziemlich gering, höchstens ein paar hundert Anfragen pro Minute.

Meine Hauptanliegen sind Wartbarkeit und Leistung (in dieser Reihenfolge). Ich denke nicht, dass ich auf mehr als einen Server skalieren oder einen Port von unserer Hauptplattform (RHEL) portieren muss, aber ich nehme an, dass es etwas zu beachten ist.

Ich kann mir folgende Optionen vorstellen:

  • Temporäre Dateien - Simplistic, wahrscheinlich die schlechteste Option in Bezug auf Geschwindigkeit und Speicheranforderungen
  • UNIX-Domänen-Sockets - Nicht portierbar, nicht skalierbar
  • Internet Sockets - Portabel, skalierbar
  • Pipes - Portable, nicht skalierbar (?)

Wenn man bedenkt, dass Skalierbarkeit und Portabilität nicht meine Hauptanliegen sind, muss ich mehr lernen. Was ist die beste Wahl und warum? Bitte kommentieren Sie, wenn Sie zusätzliche Informationen benötigen.

BEARBEITEN: Ich werde versuchen, mehr Details als Antwort auf ysths Fragen (Warnung, Textwand folgt) :

  • Sind Leser / Schreiber in einer Eins-zu-Eins-Beziehung oder etwas komplizierter?
  • Was möchten Sie dem Autor mitteilen, wenn der Leser nicht mehr da ist oder beschäftigt ist?
  • Und umgekehrt?
  • Welche anderen Informationen haben Sie über Ihre gewünschte Verwendung?

An dieser Stelle denke ich über einen dreistufigen Ansatz nach, aber ich bin mir nicht sicher, wie viele Prozesse ich in jeder Stufe haben werde. Ich denke, ich muss mehr Prozesse auf der linken und weniger auf der rechten Seite haben, aber vielleicht sollte ich die gleiche Anzahl auf der ganzen Linie haben:

%Vor%

Diese Namen sind immer noch generisch und werden es wahrscheinlich nicht in die Implementierung in diesen Formularen schaffen.

Der -Anforderungsmanager ist für das Abhören von Anforderungen von verschiedenen Schnittstellen verantwortlich, z. B. Webanforderungen und CLI (wo Antwortzeit wichtig ist) und E-Mail (wobei Antwortzeit weniger wichtig ist). Es führt die Protokollierung durch und verwaltet die Antworten auf die Anforderungen (die in einem Format ausgegeben werden, das dem Anforderungstyp entspricht).

Er sendet Daten über die Anfrage an die Geschäftslogik , die die Protokollierung durchführt, Autorisierung abhängig von Geschäftsregeln usw.

Die Geschäftslogik (falls erforderlich) fordert dann Daten von der Datenschicht an, die entweder (meistens) mit der internen MySQL-Datenbank oder einer anderen Datenquelle außerhalb der Kontrolle unseres Teams kommunizieren kann ( B. die primären LDAP-Server unserer Organisation oder unsere DB2-Mitarbeiterinformationsdatenbank usw.). Dies ist meist nur ein Wrapper, der die Daten einheitlich formatiert, so dass sie in der Geschäftslogik einfacher gehandhabt werden können.

Die Informationen fließen dann zur Präsentation an den Anforderungsmanager zurück.

Wenn, wenn Daten nach rechts fließen, der Leser beschäftigt ist, möchte ich für die interaktiven Anfragen einfach einen geeigneten Zeitraum warten und einen Zeitüberschreitungsfehler zurückgeben, wenn ich keinen Zugang in dieser Menge bekomme der Zeit (zB "Versuche es später noch einmal"). Bei nicht-interaktiven Anfragen (z. B. E-Mail) kann das Abfragesystem einfach verlassen und beim nächsten Aufruf erneut versuchen (was wahrscheinlich einmal pro 1-3 Minuten sein wird).

Wenn Daten in die andere Richtung fließen, sollte es keine Wartesituationen geben. Wenn einer der Prozesse beim Versuch, nach links zu reisen, gestorben ist, kann ich nur noch loggen und beenden.

Wie auch immer, das war ziemlich ausführlich, und da ich immer noch im frühen Design bin, habe ich wahrscheinlich noch einige verwirrte Ideen drin. Etwas von dem, was ich erwähnt habe, ist wahrscheinlich tangential zum Problem von welches IPC-System zu verwenden ist . Ich bin offen für andere Vorschläge zum Design, aber ich habe versucht, die Frage in ihrem Umfang begrenzt zu halten (zum Beispiel sollte ich vielleicht in Betracht ziehen, auf zwei Ebenen zu kollabieren, was für IPC viel einfacher ist). Was sind deine Gedanken?

    
Adam Bellaire 10.01.2009, 19:49
quelle

6 Antworten

4

Temporäre Dateien (und ähnliche Dinge wie eine geteilte Speicherregion) sind wahrscheinlich eine schlechte Wette. Wenn Sie Ihren Server auf einem Computer und Ihre Clients auf einem anderen Computer ausführen möchten, müssen Sie Ihre Anwendung neu schreiben. Wenn Sie eine der anderen Optionen auswählen, ist zumindest die Semantik im Wesentlichen die gleiche, wenn Sie zu einem späteren Zeitpunkt zwischen ihnen wechseln müssen.

Mein einziger richtiger Rat ist jedoch, das nicht selbst zu schreiben. Auf der Serverseite sollten Sie POE (oder Coro, etc.) verwenden, anstatt select auf dem Socket selbst auszuführen. Wenn Ihre Schnittstelle RPC-isch ist, verwenden Sie etwas wie JSON-RPC-Common / von der CPAN.

Schließlich gibt es IPC :: PubSub, das für Sie arbeiten könnte.

    
jrockway 11.01.2009, 01:11
quelle
6

Wenn Sie sich im Moment über Ihre genauen Anforderungen nicht im Klaren sind, versuchen Sie sich eine einfache Schnittstelle vorzustellen, die Sie programmieren können, die beliebige IPC-Implementierung (seien es temporäre Dateien, TCP / IP oder was auch immer) muss unterstützen. Sie können dann einen bestimmten IPC-Geschmack wählen (ich würde mit dem beginnen, was am einfachsten und / oder am einfachsten zu debuggen ist - wahrscheinlich temporäre Dateien) und die Schnittstelle damit implementieren. Wenn dies zu langsam ist, implementieren Sie die Schnittstelle mit z. TCP / IP. Die Implementierung der Schnittstelle erfordert nicht viel Arbeit, da Sie im Wesentlichen nur Aufrufe an eine vorhandene Bibliothek weiterleiten.

Der Punkt ist, dass Sie eine High-Level-Aufgabe durchführen müssen ("Daten von Programm A zu Programm B übertragen"), die mehr oder weniger unabhängig von den Einzelheiten ist, wie sie ausgeführt wird. Wenn Sie eine Schnittstelle und eine Kodierung einrichten, isolieren Sie das Hauptprogramm von Änderungen für den Fall, dass Sie die Implementierung ändern müssen.

Beachten Sie, dass Sie keine schwergewichtigen Perl-Sprachmechanismen verwenden müssen, um die Idee einer Schnittstelle zu nutzen. Du könntest einfach z.B. 3 verschiedene Pakete (für temporäre Dateien, TCP / IP, Unix-Domain-Sockets), von denen jeder die gleiche Menge von Methoden exportiert. Wenn Sie auswählen, welche Implementierung Sie in Ihrem Hauptprogramm verwenden möchten, wählen Sie das Modul use .

    
j_random_hacker 11.01.2009 04:40
quelle
4

Temporäre Dateien haben andere Probleme. Ich denke, Internet-Socken sind wirklich die beste Wahl. Sie sind gut dokumentiert und, wie Sie sagen, skalierbar und portabel. Auch wenn das keine Grundvoraussetzung ist, bekommen Sie es fast kostenlos. Sockets sind ziemlich einfach zu handhaben, wieder gibt es reichlich Dokumentation. Sie können Ihren Data-Sharing-Mechanismus und das Protokoll in einer Bibliothek aufbauen und müssen sich nie wieder darum kümmern!

    
BobbyShaftoe 10.01.2009 20:13
quelle
3

UNIX-Domänen-Sockets sind über Units hinweg portierbar. Es ist nicht weniger portabel als Rohre. Es ist auch effizienter als IP-Sockets.

Wie auch immer, Sie haben einige Optionen verpasst, zum Beispiel den gemeinsamen Speicher. Einige würden Datenbanken zu dieser Liste hinzufügen, aber ich würde sagen, das ist eine ziemlich schwergewichtige Lösung.

Nachrichtenwarteschlangen wären auch eine Möglichkeit, obwohl Sie eine Kerneloption ändern müssten, um so große Nachrichten verarbeiten zu können. Ansonsten haben sie eine ideale Schnittstelle für viele Dinge, und IMHO werden sie sehr wenig genutzt.

Im Allgemeinen stimme ich jedoch zu, dass es besser ist, eine bestehende Lösung zu verwenden, als etwas Eigenes zu bauen. Ich kenne die Einzelheiten Ihres Problems nicht, aber ich würde vorschlagen, dass Sie sich die IPC Abschnitt von CPAN

    
Leon Timmermans 11.01.2009 01:33
quelle
2

Es gibt so viele verschiedene Optionen, weil die meisten für einen bestimmten Fall besser sind, aber Sie haben wirklich keine Informationen angegeben, die Ihren Fall identifizieren würden.

Sind Leser / Schreiber in einer Eins-zu-Eins-Beziehung oder etwas komplizierter? Was willst du mit dem Schreiber machen, wenn der Leser nicht mehr da ist oder beschäftigt ist? Und umgekehrt? Welche anderen Informationen haben Sie über Ihre gewünschte Verwendung?

    
ysth 11.01.2009 09:08
quelle
2

Für "interaktive" Anfragen (hält die Verbindung offen, während auf eine Antwort gewartet wird (asynchron oder nicht): HTTP + JSON. JSON :: XS ist wahnsinnig schnell, jeder kann alles HTTP sprechen und es ist einfach, Balance, Debug, ... zu laden.

Für Anfragen in der Warteschlange ("Bitte tun Sie dies, danke!"): Beanstalkd und Beanstalk::Client . Serialisieren Sie die Anforderungen in der Beanstalk-Warteschlange mit JSON.

Thrift könnte auch einen Blick wert sein, abhängig von Ihrer Anwendung.

    
Ask Bjørn Hansen 05.02.2009 10:03
quelle

Tags und Links