Hallo jerch, Danke für deine Antwort!
jerch hat geschrieben:Kannst Du bitte nochmal genauer beschreiben was Dein Programm machen soll? Willst Du zeitgleich die pcap-Daten vom Netzwerk nativ erhalten (sniffen) und in die DB schreiben/lesen? Ich bin aus Deiner Beschreibung leider nicht ganz schlau geworden.
Mein Programm soll ein Ethernet-Protokoll-Logger eines firmenintern verwendeten (auf UDP aufbauenden) Netzwerkprotokolls werden.
Dazu sollte permanent auf der Netzwerkschnittstelle den Datenverkehr mitgelesen, dann gefiltert, die interessanten Daten extrahiert und schlussendlich die Information in die Datenbank eingefügt werden. Gleichzeitig soll aber der Benutzer den ganzen (!) Datenstrom in einem Qt-Steuerelement (wie z.B. QTableView) anschauen, filtern sowie hin- und herscrollen können. Deshalb war mein erster Ansatz der von verschiedenen Pipes/Threads, da ja jede einzelne Stufe ihre Rechenzeit benötigt und ich auf keinen Fall die Oberflächendarstellung blockieren wollte. In Kombination mit dem GIL hat das aber anscheinend unberechenbare Folgen, denn genau das passiert nun.
jerch hat geschrieben:Ein Frage vorweg, nutzt oder brauchst Du die Relationen später, die Dir ein SQL-DBMS bietet? Wenn ja, brauchst Du eine skalierbare Lösung, die den Verwaltungsaufwand zeitnah erschlagen kann (Wie hoch ist das Datenaufkommen/Zeit? Kann Dein jetziges System das noch ohne Drops abarbeiten?). Sqlite ist da nicht die beste Wahl, da gerade Inserts für DBs>1GB extrem langsam werden. Bis hin zu einem Oracle/DB2-Cluster wäre hier alles denkbar.
Solltest Du die Relationen nicht brauchen (danach sieht Dein Code derzeit aus), ist eine performante "Datenhalde" das Mittel der Wahl. Beispiele hierfür wären key-value DBs. Diese sind bieten meist auch eine hohe Skalierbarkeit (bei vgl. geringeren Anforderungen gegenüber den relationalen DBMSen). Das HDF5 kenne ich leider nicht, in wie weit dies Deinen Anforderungen gerecht wird, beantwortet Dir sicherlich die Spezifikation.
Relationen brauche ich eigentlich nicht, es handelt sich nur um Datenfelder wie "Timestamp", "IP-Src", "IP-Dest" und "Data" (Größe variabel zwischen wenigen Byte und bis zu einem Megabyte, das könnte auch ein Problem sein, insofern nur statische Datenfeldgrößen möglich wären)
Über Key-Value-Datenbanken hab ich noch überhaupt nicht nachgedacht, welche Lösungen wären in diesem Feld empfehlenswert? Ich muss gestehen dass ich bis jetzt immer mit relationalen Datenbanken wie MySQL oder SQLite gearbeitet habe. SQLite hab ich nun ganz abgehackt da dies aus vielen verschiedenen Gründen Probleme bereitet.
CouchDB hab ich mir auch mal angesehen, das ist aber in diesem Fall auch die falsche Wahl, soweit ich das bis jetzt beurteilen konnte.
Eine schlanke, threadsichere und hochskalierbare Key-Value-Datenbank wäre ideal!
jerch hat geschrieben:Für mich hört sich Dein jetziger Ansatz so an, als wolltest Du viele Dinge parallel in Threads abarbeiten. Das geht in Python leider nicht, wie Du es vllt. von anderen Sprachen her kennst, da Python die Ausführung von Threads mittels des global interpreter lock (GIL) koordiniert und die Ausführung von Pythoncode auf einen aktiven Thread beschränkt. Braucht ein Aufruf innerhalb eines Threads zu lange, werden die anderen mit ausgebremst. Ausnahme sind hier viele low-level-Funktionen (z.B. time.sleep) die den GIL freigeben.
Die Problematik des GILs war mir zumindest ansatzweise bewusst, ich dachte aber erst, dass auch der Zugriff auf die libpcap den Gil freigibt, da es sich hierbei um eine IO-Operation handelt.. Dem ist aber leider nicht so, es wird ja nur die libpcap verwendet, was eine C-Funktion ist und solcherart C-Funktionen waren ja soweit ich weiß, der Grund warum der GIL überhaupt notwendig war.
jerch hat geschrieben:U.a. gibt auch der Großteil der PyQt-Bibliothek den GIL frei. (Als Tip: Alles was Qt nahe threaded passiert würde ich eher mit QThread umsetzen, hat den Vorteil, dass Du das Eventsystem nutzen kannst)
Brauchst Du allerdings viel Pythoncode in den Threads, bleibt das GIL-Problem bestehen.
Interessant, das heißt es wäre von Vorteil, so viel wie möglich mit PyQt-Funktionen zu realisieren, um möglichst wenig blockierende Phasen zu haben?
Den GIL gänzlich umgehen kann man ja mit QThread auch nicht, oder? Wo liegt im Detail der Vorteil wenn man statt einem Standard [mod]threading[/mod].Thread ein QThread Objekt verwendet?
jerch hat geschrieben:Evlt. hilft Dir dann das [mod]multiprocessing[/mod]-Modul weiter.
Das wäre eine echte Alternative, eigener Prozess heißt ja eigener GIL und somit echte Parallelität. Da wäre dann nur das Problem der Interprozesskommunikation zur Datenweitergabe, oder hältst du das unter Verwendung des [mod]subprocess[/mod]-Moduls für kein Problem?
jerch hat geschrieben:Falls das alles nicht hilft, wirds hässlicher, da Du dann evtl. Teile Deiner Applikation in c auslagern oder gar über einen Wechsel der Sprache nachdenken müsstest.
Generell:
Ich bin jetzt nicht so sehr auf Deine PyQt-Problematik eingegangen, da ich glaube, dass die größeren Flaschenhälse woanders stecken (Sqlite ist hier mein Favorit). Diese Flaschenhälse solltest Du erstmal ausfindig machen (z.B. mit `time.time()` oder [mod]timeit[/mod] die Laufzeiten einzelner Programmteile bestimmen).
Vielleicht helfen Dir den Gedanken weiter und waren nicht völlig am Thema vorbei

Ja über einen Wechsel zu C habe ich auch gerade nachgedacht, ich vermisse dann allerdings die angenehmen Features von Python, sollte es nicht unbedingt notwendig sein, möchte ich schon bei Python bleiben.
Danke, deine Antwort hat mir schon sehr weitergeholfen. Ich werde mir nun den Multiprozess-Ansatz durch den Kopf gehen lassen und versuchen den jetzigen Flaschenhals zu finden, ich denke aber dass du mit deiner Vermutung, es liege an SQLite, Recht hast.