Zum Inhalt springen

Übertragen von Java-Objekten


blubbla

Empfohlene Beiträge

Hallo,

stehe vor folgendem Problem:

Ich muss über ein JMS-System ein Java-Object verschicken. Dieses ist ungefähr so aufgebaut bzw. folgende Informationen müssen Übertragen werden:


String abc;

int bcd;

.... ein paar weitere, einfache Felder ...


ValueTO[] liste1;

ValueTO[] liste2;
die beiden Listen enthalten ca. 100 Value Objecte, die wie folgt aussehen:

class ValueTO:


String xyz;

int rtz;

Object[][] value;

<- diese Value ist also ein 2-dimensionales Array, das sehr große Datenmengen transportieren könnte und entweder vom Typ int[][], String[][], double[][] oder long[][] ist.

Da ich hier erstmal an einem Prototypen rumbastle, hab ich mir bis jetzt noch keine großen Gedanken gemacht und einfach das ganze Object in eine ObjectMessage gepackt und verschickt -> es wurde einfach Serialisiert.

Nunja, das Serialisieren auf Serverseite ist relativ schnell - auf der Clientseite ist das Deserialisieren eine Katastrophe. Was meint ihr, wie könnte ich das ganze am besten angehen? Erstmal werd ich wohl versuchen, das ganze zu "Externialisieren" - also durch Implementieren des Externializable-Interface. Aber nach meinen Internet-Recherechen bringt das ganz auch "nur" ca. 20%, wass mir noch zu wenig ist.

Soll ich evtl. den Weg über XML gehen? Oder muss ich die Datenstruktur generell umstellen?

Wie gesagt, es müssen 2 Dimensionale Arrays an Werten beliebigen Typs verschickt werden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hatte ein ähnliches Problem: JMS & XML haben durchaus für große Datenmengen entsprechenden Overhead. Entweder nutzt Du eine Datenbank und hängst Dich per JDBC einfach vom Client und Server dran. Je nach Datentypen und Struktur wäre auch Hierarchical Data Format etwas zum überdenken. Ich habe, da ich 2D Matrizen vom Type byte hatte, diese in das HDF gepackt, was ich dann in der Datenbank als BLOB abgelegt hatte.

Die Frage ist, brauchst Du zwingend Java Objekte oder würde es sich anbieten nur die Daten zu transferieren und die Objekte dann zu erzeugen

Bearbeitet von flashpixx
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo, danke für die Infos.

Ich habs nun mal kurz mit Externalizable statt Serializable versucht - hat natürlich nicht sehr viel gebracht (ca. 5% - 10% maximal).

Ich würde gerne versuchen, das ganze ohne eine (gemeinsame) Datenbank zu erreichen. Durch JMS sollten die Systeme (Sender und Empfänger) eigentlich nur sehr lose gekoppelt sein, und jetzt noch eine Datenbank ins Spiel bringen... hmm ich hoffe es geht irgendwie auch anders.

Ich brauche eigentlich nur die 2D-Daten und ein paar wenige Informationen zu diesen, d.h. die Java-Objekte kann ich auch nach dem Empfangen der Daten neu konstruieren.

Eigentlich sieht es ja so aus: Die Daten kommen per SOAP-Webservice auf einem JavaEE-Server an. Dort werden ein paar Aktionen erledigt und die Daten dann anschliessend per JMS an verschiedene Empfänger versendet.

Die Umwandlung XML->Java passiert auf Serverseite sehr, sehr schnell, die Umwandlung auf dem Client Object(aus JMS Message)->Java ist extrem langsam. Vllt sollte ich doch mal probieren einfach alles als XML zu schicken? Sonst hab ich wohl nicht mehr sooo viele ALternativen, wenn ich ohne Datenbank auskommen will...

Link zu diesem Kommentar
Auf anderen Seiten teilen

JMS ist auch "nur" XML und für n-dimensionale Daten ist XML nicht geeignet, da es eine Baumstruktur ist. Zusätzlich kann man bei n-dimensionalen Strukturen durchaus überlegen, ob man evtl durch sinnvolle Skalierung sparse Strukturen verwendet, dadurch wird der Speicherplatz deutlich geringer. Bei Deinen Arrays hast Du keine sparse Strukturen, d.h. Du wirst hier eine Menge an Daten mitschleppen, die Du real nicht brauchst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmm, es stimmt natürlich dass der Overhead von XML nicht ohne ist. Ich muss aber einerseits darauf achten, dass ich jedliche Art von Daten übertragen können muss (d.h. ich kann nicht generell sagen, dass es eher dünnbesetzte Matrizen werden, wo ich noch viel optimieren könnte), ausserdem müssen diverse ältere Komponenten versorgt werden, die auf genau so eine Struktur (2D Array angewiesen sind). Deshalb auch JMS als Integrationslösung.

Zumindest bei sehr großen Datenmengen hab ich jetzt festgestellt, dass die XML-Serialisierung z.B. mit xstream einer Java-Serialisierung schon überlegen sein kann. Vllt werd ich das mal weiter verfolgen - auch wenn es natürlich nicht optimal ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

ersteinmal ein paar Fragen, die wohl eher meinem Verständnis helfen:

was hast du damit eigentlich vor? wofür ist das die Lösung?

warum weißt du denn nicht, was du bekommst?

welche Kombinationen gibt es für die Datentypen der beiden Arrays? jede Mögliche oder nur eine begrenzte Anzahl?

für die Lösung ggf. relevant:

werden die Daten auf der Clientseite tatsächlich komplett benötigt?

werden sie permanent benötigt, ohne dass weitere Abfragen notwendig sein sollen?

wie lange werden sie dort benötigt?

ggf. könntest du auf der Clientseite nicht die Objekte selbst, sondern Proxy-Objekte aufbauen (vergleichsweise zu RMI

Link zu diesem Kommentar
Auf anderen Seiten teilen

ggf. könntest du auf der Clientseite nicht die Objekte selbst, sondern Proxy-Objekte aufbauen (vergleichsweise zu RMI

Da wäre dann die Frage, ob man direkt RMI verwendet. Problematisch wäre dieses, wenn man außerhalb des Subnet kommunizieren will, denn dafür muss man dann entsprechend die Ports dann weiterleiten bzw. ACLs der Router / Firewall anpassen. RMI ist zunächst auch nicht geschützt, d.h. die Daten innerhalb der Objekte gehen unverschlüsselt über das Netz. Wenn man "nur" die Daten übertragen muss, dann wäre die Datenbank das sinnvollste + ein Proxy Objekt. Ggf könntest Du noch einen "klassisches" Webservice nehmen, da Du hier die Daten über "Standardports" überträgst, die Datenbank nur von dem Rechner, der den Webservice bereit stellt zugänglich sein muss und Du verschlüsselt (https) kommunizieren kannst. Wenn DU das dann via WSDL beschreibst, kannst Du direkt die Proxyobjekte erzeugen

Bearbeitet von flashpixx
Link zu diesem Kommentar
Auf anderen Seiten teilen

ersteinmal ein paar Fragen, die wohl eher meinem Verständnis helfen:

was hast du damit eigentlich vor? wofür ist das die Lösung?

Es geht - vereinfacht gesagt - darum, eine Middleware, die auf CORBA basiert, durch eine JavaEE Lösung zu ersetzen. Der Hauptgrund ist neben der großen Verbreitung von Webservices (die mit JavaEE sehr einfach angeboten werden können, mit CORBA und in der bestehenden Lösung nicht sehr schön umgesetzt sind) die Durchführung von verteilten Transaktionen. Aber das spielt glaub ich für die Problemstellung keine große Rolle. Hmm, also es ist so: Clients sammeln Daten und schicken sie an die Middleware. Dort wird die Transaktionsteuerung eingeleitet etc, und die Daten werden dann an verschiedene "Applikationen" verschickt. Diese Applikationen führen mit den Daten dann Funktionsaufrufe auf einer dll aus und berechnen verschiedene Sachen. Diese Antwortdaten gehen zurück an den Server, der sie wiederum als Webservice-Response an die Clients zurückschickt.

warum weißt du denn nicht, was du bekommst?

welche Kombinationen gibt es für die Datentypen der beiden Arrays? jede Mögliche oder nur eine begrenzte Anzahl?

Es sind 2D Matrizen, die mit beliegen Java-Datentypen gefüllt sind (also String[][], double[][] etc.).

Die Matrizen sind ausserdem benannt (also z.B. WertA = double[10][500], WertB = String[10][5] etc.)

für die Lösung ggf. relevant:

werden die Daten auf der Clientseite tatsächlich komplett benötigt?

werden sie permanent benötigt, ohne dass weitere Abfragen notwendig sein sollen?

wie lange werden sie dort benötigt?

ggf. könntest du auf der Clientseite nicht die Objekte selbst, sondern Proxy-Objekte aufbauen (vergleichsweise zu RMI

Link zu diesem Kommentar
Auf anderen Seiten teilen

um nochmal festzuhalten, wie ich das bisher verstanden habe:

der Client (vermutlich eine andere Anwendung, wobei das aber irrelevant ist) ruft deinen Webservice auf und übergibt die Daten

dieser soll dann die Daten an einen anderen Webservice (?) weiterreichen (das scheint die knifflige Stelle zu sein), welcher die Daten verarbeitet und zurück gibt

letztendlich wird das Ergebnis dann an den Client zurückgegeben und die Verbindung zu diesem beendet

da eine DLL, also nativer Code, für die Verarbeitung verwendet wird, wären Proxy-Objekte also eher nicht die passende Wahl (da beim Aufruf der DLLs vermutlich der gesamte Inhalt der Matrizen übergeben werden muss)

bezüglich Sicherheit spricht grundsätzlich nichts gegen Proxys, da diese auch verschlüsselte Kommunikation ermöglichen könnten

es scheint also, als müsse wirklich die Serialisierung bzw. Deserialisierung angegangen werden

XML-Dateien sind nicht grundsätzlich ungeeignet, allerdings kann man ihren "großen Vorteil" bzw. den Haupt-Einsatzgrund nicht richtig ausnutzen:

man dürfte die Matrizen nicht mit Hilfe von XML-Elementen darstellen, sondern rein textuell

HDF habe ich bisher nur überflogen, weshalb ich dazu nicht viel sagen kann (und nicht sagen kann, ob es besser als meine nachfolgende Idee ist)

evtl. ist es nicht notwendig, das Dateisystem zu verwenden, sondern es ist evtl. ja möglich, einen beliebigen Datenstrom zu verwenden

das könnte entweder direkt die Verbindung zum Zielsystem für die Daten sein, oder in einen Stream, der ein String-Objekt erzeugt

du könntest dir selbst eine Methode zur Serialisierung (und Deserialisierung) schreiben, welche ein Object-Array-Array entgegen nimmt

bei den primitiven Datentypen (int, double, boolean, ...) könntest du einfach die textuelle Repräsentation verwenden, bei Zeichenketten müsstest du erst entsprechende Zeichen (Steuerzeichen, andere Zeichen wie <, > und & und die "Aufzählungszeichen") maskieren (entweder mit einem Backslash und dem Zeichencode oder mit & und ;, wie es bei XML/HMTL-Texten gemacht wird)

um die Größe zu kennzeichnen, musst du 2 Werte mitgeben (Breite und Höhe) und die einzelnen Werte voneinander mit einem oder 2 Zeichen abgrenzen

allerdings kann ich auch nicht sagen, ob das performanter ist, als deine bisherigen Versuche

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es geht - vereinfacht gesagt - darum, eine Middleware, die auf CORBA basiert, durch eine JavaEE Lösung zu ersetzen.

Eine Middleware ist sicher immer eine Überlegung wert, aber durch die Middleware holt man sich immer einen gewissen Overhead hinzu. Evtl wäre hier die Überlegung, ohne Middleware zu arbeiten. Gerade wenn es hier um sehr große mehrdimensionale Datenmengen geht, würde ich davon abraten.

Clients sammeln Daten und schicken sie an die Middleware. Dort wird die Transaktionsteuerung eingeleitet etc, und die Daten werden dann an verschiedene "Applikationen" verschickt. Diese Applikationen führen mit den Daten dann Funktionsaufrufe auf einer dll aus und berechnen verschiedene Sachen. Diese Antwortdaten gehen zurück an den Server, der sie wiederum als Webservice-Response an die Clients zurückschickt.

Die Frage hier wäre, über welche Datenmengen reden wir und welche Art von Berechnungen finden statt. Evtl wäre auch eine P2P Lösung eine Möglichkeit.

Es sind 2D Matrizen, die mit beliegen Java-Datentypen gefüllt sind (also String[][], double[][] etc.).

Die Matrizen sind ausserdem benannt (also z.B. WertA = double[10][500], WertB = String[10][5] etc.)

Was die Berechnung angeht, würde ich hier die Frage stellen, ob es überhaupt notwendig ist, dass ein Client immer eine komplette Matrix erhalten muss. Wenn man die Matrix von a nach b übertragen muss und dann immer mit der kompletten Matrix arbeitet, dann ist das recht ineffizient. Evtl wäre es sinnvoller den Algorithmus, der die Matrix verarbeitet an zu passen, so dass nur mit Patches (Blöcke) der Matrix gearbeitet werden muss. Somit kann die Matrix auf mehrere Clients verteilt werden und das Ergebnis muss dann nur später einmal zusammen gefügt werden. Das ganze als P2P ermöglich dann auch eine lose Kopplung.

Was HDF angeht: ich habe mir das gestern und heute mal angeschaut - sieht sehr interessant aus und von der Performance her natürlich in einer anderen Liga, wenn es um große Datenmengen geht.

Ja, vor allem weil HDF ebenso Message Passing Interface unterstützt, somit kann man auf die Hyperslaps innerhalb des Formates von unterschiedlichen Prozesses schreib/lesend zugreifen.

Ist es auch möglich, mit HDF Objekten nur im Speicher zu arbeiten - ohne ein HDF4/5 File zu beschreiben? Da ich das ganze gerne auf einem Applikationsserver ausprobieren würde, wäre es schon praktisch wenn es ohne Filesystem klappt.

Was spielt das für eine Rolle? HDF wäre dafür geeignet die Daten strukturiert zu speichern. Der Datentransfer muss natürlich über ein anderes Protokoll statt finden.

um nochmal festzuhalten, wie ich das bisher verstanden habe:

der Client (vermutlich eine andere Anwendung, wobei das aber irrelevant ist) ruft deinen Webservice auf und übergibt die Daten

dieser soll dann die Daten an einen anderen Webservice (?) weiterreichen (das scheint die knifflige Stelle zu sein), welcher die Daten verarbeitet und zurück gibt letztendlich wird das Ergebnis dann an den Client zurückgegeben und die Verbindung zu diesem beendet

Wenn das der Fall ist, ist das letztendlich eine Kaskade von Webservices. Ich würde davon wirklich abraten, denn entweder kann man die einzelnen Clients via P2P lose koppeln, so dass die Clients letztendlich die Berechnung untereinander aushandeln. Ansonsten würde ich dann zu einem eher klassischen Ansatz gehen und einen Webservice nehmen, der die Daten entgegen nimmt und hinter dem Webservice einen HPC (Hochleistungsrechnen) erzeugen, den ich dann via MPI steuere. Wobei ich aber hier direkt sage, dass ich von einer Javaabasierten Lösung dann direkt absehen würde und die Berechnung direkt passend in C/C++ implementieren würde und über JNI an die Java Komponente anhängen würde (alternativ ginge auch dort sicherlich etwas anderes).

da eine DLL, also nativer Code, für die Verarbeitung verwendet wird, wären Proxy-Objekte also eher nicht die passende Wahl (da beim Aufruf der DLLs vermutlich der gesamte Inhalt der Matrizen übergeben werden muss)

bezüglich Sicherheit spricht grundsätzlich nichts gegen Proxys, da diese auch verschlüsselte Kommunikation ermöglichen könnten

Das stellt kein Problem dar, ich arbeite selbst mit Java, JNI und Boost C++ Libraries und kann dort habe ich keine Probleme große Datenmengen von Java in die entsprechenden C++ Strukturen zu portieren und dann dort zu verarbeiten.

es scheint also, als müsse wirklich die Serialisierung bzw. Deserialisierung angegangen werden

XML-Dateien sind nicht grundsätzlich ungeeignet, allerdings kann man ihren "großen Vorteil" bzw. den Haupt-Einsatzgrund nicht richtig ausnutzen:

man dürfte die Matrizen nicht mit Hilfe von XML-Elementen darstellen, sondern rein textuell

Bei große Datenmengen ja.

HDF habe ich bisher nur überflogen, weshalb ich dazu nicht viel sagen kann (und nicht sagen kann, ob es besser als meine nachfolgende Idee ist)

evtl. ist es nicht notwendig, das Dateisystem zu verwenden, sondern es ist evtl. ja möglich, einen beliebigen Datenstrom zu verwenden

das könnte entweder direkt die Verbindung zum Zielsystem für die Daten sein, oder in einen Stream, der ein String-Objekt erzeugt

Nein, wenn Du Deine Matrizen als Stringdaten repräsentierst, ist das wieder uneffizient, da z.B. Zahlendaten als Stringdaten umgewandelt werden müssen. Bei großen Datenmengen sollte man auf Stringverarbeitung verzichten. Z.B. ein int als 32 Bit typ benötigt 4 Byte, die Zahl als String 32565 schon mindestens 5 Byte. Je nach System auch 10 Byte wie bei Unicode.

du könntest dir selbst eine Methode zur Serialisierung (und Deserialisierung) schreiben, welche ein Object-Array-Array entgegen nimmt

bei den primitiven Datentypen (int, double, boolean, ...) könntest du einfach die textuelle Repräsentation verwenden, bei Zeichenketten müsstest du erst entsprechende Zeichen (Steuerzeichen, andere Zeichen wie <, > und & und die "Aufzählungszeichen") maskieren (entweder mit einem Backslash und dem Zeichencode oder mit & und ;, wie es bei XML/HMTL-Texten gemacht wird)

um die Größe zu kennzeichnen, musst du 2 Werte mitgeben (Breite und Höhe) und die einzelnen Werte voneinander mit einem oder 2 Zeichen abgrenzen

Wofür so etwas selbst entwickeln, Daten in eine HDF Datei speichern und diese via FTP übertragen. Man hat ein definiertes Datenformat und eine entsprechend performante Übertragung.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@flashpixx:

zur Struktur:

der Webservice in der Mitte macht so lange Sinn, wie er eine gewisse Abstraktion schafft bzw. Verarbeitungen durchführt (wobei allerdings noch keine Rücksicht auf Bearbeitungsgeschwindigkeit, Netzwerkbelastung oder ähnliches gelegt wird)

das Abwägen, ob eher auf diese "Sauberkeit" oder eher auf Performance geachtet werden sollte, muss dabei der Threadersteller übernehmen, womit ich aber nicht sagen will, dass du keine Ratschläge geben/deine Meinung äußern darfst

wie bereits geschrieben habe ich quasi keine Ahnung von HDF

wenn es sich für diesen Anwendungsfall einsetzen lässt, dann dürfte es wohl auch geeigneter sein (und: ja, es ist grundsätzlich besser auf vorhandene Entwicklungen zurück zu greifen)

ansprechen nativen Codes/Proxy-Objekt:

ich wollte nicht darauf hinaus, dass es schwierig ist, die DLL aufzurufen und die daten zu übergeben, sondern, dass dafür die gesammten Daten vorhanden sein müssen

wenn nicht alle Daten auf einmal benötigt worden wären (wobei das nicht explizit geschrieben wurde sondern eine Vermutung meinerseits ist), dann wären Proxy-Objekte evtl. etwas geeigneter gewesen (nach meiner Einschätzung zumindest)

einfacher könnte es aber sein, sofern möglich, ein vorhandenes Protokoll zu verwenden, wie FTP oder eine verschlüsselte Variante dessen

vielleicht sollte ich mich mangels Kenntnisse (HDF) doch ein wenig mehr aus der Debatte zurück halten... :floet:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eine Middleware ist sicher immer eine Überlegung wert, aber durch die Middleware holt man sich immer einen gewissen Overhead hinzu. Evtl wäre hier die Überlegung, ohne Middleware zu arbeiten. Gerade wenn es hier um sehr große mehrdimensionale Datenmengen geht, würde ich davon abraten.

Die Frage hier wäre, über welche Datenmengen reden wir und welche Art von Berechnungen finden statt. Evtl wäre auch eine P2P Lösung eine Möglichkeit.

Es wird zwingend ein Transaktionmanager benötigt, der mit 2PC-fähigen Ressourcen umgehen kann... das ist ohne Middleware nur sehr schwer zu realisieren (bzw. es würde sich wohl nicht lohnen, sowas nochmal neu zu schreiben :)). Gerade dieses Transaktionsmanagement verhindert es auch, dass man einen P2P-Ansatz verfolgen könnte (ist zumindest meine Meinung).

Was die Berechnung angeht, würde ich hier die Frage stellen, ob es überhaupt notwendig ist, dass ein Client immer eine komplette Matrix erhalten muss. Wenn man die Matrix von a nach b übertragen muss und dann immer mit der kompletten Matrix arbeitet, dann ist das recht ineffizient. Evtl wäre es sinnvoller den Algorithmus, der die Matrix verarbeitet an zu passen, so dass nur mit Patches (Blöcke) der Matrix gearbeitet werden muss. Somit kann die Matrix auf mehrere Clients verteilt werden und das Ergebnis muss dann nur später einmal zusammen gefügt werden. Das ganze als P2P ermöglich dann auch eine lose Kopplung.

Ja, leider sind die Applkationen schon relativ alt - auf der berühmten grünen Wiese würde man sicherlich viel optmieren oder ganz anders lösen können - geht leider nicht so ohne weiteres.

Was spielt das für eine Rolle? HDF wäre dafür geeignet die Daten strukturiert zu speichern. Der Datentransfer muss natürlich über ein anderes Protokoll statt finden.

Ok, vllt hab ich das falsch ausgedrückt. Ich habe nun ein bisschen mit HDF experimentiert - allerdings nur mit dem HDF-Object Wrapper. Und da ist es anscheinend nicht möglich, ohne ein Filesystem zu arbeiten (oder ich bin blind). Dann werd ich wohl mit dem JHI5 Interface beschäftigen müssen.

Das stellt kein Problem dar, ich arbeite selbst mit Java, JNI und Boost C++ Libraries und kann dort habe ich keine Probleme große Datenmengen von Java in die entsprechenden C++ Strukturen zu portieren und dann dort zu verarbeiten.

Der Weg Java -> JNI -> native Lib ist auch sehr peformant - das passt. Nur der Weg Java (Server) -> Java (ClientApplikation) bereitet mir Kopfzerbrechen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es wird zwingend ein Transaktionmanager benötigt, der mit 2PC-fähigen Ressourcen umgehen kann... das ist ohne Middleware nur sehr schwer zu realisieren (bzw. es würde sich wohl nicht lohnen, sowas nochmal neu zu schreiben :)). Gerade dieses Transaktionsmanagement verhindert es auch, dass man einen P2P-Ansatz verfolgen könnte (ist zumindest meine Meinung).

Wofür brauchst Du diese? Ich nehme mal ein Datensatz besteht aus mehreren Matrizen und die Bearbeitung ist dann abgeschlossen, wenn alle Matrizen verarbeitet wurden. Wenn ich nun einem Client eine Matrix zur Berechnung gebe, dann erhalte ich eine Antwort von diesem zurück, im Sinne eines Fehlers (Timeout, fertige Berechnung der Daten etc). Anhand der Antwort kann ich entscheiden, wie ich weiter arbeite, z.B. wenn der Client ein Timeout verursacht, dann kann ich die zu berechnende Matrix ggf an einen anderen Client geben. In analoger Weise könnte ich das Spiel rekursiv machen, d.h. ich zerlege die Matrizen noch einmal in Patches.

Ich kann die Transaktionsmechanismen relativ lose halten und trotzdem gut skalieren.

Ja, leider sind die Applkationen schon relativ alt - auf der berühmten grünen Wiese würde man sicherlich viel optmieren oder ganz anders lösen können - geht leider nicht so ohne weiteres.

Da Du eh schon eine Abstraktion zwischen Client und Server hast, wäre evtl durchaus die Überlegung ob man den Server entsprechend verändert.

Ok, vllt hab ich das falsch ausgedrückt. Ich habe nun ein bisschen mit HDF experimentiert - allerdings nur mit dem HDF-Object Wrapper. Und da ist es anscheinend nicht möglich, ohne ein Filesystem zu arbeiten (oder ich bin blind). Dann werd ich wohl mit dem JHI5 Interface beschäftigen müssen.

Du hast nicht verstanden was der Object-Wrapper macht

Der Weg Java -> JNI -> native Lib ist auch sehr peformant - das passt. Nur der Weg Java (Server) -> Java (ClientApplikation) bereitet mir Kopfzerbrechen.

Ich werfe noch einmal das Stichwort Datenbanken in den Raum. Vor allem sollte man sich je nach Daten auch mal von einem realtionellen Datenbankmodell lösen und ggf NoSQL oder Graphdatenbank in Betracht ziehen.

Gerade bei Deinem Schlagwort "Matrix" könnte man auch Repräsentation von Graphen im Computer denken, so dass man eine Graphdatenbank einsetzen kann. Du müsstest nur einmal konkret sagen, um welche Art von Daten es sich handelt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wofür brauchst Du diese? Ich nehme mal ein Datensatz besteht aus mehreren Matrizen und die Bearbeitung ist dann abgeschlossen, wenn alle Matrizen verarbeitet wurden. Wenn ich nun einem Client eine Matrix zur Berechnung gebe, dann erhalte ich eine Antwort von diesem zurück, im Sinne eines Fehlers (Timeout, fertige Berechnung der Daten etc). Anhand der Antwort kann ich entscheiden, wie ich weiter arbeite, z.B. wenn der Client ein Timeout verursacht, dann kann ich die zu berechnende Matrix ggf an einen anderen Client geben. In analoger Weise könnte ich das Spiel rekursiv machen, d.h. ich zerlege die Matrizen noch einmal in Patches.

Ich kann die Transaktionsmechanismen relativ lose halten und trotzdem gut skalieren.

Bestimmte Module berechnen nicht nur etwas, sondern speichern Ergebnisse etc. auch ab. Diese Ressourcen dürfen aber nur dann verändert werden, wenn alle anderen Module/Applikationen, die innerhalb eines einzigen "Aufrufes" ebenfalls Aktionen ausführen, positiv Antworten. Die ganze Transaktion muss also atomar sein. Der Java-Wrapper um die Module sorgt dafür, dass die nativen Libs jeweils im Context einer Transaktion ausgeführt werden, obwohl diese Programme selbst gar nicht "wissen", dass ihre Ressourcen Teil einer globalen Transaktion sind. Der Transaktionsmanager auf dem Server überwacht alles und - falls alle Berechnung erledigt sind und sämtliche weiteren Bedingungen erfüllt sind - führt dann das endgültige Commit im 2PC-Prozess aus.

Ein kleines Beispiel (ist vllt nicht optimal, aber was bessere fällt mir grade nicht ein):

Eine Maschine schickt Testdaten an einen Prozessrechner. Diese Daten beinhalten sowohl die eigentlichen Messwerte als auch Daten über den Zustand der Maschine. Die Messwerte sollen ausgewertet und in einer DB gespeichert werden, die Maschinendaten sollen analysiert werden und ebenfalls gespeichert.

Es kann nun folgendes passieren: Die Messwerte ergeben überhaupt keinen Sinn - das QM-System meldet, dass diese Werte ausserhalb der Norm liegen und nicht beachtet werden sollen. Das würde auch bedeuten, dass die Maschinendaten u.U. keine Relevanz haben, egal wie sie bewertet werden.

Oder es kann sein, dass die Messwerte ganz normal aussehen, die Maschinendaten aber darauf hinweisen, dass die Messungen zu einem Zeitpunkt genommen worden sind, in dem ein Defekt oder eine Abweichung vorliegt.

Diese 2 Änderungen im Datenbestand (Messwerte & Maschinendaten) sind - aus Applikationssicht - völlig unabhängig voneinander. Wenn ich nun 2 versch. Applikationen habe, die jeweils eine SQL-Datenbank "bearbeiten" und die Mess/Maschinendaten berechnen und protokollieren, muss ich sicher gehen, dass diese (in dem Fall 2) Ressourcen entweder geändert werden oder eben nicht. Diese Entscheidung trifft der Server, nachdem beide Applikationen die Berechnungen durchgeführt haben - aber noch keine Daten geschrieben wurden, da alle relevanten Änderungen (in dem Fall SQL-Kommandos) innerhalb eines Transaktionscontexts durchgeführt wurden.

Du hast nicht verstanden was der Object-Wrapper macht

Das kann sein. Ich habe bis jetzt nur aus diversen Testdaten HDF-Files erzeugt, beschrieben/belesen und das ganze mit Serialisierung/XStream verglichen - in Java logischerweise mit dem HDF-Object-Wrapper. Nun wollte ich das ganze "ohne" Files probieren und habe festgestellt, dass die API von HDF-Object wohl nur darauf ausgelegt ist, mit Files zu arbeiten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Bestimmte Module berechnen nicht nur etwas, sondern speichern Ergebnisse etc. auch ab. [..]

mir ist schon klar was Transaktionen sind und wie sie funktionieren.

Es kann nun folgendes passieren: Die Messwerte ergeben überhaupt keinen Sinn - das QM-System meldet, dass diese Werte ausserhalb der Norm liegen und nicht beachtet werden sollen. Das würde auch bedeuten, dass die Maschinendaten u.U. keine Relevanz haben, egal wie sie bewertet werden.

Oder es kann sein, dass die Messwerte ganz normal aussehen, die Maschinendaten aber darauf hinweisen, dass die Messungen zu einem Zeitpunkt genommen worden sind, in dem ein Defekt oder eine Abweichung vorliegt.

Wo ist das Problem bezüglich der Transaktion?

Diese 2 Änderungen im Datenbestand (Messwerte & Maschinendaten) sind - aus Applikationssicht - völlig unabhängig voneinander. Wenn ich nun 2 versch. Applikationen habe, die jeweils eine SQL-Datenbank "bearbeiten" und die Mess/Maschinendaten berechnen und protokollieren, muss ich sicher gehen, dass diese (in dem Fall 2) Ressourcen entweder geändert werden oder eben nicht. Diese Entscheidung trifft der Server, nachdem beide Applikationen die Berechnungen durchgeführt haben - aber noch keine Daten geschrieben wurden, da alle relevanten Änderungen (in dem Fall SQL-Kommandos) innerhalb eines Transaktionscontexts durchgeführt wurden.

Wo ist auch hier das Problem bezüglich der Transaktion !?

Der Server bekommt die Daten und startet die Transaktion, die Daten werden an die Clients gesendet und berechnet. Ein Client meldet einen Fehler, Server bricht Transaktion ab. Es wurden keine Daten geschrieben.

Wenn jeder Client die Daten berechnet hat, es der Spezifikation entsprechend fehlerfrei ist, sendet er diesen Status an den Server, der Server teil nun jedem Client mit, dass er die Daten schreiben soll. Tritt ein Fehler auf, wird eben die gesamte Transaktion abgebrochen.

Letztendlich ist das eine Transaktion, die aus 2 Teiltransaktion (Berechnung / Schreiben der Daten) besteht, sie ist atomar und die Daten müssen nur einmal transportiert werden, nachdem sie der Server erhalten hat, denn das Schreiben übernimmt der Client, der auch die Berechnung durchführt.

Wenn der Server nachdem er die Daten erhalten hat, diese in eine temporäre Datenbankstruktur schreibt und den Clients mir mitteilt wie die Session lautet, dann kann jeder Client auf die Daten zugreifen und seine Berechnungen durchführen. Wenn die Clients fehlerfrei beendet haben, melden sie dies an den Serverprozess, der dann die temporäre Session per Datenbanktransaktion in die Tabellen der Datenbank schreibt. Wenn ein Fehler auftritt, dann wirft man die Session einfach weg und trennt die Verbindung zur Datenbank. Die Transaktion wurde somit nie durchgeführt.

Ich sehe beim besten Willen keine Probleme bezüglich der Transaktionen, mir scheint nur, dass Du eben große Datenmengen durch entsprechende Java Strukturen weiter aufblähst. Bei einer Transaktion müssen zwar die Daten innerhalb des Contextes vorhanden sein, wie diese aber zwischen den Rechnern ausgetauscht werden, ist eine völlig andere Sache. Theoretisch kann ich auch Dateien zwischen den Systemen hin und her kopieren, z.B. via NFS, FTP und damit arbeiten.

Ich würde nie an die Transaktion selbst die Daten hängen, das scheinst Du aber zu machen, sondern lediglich nur einen Link zu den Daten in der Transaktion mit geben. Wenn Du die Daten z.B. auf ein SAN / NAS legst, dann brauchst Du in der Transaktion nur den Link mit geben und je nach OS kannst Du es Dir sogar sparen, Daten die Du nicht verarbeitest selbst zu löschen, weil dass das System auf dem die Daten liegen von sich aus macht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wo ist auch hier das Problem bezüglich der Transaktion !?

Der Server bekommt die Daten und startet die Transaktion, die Daten werden an die Clients gesendet und berechnet. Ein Client meldet einen Fehler, Server bricht Transaktion ab. Es wurden keine Daten geschrieben.

Wenn jeder Client die Daten berechnet hat, es der Spezifikation entsprechend fehlerfrei ist, sendet er diesen Status an den Server, der Server teil nun jedem Client mit, dass er die Daten schreiben soll. Tritt ein Fehler auf, wird eben die gesamte Transaktion abgebrochen.

Letztendlich ist das eine Transaktion, die aus 2 Teiltransaktion (Berechnung / Schreiben der Daten) besteht, sie ist atomar und die Daten müssen nur einmal transportiert werden, nachdem sie der Server erhalten hat, denn das Schreiben übernimmt der Client, der auch die Berechnung durchführt.

Wenn der Server nachdem er die Daten erhalten hat, diese in eine temporäre Datenbankstruktur schreibt und den Clients mir mitteilt wie die Session lautet, dann kann jeder Client auf die Daten zugreifen und seine Berechnungen durchführen. Wenn die Clients fehlerfrei beendet haben, melden sie dies an den Serverprozess, der dann die temporäre Session per Datenbanktransaktion in die Tabellen der Datenbank schreibt. Wenn ein Fehler auftritt, dann wirft man die Session einfach weg und trennt die Verbindung zur Datenbank. Die Transaktion wurde somit nie durchgeführt.

Das problem ist, dass innerhalb der Client/Module/Applikationen/wie auch immer, schon Daten geschrieben werden. Für das Beispiel: Die Applikation, die die Messdaten analysiert, schreibt diese schon auf Ressourcen (z.B. mit SQL INSERTS). Diese Änderungen dürfen aber nicht mit einem Commit beendet werden, da diese Daten überhaupt nicht exisitieren dürften, falls die Maschinendaten vllt noch ergeben, dass die Maschine "kaputt" ist.

Der Jaqva-Wrapper eröffnet deshalb für das Modul eine SQL-Connection die auf dieser Transaktion arbeitet - das Modul selbst bekommt davon gar nichts mit (ist wie gesagt eine alte Anwendung). Er wen alle Module antworten, geht der Befehl an die beteiligten Ressourcen, die Änderungen zu Committen (was natürlich nicht nur einen SQL-Commit bedeuten könnte, sonder auch das Versenden einer JMS-Message usw.)

Mach jetzt gleich Feierabend - ich schreib dann morgen weiter :). Ich muss aber dazu sagen, dass ich mich mit dieser speziellen Problemstellung insgesamt 6 Monate im Rahmen meiner Bachelorarbeit beschäftigt habe - ohne 2PC geht diese ganze Struktur leider nicht, denn es wäre in der Tat vieles einfacher, könnte man darauf verzichten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Diese Änderungen dürfen aber nicht mit einem Commit beendet werden, da diese Daten überhaupt nicht exisitieren dürften, falls die Maschinendaten vllt noch ergeben, dass die Maschine "kaputt" ist.

Tun sie doch auch nicht, wenn ich das temporär in einer Session der Datenbank mache und bei einem Fehler die Session einfach beende, wäre es so als wären die Daten nie geschrieben worden.

Mach jetzt gleich Feierabend - ich schreib dann morgen weiter :). Ich muss aber dazu sagen, dass ich mich mit dieser speziellen Problemstellung insgesamt 6 Monate im Rahmen meiner Bachelorarbeit beschäftigt habe - ohne 2PC geht diese ganze Struktur leider nicht, denn es wäre in der Tat vieles einfacher, könnte man darauf verzichten.

Ich habe nie gesagt, dass Du auf Transaktionen verzichten sollst! Ich habe nur gesagt, dass Du die Daten nicht innerhalb Deiner Transaktions-Message transportieren sollst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Tun sie doch auch nicht, wenn ich das temporär in einer Session der Datenbank mache und bei einem Fehler die Session einfach beende, wäre es so als wären die Daten nie geschrieben worden.

Dann bräuchte man aber schonmal eine Instanz, die entscheidet, ob die einzelnen Sessions festgeschrieben werden sollen oder nicht. Dann kommt noch das große Problem hinzu:

Angenommen ModulA und ModulB führen Berechnungen und Veränderungen jeweils einer Datenbank-Ressource innerhalb einer Session durch. Beide Module antworten positiv - beide Sessions können also geschrieben werden. Nun teilt der Server mit, dass ModulA die Session schreiben soll (oder schreibt sie selbst - bin mir grade nicht sicher ob man z.B. in Oracle so ohne weiteres eine Session schreiben kann, die man nicht selbst initiiert hat).

SessionA wird geschrieben - SessionB kann aber nicht geschrieben werden und führt beim Versuch des Commit zu einem Rollback. Nun sind Daten von ModulA auf Ressourcen, die von ModulB aber nicht - und das darf nicht sein. So etwas kann man mit einem 2PC relativ einfach lösen - sofern die Ressource einen 2PC-fähigen Treiber anbietet.

Ja, generell hab ich mir mit dem Transport von großen Daten in dieser Struktur noch nicht befasst. Bis jetzt war es so, dass es sich bei den meisten Anwendungsfällen um double bzw. String 2D-Arrays gehandelt hat, in denen insgesamt nicht mehr als 20-30 Werte waren - und sowas war natürlich mit normaler Java-Serialisierung kein Problem. Nun teste ich eben gerade wie es mit wirklich großen Datenmengen aussieht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dann bräuchte man aber schonmal eine Instanz, die entscheidet, ob die einzelnen Sessions festgeschrieben werden sollen oder nicht. Dann kommt noch das große Problem hinzu:

Nein kommen sie nicht. Du hast das 2-Phasen-Commit nicht richtig verstanden (Commit-Protokoll).

Entweder es müssen alle Teilnehmer das Ack senden und wenn einer Fail sendet, wird komplett abgebrochen.

In dem geschilderten Fall erweitere ich das 2-Phasen-Commit noch mit einem sequentiellen Teil, der durch den Koordinator durchgeführt wird. Nachdem (!) alle Daten berechnet wurden, muss ein Ack von jedem Teilnehmer gesendet werden, wenn ein Fail auftritt wird die Transaktion verworfen. Erst nach dem Ack öffnet der Koordinator eine Datenbanktransaktion in die jeder Teilnehmer seine Daten einfügt. Tritt ein Fehler auf, geschieht ein Rollback der Datenbank und die gesamte vorherige Session wird ungültig. Wenn alle Teilnehmer die Daten eingefügt haben wird der Commit durchgeführt.

Damit ist der gesamte Vorgang atomar. Der Koordinator startet die Transaktion und beendet sie.

Ich habe auch nicht von "einzelnen Sessions" (Plural) gesprochen, sondern von "einer Session" (Singular). Der Koordinator öffnet eine Session und nur er beendet sie auch wieder, entweder mit einem Rollback oder mit einem Commit. Natürlich muss der Koordinator bezüglich der Datenbanksession den Clients so etwas wie das Sessionhandle mitteilen, damit jeder Teilnehmer in die gleiche Session seine Daten ablegen / erhalten kann.

Generell empfehle ich Dir, dass Du Dich einmal mit der Problematik unabhängig von Java befasst, denn die Probleme, die Du hast sind nicht Java bezogen. Du versuchst hier mit vordefinierten Frameworks etwas zu erreichen, was nur schwer möglich ist. Eine Technologie wie JMS kann man durchaus verwenden, nur Du musst sie eben problemspezifisch erweitern.

Du wirst hier, wenn Du innerhalb der Transaktion Deine Daten transportierst an sehr große Schwierigkeiten stoßen. Deshalb der Hinweis, dass Du die Daten temporär (innerhalb einer Session über alle Teilnehmer) in der Datenbank lagerst. Wenn die Teilnehmer via InfiniBand an die Datenbank angeschlossen werden, dann wird das Transportproblem sich sehr leicht lösen lassen. Der Nachrichtenaustausch bezüglich der Transaktion ist dann sehr gering, weil nur ein Sessionhandle für die Datenbank mitgeben wird, so dass jeder Teilnehmer Zugriff auf die Datenbank bekommt.

Rein technisch:

1. Koordinator nimmt Daten entgegen

2. Koordinator erzeugt Datenbanksession

3. Koordinator schreibt Daten in Datenbanksession

4. Koordinator sendet Nachricht an Teilnehmer mit Sessionhandle

5. Teilnehmer verarbeiten Daten und schreiben Daten in Session

6. Teilnehmer senden Fail oder Ack

7. Wenn Koordinator von allen Teilnehmern Ack erhält starten er ein Datenbanktransaktion, die die Daten aus der Session in die realen Tabellen überträgt und committet

8. Tritt ein Fehler auf, wird Session verworfen bzw. Rollback der Datenbanktransaktion

Die Nachrichten zwischen dem Koordinator und den Teilnehmern enthalten lediglich den Status "Ack" bzw "Fail" (bzw. Prepare) und das Sessionhandle. Ein Undo-Log brauchst Du hier nicht, denn die Änderungen an den realen Daten werden erst zum Schluss geschrieben, so dass Du dieses durch die Transaktion der Datenbank absicherst. Generell habe ich die Punkte 1-3, 4-6 und 7-8 in eine eigene 2PC Struktur gelegt und ich sorge dafür, dass diese sequentiell durch den Koordinator ausgeführt werden. Da jede Struktur atomar ist, gilt hier direkt, wenn ein Fehler auftritt schlägt die gesamte Transaktion fehl, da nur im letzten Schritt die Daten in den realen Tabellen verändert werden, brauche ich mich nicht um ein Rollback kümmern, sondern verwerfe einfach die temporäre Session. Tritt im letzten Schritt ein Transaktionsfehler auf, dann macht die Datenbank für mich die Transaktion rückgängig.

Generell solltest Du in den Nachrichtenaustaisch keine Nutzdaten legen, sondern die Nachrichten, die die Transaktion koordinieren sollten nur die notwendigen Informationen enthalten, die für die Transaktion benötigt werden. Alles andere gehört in andere Protokolle / Technologien. Außerdem würde man den Nachrichtenaustausch bei den Transaktionen auch als unabhängige eigenständige Struktur entwerfen, damit man nicht hier zwei Dinge vermischt. Entscheidend bezüglich des Datenvolumens ist die Anbindung der Teilnehmer an die "zentrale Datenbank", wobei Datenbank hier nicht zwingend ein DBMS sein muss, letztendlich kann man auch rein dateibasiert die Daten z.B. via NFS austauschen. In diesem Fall würde der Koordinator eben eine oder mehrere HDF Dateien auf ein zentrales Share legen und jeder Teilnehmer holt sich von dort seine Daten.

Sollte man feststellen, dass ein Client die Daten nicht mehr in den geforderten Zeitschritten verarbeiten kann, ersetzt man einfach den Singleteilnehmer durch eine Clusterlösung, so dass man hier direkt einzelne Teilnehmer hoch skalieren kann. Da man nur einen zentralen Punkt an, an dem die Nutzdaten liegen, kann man sehr leicht darauf zugreifen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nein kommen sie nicht. Du hast das 2-Phasen-Commit nicht richtig verstanden (Commit-Protokoll).

Entweder es müssen alle Teilnehmer das Ack senden und wenn einer Fail sendet, wird komplett abgebrochen.

Danke, aber das hab ich schon verstanden, keine Sorge ;) Der von dir beschriebene Weg hat auch nichts mit einem 2Phasen Commit zu tun, weil es auf Datenbank-Ebene nur eine Phase gibt - Commit oder Rollback durch den "Koordinator". Die Rückmeldung der Module mit ACK oder Fail haben ja erstmal nichts mit der eigentlich Persistenz der Daten zu tun - und eine PREPARE-Phase laut 2PC commit fehlt völlig.

Ich habe auch nicht von "einzelnen Sessions" (Plural) gesprochen, sondern von "einer Session" (Singular). Der Koordinator öffnet eine Session und nur er beendet sie auch wieder, entweder mit einem Rollback oder mit einem Commit. Natürlich muss der Koordinator bezüglich der Datenbanksession den Clients so etwas wie das Sessionhandle mitteilen, damit jeder Teilnehmer in die gleiche Session seine Daten ablegen / erhalten kann.

Und was machst du, wenn ModulA an einer OracleDB hängt, ModulB an einer MySQL-DB und die Ressourcen, die ModulC benutzt, die Form eines JMS-Systems haben?

Dann hast du 3 völlig unabhängige "Sessions", und die kannst du eben praktisch nur sequentiell committen oder auch nicht, wenn man das mit "normalen" Mitteln erledigen will. Genau das ist ja das Problem. Würden wir hier von homogenen Umgebungen reden, bei der jedes Modul eine OracleDB "bearbeitet", dann könnte man sich den ganzen Overhead natürlich von vornherein sparen.

Ausserdem hab ich hier noch mehr Freiheiten, was die Transaktionsausführung auf dem Koordinator/Server z.B. innerhalb eines Workflows betrifft.

Ich könnte z.B. Messdaten für 2 Module (A und B) empfangen, diese an die Module verschicken und abhängig von dem Ergebnis eine Nachricht (der Einfachheit halber eine JMS-Nachricht ;)) an ein externes System schicken.

So, ModulA und B verarbeiten alles, der koordinator emfpägt 2 mal "ok" und comitted die Session. Nun kann er aber die JMS-Nachricht nicht verschicken, weil ein Fehler auftritt. Obwohl die Daten also auf den eigentlichen Ressourcen gespeichert sind, wird keine Nachricht verschickt - was aber eigentlich Teil des Workflows/des Prozesses ist. Dieser ganze Prozess wurde also auch nicht atomar durchgeführt.

Rein technisch:

1. Koordinator nimmt Daten entgegen

2. Koordinator erzeugt Datenbanksession

3. Koordinator schreibt Daten in Datenbanksession

4. Koordinator sendet Nachricht an Teilnehmer mit Sessionhandle

5. Teilnehmer verarbeiten Daten und schreiben Daten in Session

6. Teilnehmer senden Fail oder Ack

7. Wenn Koordinator von allen Teilnehmern Ack erhält starten er ein Datenbanktransaktion, die die Daten aus der Session in die realen Tabellen überträgt und committet

8. Tritt ein Fehler auf, wird Session verworfen bzw. Rollback der Datenbanktransaktion

Geht wie gesagt aus meiner Sicht nur in einer absolut homogenen Umgebung (dann wäre es natürlich einfacher). Und hat mit einem 2PC-Protokoll auch nichts zu tun (wie gesagt nur eine Phase aus Ressourcen/Teilnehmer-Sicht).

// Edit:

Du darfst das Wort "Teilnehmer", z.B. aus dem Wiki-Artikel zu 2PC, hier nicht mit Modulen, die etwas berechnen, verwechseln. Wenn du 10 Module hast, die alles etwas anderes berechnen, aber auf einer gemeinsamen Ressource arbeiten (z.B. einer Oracle-DB), hast du trotzdem nur einen Teilnehmer in der gesamten Transaktion. 2PC könnte man natürlich auch mit nur einem Teilnehmer machen - macht aber keine Sinn und wird meistens implizit durch den Koordinator zu einem ein-Phase-Commit optimiert, also ohne eine PREPARE-Phase, die bei einem Teilnehmer sowieso keine Relevanz hätte.

Commit-Protokolle machen (zumindest bei 2PC/3PC) nur Sinn, wenn verschiedene Ressourcen, die man nicht in einer einzigen Session kapseln kann, an einer gemeinsamen Transaktion beteiligt sein sollen.

Die Nachrichten zwischen dem Koordinator und den Teilnehmern enthalten lediglich den Status "Ack" bzw "Fail" (bzw. Prepare) und das Sessionhandle.

Ist im Moment auch so (nur statt dem Sessionhandle eben die Transaktions-ID gesendet wird) - und eben die Messdaten, für die ich eben nun einen anderen Weg finden muss.

Ich würde trotzdem gerne mal ausprobieren wie es sich mit ByteMessages und JMS verhält. Gerade HornetQ macht als JMS-Implementierung einen recht performanten Eindruck. Ich bin mir eigentlich fast sicher, dass eine File-System basierte Lösung da nicht schneller sein dürfte. HDF als Format sieht schonmal sehr nett aus.

Bearbeitet von blubbla
Link zu diesem Kommentar
Auf anderen Seiten teilen

Und was machst du, wenn ModulA an einer OracleDB hängt, ModulB an einer MySQL-DB und die Ressourcen, die ModulC benutzt, die Form eines JMS-Systems haben?

Dann hast du 3 völlig unabhängige "Sessions", und die kannst du eben praktisch nur sequentiell committen oder auch nicht, wenn man das mit "normalen" Mitteln erledigen will. Genau das ist ja das Problem. Würden wir hier von homogenen Umgebungen reden, bei der jedes Modul eine OracleDB "bearbeitet", dann könnte man sich den ganzen Overhead natürlich von vornherein sparen.

Diese Information hat gefehlt, dass Du hier ein hetrogenes System hast. Im Normalfall ist das eigentlich ja kein Problem, denn man würde ja die Resource, auf der die Nutzdaten liegen einfach homogen setzen.

Aber ich stelle hier jetzt die Frage, warum Du Dir gerade bezüglich der Transaktion es so schwer machst. Wäre es nicht sinnvoller zu sagen, dass man ggf eine Resource verwenden z.B. die von Dir genannte Oracle Datenbank und lediglich die Zielsysteme anpasst. Ich meine bei entsprechender Abstraktion muss man nur die Datenbankanbindungskomponenten tauschen.

Oder Du würdest die Daten, wie gesagt, auf ein Shared Medium (z.B. NFS) als HDF Dateien legen, jeder Teilnehmer arbeitet darauf und der Koordinaten schiebt später die Daten in die jeweiligen Datenbanken. Der Vorteil wäre hier, dass nur der Koordinator Zugang zum DBMS haben müsste und nicht jeder Teilnehmer

Du darfst das Wort "Teilnehmer", z.B. aus dem Wiki-Artikel zu 2PC, hier nicht mit Modulen, die etwas berechnen, verwechseln. Wenn du 10 Module hast, die alles etwas anderes berechnen, aber auf einer gemeinsamen Ressource arbeiten (z.B. einer Oracle-DB), hast du trotzdem nur einen Teilnehmer in der gesamten Transaktion.

Ich arbeite mit MPI, da ist der Begriff "Teilnehmer" als Prozess (z.B. ein einzelner CPU) zu sehen, wobei hier gilt, dass ich den Teilnehmer eben noch über Multithreadding weiter aufbauen kann. Mehrere Teilnehmer kann ich dann zu einer Gruppe bündeln, die dann z.B. eine Node (einen oder mehrere physikalische Rechner) bündeln. Alle Nodes zusammen ergeben dann den Cluster.

Ich würde trotzdem gerne mal ausprobieren wie es sich mit ByteMessages und JMS verhält. Gerade HornetQ macht als JMS-Implementierung einen recht performanten Eindruck. Ich bin mir eigentlich fast sicher, dass eine File-System basierte Lösung da nicht schneller sein dürfte. HDF als Format sieht schonmal sehr nett aus.

Die Frage, die ich dabei immer habe, ist die Strukturierung der Daten. Ich hatte ein ähnliches Problem mit 3-dimensionalen Daten, die in Matlab verarbeitet werden sollten und ggf später auch in anderen Systemen. Ich habe die Daten in HDF gespeichert, weil n-dimensionale Daten in einem relationellen Datenbanksystem sehr unperformant werden, vor allem konnte ich durch sinnvolle Skalierung sparse Datenstrukturen verwenden. Die HDF Dateien habe ich dann als BLOB Daten in eine Postgresdatenbank gelegt, dort wurden dann noch weitere Metainformationen abgelegt. Damit hatte ich direkt auch ein Caching implementiert, denn ich habe beim Zugriff die HDF Datei aus der Datenbank geladen und lokal temporär gespeichert, somit musste ich die Session nicht offenhalten. Die 3D Matrizen waren unveränderbar, d.h. nach dem Import brauchten sie nicht mehr verändert werden, so dass ich lediglich dann in die Datenbank Informationen abgelegt habe, die sich aus der Berechnung der Matrizen ergeben haben.

Die Frage wäre somit, wenn Du Bytedaten zwischen den Teilnehmern austauschst, ob Du ggf zur Strukturierung HDF verwendest, als die Raw Daten zu übertragen. Wie schon geschrieben wäre wirklich die Frage, was Du überhaupt für Realdaten hast und ob man ggf dieses ausnutzen kann. HDF unterstützt meines Wissen auch Zip-Algorithmen on-fly.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Diese Information hat gefehlt, dass Du hier ein hetrogenes System hast. Im Normalfall ist das eigentlich ja kein Problem, denn man würde ja die Resource, auf der die Nutzdaten liegen einfach homogen setzen.

Aber ich stelle hier jetzt die Frage, warum Du Dir gerade bezüglich der Transaktion es so schwer machst. Wäre es nicht sinnvoller zu sagen, dass man ggf eine Resource verwenden z.B. die von Dir genannte Oracle Datenbank und lediglich die Zielsysteme anpasst. Ich meine bei entsprechender Abstraktion muss man nur die Datenbankanbindungskomponenten tauschen.

So etwas kann man aber eigentlich nur in einem abgeschlossenen System machen. Beispiel: ModulA verarbeitet Messwerte, ModulB Maschinendaten, beide Module auf einer OracleDB. Nun will ich einen Prozess definieren, in dem ich beide Module die Daten prüfen lasse und bei Erfolg an den Leitrechner ein Signal sende, dass die Daten verarbeitet wurden.

Mit einem 2PC-fähigen Transaktionsmanager kann ich das sehr einfach bewerkstelligen. Ich definiere z.B. in Java eine Methode, die auch die globale Transaktion klammert. Nun kann ich die 3 Teilschritte (ModulA, ModulB, externerAufruf) als Branches einer Transaktion ausführen. Der externeAufruf könnte also z.B. eine JMS-Message sein, oder ein Webservice-Aufruf etc. Ich kann sicher sein, dass, wenn ich nach den ModulA/ModulB Berechnungen eine Exception beim externen Systeme auslöse oder die Message letztlich doch nicht gesendet werden kann, der Transaktionsmanager die von ModulA und ModulB verwendeten Ressourcen zurücksetzt. Das alles passiert absolut transparent - d.h. wenn ich irgendeine Anwendung/ein System habe, dass ich im Laufe einer Methode/eines Workflows ansprechen will, muss ich nur die 2PC-fähige Ressource des Systems kennen, die verwendet wird, und sie innerhalb der Transaktion enlisten. Um alles andere muss ich mir dann keine Gedanken mehr machen - und falls doch etwas schief geht (Ausfall des Koordinators = Transaktionsmanagers = z.B. JavaEE AS), kann man sich in die Tiefen des transaction recovery begeben :)

Oder Du würdest die Daten, wie gesagt, auf ein Shared Medium (z.B. NFS) als HDF Dateien legen, jeder Teilnehmer arbeitet darauf und der Koordinaten schiebt später die Daten in die jeweiligen Datenbanken. Der Vorteil wäre hier, dass nur der Koordinator Zugang zum DBMS haben müsste und nicht jeder Teilnehmer

Es kann auch durchaus sein, dass dem Koordinator gar nicht bekannt ist, welche Daten überhaupt geschrieben werden müssen (das ist eigentlich der Normallfall). Es muss auch reichen: ModulA sagt dem Koordinator: "Hallo ich bin da, ich habe eine Oracle Datenbank als Ressource, Username und PW sind soundso, warte auf Nachrichten". Der Koordinator kennt weder die Struktur noch die Nutzung der Daten - er eröffnet die Transaktion, leitet die Daten weiter und schliesst sie. Leider sind die Module auch zum Großteil wirklich Black Boxes, wo man an der eigentlichen "Business" Logik auch nicht mehr großartig rumschrauben kann.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Leider sind die Module auch zum Großteil wirklich Black Boxes, wo man an der eigentlichen "Business" Logik auch nicht mehr großartig rumschrauben kann.

Ich denke, dass das ja das Problem ist, dass Du hier Standard Frameworks verwendest, aber eigentlich etwas individuelleres brauchst. Wenn ich das jetzt OOP technisch sehe, dann müsstest Du doch letztendlich von einem bestehenden System Dein eigenes ableiten können, damit hättest Du doch weiterhin die gesamte Technologie für die bestehenden Workflows, hast aber an den entsprechenden Stellen Deine eigenen Erweiterungen. Im worst-case müsstest Du Deine eigene JTA Komponente schreiben (Java Transaction API).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...