[erledigt] Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
buhtz
Beiträge: 1105
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

[erledigt] Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von buhtz » 30.12.2017 05:59:39

Ich denke gerade darüber nach, wie ich effizient und insbesondere ressourcensparend Daten in meiner Anwendung halten kann.

Es geht um 100 bis 200 Newsfeeds. Deren Meta-Daten sind in einer JSON-Datenstruktur vorhanden, die in einer Datei persistent gespeichert sind und bei Anwendungsstart ins RAM geholt werden und dort auch verbleiben.

Der Knackpunkt sind nun die Einzeleinträge (nenne ich jetzt mal "Nachrichten") je Feed. Mit enstprechender Nutzungszeit des Newsreaders kommen da schnell mehrere 1000 "Nachrichten" je Newsfeed zusammen. Wann ich diese Daten brauche, kann ich nicht voraussehen, weil ich nicht weiß, welche Feeds der Nutzer anklicken wird.
  1. Eine echte Dantenbank drunter legen, die solche Dinge für mich "lösen" würde, möchte ich nicht.
  2. Ich könnte je Feed eine eigenen Daten mit den Einzelnachrichten (auch im JSON-Format) anlegen. Die wird dann bei Bedarf geöffnet und ins RAM gelesen.
  3. Ich könnte alle diese Dateien (100-200) Stück bei Programmstart schon mal öffnen, aber noch nicht lesen. Das spart RAM. Würde es die Zugriffszeit verbessern?
  4. Alle Dateien und deren Daten (ca 200 x 2000 Feeds) bei Programmstart öffnen und ins RAM holen... Klingt nach overhead.
  5. Ich könnte auch ein bisschen jonglieren: Je Newsfeed, ungelesene "Nachrichten" in eine Dateie, die gelesenen der letzten drei Monate in eine zweite Datei und den noch älteren Rest in eine Dritte. Komplex. Ob das durch den Benefit aufgewogen wird?
Mhm... Was meint ihr?
Zuletzt geändert von buhtz am 28.08.2019 11:38:01, insgesamt 2-mal geändert.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
shoening
Beiträge: 898
Registriert: 28.01.2005 21:05:59
Lizenz eigener Beiträge: MIT Lizenz

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von shoening » 30.12.2017 09:07:28

Hi,

im Sinne von „premature optimization is the root of all evil.“ würde ich erst mal in etwa Deine 2. Lösung implementieren (1 Verzeichnis pro Feed und pro Nachricht eine Datei) implementieren.

Wenn das dann zu langsam ist, legst Du um Deine Methode/Funktion einen Proxy, der z.B. einen LRU-Cache implementiert.
Einen LRU-Cache gibt es fertig in der Python Standard Bibliothek „functools“ - Batteries incuded :-).

Damit trennst Du dann ganz natürlich Deine eigentliche Funktionalität von dem „Optimierungscode“ und kannst beides auch unabhängig voneinander testen.

Ciao
Stefan
Zuletzt geändert von shoening am 30.12.2017 10:19:32, insgesamt 1-mal geändert.
Bürokratie kann man nur durch ihre Anwendung bekämpfen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von Meillo » 30.12.2017 10:01:37

Ich moechte hier auch gerne meine Gedanken zur Optimierung einbringen, die ich in einem Vortrag zusammengestellt habe: http://marmaro.de/docs/chaosseminar/on-performance/

Im Videomitschnitt ab 0:36:50 betrachte ich genau diese Situation, ueber die du hier nachdenkst, bei rss2email. Das solltest du dir anschauen und darueber nachdenken, bevor du unbewusst in das gleiche Problemmuster verfaellst.
Use ed once in a while!

inne
Beiträge: 3281
Registriert: 29.06.2013 17:32:10
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von inne » 30.12.2017 14:40:54

buhtz hat geschrieben: ↑ zum Beitrag ↑
30.12.2017 05:59:39
  1. Eine echte Dantenbank drunter legen, die solche Dinge für mich "lösen" würde, möchte ich nicht. Das wäre mir zu aufgebläht für den Anwendungsfall und würde Abhängigkeiten zu weiteren Paketen (z.B. sqlalchemy und sqlite) schaffen.
Deine Datenbank wie sqlite wirst du brauchen – weil alles andere ungut ist.

ChronoBoost
Beiträge: 140
Registriert: 29.01.2013 11:03:50

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von ChronoBoost » 30.12.2017 15:32:31

Zumindest sqlite ist doch schon in jeder python Distribution enthalten und ein import sqlite3 sollte den Quellcode weniger aufblähen als die ganze Funktionalität selbst zu implementieren (Sortieren, Transaktionen, Joins usw.). Die Konfiguration könntest Du ja in den json Dateien belassen, so dass sie mit dem Texteditor einfacher geändert werden können.

Milbret
Beiträge: 827
Registriert: 26.05.2008 12:04:54
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Nörten-Hardenberg
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von Milbret » 30.12.2017 22:13:35

Klingt wegen JSON weniger nach einer Relationalen DB wie Sqlite und mehr einer Dokumenten DB.
Diese speichern dann JSON Strukturen und bieten auch die Möglichkeiten zu entsprechenden Abfragen mit eigenem Syntax.
Dürfte hier aber auch mit Sqlite gehen, musst dann eben deine JSON Objekte auf die Tabellen mappen.
Je nach Umfang der Struktur hast du dann einige Tabellen und mit der Zeit auch entsprechend große DBs.

Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever :D

buhtz
Beiträge: 1105
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von buhtz » 31.12.2017 06:03:24

Datenbank ist keine Option und möchte ich an dieser Stelle auch nicht diskutieren. Habe (ausnahemsweise) in diesem Bereich ausreichend Erfahrung, um das beurteilen zu können. Eine Datenbank (auch so simple wie sqlite) wäre overkill - aus verschiedenen Gründen.
ChronoBoost hat geschrieben: ↑ zum Beitrag ↑
30.12.2017 15:32:31
Zumindest sqlite ist doch schon in jeder python Distribution enthalten und ein import sqlite3 sollte den Quellcode weniger aufblähen als die ganze Funktionalität selbst zu implementieren (Sortieren, Transaktionen, Joins usw.).
Diese "Funktionalität" ist meinem Szenario nicht notwendig.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
novalix
Beiträge: 1909
Registriert: 05.10.2005 12:32:57
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: elberfeld

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von novalix » 31.12.2017 13:41:55

Was ist eine Datenbank?
Ein RDBMS - auch ein leichtgewichtiges wie SQLite - verursacht in Deinem Szenario mit Sicherheit einen fehleranfälligen Mehraufwand in der Programmierung, da Du die Struktur der JSON-Objekte auf ein relationales Schema mappen müsstest.
Dafür kann man wie @Milbret schon anführte gerne NoSQL-Systeme verwenden (Mongo, RethinkDB, etc.)
Die sind aber meistens selbst nicht unfett und für potentiell größere Datenmengen und -operationen ausgelegt.
Dann gäbe es da auch noch Key-Value-Stores à la redis oder memcached.
https://db-engines.com/de/ranking/key-value+store
Das Wem, Wieviel, Wann, Wozu und Wie zu bestimmen ist aber nicht jedermannns Sache und ist nicht leicht.
Darum ist das Richtige selten, lobenswert und schön.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von Meillo » 31.12.2017 14:44:44

Stellen wir uns doch mal ganz dumm, denn in den meisten Faellen ist Brute Force der beste Ansatz ... jedenfalls bis man sich sicher ist, dass es nicht der Fall ist und dann ueberarbeitet man die Anwendung iterativ.

Also 200 Feeds, die du in einer Datei ablegst. Dann fuer jeden Feed eine eigene Datei in der die 2000 Eintraege abgelegt werden. Damit hast du 201 Dateien.

Die Feeddatei liest du beim Programmstart ein (notwendigerweise). Die anderen Dateien liest du dann ein wenn du sie brauchst.

Das Einlesen einer Datei ist fuer dein Nutzungsszenario sehr sicher ausreichend schnell, weil so ein Feedreader ja nicht oefter als sagen wir mal alle 10 Minuten die Feeds abruft.

Was den Arbeitsspeicherbedarf angeht, so kommt es darauf an, wieviel Datenmenge das je Feed tatsaechlich sind. Das kannst du ausrechnen. Je nachdem wie gross der Wert ist, musst dein Programm zwischendurch mal wieder Feeddaten freigeben oder nicht.


Ich sehe nicht ganz wo das Problem eigentlich liegt. Im Eingangspost schreibst du, dass der Knackpunkt sei, dass du nicht weisst wann die Feeddaten gebraucht werden ... aber du schreibst implizit auch, dass es dann sein wird, wenn der User auf den jeweiligen Feed klickt. Dann lade sie doch einfach in dem Moment. Wenn ich auf der Kommandozeile eine 2000-Zeilen-Datei sortiere (was Einlesen in den Speicher und noch verschiedene Rechnerei beinhaltet und damit in etwa dem entspricht was du machen musst) dann dauert das 0,05s -- das ist fuer den User unmerklich.

Ich schlage vor, dass du dir nicht so viele Gedanken machst, sondern einfach anfaengst und spaeter nacharbeitest, falls noetig.
Use ed once in a while!

Benutzeravatar
bluestar
Beiträge: 2346
Registriert: 26.10.2004 11:16:34
Wohnort: Rhein-Main-Gebiet

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von bluestar » 02.01.2018 00:03:09

Im Zeiten wo wir bei RAM-Größen im GB-Bereich leben, würde ich mir da auch keine all zu großen Gedanken über den Speicherbedarf machen.

Einfach mal loslegen wäre auch mein Ansatz...

buhtz
Beiträge: 1105
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von buhtz » 28.08.2019 11:37:52

Meillo hat geschrieben: ↑ zum Beitrag ↑
31.12.2017 14:44:44
Also 200 Feeds, die du in einer Datei ablegst. Dann fuer jeden Feed eine eigene Datei in der die 2000 Eintraege abgelegt werden. Damit hast du 201 Dateien.
...Ich schlage vor, dass du dir nicht so viele Gedanken machst, sondern einfach anfaengst und spaeter nacharbeitest, falls noetig.
Genauso hab ichs gemacht und komme bisher gut damit zurecht.

Eine JSON Datei für die Feeds.
Je Feed eine weitere JSON Datei mit den Feed-Beiträgen. Hier muss ich mir ab einigen 1000 Einträgen mal Gedanken um die Archivierung und das Verwerfen machen.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [erledigt] Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von Meillo » 28.08.2019 11:45:40

:THX:
Use ed once in a while!

uname
Beiträge: 12072
Registriert: 03.06.2008 09:33:02

Re: [erledigt] Python: Daten effizient in Dateien und/oder RAM ohne Datenbank halten

Beitrag von uname » 28.08.2019 12:27:07

Schau dir mal Berkley DB an, die unter anderen von SquidGuard zur Verwaltung und Echtzeitdurchsuchen von Millionen Backlisteinträge verwendet wird. Für Python schau hier. Scheinbar wurde die Lizenz geändert. Da musst du evtl. etwas aufpassen.

Antworten