Forum: Mikrocontroller und Digitale Elektronik Raspberry Pi: Werte vom Temperaturlogger in SQL oder RoundRobin DB speichern?


von Bernd Schuster (Gast)


Lesenswert?

Hallo,

habe am Wochenende einen Raspberry Pi gekauft und an diesen aktuell 8 
DS18S20 Temperatursensoren angeschlossen. Das läuft auch soweit, wobei 
die Sensoren noch nicht an ihren späteren Stellen verbaut sind, sondern 
erst einmal nur fliegend an ein paar Metern Leitung. Der Raspberry soll 
im Grunde demnächst anfangen ein Leben lang zu loggen. Bzgl. der 
Datenmengen mache ihc mir ein paar sorgen bzgl. der Leistungsfähigkeit. 
So ganz grob überschlagen fallen ja die folgenden Daten an:
- jeder Sensor liefert 2 Byte (Nutz-)Daten für die Temperatur
- all 5min frag ich jeden Sensor nacheinander ab

-> bei 8 Sensoren macht das also:
100Jahre  365Tage  24h * 12Messwerte/h  8Sensoren  2Byte = ~160MByte

Dazu kommt dann noch die (SQL-)ID, der Timestamp und (einmalig) die 
Sensornr. zu jedem der 8 Sensoren

Idealerweise würde ich natürlich gerne alle Daten (in einer SQlite DB) 
aufheben, habe aber bedenken ob der Datenmengen und der vergleichsweise 
kleinen HW des Raspberry. Ist daher eher ein verwerfen von Daten unter 
Nutzung von Round-Robin anzuraten?

Hat da jemand von euch Erfahrungen? sonst mache ich einfach trial and 
error ;=)

Gruß, Bernd

P.S: Der Raspberry soll ansonsten noch einen Webserver bereitstellen der 
ein paar schöne Logs anzeigt, daneben aber keine weiteren Dienste 
anbietet

von Karl H. (kbuchegg)


Lesenswert?

Bernd Schuster schrieb:

> 100Jahre


du bist ja sehr optimistisch :-)
Wie alt ist eigentlich dein PC?

von Karol B. (johnpatcher)


Lesenswert?

Bernd Schuster schrieb:
> Dazu kommt dann noch die (SQL-)ID, der Timestamp und (einmalig) die
> Sensornr. zu jedem der 8 Sensoren

Und was heißt einmalig? Wenn du das Ganze normalisiert ablegen willst, 
dann musst du zu jedem Datensatz eine Sensornummer ablegen.

Das reine Ablegen der Daten ist übrigens überhaupt kein Problem, sofern 
genug Speicher vorhanden ist. Interessant wird es erst bei (komplexen) 
Anfragen. Dann wirst du aber schnell merken, dass sich ein Raspberry Pi 
kaum für High-Performance Datenbankanwendungen eignet.

Ansonsten machst du dir hier Gedanken über Probleme, die keine sind. 
Kein Mensch weiß wie lange dein Raspberry Pi überhaupt überleben wird. 
100 Jahre werden es wohl kaum werden.

Um wirklich "dauerhaft" und sicher zu speichern, kommst du um Redundanz 
nicht herum. Schick die Werte an einen "vernünftigen" Rechner, da ist 
die Verarbeitung und Archivierung von etlichen Gigabytes überhaupt kein 
Problem.

Mit freundlichen Grüßen,
Karol Babioch

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Bernd Schuster schrieb:

> erst einmal nur fliegend an ein paar Metern Leitung. Der Raspberry soll
> im Grunde demnächst anfangen ein Leben lang zu loggen. Bzgl. der
> Datenmengen mache ihc mir ein paar sorgen bzgl. der Leistungsfähigkeit.
> So ganz grob überschlagen fallen ja die folgenden Daten an:
> - jeder Sensor liefert 2 Byte (Nutz-)Daten für die Temperatur
> - all 5min frag ich jeden Sensor nacheinander ab
>
> -> bei 8 Sensoren macht das also:
> 100Jahre  365Tage  24h * 12Messwerte/h  8Sensoren  2Byte = ~160MByte
>
> Dazu kommt dann noch die (SQL-)ID, der Timestamp und (einmalig) die
> Sensornr. zu jedem der 8 Sensoren

So speichert man das zwar nicht, aber egal. Die Größenordnung kommt 
jedenfalls hin.

> Idealerweise würde ich natürlich gerne alle Daten (in einer SQlite DB)
> aufheben

Warum? Was glaubst du, wird es dir nützen, wenn du irgendwann mal weißt 
daß vor 63 Jahren, am 14. Februar 10:15 Uhr morgens der Sensor in der 
Waschküche 16.4°C gemessen hat und 10:20 Uhr dann 16.6°C?

> habe aber bedenken ob der Datenmengen und der vergleichsweise
> kleinen HW des Raspberry. Ist daher eher ein verwerfen von Daten unter
> Nutzung von Round-Robin anzuraten?

Auf jeden Fall. RRDtool ist für genau solche Anwendungen gemacht, wo die 
Anforderungen an die Auflösung der Daten umso geringer werden, je weiter 
die Daten in der Vergangenheit liegen. Konkret auf deine Umgebung 
bezogen, reicht es vermutlich, für ein paar Monate Meßwerte aller 5 
Minuten zu haben. Dann für einige Jahre den min/max/Mittelwert pro 
Stunde und schließlich für ein paar Dekaden den min/max/Mittelwert pro 
Tag. Als netten Nebeneffekt hat man dann eine konstante Größe der 
Datenfiles.

> Hat da jemand von euch Erfahrungen?

Ich hab mal ein Monitoring-Tool für ein paar Hundert Meßstellen (Server, 
Switches etc.) gebaut. Wie ein Vorposter schon bemerkte, ist das 
Speichern der Daten das kleinste Problem. Die Abfragen sind es. Die 
werden immer langsamer, je mehr Daten du hast. Und schon das simple 
Zeichnen eines Zeitdiagramms bedeutet eine Menge Aufwand für die 
Datenbank (erst recht, wenn man automatische Skalierung will, und das 
will man eigentlich immer).

Langer Rede kurzer Sinn: mit MySQL als Datenspeicher war das langsam und 
häßlich. Richtig schick wurde es erst, als ich auf RRDtool umgestellt 
habe. IMHO lohnt es sich nicht, für Zeitreihen überhaupt etwas anderes 
verwenden zu wollen.


XL

von Florian H. (heeen)


Lesenswert?

mach doch mal ein df -H auf deinem raspi, dann siehst du wieviel 
speicher du noch auf deiner SD Karte frei hast. Das werden 1-2 GB sein 
bei einer 4gb Karte.

Ich würde mir eher um das wear leveling von flash Speicher Gedanken 
machen.

von Karl Käfer (Gast)


Lesenswert?

Hallo Axel,

Axel Schwenke schrieb:
>> habe aber bedenken ob der Datenmengen und der vergleichsweise
>> kleinen HW des Raspberry. Ist daher eher ein verwerfen von Daten unter
>> Nutzung von Round-Robin anzuraten?
>
> Auf jeden Fall. RRDtool ist für genau solche Anwendungen gemacht,

Wenn das "auf jeden Fall" so wäre, würde der TO nicht fragen.

> Ich hab mal ein Monitoring-Tool für ein paar Hundert Meßstellen (Server,
> Switches etc.) gebaut. Wie ein Vorposter schon bemerkte, ist das
> Speichern der Daten das kleinste Problem. Die Abfragen sind es. Die
> werden immer langsamer,

Wenn man mit Datenbanken umgehen kann (und vielleicht nicht ausgerechnet 
MySQL benutzt), dann nicht. In PostgreSQL kann man beispielsweise die DB 
mithilfe des Vererbungs-Feature partitionieren und über einen Trigger 
auf INSERTs a) die Daten verteilen sowie b) veraltete Tabellen 
akkumulieren oder wegsichern oder oder oder...

LG,
Karl

von Bernd Schuster (Gast)


Lesenswert?

Hallo zusammen,

vorab schon mal danke für eure Antworten, wobei es mir weniger um den 
verfügbaren Speicher geht. Habe ein "All-In" Satz von Reichelt, da ist 
gleich eine 8GB Karte dabei. Selbst die könnte ich gegen was größeres 
tauschen.


@Karl Heinz: ok, das werde ich wohl nicht miterleben, bis zur 90 sind es 
nur noch 35 Jahre... Also halbieren wir die hundert mal ;=) War eher 
eine worst-case Rechnung um die max. Datenmenge zu ermitteln.
Was den PC angeht ging es beim 286 los, der 386SX war schon toll, aber 
mit dem DX ging die Post erst ab. Der 386DX steht immer noch im Keller 
mit DOS und einigen Programmen, aber keine Angst: gibt auch was 
moderneres im Hause Schuster.

@Karol: Danke für die Erklärungen, habe mich da mal ein wenig belesen 
und war völlig auf dem Holzweg was die interne Struktur anging. Das 
Platz nicht das Problem ist, war mir wohl bewusst. Geht mir auch eher um 
Abfragen, z.B. zeichne mir die Temperatur übers Jahr unter Berechnung 
eines Mittelwertes pro Tag (oder min/max), oder Temperatur im Januar der 
letzten 10 Jahre, oder, oder, oder.
Wie gesagt: um die Speicherung an sich mache ich mir weniger Sorgen, 
eher um den Betrieb und Abfrage der Daten über das Webinterface für 
Grafiken.

@Axel: die Waschküche interessiert mich wirklich weniger, aber alle vier 
Seiten des Hauses, Dachgeschoss, Kessel & Boiler sowie Garage. Würde 
mich schon interessieren wie z.B. die Temperaturen vor einem Jahr waren. 
Ob das Sinn macht: ehrlich gesagt nein. Ist eher die Neugier.
Hast du ggf. Grenzen bzgl. Performance bei Round-Robin parat? Meine 
Vorstellung wäre sonst:
1,5 Jahre alle Werte zu speichern (Vergleich zum Vorjahr mit ein wenig 
Überlappung möglich)
dann auf Mittelwert/min/max über 3h zusammenfassen (aufstehen um kurz 
nach sechs), Rückkehr gegen 17Uhr-18Uhr jeweils mit Werten erfasst
nach 10 Jahren dann auf einen Tag

@Florian: das soll die Karte mal schön selber übernehmen, 
schlimmstenfalls ist sie halt kaputt. Könnte die Daten ja alle 24h aufs 
NAS schieben (lassen).


Danke für eure Erfahrungen, wird demnach wohl auf Round-Robin 
hinauslaufen. Gibt dazu ja genügend Beispiele im Netz, werde dann 
nächstes WE und über die Feiertage mal schauen.
Frage am Rande: kann man alte RRT Dateien "importieren"? Hintergrund: 
würde die dann jeden Monat sichern und irgendwo ablegen um sie bei 
Bedarf rauskramen zu können für Detailwerte.


Danke und Grüße, Bernd

von c-hater (Gast)


Lesenswert?

Bernd Schuster schrieb:

> -> bei 8 Sensoren macht das also:
> 100Jahre  365Tage  24h * 12Messwerte/h  8Sensoren  2Byte = ~160MByte
>
> Dazu kommt dann noch die (SQL-)ID, der Timestamp und (einmalig) die
> Sensornr. zu jedem der 8 Sensoren

Wer Timestamps hat, braucht keine zusätzlichen IDs. Und wer das Prinzip 
einer Daten-Spalte entdeckt hat, braucht keine Sensornummern zu 
speichern, sondern sieht einfach eine entsprechende Anzahl Spalten vor. 
Und übrigens: zum Speichern von Timestamps braucht man nicht unbedingt 
den so benannten Datentyp zu verwenden, wenn dieser für den geplanten 
Zweck viel zu genau ist, da tut es auch ein (U)Integer, bei dem dann 
halt ein Zählschritt 5 Minuten entspricht und der Wert 0 dem 
Startzeitpunkt der Aufzeichnung. Die Umrechnung von Zeit zu proprietärer 
Zeitstempel und zurück ist trivial, man kann das entweder mit 
Datenbankfunktionen oder Funktionen im Anwenderprogramm erschlagen.

Kurzfassung: zu deiner obigen Rechnung kommt nur noch der 
Int-Zeitstempel mit vier Byte dazu, der reicht dann sicher auch für ein 
wesentlich längeres Leben. Ideal wäre für deine Anforderungen ein 
uint-Datentyp mit drei Byte, aber den jibbet wohl nicht bei SQlite. 
Möglichwerweise gibt es aber die Möglichkeit, Custom-Datentypen zu 
bauen, keine Ahnung. Dann könnte es doch was werden mit dem idealen 
Datentyp für deinen Zeitstempel.

> Idealerweise würde ich natürlich gerne alle Daten (in einer SQlite DB)
> aufheben, habe aber bedenken ob der Datenmengen und der vergleichsweise
> kleinen HW des Raspberry. Ist daher eher ein verwerfen von Daten unter
> Nutzung von Round-Robin anzuraten?

SQlite ist ganz nett für kleinere Datenbestände. Richtest du auf einem 
richtigen Rechner noch eine richtige DB ein und auf dem RasPi einen Job, 
der die kleine mit der großen DB synchronisiert, wann immer die große DB 
verfügbar wird und danach denn die lokale DB nach unten hin ausdünnt, 
hast du alles: kleine Datenbestände auf dem RasPi und trotzdem alle 
Daten und diese auf einer Maschine, die mit den Datenmengen auch 
tatsächlich umgehen kann.

Das wirst du spätestens zu schätzen lernen, wenn du z.B. mal wissen 
willst, wie hoch etwa der größte Temperaturgradient innerhalb einer 
Stunde über alle Meßstellen und den gesamten Meßzeitraum war. Da dürfte 
der Pi schon eingehen wie eine Primel, wenn er auch nur aus dem 
Datenbestand eines Jahres das Ergebnis extrahieren soll. Das läuft 
nämlich auf einen Self-Join einer Tabelle mit 365*24*12=ca. 100.000 
Zeilen hinaus, die beim join entstehende (virtuelle) Zwischentabelle hat 
also flockige 100.000*100.000=10.000.000.000 Zeilen. Da rechnet auch ein 
ordentlicher Desktop-PC schon eine geraume Weile dran, aber er kommt 
immerhin zu einem Ergebnis, und das sehr deutlich bevor die 100 Jahre 
deiner geplanten Lebenszeit abgelaufen sind...

Der RasPi hingegen würde wegen Speichermangel schlicht abkacken. Selbst 
mit allen Tricks, die sich die Entwickler von RDBMs im Laufe der Zeit 
haben einfallen lassen, um den Impact solcher Riesenjoins zu minimieren, 
es bleibt immer noch genug über, um den RasPi völlig zu überfordern.

Das ist nur ein Kinderspielzeug, kein Datenbankserver!

von Karol B. (johnpatcher)


Lesenswert?

c-hater schrieb:
> Und wer das Prinzip
> einer Daten-Spalte entdeckt hat, braucht keine Sensornummern zu
> speichern, sondern sieht einfach eine entsprechende Anzahl Spalten vor.

Und wer das so macht hat das Prinzip der Normalisierung nicht 
verstanden.

Überhaupt scheinen mir hier viele mit Kanonen auf Spatzen schießen zu 
wollen und ihre persönlichen Vorlieben mit einbringen zu wollen. MySQL 
ist kein richtiges DBMS? Auch wenn ich das für ein Klischee halte, 
welches größtenteils auf Erfahrungen mit alten MySQL Versionen basiert 
und diese Einschätzung nicht teile, so spielt das in diesem Fall doch 
überhaupt keine Rolle. Partionierung? Ernsthaft? Wir sprechen hier über 
eine Datenmenge, die selbst ein Raspberry Pi in den Arbeitsspeicher 
bekommt. Die Anforderungen an die Anfragen halten sich auch in Grenzen 
und lassen sich im Prinzip alle direkt mit einer entsprechenden 
Indexstruktur berechnen.

Soll heißen: Nimm was immer du willst (MySQL, PostgreSQL, SQLite) und 
mach einfach mal. Solange du die Daten vernünftig ablegst (Stichwort: 
Normalisierung) lässt sich das im Fall von konkreten 
Performanceengpässen problemlos migrieren.

Wear-Leveling hingegen ist ein echtes Problem. Meiner Erfahrung nach 
gibt es nämlich viele Stufen zwischen "funktioniert" und "kaputt", die 
sich oft durch verschiedenste Macken bemerkbar machen und auf der ersten 
Blick nicht zusammenhängen. Hier würde ich in der Tat präventiv werden, 
z.B. durch den Einsatz einer Ramdisk, und die Daten bei Zeiten in 
sicheres Terrain verfrachten.

Mit freundlichen Grüßen,
Karol Babioch

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Karol Babioch schrieb:

> Und wer das so macht hat das Prinzip der Normalisierung nicht
> verstanden.

Vollständige Normalisierung kann auch der Untergang sein. Das erklärt, 
warum praktisch keine realexistierende DB mit nennenswerter Zeilenzahl 
vollständig nomalisiert ist.

Der Unterschied in SQL:

Meine Variante:

create table
 temperatures
(
 ts int primary key,
 sens1 int16,
 sens2 int16,
 ...
 sens8 int16
);

..fertig

Deine Variante:

create table
 sensors
(
 id int primary key,
 ...was es sonst noch über den sensor zu speichern gibt
)

create table
 temperatures
(
 ts int,
 sens int foreign key references sensors(id),
 value int16,
 primary key (ts,sens)
)

..fertig?

Nicht ganz... Hier zeigt sich nämlich schon das erste Problem. Für die 
temperatures-Tabelle ist es nicht mehr möglich, ts als Primärschlüssel 
zu benutzen. Hier braucht man einen Primärschlüssel, der über zwei 
Spalten reicht. Das ist in SQL natürlich möglich, aber es ist schon von 
vorherein deutlich ineffizenter bei ALLEN Operationen, die den 
Primärschlüssel bzw. seinen Index benutzen.

Aber jetzt wird's hammerhart: Meine Beispielabfrage, angewendet auf 
diese zwei Beispiel-DBs, die dieselben Informationen enthalten, also 8 
Sensoren und deren Meßwerte alle 5 Minuten über ein Jahr.

Die Ausgangsbedingungen sind dann:

Meine Variante enthält eine Tabelle mit gut 100.000 Zeilen. Deine 
Variante zwei Tabellen, davon eine mit 8 Zeilen und eine mit gut 800.000 
Zeilen.

Die Abfragen lauten nun (nur der kritische Teil, der eine 
Zwischentabelle erstellt, wie sie auch die DB intern erstellen würde, um 
die Aggregatfunktionen darauf anzuwenden):

Meine Variante:

select
 t1.sens1,
 t1.sens2,
 ...
 t1.sens8,
 t2.sens1,
 t2.sens2,
 ...
 t2.sens8
from
 temperatures as t1
 join temperatures as t2 on t1.ts+12=t2.ts;

Hier sind 100.000 Zeilen * 100.000 Zeilen * 1 Vergleich zu erledigen. 
Also
*10.000.000.000*
Operationen.

Deine Variante:

select
 t1.value,
 t1.sens,
 t2.value
from
 temperatures as t1
 join temperatures as t2 on t1.ts+12=t2.ts and t1.sens=t2.sens;

Hier sind 800.000 Zeilen * 800.000 Zeilen * 2 Vergleiche plus deren 
logische Verknüpfung zu erledigen. Letzteres erfolgt im 
Kurzschlußverfahren, knallt also zu deinem Gunsten nur halb rein. 
Trotzdem ergibt sich immer noch folgender Aufwand:
800.000 Zeilen * 800.000 Zeilen * 1 Vergleich +
800.000 Zeilen * 800.000 Zeilen * 1/2 Vergleich
Insgesamt
*960.000.000.000*
Operationen.

Also mal flockig der 96fache Rechenaufwand.

Danach sind dann beide Varianten weitgehend gleich, weil sich die höhere 
Zeilenzahl der Zwischentabelle deiner Variante und die höhere Zahl der 
nötigen Operationen bei der Zwischentabelle meiner Variante bei der 
Aggregatbildung ziemlich exakt ausgleichen.

von Axel S. (a-za-z0-9)


Lesenswert?

Bernd Schuster schrieb:
> @Axel:

> Hast du ggf. Grenzen bzgl. Performance bei Round-Robin parat? Meine
> Vorstellung wäre sonst:
> 1,5 Jahre alle Werte zu speichern (Vergleich zum Vorjahr mit ein wenig
> Überlappung möglich)
> dann auf Mittelwert/min/max über 3h zusammenfassen (aufstehen um kurz
> nach sechs), Rückkehr gegen 17Uhr-18Uhr jeweils mit Werten erfasst
> nach 10 Jahren dann auf einen Tag

Das ist gar kein Problem. Pro Sensor kriegst du so ein ca. 2.7MB 
Datenfile für 1.5 Jahre alles + 10 Jahre min/max/avg über 3h + 100 Jahre 
min/max/avg über 24h. Da werden dann alle 5 Minuten mal jeweils einige 
10 Bytes drin geändert. Pillepalle.

Ich hatte damals bei meinem ex-AG knapp 1GB RRD-Files. Oben drauf hockte 
ein simpler in C geschriebener Daemon, der auf einem UDP-Port auf Pakete 
für RRD-Updates lauschte. Der hat vollkommen unauffällig (weniger als 1% 
CPU auf einem alten 800MHz(?) Pentium3) die Meßwerte von ca. 100 Servern 
entgegen genommen. Wobei manche der Server nicht nur ihre eigenen Daten 
angeliefert haben, sondern auch noch Daten für ein gutes Dutzend 
Ethernet-Switches (die sie von denen per SNMP abgeholt haben). Alles in 
allem waren das über 10000 Datenquellen in gut 1000 RRD Files.

Auf dem gleichen Server lief auch unser Intranet. Und darin per PHP 
erzeugt die Graphen von RRD.


Bernd Schuster schrieb:
> Frage am Rande: kann man alte RRT Dateien "importieren"? Hintergrund:
> würde die dann jeden Monat sichern und irgendwo ablegen um sie bei
> Bedarf rauskramen zu können für Detailwerte.

Klar doch. man rrddump; man rrdrestore

Braucht man z.B. auch, wenn man nachträglich Änderungen an der 
Definition der RRD Files vornehmen will (z.B. ein RRA länger machen). 
Dann dumpt man die alten Daten, legt das RRD File neu an und lädt die 
alten Daten wieder rein. BTDTMT.

-----

Wenn man die Daten nicht in ein round-robin Archiv legen will, dann 
würde man trotzdem keine relationale Datenbank nehmen, sondern (binäre) 
flatfiles. Pro Sensor gibt es dann eine Anzahl Files. Jedes File 
speichert eine feste Anzahl Datenpunkte, z.B. für 30 Tage. Da die 
Datenpunkte auf einem festen Raster liegen, reicht es, die Anfangszeit 
und die Sensornummer in den Filenamen (bzw. vorgelagerte 
Verzeichnisnamen) zu codieren. Zum Zugriff wird so ein File einfach per 
mmap() in den Speicher gemappt und wie ein Array benutzt.

Das einzige was ein bisschen Hirnschmalz erfordert, ist die Speicherung 
und Auswertung des Wertes für "keine Messung".


XL

von Bernd Schuster (Gast)


Lesenswert?

Hallo zusammen,

danke für die Erläuterungen. Nach euren Ausführungen bin ich nun weg von 
SQL, das übersteigt dann doch ein wenig meine Anforderungen und 
Kapazitäten des kleinen Raspberry. Größtenteils bin ich da aber auch 
überfordert, so einen guten Einblick habe ich dann doch nicht.

@Axel: danke. Tendiere aktuell zu Round-Robin und nach deinen 
Anmerkungen parallel zu einer Text/CSV Datei pro Sensor pro Monat (ggf. 
auch pro Tag). Ersteres kann der Raspberry verarbeiten, die Textdateien 
fürs Archiv auf dem NAS. Wenn der Raspberry performant genug ist, würde 
ich ihn sonst auch noch gleich Stunden/Tages min/max/Schnittwerte in 
einer extra Textdatei berechnen lassen, da der Raspberry eh immer laufen 
muss und der Zeit genug hat. Speicherplatz ist halt vorhanden, und 
Berechnungen die mich interessieren kann er auch vorab erledigen.

Gruß, Bernd

von Axel S. (a-za-z0-9)


Lesenswert?

Bernd Schuster schrieb:

> @Axel: danke. Tendiere aktuell zu Round-Robin und nach deinen
> Anmerkungen parallel zu einer Text/CSV Datei pro Sensor pro Monat (ggf.
> auch pro Tag).

Das würde ich nun nicht machen. Entweder oder. Wenn die primäre 
Anwendung das Zeichnen eines/mehrerer Diagramme auf einer Webseite ist, 
dann bietet sich RRD als Speicherformat an. Flat File wäre die 
Alternative, wenn wirklich zwingend alle Meßwerte aufgehoben werden 
müssen. Und auch dann solltest du davon abgehen, jede Zeile mit 
Timestamp zu speichern. Sonst ist am Ende der Timestamp die größte 
Spalte in deinen Daten.

> Ersteres kann der Raspberry verarbeiten, die Textdateien
> fürs Archiv auf dem NAS.

Der Output von "rrdtool dump" ist doch Text.

> Wenn der Raspberry performant genug ist, würde
> ich ihn sonst auch noch gleich Stunden/Tages min/max/Schnittwerte in
> einer extra Textdatei berechnen lassen

Auch die sind im Dump des RRD mit drin, vorausgesetzt du hast die 
entsprechenden RRA's definiert.


XL

von old man (Gast)


Lesenswert?

Wenn es nur um Temperaturen in einem bestimmtem Messintervall geht, dann 
nehme ich für diesen Zweck eine low-level Datei. Jeder Record bekommt 
einen 32bit Zeitstempel und n*16bit Messwerte. Genauer als 16bit ist in 
der Regel keine physik. Größe im Heimgebrauch. Mit anderen Worten eine 
binäre Datei mit fester Recordlänge. Als Intervall werden z.B. 2 Minuten 
gewählt. Bei 64 Messwerten ergibt das ca. 277Mb pro Jahr. Die 
Schreibroutine sorgt dafür, dass ab dem ersten Wert immer alle Records 
geschrieben werden. Dabei werden Lücken mit Dummywerten gefüllt. Selbst 
nach 20 Jahren und einer Datei von ca. 5GB braucht man nur 2 
Leseoperationen auf die Datei um die Werte zu einem bestimmten Zeitpunkt 
zu bekommen. Einmal die ersten 4 Byte am Anfang um den Startzeitpunkt zu 
ermitteln. Daraus ergibt sich dann ein fester Offset in die Datei wo die 
Daten stehen. Eine einfache Konsistenzprüfung erfolgt über den 
Zeitstempel jedes Eintrags gegen seine Position in der Datei.
Das ganze macht zwar erst mal ein wenig Arbeit, spart aber den 
kompletten Overhead einer Sql-Datenbank und ist obendrein noch schneller 
und kompakter. Wenn ich z.B. einen bestimmten Monat analysieren will, 
lese ich ab dem Startoffset (n*16+32)*31Tage Bytes aus der Datei in den 
Speicher und mache die Analyse ausschließlich im Speicher.
Nur mal so als Beispiel wie es auch ohne Sql gehen kann. cvs-Dateien 
oder Textformate ohne feste Recordlänge halte ich aber auch nicht für 
klug.

von Karl Käfer (Gast)


Lesenswert?

Hallo Bernd,

Bernd Schuster schrieb:
> danke für die Erläuterungen. Nach euren Ausführungen bin ich nun weg von
> SQL, das übersteigt dann doch ein wenig meine Anforderungen und
> Kapazitäten des kleinen Raspberry.

Deine Anforderungen vielleicht, die Kapazitäten des RasPi sicher nicht.

Sogar die mit Abstand leistungsfähigste der hier besprochenen 
Datenbanken, PostgreSQL, läuft wunderbar rund auf dem RasPi. Damit ist 
es kein Problem, veraltete Daten automatisch zu verwerfen, zu 
akkumulieren, sie in andere Tabellen oder Logdateien zu überführen oder 
oder oder... die Möglichkeiten werden dabei nur durch Deine Fähigkeiten 
begrenzt.

Viel Erfolg mit Deinem Projekt,
Karl

von c-hater (Gast)


Lesenswert?

Karl Käfer schrieb:

> Sogar die mit Abstand leistungsfähigste der hier besprochenen
> Datenbanken, PostgreSQL, läuft wunderbar rund auf dem RasPi.

Dann frage sie doch einfach mal die von mir vorgegebene Frage...

Also: Bei welchem Sensor gab es im letzten Jahr innerhalb einer Stunde 
den größten Temperatursprung und wie groß war der?

Dann wirst du sehen, wie "wunderbar rund" PostgreSQL auf dem RasPi 
tatsächlich läuft...

Und PostgreSQL ist wirklich ein sehr schönes und hervorragend 
optimiertes relationales DB-System. Aber auch die Postgre-Entwickler 
können nunmal keine Wunder vollbringen. Wenn die Komplexität einer 
Abfrage die Resourcen der Maschine überfordert, dann ist das halt so. Da 
hilft kein Wunschdenken und kein Verbreiten gegenteiliger Behauptungen, 
sondern nur eins: eine leistungsfähigere Maschine.

von Bernd Schuster (Gast)


Lesenswert?

Hallo zusammen,

danke für eure Anmerkungen., so langsam bekomme ich immer mehr eine 
Vorstellung davon was ich wirklich will und am Ende mit vertretbarem 
Aufwand auch realisierbar ist.

@Axel: Großeltern (schon lange tot) hatten einen Bauernhof, die hatten 
noch Aufzeichnungen von jedem Tag in Kladden. Interessanterweise konnte 
man mit den Daten im Frühjahr sehr gut vorhersagen wie die Ernte ausfiel 
(mal abgesehen von ein paar Ausreißern). Daher der Wunsch irgendwie alle 
Werte zu behalten, ist eher eine Macke aus der Kindheit. Primär 
interessiert aber nur ein Verlauf in Form eines Graphen.
Was den Timestamp angeht: dann wird die Datei halt 50MB größer. Stört 
das die SD-Karte? Außerdem habe ich so eine Sicherung gegen 
Stromausfall, verschlampte Sensorwerte o.ä., als wenn ich nur über einen 
C-Pointer stumpf an eine Stelle auf Grundlage der Anzahl von Messwerten 
springe.
Das RRD die gewünschten Werte gleich mit berechnet und ausgibt wusste 
ich nicht. Muss mich weiterhin einlesen.

@old man: da fehlt mir die "einfache" Auswertung. Hatte mir in der 
Vergangenheit einmal http://dygraphs.com angesehen, aber dafür müsste 
ich mir ein Array selber im Speicher aufbauen und ob das überhaupt auf 
dem Raspberyy läuft kann ich auch noch nicht sagen.

@Karl & c-hater: komplexe DB Abfragen wie die genannte benötige ich 
wahrscheinlich gar nicht, bzw. kann mir das aktuell nicht vorstellen. Es 
geht rein um die Aufzeichnung und Darstellung von Temperaturkurven. 
Einzig die Zeiträume (z.B. alle Daten jedes aufgezeichneten Januars) 
sollten sehr variabel sein. Zusätzlich interessieren mich halt noch 
min/max/Mittelwerte.

Danke und Gruß,

Bernd

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

ich zeichne diverse Wetterdaten (Temperaturen, Luftdruck, 
Luftfeuchtigkeiten, Helligkeiten etc.) teilweise seit 3 Jahren mit einen 
Dockstar-Dinges auf und speichere die gewonnen Daten in einer SQLite-DB 
ab. Dabei werden alle Minute die Sensoren abgefragt. Die Datenbankgröße 
liegt derzeit bei ca. 370MB und rund 4,7 Millionen Datensätzen.

http://bergeruw.spdbs.org/~bergeruw/temp  (wenn es mal erreichbar 
ist...)


Wenn man sich ein paar Gedanken um die Strukturierung der Daten macht, 
sinnvolle Indizes auf Tabellen legt etc. ist die ganze Sache auch 
performant genug, um auch anspruchsvolle Abfragen in "endlicher" Zeit zu 
erledigen.

Hammerabfrage bei mir ist beispielsweise ein Join über jeweils zwei 
Tabellen, um die gnuplot-Daten zur Generierung von sogenannten Heatmaps 
über ein ganzes Jahr zu generieren (Laufzeit für eine Heatmap ca. 7min). 
Klar ist natürlich, dass solche Dinge nicht ständig (z.B. stündlich) 
erfolgen sollten. Einmal am Tag, gesteuert via Cron, reicht vollkommen 
aus...

Wegen "Lebenszeit" SD-Karte bzw. bei mir USB-Stick --> meine SQLite-DB 
liegt auf dem NAS, das entsprechende Laufwerk ist ins Filesystem des 
Dockstar gemountet. Sämtliche temporären Daten werden ebenfalls in 
dieses Netzlaufwerk gelegt. Weiterhin läuft der Webserver zur Anzeige 
der Wetterdaten ebenfalls auf dem Dockstar, das entsprechende 
public_html-Verzeichnis liegt ebenfalls auf dem NAS... Das hat auch den 
Vorteil, dass man an die DB auch von anderen Rechnern ran kommt und 
lustige Dinge ausprobieren kann.

Also mit ein paar Überlegungen, teilweise "historisch gewachsen", geht 
es sehr gut und ist kein Hexenwerk und man muss auf die Vorzüge einer 
SQL-Datenbank nicht verzichten! Deshalb, nimm eine SQLite-Datenbank, 
speichere alle Rohdaten dort ab und komprimiere nicht nach ein paar 
Wochen, Monaten... Man weis nie, was einem noch so einfällt, was man so 
noch mit den Rohdaten machen könnte!

Grüße Uwe

von Karl Käfer (Gast)


Lesenswert?

Hallo,

c-hater schrieb:
> Karl Käfer schrieb:
>> Sogar die mit Abstand leistungsfähigste der hier besprochenen
>> Datenbanken, PostgreSQL, läuft wunderbar rund auf dem RasPi.
>
> Dann frage sie doch einfach mal die von mir vorgegebene Frage...
>
> Also: Bei welchem Sensor gab es im letzten Jahr innerhalb einer Stunde
> den größten Temperatursprung und wie groß war der?
>
> Dann wirst du sehen, wie "wunderbar rund" PostgreSQL auf dem RasPi
> tatsächlich läuft...
>
> Und PostgreSQL ist wirklich ein sehr schönes und hervorragend
> optimiertes relationales DB-System. Aber auch die Postgre-Entwickler
> können nunmal keine Wunder vollbringen. Wenn die Komplexität einer
> Abfrage die Resourcen der Maschine überfordert, dann ist das halt so. Da
> hilft kein Wunschdenken und kein Verbreiten gegenteiliger Behauptungen,
> sondern nur eins: eine leistungsfähigere Maschine.

Ach, weißt Du, wenn ich mir etwas Mühe gebe, dann kann ich mir für jede 
beliebige Maschine und jede beliebige Datenbank etwas ausdenken, um die 
Veranstaltung ins Schwitzen zu bringen. Und das, was Du da vorschlägst, 
ist dabei allerdings sogar noch eher witzlos, dank window functions und 
index-only scans (seit PostgreSQL 9.2). ;-)

Aber ja, wen wundert's: komplexe statistische Auswertungen sind auf dem 
Pi zwar möglich, erfordern aber ein wenig Zeit. Kein Problem: wenn man 
solche Daten gewinnen will, kann das der Pi in seiner Idle-Zeit 
vorberechnen (als Datenlogger hat er ja genug Idle-Zeit dafür) oder man 
lädt sich die Daten auf eine schnellere Büchse und kann dann mit R, 
Python+Matplotlib, Matlab oder Ähnlichem arbeiten. Ein Datenlogger (und 
darum geht es dem TO ja) muß keine riesige Rechenleistung haben. Wow, 
große Überraschung allenthalben. Wer hätte das denn ahnen können...

Und jetzt? Hast Du jetzt "gewonnen"? Dann bist Du ein ja ein richtiger 
kleiner Held!

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Angehängte Dateien:

Lesenswert?

Hi Bernd,

Bernd Schuster schrieb:
> @Karl & c-hater: komplexe DB Abfragen wie die genannte benötige ich
> wahrscheinlich gar nicht, bzw. kann mir das aktuell nicht vorstellen. Es
> geht rein um die Aufzeichnung und Darstellung von Temperaturkurven.
> Einzig die Zeiträume (z.B. alle Daten jedes aufgezeichneten Januars)
> sollten sehr variabel sein. Zusätzlich interessieren mich halt noch
> min/max/Mittelwerte.

In meinem Fall läuft auf dem RasPi ein kleiner Paste-Webserver mit einer 
Bottle.py-Webseite, der Temperaturdaten über AJAX zieht und daraus 
Kurven mithilfe von jQuery-Flotcharts zeichnet. (siehe Anhang) Der 
Vorteil: das Rendering findet auf dem schnellen Client statt, der RasPi 
macht nur einen simplen SELECT und stellt die Daten via AJAX bereit. Das 
SELECT ist dank Index auf der zeitpunkt-Spalte sehr schnell; natürlich 
könnte das ganz leicht etwa so umgebaut werdenm, daß statt eines 
Zeitraumes von n Tagen bis jetzt zwei Timestamps, einzelne 
Wochen/Monate/Jahre oder Ähnliches angegeben werden.

Übrigens: wenn Du komplexere Sachen machen willst, dann kann der Pi die 
natürlich mit einem Cronjob vorausberechnen. Ich könnte mir zum Beispiel 
vorstellen, mit Python + Matplotlib die Daten beispielsweise mehrerer 
Jahre übereinander zu legen und daraus hübsche Box-Whisker-Plots mit 
Standardabweichungen, Minima und Maxima zu zeichnen.

HTH,
Karl

von Axel S. (a-za-z0-9)


Lesenswert?

Karl Käfer schrieb:
> das, was Du da vorschlägst,
> ist dabei allerdings sogar noch eher witzlos, dank window functions und
> index-only scans (seit PostgreSQL 9.2). ;-)

Mal wieder ein Feature, das PostgreSQL von dem angeblich doch sooo 
unterlegenen MySQL übernommen hat. MySQL hat covering indexes übrigens 
seit ... schon immer.


XL

von c-hater (Gast)


Lesenswert?

Karl Käfer schrieb:

> Ach, weißt Du, wenn ich mir etwas Mühe gebe, dann kann ich mir für jede
> beliebige Maschine und jede beliebige Datenbank etwas ausdenken, um die
> Veranstaltung ins Schwitzen zu bringen.

Natürlich.

Allerdings ist meine Frage ja nun auch nicht so weit hergeholt, bei der 
Analyse von Sensordaten ist es ganz allgemein die erste Aufgabe, 
Irregularitäten im Datenmaterial zu finden und auszufiltern, bevor die 
eigentliche Auswertung erfolgt. Und was wäre deiner Meinung nach dazu 
besser geeignet als die Suche nach Sprüngen (und auch über längere 
Zeiträume quasikonstante Meßwerte, was von der Komplexität der Abfrage 
her exakt dieselbe Problematik darstellt)?

Wenn du zu blöd bist, den Sinn hinter solchen Abfragen zu erkennen, nur 
als Stichworte: Wackelkontakt, Kabelbruch...

> Und das, was Du da vorschlägst,
> ist dabei allerdings sogar noch eher witzlos, dank window functions und
> index-only scans (seit PostgreSQL 9.2). ;-)

Das hilft bei diesem Problem ziemlich exakt genau garnix. Hier wird in 
der ersten (also der wirklich teuren) Stufe sowieso nur der Index des 
Primärschlüssels benutzt. Und zwar in beiden dargestellten Varianten 
gleichermaßen. Und das gilt übrigens für alle ernstzunehmenden RDBMs 
mindestens der letzten 30 Jahre, ebenfalls gleichermaßen.

Vielleicht wirfst du einfach mal einen Blick auf die Joinbedingungen und 
vergleichst das mit den jeweils im Primärschlüssel enthaltenen Spalten?

Merke: Die Fähigkeit zur Buzzword-Replikation ist was völlig anderes als 
echter Sachverstand. Verkäufer und Marketingfritzen machen grundsätzlich 
ersteres, wirkliche Programmierer haben im Idealfall letzteres.

> oder man
> lädt sich die Daten auf eine schnellere Büchse

Das war genau, was ich eingangs vorgeschlagen habe. Und deine Erwiderung 
war im Prinzip: NEEIIIN, der RasPi kann das alles wunderbar alleine, 
das läuft immer völlig rund und ohne jedes erwartbare Problem...

von old man (Gast)


Lesenswert?

c-hater schrieb:
> Allerdings ist meine Frage ja nun auch nicht so weit hergeholt, bei der
> Analyse von Sensordaten ist es ganz allgemein die erste Aufgabe,
> Irregularitäten im Datenmaterial zu finden und auszufiltern,


c-hater schrieb:
> Wenn du zu blöd bist, den Sinn hinter solchen Abfragen zu erkennen, nur
> als Stichworte: Wackelkontakt, Kabelbruch...

Na ja, deine Aussage bezog sich darauf sowas in einem Zeitraster von 
einem Jahr zu finden. Wer ein Jahr braucht um einen Wackelkontakt oder 
Kabelbruch zu detectieren ist wirklich zu blöd...

Ich werfe trotzdem nochmal den Ansatz einer binären Datei in den Ring. 
In meinem Beispiel waren das 277Mb pro Jahr bei 64 Messwerten. Das 
kriegt ein Rpi noch problemlos in den Speicher. Die einzige Zeit die 1 
Jahr Analyse braucht, ist die Zeit um die Daten zu lesen. Alle anderen 
Routinen laufen dann komplett im Speicher und damit "sauschnell". 
Natürlich muss man da ein wenig Grips in die Programierung investieren. 
Das ist aber besser investierte Zeit als hier über die Fähigkeiten von 
Sql-Datenbanken zu streiten. Aber sich wirklich auf eine low level Ebene 
zu begeben ist heute nicht mehr zeitgemäß...

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Nur so als Gedanke.

Nimm für die Auslagerung der Daten den größten Speicher der Welt; das 
Internet. Dann haben eventuell andere Leute auch etwas davon (ok, der 
Heizungsvorlauf ist eher uninteressant; eher aber die 
Außentemperaturen).

von c-hater (Gast)


Lesenswert?

old man schrieb:

> Na ja, deine Aussage bezog sich darauf sowas in einem Zeitraster von
> einem Jahr zu finden. Wer ein Jahr braucht um einen Wackelkontakt oder
> Kabelbruch zu detectieren ist wirklich zu blöd...

Nun, es soll Leute geben, die haben tatsächlich was anderes zu tun, als 
magisch gebannt auf die grafischen Darstellungen irgendwelcher 
Sensorwerte zu starren, um Irregularitäten darin zu entdecken. Diese 
Leute überlassen die Suche nach solchen Problemen gern Computern, denn 
deren Aufmerksamkeit erschlafft nicht, wenn das Endspiel der Fußball-WM 
läuft oder irgendeine Tussi in irgendeinem Film das Oberteil ablegt.

> Ich werfe trotzdem nochmal den Ansatz einer binären Datei in den Ring.

Hossa. Du weißt schon, daß die Daten aller RDBMs in "binären Dateien" 
abgelegt werden?

> Natürlich muss man da ein wenig Grips in die Programierung investieren.

Ja, was glaubst du denn, womit die Entwickler von Datenbank-Engines ihre 
Zeit vertrödeln? Vielleicht versuchst du einfach mal, die Abfrage in 
deiner bevorzugten Sprache auf deine "Binärdateien" anzuwenden.

Dann wirst du, wenn du nicht völlig verblödet bist, doch irgendwann 
feststellen, daß selbst du zehn Milliarden Vergleiche machen musst, um 
zweimal hunderttausend Datensätze einer bestimmten Bedingung folgend 
miteinander zu kombinieren. Diese öde, blöde Mathematik läßt leider auch 
für Möchtegern-Genies wie dich keinerlei Ausnahmen zu...

Natürlich lassen sich für spezielle Probleme Vereinfachungen finden. Um 
mal beim konkreten Beispiel zu bleiben: Statt die Datensätze alle 
miteinander zu vergleichen, könnte man sich natürlich zunutze machen, 
daß es eine gewisse Beziehung zwischen ihnen gibt, nämlich, daß pro 
Stunde eben normalerweise genau 12 davon auflaufen. War das aber 
irgendwann mal nicht der Fall (weil z.B. der Server mal down war), 
dann liefert diese Vereinfachung nur noch Müll, und ist dann für ihren 
eigentlichen Zweck (Irregularitäten im Datenmaterial zu entdecken) nicht 
mehr zu gebrauchen.

Ganz allgemein lassen sich also komplexitätverringernde Optimierungen 
nur realisieren, wenn man bestimmte Eigenschaften der Daten sicher 
kennt. Kennt man aber solche Eigenschaften, lassen sie sich gewöhnlich 
auch mit SQL nutzen. Wenn man SQL kann...

> Aber sich wirklich auf eine low level Ebene
> zu begeben ist heute nicht mehr zeitgemäß...

Du begreifst garnix. SQL ist nur eine andere Art der Darstellung des 
Problems. Das Problem und die ihm innewohnende Komplexität bleibt aber 
über alle Darstellungen des Problems exakt dieselbe. SQL-RDBMs sind der 
(einigermaßen gelungene) Versuch, diese Komplexität mit einer Sprache zu 
beschreiben und für die Menge aller Probleme möglichst effizient 
umzusetzen.

Das Problem von SQL ist nur, daß höchstens 1% der Menschheit es 
schaffen, in Mengen zu denken. Und, noch viel schlimmer: die meisten 
prozeduralen Programmierer schaffen das ebenfalls nicht. Das ist 
schlimm, weil die es eigentlich sind, die aus den Fähigkeiten der 
Datenbanken wirklich Vorteile ziehen könnten und massiv 
Entwicklungsaufwand sparen könnten, wenn sie den neben ihrer bevorzugten 
Sprache auch noch SQL wirklich beherrschen würden. Also alles jenseits 
von "select elephant from africa where isdead=1;"

von old man (Gast)


Lesenswert?

Hallo C und auch alle anderen Hasser,


Au weia, ich hatte zuerst nicht bemerkt mit wem ich hier diskutiere. 
Sorry, von deinen Aussagen habe ich schon genügend unkommentiert 
gelesen. So werde ich auch weiter verfahren. Der Ton alleine ist schon 
das allerletzte. Warum gehst du nicht in die Politik, da ist Schreien im 
Moment auch das Mittel der Wahl?

Wer glaubt nur seine eigene Denke ist die einzig richtige, der 
disqualifiziert sich von vorn herein. Ich sage nicht dass mein Weg der 
einzig mögliche ist, aber für die Auswertung von im Zeitraster geloggten 
Daten wage ich die Behauptung meine Routinen schneller in der Sprache 
meiner Wahl zu programmieren als du das in SQL formulierst. Ich habe ja 
schließlich noch die Zeit zusätzlich die du mit Schreien verbringst.

Was ist den SQL in dem Fall von geloggten Daten? Eine flache Tabelle mit 
maximal ein paar Indexen über die Felder. Da kannst du fitt in SQL sein 
oder auch nicht und von Mengen was verstehen oder auch nicht, am Ende 
bleibt ausser der Tabelle und ein paar Sortierschlüsseln nichts 
brauchbares übrig. Und gegen sowas an zu stinken ist nun wirklich keine 
Kunst. Ausser man ist so verbohrt und kann die Realität schon nicht mehr 
wahrnehmen.

Aber das Problem hast du ja sowieso. Jedenfalls hier im Forum. Und damit 
beende ich mein Statement in diesem Thread.

von Karl Käfer (Gast)


Lesenswert?

Hallo Axel,

Axel Schwenke schrieb:
> Mal wieder ein Feature, das PostgreSQL von dem angeblich doch sooo
> unterlegenen MySQL übernommen hat. MySQL hat covering indexes übrigens
> seit ... schon immer.

Ach Gottchen, ja. MySQL ist trotzdem nichts weiter als eine vollkommen 
überbewertete Datenbanksimulation. Nimmt es immer noch "0000-00-00" als 
Datum an? Wirft es immer noch keinen Fehler, wenn man einen 300 Zeichen 
langen String in einem VARCHAR(255) speichert, sondern schneidet die 
Zeichenkette kommentarlos einfach ab? Kann MySQL immer noch NULL-Werte 
in NOT NULL-Spalten schreiben? Bleiben MySQL-Frontendprozesse immer noch 
ewig in einem select(2) hängen, wenn das Backend abraucht (mal davon ab: 
wie kann das eigentlich passieren?), und muß man dann immer noch die 
ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart 
und kill -9 nicht abgeschossen bekommt?

Solange das alles so ist, ist MySQL nicht "angeblich", sondern 
tatsächlich unterlegen, und für ernsthafte Arbeiten leider unbrauchbar. 
Sorry, lieber Herr MySQL Performance Engineer, aber eine Schwalbe macht 
noch keinen Sommer, und eine einzige (vergleichsweise nebensächliche und 
ausschließlich performancerelevante) Funktion, die MySQL schon länger 
hat als PostgreSQL, kann MySQLs beschriebene kritische Fehler und seine 
Instabilität leider nicht ausgleichen. Und invalide Daten anzunehmen, 
Constraints zu verletzten oder sogar angenommene Daten kommentarlos zu 
kürzen, sorry, das geht nunmal wirklich überhaupt gar nicht.

Liebe Grüße,
Karl

von Karol B. (johnpatcher)


Lesenswert?

Karl Käfer schrieb:
> und muß man dann immer noch die
> ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart
> und kill -9 nicht abgeschossen bekommt?

Wobei man das auch dem Betriebssystem zurechnen könnte ;).

Mit freundlichen Grüßen,
Karol Babioch

von Karl Käfer (Gast)


Lesenswert?

Hallo,

c-hater schrieb:
>> Und das, was Du da vorschlägst,
>> ist dabei allerdings sogar noch eher witzlos, dank window functions und
>> index-only scans (seit PostgreSQL 9.2). ;-)
>
> Das hilft bei diesem Problem ziemlich exakt genau garnix.

Ach ja? Unter der Voraussetzung, daß jemand Karols DB-Design verwendet, 
mag das sein. Ich bin aber nicht Karol, und in der realen Welt schreibe 
ich Daten lockerflockig in eine einzelne Tabelle, wie Du ja oben selbst 
schon ganz richtig vorgeschlagen hast. Ich habe mir jedoch die Freiheit 
genommen, die Daten auf hübsche Monatstabellen zu verteilen:
1
CREATE TABLE temperatur (
2
  id SERIAL PRIMARY KEY,
3
  zeit TIMESTAMP DEFAULT NOW(),
4
  ch0 INTEGER DEFAULT 0,
5
  ch1 INTEGER DEFAULT 0,
6
  ch2 INTEGER DEFAULT 0,
7
  ch3 INTEGER DEFAULT 0
8
);
9
CREATE OR REPLACE FUNCTION parent_insert_trigger()
10
RETURNS TRIGGER AS $_$
11
DECLARE
12
    ayear VARCHAR(4)      := substring(NEW.zeit::CHAR(18) from 0 for 5);
13
    amonth VARCHAR(2)     := substring(NEW.zeit::CHAR(18) from 6 for 2);
14
    datum DATE            := NEW.zeit::DATE + INTERVAL '1 month';
15
    nyear VARCHAR(4)      := substring(datum::CHAR(18) from 0 for 5);
16
    nmonth VARCHAR(2)     := substring(datum::CHAR(18) from 6 for 2);
17
    tablename VARCHAR(32) := 'temperatur_' || ayear || '_' || amonth;
18
BEGIN
19
    IF NOT EXISTS(
20
        SELECT * 
21
        FROM information_schema.tables 
22
        WHERE table_catalog = CURRENT_CATALOG
23
          AND table_schema = CURRENT_SCHEMA
24
          AND table_name = tablename) THEN
25
        EXECUTE format(
26
          'CREATE TABLE %I (
27
             CONSTRAINT zeit_cstr CHECK (
28
               zeit::date >= %L::date 
29
               AND zeit::date < %L::date) ) 
30
           INHERITS (temperatur);', 
31
          tablename, 
32
          ayear||'-'||amonth||'-01', 
33
          nyear||'-'||nmonth||'-01');
34
        EXECUTE format(
35
          'CREATE INDEX %I ON %I USING btree (%I)',
36
          tablename||'_zeit_idx', tablename, 'zeit');
37
    END IF;
38
    EXECUTE format('INSERT INTO %I VALUES (($1).*)', tablename) USING NEW;
39
  RETURN NULL;
40
END;
41
$_$ LANGUAGE plpgsql;
42
CREATE TRIGGER insert_parent_trigger BEFORE INSERT ON temperatur 
43
  FOR EACH ROW EXECUTE PROCEDURE parent_insert_trigger();

So eine Monatstabelle kann man dann jederzeit auf Anomalien prüfen, wo 
ist das Problem? Wobei es natürlich sinnvoller wäre, wenn das 
Programm/Skript, das die Sensoren ausliest, schon eine 
Plausibilitätsprüfung macht und bei merkwürdigen Werten gleich eine 
E-Mail schickt oä...

Aber ich schweife ab. Für so eine Monatstabelle ist die Prüfung mit den 
von mir genannten Features dann auch ziemlich einfach und performant:
1
SELECT DISTINCT 
2
  date_trunc('hour', zeit), 
3
  MIN(ch0) OVER (PARTITION BY date_trunc('hour', zeit)),
4
  AVG(ch0) OVER (PARTITION BY date_trunc('hour', zeit)),
5
  MAX(ch0) OVER (PARTITION BY date_trunc('hour', zeit)),
6
  STDDEV(ch0) OVER (PARTITION BY date_trunc('hour', zeit))
7
FROM ONLY temperatur_2014_04
8
ORDER BY date_trunc('hour', zeit);

Damit habe ich Minimum, Maximum, Durchschnitt und Standardabweichung für 
jede Stunde im betrachteten Zeitraum April 2004. Das braucht für einen 
Kanal in einer Monatstabelle auf dem RasPi 4 (in Worten: vier) Sekunden. 
Das noch für die anderen Kanäle zu implementieren ist dem geneigten 
Leser als Hausaufgabe überlassen (mit vier Kanälen benötigt der Query 
allerdings insgesamt 15 Sekunden).

Natürlich kann man daraus einen View machen, sinnvollerweise gar einen 
Materialized View, da eine Monatstabelle nach Monatsende natürlich nicht 
mehr verändert wird. Mit einem Select auf den View (oder einen Subquery) 
kann man sich auch wunderschön die Minima und Maxima aus der kleinen 
Ergebnistabelle holen, damit kann man Fehler und Störungen schon sehr 
schön zeitlich eingrenzen...

> Merke: Die Fähigkeit zur Buzzword-Replikation ist was völlig anderes als
> echter Sachverstand.

Da muß ich mich auf Dein hochgeschätztes Urteil verlassen, mit 
Buzzword-Replikation kennst Du Dich offensichtlich viel besser aus als 
ich.

> Das war genau, was ich eingangs vorgeschlagen habe.

Dem hatte ich gar nicht widersprochen, warum sollte ich auch? 
Schließlich habe ich selbst genau das schon seit einem guten Jahr in 
Betrieb.

> Und deine Erwiderung war im Prinzip: NEEIIIN, der RasPi kann das alles
> wunderbar alleine,

Ach, das war meine Erwiderung? Komisch, zu Deinen Ausführungen hatte 
ich doch tatsächlich gar nichts geschrieben. Aber wie ich bewiesen habe, 
kann man das ziemlich einfach und ausgesprochen performant lösen, wenn 
man ein bisschen Sachverstand hat.

Nun, nachdem ich mir nun Deinen Merksatz eingeprägt habe, demzufolge die 
Fähigkeit zur Buzzword-Replikation etwas völlig anderes ist als echter 
Sachverstand, möchte ich Dir herzlich danken, daß Du mich daran erinnert 
hast. Als Gegenleistung möchte ich Dir gerne auch einen Merksatz mit auf 
Deinen vermutlich nicht einfachen Weg geben: eine große Klappe ersetzt 
jedenfalls keinen echten Sachverstand. ;-)

Vielen Dank für Deine Aufmerksamkeit,
Karl "nicht Karol" Käfer

von Karl Käfer (Gast)


Lesenswert?

Hallo,

Karl Käfer schrieb:
> Damit habe ich Minimum, Maximum, Durchschnitt und Standardabweichung für
> jede Stunde im betrachteten Zeitraum April 2004. Das braucht für einen
> Kanal in einer Monatstabelle auf dem RasPi 4 (in Worten: vier) Sekunden.

Ach so, das hatte ich vergessen zu erwähnen: bei mir werden die Sensoren 
einmal pro Minute ausgelesen und die Daten abgespeichert. Meine Tabelle 
enthält demzufolge 43.200 Datensätze anstatt nur 8640 bei einem 
Intervall von 5 Minuten.

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo Karol,

Karol Babioch schrieb:
> Karl Käfer schrieb:
>> und muß man dann immer noch die
>> ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart
>> und kill -9 nicht abgeschossen bekommt?
>
> Wobei man das auch dem Betriebssystem zurechnen könnte ;).

Ja, das würde ich auch sagen, wenn ich es nicht schon sowohl unter 
diversen Linuxen als auch unter Solaris gesehen hätte. Aber selbst wenn 
es wirklich nur daran läge... die anderen erwähnten Sachen sind mE. 
sogar noch viel schlimmere Showstopper als ein Zombie, der einen Core 
verbrennt.

Liebe Grüße,
Karl

von Axel S. (a-za-z0-9)


Lesenswert?

Karl Käfer schrieb:
> Axel Schwenke schrieb:
>> Mal wieder ein Feature, das PostgreSQL von dem angeblich doch sooo
>> unterlegenen MySQL übernommen hat. MySQL hat covering indexes übrigens
>> seit ... schon immer.
>
> Ach Gottchen, ja. MySQL ist trotzdem nichts weiter als eine vollkommen
> überbewertete Datenbanksimulation. Nimmt es immer noch "0000-00-00" als
> Datum an? Wirft es immer noch keinen Fehler, wenn man einen 300 Zeichen
> langen String in einem VARCHAR(255) speichert, sondern schneidet die
> Zeichenkette kommentarlos einfach ab? Kann MySQL immer noch NULL-Werte
> in NOT NULL-Spalten schreiben? Bleiben MySQL-Frontendprozesse immer noch
> ewig in einem select(2) hängen, wenn das Backend abraucht (mal davon ab:
> wie kann das eigentlich passieren?), und muß man dann immer noch die
> ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart
> und kill -9 nicht abgeschossen bekommt?

Ach Jungchen, du mußt deine Vorurteile dringend mal updaten. Sonst 
machst du dich noch lächerlicher als ohnehin schon. Alles das, was an 
deiner Liste nicht sowieso FUD ist, kann man seit Jahren(!) so 
konfigurieren, wie man gerne möchte.

Ansonsten soll jeder das DBMS seiner Wahl nehmen. Ich wollte (konnte) 
bloß dein Getrolle nicht unkommentiert lassen. Womöglich glaubt dir 
sonst am Ende noch jemand.

Für mich an dieser Stelle EOD. Dir ist sowieso nicht zu helfen.


XL

von Axel S. (a-za-z0-9)


Lesenswert?

Karl Käfer schrieb:
> Karol Babioch schrieb:
>> Karl Käfer schrieb:

>>> und muß man dann immer noch die
>>> ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart
>>> und kill -9 nicht abgeschossen bekommt?
>>
>> Wobei man das auch dem Betriebssystem zurechnen könnte ;).
>
> Ja, das würde ich auch sagen, wenn ich es nicht schon sowohl unter
> diversen Linuxen als auch unter Solaris gesehen hätte.

Entweder lügst du oder du hast das während einer Therapiesitzung 
geträumt. Kein Prozeß kann SIGKILL abfangen oder anders darauf 
reagieren als daß er sich beendet. Und zwar deswegen, weil das außerhalb 
der Kontrolle des Prozesses liegt. Da ist allein das Betriebssystem 
dafür zuständig.

von Tek (Gast)


Lesenswert?

Hallo Bernd,

ich habe eine ähnliche Anwendung wie Du planst am laufen.
Bei mir sind aber ausser Temperatur noch Zählerdaten von 2 eHZ und einem 
Wärmemengenzähler dabei.

Im Moment werden Temperaturen und Zählerstände in eine MySQL Datenbank 
auf meinem NAS geschrieben. Per Insert-Trigger werden aus den 
Zählerdaten Leistungsdaten generiert, damit habe ich dann, immer über 
5min gemittelt, die aktuelle Leistung. Da sieht man dann über den Tag 
den Kühlschrankkompressor takten oder erkennt wenn man vergessen hat ein 
Licht auszuschalten.

Auf dem NAS läuft zusätzlich ein Webserver zum darstellen von Graphen 
und Tabellen. Performancetechnisch funktioniert das nicht schlecht, nur 
wenn ich bei den Leistungscharts zwischen Tagen hin und herspringe 
dauert es halt immer ein paar Sekunden bis die Daten abgefragt sind.

Ein Dorn im Auge ist mir aber noch das ich ne Menge Daten mitschleife, 
die eigentlich nicht mehr gebraucht werden. Die Zählerstände im 5 min 
Raster zb sind nachdem daraus die Leistung errechnet wurde eigentlich 
nutzlos, da würde ein Wert pro Tag reichen.

Durch diesen Thread motiviert werde ich da das Konzept auch nochmal 
überarbeiten.

Variante 1:
Ich stelle komplett auf RRDtool um. Ich habe nur etwas bedenken da ich 
wie Du, die Tagesdaten schon gerne mindestens über 2 Jahre in voller 
Genauigkeit hätte um auch mal einen Vergleich zu ziehen. Ich weis nicht 
wie da die Performance ist wenn da soviele Daten im 5 Min Raster drin 
sind.


Variante 2:
Mittelwerte, Max, Min und Tagesverbrauch in die SQL DB und für jeden Tag 
die Detailwerte wie Leistung und Temperatur im JSON Format in eine Datei 
geschrieben. Die sind recht fix als Chart angezeigt und belasten nicht 
die Datenbank, vielleicht noch den Dateinamen mit in die Tagestabelle 
damit man schnell das File findet.

Im Moment tendiere ich zu Variante 2 obwohl mir das Konzept hinter 
RRDTool echt gut gefällt.

Vielleicht kommen hier ja noch ein paar gute Vorschläge wenn mal die 
Glaubenskriege beendet sind...

von Axel S. (a-za-z0-9)


Lesenswert?

Tek schrieb:
> Variante 1:
> Ich stelle komplett auf RRDtool um. Ich habe nur etwas bedenken da ich
> wie Du, die Tagesdaten schon gerne mindestens über 2 Jahre in voller
> Genauigkeit hätte um auch mal einen Vergleich zu ziehen. Ich weis nicht
> wie da die Performance ist wenn da soviele Daten im 5 Min Raster drin
> sind.

Für die Performance ist das weitgehend egal. RRDtool faßt nur die 
Datensätze im RRA an, die um den aktuellen Zeitpunkt herum liegen.
Und die Position der Datensätze ist direkt von der Zeit abhängig.
Man braucht also im Gegensatz zu einer SQL-Tabelle nicht erst nach
dem richtigen Datensatz zu suchen, sondern rechnet mit

((Zeit - RRA-Startzeit) / RRA-Schrittgröße) mod RRA-Länge

direkt die Position des Datensatzes im RRA aus. Die Größe der RRAs hat 
so keinen [1] Einfluß auf die Performance, vorausgesetzt das darunter- 
liegende Filesystem kann seek() effizient implementieren (beim Raspi ist 
das standardmäßig ext4, das paßt).


XL

[1] etwas technischer ausgedrückt ist die Komplexität der wesentlichen 
Operationen O(1). Dito bei den von mir und anderen vorgeschlagenen
flat file Speichervarianten. Datenbanken kommen auch mit Index nur auf 
O(log N) (N ist die Datenmenge). Schlechte Datenbanken ohne Indizes gar 
auf O(N).

von c-hater (Gast)


Lesenswert?

Karl Käfer schrieb:

[...]

Dir ist schon klar, daß das zwar eine Lösung ist, aber nicht die Lösung 
der gestellten Aufgabe, sondern für etwas völlig anderes (mit um viele 
Größenordnungen geringerer Komplexität)?

Es ist eine Lösung für das Problem, kontinuierlich auflaufende Daten auf 
für willkürliche Zeiträume separierte Tabellen zu verteilen.

Das ist nett und performancefördernd, wenn man dann ausschließlich 
Abfragen fährt, die sich auf den willkürlich gewählten oder einen 
kleineren Zeitraum beziehen.

Es ist aber nicht nur keine Lösung für jegliche Abfragen, die sich auf 
den gesamten Zeitraum beziehen, sondern im Gegenteil für diesen Fall die 
schlimmste aller denkbaren Performance-Bremsen.

von Karl Käfer (Gast)


Lesenswert?

Hallo Axel,

Axel Schwenke schrieb:
> Entweder lügst du oder du hast das während einer Therapiesitzung
> geträumt. Kein Prozeß kann SIGKILL abfangen oder anders darauf
> reagieren als daß er sich beendet.

Tja, das sollte man meinen, und vielleicht würde ich es auch nicht 
glauben, wenn ich es nicht selbst erlebt hätte. Aber vielleicht möchtest 
Du mal in die Manpage von select(2) schauen? Da stehen ein paar extrem 
interessante Sachen drin, insbesondere zu den Themen Blocking, Timeouts 
und Multithreading.

> Und zwar deswegen, weil das außerhalb
> der Kontrolle des Prozesses liegt. Da ist allein das Betriebssystem
> dafür zuständig.

Mir ist natürlich klar, daß jemand, der sein Geld mit MySQL verdient, es 
verteidigen muß und vielleicht auch einen etwas geschönten Blick darauf 
haben muß. Aber ich habe schon genug Probleme und sogar Datenverluste 
mit MySQL erleben müssen und bin aus genau diesem Grund schon vor Jahren 
auf eine Datenbank umgestiegen, die mir keine solchen Schwierigkeiten 
macht. Ob man in MySQL heute etwas konfigurieren kann, finde ich schon 
ziemlich lächerlich -- was für eine Datenbank soll denn das sein, bei 
der man die Datenintegrität erst konfigurieren muß? -- aber letztlich 
ist mir das ehrlich gesagt schnurzpiepegal. Wenn mein Vertrauen einmal 
weg ist, dann ist es erstmal weg. Und indem Du mich beschimpfst oder mir 
irgendwelchen Unsinn unterstellst, werden Du und Dein MySQL-Team mein 
Vertrauen sicher nicht zurückgewinnen. Deswegen habe ich jetzt 
PostgreSQL und komme damit endlich wieder in den Genuß von etwas, das 
ich mit MySQL eben leider nicht mehr hatte: nämlich einen ruhigen 
Schlaf.

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo,

c-hater schrieb:
> Dir ist schon klar, daß das zwar eine Lösung ist, aber nicht die Lösung
> der gestellten Aufgabe, sondern für etwas völlig anderes (mit um viele
> Größenordnungen geringerer Komplexität)?

Nö. Ich habe genau die Aufgabe gelöst, die Du gestellt hattest, mit 
einer überschaubaren Komplexität -- das die Komplexität überschaubar 
ist, hatte ich ja schon in meinem ersten Beitrag erwähnt -- mit einer 
hervorragenden Performanz und mit genau jenem Feature, das ich erwähnt 
und welches Du als "Buzzword-Replikation" abgetan hattest.

> Es ist aber nicht nur keine Lösung für jegliche Abfragen, die sich auf
> den gesamten Zeitraum beziehen, sondern im Gegenteil für diesen Fall die
> schlimmste aller denkbaren Performance-Bremsen.

Nachträglich die Aufgabe ändern und dann behaupten, die präsentierte 
Lösung würde nicht dazu passen, ist einfach lächerlich. Wenn Du schon zu 
solchen Tricksereien greifen mußt, kannst Du in der Sache offensichtlich 
nichts mehr entgegnen.

Auch Deine Aussage, die Verteilung der Daten auf mehrere Tabellen sei 
eine Performancebremse, ist totaler Quatsch. Abfragen, die sich über den 
ganzen Zeitraum beziehen, werden im besten Fall beschleunigt, und im 
schlimmsten nicht verlangsamt. Wenn man keine Ahnung hat, ... genau.

Liebe Grüße,
Karl

von Konrad S. (maybee)


Lesenswert?

>>>> und muß man dann immer noch die
>>>> ganze Büchse rebooten, weil man den Prozeß auch mit einem MySQL-Restart
>>>> und kill -9 nicht abgeschossen bekommt?

>>> Wobei man das auch dem Betriebssystem zurechnen könnte ;).

>> Ja, das würde ich auch sagen, wenn ich es nicht schon sowohl unter
>> diversen Linuxen als auch unter Solaris gesehen hätte.

> geträumt. Kein Prozeß kann SIGKILL abfangen oder anders darauf
> reagieren als daß er sich beendet. Und zwar deswegen, weil das außerhalb
> der Kontrolle des Prozesses liegt. Da ist allein das Betriebssystem
> dafür zuständig.

Wenn ein Prozess in einem nicht unterbrechbaren Systemcall hängt, dann 
richtet ein kill -9 auch nichts mehr aus. Ja, das kenne ich gut ... aus 
den Zeiten von Solaris 2.3, so Mitte der 1990er etwa. Seitdem hat sich 
aber doch einiges getan. Solche Effekte habe ich schon seit Jahren nicht 
mehr erlebt, weder unter Solaris, noch unter Linux.

von Bernd Schuster (Gast)


Lesenswert?

Hallo zusammen,

kurze Rückmeldung: habe zig Seiten im Internet gelesen und in alten 
Büchern gewühlt und bin dann letztendlich doch bei einer SQL Tabelle 
(derzeit: SQLite) gelandet. Habe an der Stelle keine Performance 
Einbrüche festgestellt (ok, die kommen auch erst über die Zeit wenn die 
Tabelle wächst), wobei auch rrdtool mehr als ausreichend schnell war. 
Entscheidung für SQL war dann ein "gewohntes" Umfeld und die Möglichkeit 
alle Daten aufzuheben. Wenn es denn mal eng werden sollte, gibt es 
sicher die Rev D des Raspberyy Pi mit mehr Power...  Ich kann aber auch 
gerne ein paar Sekunden auf eine Grafik warten, frage die ja nicht alle 
drei Sekunden ab.
Derzeit kämpfe ich mehr mit der richtigen Verdrahtung, bin jetzt weg von 
parasitärer Versorgung, da ich bei einigen Sensoren manchmal keine Werte 
erhalten hatte. Gibt es eine "perfekte" Anschaltung für 1-wire Sensoren 
an einen Controller der gegen Störungen geschützt ist und lange 
Leitungslängen erlaubt?
Danke für eure Mühen und begrabt das Kriegsbeil.

Gruß, Bernd

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.