Wenn man bei Änderungen der Daten nicht jedes Mal alles speichern will, bietet sich ein "append only"-Verfahren an, bei dem nur das Neue zu einer immer größer wachsenden Datei hinzugefügt wird. Wenn man sich nicht darauf verlassen will/kann, dass das Dateisystem transaktional ist, muss man aber wieder einigen Aufwand treiben. Auch das Einlesen der Daten wird aufwendiger. Und man ist immer noch auf den eigenen Hauptspeicher begrenzt. Kann mal alles noch relativ einfach bauen - oder etwas wie Redis benutzen.
Will man mehr speichern können, als in den Hauptspeicher passt, könnte man Index und Daten getrennt verwalten und hoffen, dass zumindest der Index in den Hauptspeicher passt. Nun gilt es aber beide Dateien zu sychronisieren bzw. beides wieder in eine "append only"-Datei zu stecken und etwas zu entwickeln, dass andere schon längst erfunden haben.
Wartet man noch etwas, kann Redis wohl auch virtuellen Speicher (auf Platte) effizient verwalten und alles wird gut. Oder man nutzt berkeleyDB oder ein vergleichbares System. Was anderes liegt letztlich auch nicht unter etwas wie Tokyo Tyrant drunter. Übrigens, größeres Kaliber wäre eine Document-DB wie Couch oder Mongo.
Noch einfacher ist es aber wahrscheinlich, einfach SQLite zu benutzen. Man definere sich eine Tabelle mit zwei Spalten: Key und Value und speichere als Werte gepickelte Python-Objekte. Möglicherweise ist eine einfachere Kodierung noch schneller. Weiß man etwa, dass man nur int, bool, str, bytes, list und dict in nicht-rekursiven Datenstrukturen ablegen können will, gibt es effiziente binäre Formate.
Dinge wie Tags oder eine Suchfunktion würde ich da oben drauf setzen. Hält man alles im Hauptspeicher, sind diese Dinge natürlich wieder trivial.
Die Trennung von Key und ID verwirrt mich übrigens. IMHO wäre die Eigenschaft des Keys, ein eindeutiger Schlüssel zu sein und jetzt noch einen zweiten Primärschüssel haben zu wollen finde ich komisch. Eine Indirektion mehr löst das Problem doch auch.
Stefan
jStore - simpler Key/Value Store mit JSON backend
Stimmt schon. Mein Ansatz ist, das wenn ich zum Beispiel User habe:Die Trennung von Key und ID verwirrt mich übrigens. IMHO wäre die Eigenschaft des Keys, ein eindeutiger Schlüssel zu sein und jetzt noch einen zweiten Primärschüssel haben zu wollen finde ich komisch. Eine Indirektion mehr löst das Problem doch auch.
Code: Alles auswählen
id key value
--------------------------------------------------------------------
1 u1@bla.de { 'password' : '12345', 'realname' : 'U1 Bla' }
2 u2@bla.com { 'password' : '54321', 'realname' : 'U2 Bla' }
Ohne KEY müsste ich ja mindestens 2 Datensätze haben.
Code: Alles auswählen
key value
--------------------------------------------------------------
unic_key_1 { 'password' : '12345', 'realname' : 'U1 Bla' }
unic_key_2 { 'password' : '54321', 'realname' : 'U2 Bla' }
key value
---------------------------
u1@bla.de 'unic_key_1'
u2@bla.com 'unic_key_2'
Das Konzept das Locking über Lockdateien zu realisieren erscheint mir daher gar nicht so abwegig, zumal ja auch andere z.B. Firefox einen solchen Mechanismus nutzen. Damit das Ganze auch dann noch funktioniert, wenn ein Prozess abstürzt, müsste es einen Timeout geben nach dem die Lockdatei auch von anderen Prozessen entfernt werden darf.
Da ja auch Lesezugriffe die Datei gegen Überschreibung sichern müssen, wären zwei verschiedene Lockarten sinnvoll. SharedLock und ExclusivLock.
Realisieren könnte man den SharedLock durch ein Verzeichnis in dem für jede PID eine Datei erstellt wird, die einen Timestamp und den Timeout enthält.
datei.txt
datei.txt.lock/
42342
98797
24377
Nachdem der Lock freigegeben wird, wird die PID-Datei entfernt. Sollte ein Prozess abstürzen, kann die Datei nach dem Timeout gelöscht werden.
Der ExclusivLock muss in dem Fall warten, bis alle Lesezugriffe beendet sind (hier sehe ich noch Schwierigkeiten aber dazu später mehr). Dieser erstellt nur eine einzige Datei, ebenfalls mit Timestamp und Timeout.
datei.txt
datei.txt.lock
Das Problem ist, dass der Schreibzugriff warten muss, bis alle SharedLocks beendet oder aufgeräumt wurden. In einem Szenario, wo es andauernde Lesezugriffe gibt, kann das natürlich ewig dauern. Besser währe daher eine Art Queue doch da gibt es dann das "Henne Ei" Problem da diese natürlich ebenfalls in irgendeiner Art gesperrt werden müsste. Andererseits wie realistisch ist es, das es so großen permanenten Zugriff gibt, dass die Datei ständig gelockt ist?
mokey
...oder du nimmst einfach Sqlite (siehe z.B. http://www.python-forum.de/post-165450.html#165450), denn dort hat jemand schon die ganze Locking-Problematik gelöst. Natürlich ginge auch ein externer KV-Store, doch Sqlite hat den Vorteil, eingebaut zu sein.
Stefan
Stefan