Welche Persistenz für große Datenmengen?

Sandra Haupt

Grünschnabel
Hallo,

ich benutze derzeit eine MySQL Datenbank und habe festgestellt, dass sie ein richtiges Nadelöhr für meine Performance ist. Ich muss oftmals Zehntausende von Datensätzen auslesen oder verändern und suche nun eine geeignete Speichermöglichkeit. Dabei stieß ich auf JDO und FastObjects von der Firma Poet. Leider habe ich beim ersten Überlesen der Features den Eindruck bekommen, dass sich FastObjects nicht nur auf festgelegte Standards verläßt, sondern auch eigene Möglichkeiten anbietet. Ich möchte mich aber nicht durch die Verwendung von Nicht-Standardbefehlen auf FastObjects festlegen, sondern suche mehr eine Open Source Standart Objekt Datenbank, wie sie jetzt wohl vom Jakarta Projekt in der Entwicklung ist.

Welche Speichermethode würdet ihr mir empfehlen für große Datenmengen und einer objektbezogenen Speicherart?

Danke, Sandra
 
Persistenz ist meiner Meinung nach die Fähigkeit Änderungen nachzuvollziehen bzw. Rückgängig zu machen und zu Branchen. Ich hatte das so gelernt: keine Persistenz der Daten - keine Änderungen rückgängig machen. Semi-Persistent: Änderungen rückgängig machen aber keine Branches. Volle Persistenz: im Prinzip wie CVS - an beliebigen Stellen verzweigen usw.

Was das allerdings mit deiner Frage zu tun hat, weiss ich nicht.
 
@squeaker:
"Persistenz = dauerhaftes Speichern von Daten auf einem externen Datenträger
so das diese auch nach dem Beenden des Programms erhalten bleiben"

@Sandra
Also soviele Möglichkeiten gibts da meines Erachtens nicht. Entweder du benutzt
eine DB für die persistente Speicherung deiner Daten, oder du
verwendest das Streaming(File IO) der Java API, was allerdings bei großen
Datenmengen relativ schnell unübersichtlich werden kann.
Wenn du nach Open Source Datenbankenaltenativen suchst kann ich dir
sourceforge.net empfehlen.
Mit dem Suchwort database findest du eine Menge Suchergebnisse.

Gruß

RedWing
 
Hallo!

Eigentlich sollte MySQL auch mit dieser Datenmenge zurecht kommen.
Ein Flaschenhals bei der DB kann viele Ursachen haben. Ungünstiges Datenbank Design (keine Indizierung, unvorteilhafte Abfragen), alter JDBC Treiber oder dessen unsachgemäße Verwendung.

Verwendest du PreparedStatements? Batch Updates? Hast du Abfragen mit sehr vielen Joins?

Das sind dann im Allgemeinen die Stellschrauben an denen man drehen kann.
Also erstmal danach schauen, bevor man sich an andere Technologien heranwagt.

@squeaker: -> http://de.wikipedia.org/wiki/Persistenz

Gruß Tom
 
Hallo,

@RedWing
Danke für den Link.

@Tom
Ich stimme dir zu, dass die MySQL Datenbank mit der Menge an Daten fertig wird. Ich habe mit PHP auch keine Probleme. Unter Java geht die Performance aber deutlich nach unten. Ich vermute das liegt daran, dass ich meine objektorientierte in eine relationale Struktur umwandeln muss. Z.B. muss ich mein Objekt erst in mehrere Tupel umwandeln, danach muss ich SQL Befehle zum Abspeichern schreiben, umgekehrt beim Laden genauso. Ausserdem möchte ich ab und an Objekte cachen, ich muss also das objektbezogene Caching mehreren relationalen Tabellen zuordnen, was den Code nicht einfacher macht.

Kurz gesagt, um in MySQL etwas abzuspeichern oder daraus etwas zu laden ist ein sehr großer Overhead erforderlich, der meiner Meinung nach die Bremse ist. Ich suche nun eine Persistenz, bei der nicht diverse Umwandlungen notwendig sind, sondern bei der ich gleich meine Objekte speichern kann und bin gerne bereit dafür auch neue Techniken zu erlernen.

P.S. Ich nutze den neusten JDBC Treiber von der MySQL Homepage.

Grüße, Sandra
 
machst du viele Objekte und löschst sie danach wieder? das ist unter Java sehr langsam. Vielleicht kannst du dir einen Objekt-Pool bauen. Die Objekte werden erstellt und wenn sie nicht mehr benötigt werden, werden sie zurück in den Pool gestellt. Falls nun ein neues Objekt benötigt wird, holt man sich eines aus dem Pool und setzt nur die Daten neu. So müssen die einzelnen Objekte nicht stets neu erstellt werden, Speicher alloziert werden ... und am Ende wieder zerstört werden.

Ich hoffe das hilft. Schau dir auch mal dein Java-Programm mit einem Profiler an. Der kann dir sagen in welchem Teil deines Programmes am meisten Zeit vertrödelt wird.
 
Original geschrieben von squeaker
machst du viele Objekte und löschst sie danach wieder? das ist unter Java sehr langsam. Vielleicht kannst du dir einen Objekt-Pool bauen. Die Objekte werden erstellt und wenn sie nicht mehr benötigt werden, werden sie zurück in den Pool gestellt. Falls nun ein neues Objekt benötigt wird, holt man sich eines aus dem Pool und setzt nur die Daten neu. So müssen die einzelnen Objekte nicht stets neu erstellt werden, Speicher alloziert werden ... und am Ende wieder zerstört werden.

Ich hoffe das hilft. Schau dir auch mal dein Java-Programm mit einem Profiler an. Der kann dir sagen in welchem Teil deines Programmes am meisten Zeit vertrödelt wird.

Das mit der Overhead würde ich nicht unterschreiben halte ich für fraglich.
Das war damals bei 1.1. so, aber seit der HotSpot VM und der relational GC
ist das nicht mehr so der Fall.

@ Sandra:
Mal Ibatis oder Hibernate angeschaut?
Einfach mal nach googlen gibt es links ohne Ende dazu!

Ciao
 
Peristenz: Besagt lediglich das etwas außerhalb des Programlebenszyklus erhalten bleibt. Hat also nichts mit Branches & Co an sich zu tun.

JDO: Momentan wohl der neue Standard der Persistierung. Vielleicht ein Standard mit dem Potential, irgendwann mal JDBC ersetzen zu können. Im Grunde genommen die Weiterentwicklung von ODMG, nur das JDO im Gegensatz zu ODMG von der Wirtschaft akzeptiert wird.

Warum JDO anstelle von SQL basierten Datenbanken? Simpel: Weil der Programmierer nicht in SQL / Tupeln denken will. Der Programmierer will ausschließlich mit Objekten arbeiten und gerade hierfür ist JDO gebaut worden. Es ist zudem so ausgelegt worden das man dahinter sowohl relationale als auch objektorientierte Datenbanken pappen kann.

Die Versant DB ist im übrigen eine solche Objektdatenbank. Im Grunde genommen sind OO DBs den relationalen Brüdern überlegen, aber dennoch konnten sie bis heute keinen Fuß fassen. Ausnahmen sind vielleicht einige wenige Nischen wie z.b. im embedded Bereich, wo Datenbanken wie db4o.de durchaus einen guten Weg darstellen. Auch Versant bedient im Grunde genommen nur eine Nische, da die meisten Firmen an Oracle & Co gebunden sind.

Welchen Vorteil bringt es dir als Programmierer auf JDO zu setzen? Simpel: Du kannst dahinter jederzeit beliebige Datenbanken hängen und somit effektiv diese in der Performance vergleichen. Zudem ist es in der Regel so, das die automatische SQL Generierung des JDO Mappers gut genug ist. Sicher wenn man ein einzelnes Statement handoptimiert wird der Mapper langsamer sein, aber in der Regel produziert dieser schnelleres SQL als man dies händisch ausformulieren könnte.

Zudem sind die meisten JDO Mappern einem direkten SQL Zugriff überlegen, da sie mehrere Level an Caches vorweisen können. Bis hin zu VM übergreifenden Distributed Caches ist alles denkbar.

Zur Frage des Urpsrungsposters: Kauf dir ein Datenbankenbuch das sich dem Them Performance widmet. Es wäre hier und jetzt ein wenig vermessen dir die Basics beibringen zu wollen.

Warum kann eine DB langsamer sein als sie sein könnte? Sind Indexe effizient gesetzt? Normalisierungsfehler? Muß man eventuell an einer bestimmten Stelle denormalisieren um der Performance genügen zu können? Sollte man vielleicht den Index auf eine andere physische Platte legen? Sollte man vielleicht anstelle des normalen Filesystems dem RDBMS ein Raw Device zuweisen, wodurch er sich den Umweg übers Filesystem ersparen kann? Wäre vielleicht ein Raid die Lösung zur Problembehebung?

Oder sind wir gerade in die falsche Richtung gegangen? Ist vielleicht einfach nur deine Applikation der Flaschenengpass? Vielleicht irrst du dich ja und die DB stellt gar nicht den Engpass dar. Ja selbst dies wäre möglich.

MySQL ist im übrigen nicht wirklich eine schnelle DB. Ja sicher bei den Hobbyentwicklern ist es die schnellste / bestigste DB überhaupt, aber mal ehrlich, deren Anforderungen spiegeln nicht wirklich eine reale Applikation wieder. Sobald viele Relationen bestehen, multiple Threads transaktionssicherheit wollen und einfach die Anforderungen nach oben geschraubt werden. Ja ab da sind in der Regel ganz andere Datenbanken "schnell". Sogar die angeblich langsamere PostgreSQL kann hier recht schnell als Sieger hervorgehen.

Hol dir ein Buch das all diese Themen abdeckt und lern dich dort ein wenig ein. Eventuell lohnt es sich auch einen Consultant hinzuzuziehen der exakt nach deinen Randbedingungen Lösungen vorschlägt. (Bedenke, für den Preis einer VersantDB / Oracle kannst du schon einiges an Hardware upgraden, was eventuell also eine effizientere Lösung darstellt).

Die meisten relevanten Bedingungen sind eben Applikationsspezifisch und somit können wir eigentlich nur generisch ins Blaue raten.

Im übrigen finde ich deinen Beitrag witzig.

Ich möchte mich aber nicht durch die Verwendung von Nicht-Standardbefehlen auf FastObjects festlegen, sondern suche mehr eine Open Source Standart Objekt Datenbank, wie sie jetzt wohl vom Jakarta Projekt in der Entwicklung ist.

Cybis Interpretierung: Ich möchte nicht eine teure FastObjects sondern eine gratis Jakarta. Ich möchte nicht einen bezahlten Consultant bemühen, sondern hier gratis Lösungen erhalten;o)

Warum denke ich so? JDO und somit Versant ist eher Standard als die meisten Implementierungen auf Jakarta. Jakarta Projekte hingegen sind frei / gratis aber nunmal in der Regel nicht Standard, denn Projekte wie Torque sind weit weg vom Standard. OJB wird JDO irgendwann mal wirklich supporten (angestrebt bei 2.0 wenn ich mich nicht irre). Etc. etc.

cybi
 
Hallo Cybi,

vielen Dank für deine ausführlichen Erläuterungen. Du hast meinen zitierten Satz in der Tat richtig verstanden. Ich hatte hier auf eine effektive und kostengünstige Lösung gehofft, weil sich die von dir erwähnten Datenbanksysteme im fünfstelligen Bereich bewegen.

Nun habe ich mich drei Tage lang, 18 Stunden am Tag incl. Freizeit, mit den Dokumentationen der verschiedensten Datenbanken herumgeplagt. Zum Dank setzt mir mein Chef heute die Pistole auf die Brust und möchte greifbare Resultate sehen. Er hat mir als "Leitender Programmierer" (ohne Java Kenntnisse) befohlen, die PostgreSQL Datenbank zu verwenden und für alle zu speichernden Klassen jeweils eine separate Tabelle anzulegen, also eine Objekt-Tabelle ohne Relationen. Damit wären dann alle Probleme gelöst.

Trotzdem Danke für eure Hilfe.

Grüße, Sandra
 
Original geschrieben von Valentin-
Das mit der Overhead würde ich nicht unterschreiben halte ich für fraglich.
Das war damals bei 1.1. so, aber seit der HotSpot VM und der relational GC
ist das nicht mehr so der Fall.
Ciao

schön - stimmt aber trotzdem. Daher ist Java im numerischen Bereich noch vergleichsweise (zu Fortran z.B.) langsam, da es keine "leightweight" Objekte für numerische Klassen gibt (siehe dazu auch Ninja, link habe ich keinen, aber darüber musste ich mal Seminar halten) und ich weiss von einem Lehrstuhl bei uns der obiges Verfahren aus genau diesem Grund implementiert hat.

Es ist einfach so - gc kostet Zeit (und wird immer), Speicher vom OS anfordern und releasen kostet Zeit und diesen mit den Objekt-Headern zu füllen kostet auch Zeit. Daher ist es vielleicht besser geworden - aber gut ist es sicher noch nicht.
 
Zurück