Live Coding: Entdeckung von DuckDB am Donnerstag, den 20. Juni um 10 Uhr!

Es ist schwer, die Transferzeit vorherzusagen, das hängt von vielen Faktoren ab, hauptsächlich von der Geschwindigkeit der Festplatte, das ist wirklich einzigartig für jedes Hardware.

Der « Transfer »-Teil ist nicht blockierend, Gladys kann gleichzeitig verwendet werden.

Andererseits werden die Grafiken während der Transferdauer möglicherweise nicht verfügbar sein, ich muss noch entscheiden, ob ich den doppelten Code in Gladys lebenslang belasse oder ob wir den Code eliminieren und somit die Grafiken während der Migrationszeit leer sind, was vielleicht ein akzeptabler Kompromiss ist.

Was jedoch blockierend ist, ist der « VACUUM »-Teil der SQLite-DB, um die « finale » Reduzierung der Festplattengröße durchzuführen, und hier muss man sehen, ob man das erzwingt oder ob man den Benutzer dazu auffordert. Es ist sicherlich klüger, den Benutzer dazu aufzufordern, um seine Instanz nicht zu blockieren.

Zur Info, auf meiner Festplatte dauerte der VACUUM deiner 13GB-DB 30 Sekunden, aber ich habe einen Macbook Pro der Zukunft (10-Kern-CPU / SSD NVMe mit 4,5 GB/s Durchsatz), auf Pi wird das meiner Meinung nach eine ganze Weile dauern

Ich rate dir, es trotzdem zu tun, du wirst jetzt täglich Warnungen erhalten, seit die Version 4.44 herausgekommen ist.

Und ich bin wirklich noch nicht bereit, die Version mit DuckDB herauszubringen, ich hatte von Monaten gesprochen :slight_smile:

Sehr produktiver Entwicklungstag heute!

Um euch auf dem Laufenden zu halten, was bereits codiert ist:

  • Einfügen der Zustände in DuckDB anstelle von SQLite :white_check_mark:
  • Graphische API-Abfragen über DuckDB :white_check_mark:
  • Löschen veralteter Aggregationsaufgaben :white_check_mark:
  • Datenbank-Migrationsaufgabe :white_check_mark:

(Ich schreibe die Tests gleichzeitig, daher ist alles, was erledigt ist, auch getestet)

In Entwicklung:

  • Backup und Wiederherstellung von Gladys Plus :construction:

Das Backup wird nicht einfach durch das Sichern der .duckdb-Datei erfolgen, DuckDB bietet eine API, die eine komprimierte .parquet-Datei exportiert (Parquet, was ist das?) ein Format, das speziell für Zeitreihendaten entwickelt wurde. Diese Datei ist jedoch etwas speicherintensiver als eine DuckDB-Datei, aber ich folge den DuckDB-Empfehlungen und der offiziellen Export/Import-API. Ich denke nicht, dass es sinnvoll ist, eine .duckdb-Datei während des Betriebs zu kopieren, um ein Backup zu erstellen.

  • Sauberes Feedback in der Benutzeroberfläche während der Migration :construction:

Die Benutzeroberfläche muss sehr klar sein und dem Benutzer erklären, was passiert.

To-Do:

  • Überprüfen, wann die Daten in SQLite gelöscht werden. Bisher habe ich mich dafür entschieden, sie nicht automatisch zu löschen, um Datenverluste zu vermeiden, und dem Benutzer die Wahl zu lassen, diese Daten nachträglich selbst über einen Button in der Benutzeroberfläche (noch nicht codiert) zu löschen :cross_mark:
  • Echte Tests und Optimierung der Migration auf Instanzen mit vielen Daten und geringer CPU/Festplattenleistung :cross_mark:
  • Testen von Unterbrechungen und Fortsetzung der Migration :cross_mark:
  • Mehrere Tage/Wochen realer Nutzung von Gladys mit DuckDB testen. Ziel: Stabilität/keine Abstürze akzeptiert :cross_mark:
  • Sicherlich habe ich noch etwas vergessen :grinning_face_with_smiling_eyes:

Ich halte euch auf dem Laufenden!

Wow! Für ein mehrmonatiges Projekt… Man spürt die Motivation :wink:.
Ich werde dir das gleich korrigieren: « in Richtung (…) zu DuckDB » wäre korrekter und « eine gewisse Zeit, in der Ihre » klingt schöner. Also, erledigt! :innocent:
Zur Erinnerung: Ich habe einen RPi2 und einen Zero2W (RPi3-äquivalent) für Tests bereit. Und ich bin Lehrer, also im Sommer frei…

Ich habe heute wieder gute Fortschritte gemacht, der Benutzer kann im Systemtab sehen, ob die Migration erfolgreich war:

Er kann selbst die SQLite-Zustände bereinigen (das wird nicht automatisch erfolgen, um dem Benutzer die Kontrolle zu lassen).

Im Tab « Aufgaben » kann er den Fortschritt der Migrationsaufgabe in Echtzeit sehen / Fehler, falls welche auftreten:

Ich finde, die Oberfläche ist sauber. Cool. Ich nehme an, dass der Button „SQLite-Zustände bereinigen“ nicht aktivierbar ist, solange die Migration nicht durchgeführt wurde…

Und andererseits, auch wenn ich es gut finde, dass eine manuelle Aktion erforderlich ist, um die Datenbankdaten von SQLite zu löschen, sehe ich aus Nutzersicht keinen Sinn darin, zwei manuelle Aktionen durchführen zu müssen: bereinigen und dann bereinigen. Gibt es dafür einen Grund?

Nicht dumm, ich werde das ändern :slight_smile: Das war bisher nicht der Fall!

Das Leeren ist eine Aktion, die im Hintergrund ausgeführt wird und nicht blockierend ist. Du kannst das Leeren tagsüber ohne Probleme laufen lassen, es löscht schrittweise in Batches. Es kann zwar etwas Zeit in Anspruch nehmen, aber es ist nicht blockierend.

Die Bereinigung ist ein SQLite-Befehl („VACUUM“), der blockierend ist. Gladys ist während dieser Aktion vollständig blockiert. Auf einem sehr leistungsfähigen SSD NVMe in einem Mini-PC wird die Blockierung zeitlich begrenzt sein.

Auf einem USB-SSD auf einem Pi oder schlimmer auf einer SD-Karte kann die Blockierung mehrere Stunden dauern (das wird auf der Seite des Bereinigungs-Buttons erwähnt).

Daher habe ich die beiden Aktionen getrennt, damit der Benutzer die Wahl hat, wann er jede Aktion durchführen möchte.

Wenn wir die beiden Aktionen hintereinander ausführen und du das Leeren startest, Gladys läuft, und dann 2 Stunden später die Bereinigung startet und Gladys blockiert wird, könnte der Benutzer das nicht verstehen und denken, es sei ein Bug!

Sehr klar. Und die Wahl, die du triffst, ist also die richtige.

Ich nutze die Gelegenheit, um dir für die Pädagogik zu danken, die du regelmäßig unter Beweis stellst, um auf diesem Forum Fragen zu beantworten :+1:

Ich habe heute Nachmittag einen manuellen Docker-Build gestartet, um Tests auf dem Raspberry Pi durchzuführen…

Und es läuft immer noch!! ^^ (normalerweise dauert es 40 Minuten)

Offensichtlich ist der Build für armv6 seit DuckDB in den Abhängigkeiten sehr langsam, es muss eine vollständige Kompilierung von DuckDB sein

Edit: Bestätigt in den GitHub-Issues von DuckDB, sie stellen Builds für arm64 bereit, aber nicht für armv7 oder armv6

Ich verstehe nichts davon, aber kann das nicht in ein System wie ‹ Cache › gesteckt werden?
Falls nicht, wird das für dich nervig werden!

Das ist bereits der Fall :slight_smile: In jedem Fall braucht man einen ersten Build, um den Cache zu initialisieren / den Cache zu erneuern, wenn sich die Abhängigkeiten ändern

Das hat insgesamt mehr als 4 Stunden gedauert:

Dann stellt sich die Frage nach der Unterstützung von armv6/v7, es gibt andere Themen, die auf armv6 nicht mehr funktionieren (Node 20) usw., und wir werden wahrscheinlich schnell gezwungen sein, diese Plattform aufzugeben… (Ende der Pi Zero usw., aber ist Gladys wirklich dafür gedacht, auf diesen Maschinen zu laufen, wenn es schon auf einem Pi 3/4 nicht besonders gut läuft ^^)

Hallo zusammen!

Heute teste ich die Docker-Image-Performance mit DuckDB auf einem Pi (um es absichtlich in einer langsamen Umgebung zu testen)

Das Docker-Image, das ich verwende:

gladysassistant/gladys:duckdb

Interessiert es dich, wenn ich das Image auf einem PiZero 2 starte? Oder auf meinem Pi 4 in der Produktion (4 GB RAM — nach einem Backup der Datenbank natürlich)?

Nicht für den Moment :slight_smile: Das Bild funktioniert im Moment nicht einmal :joy:

Okay, ich habe es endlich geschafft, das Bild zum Laufen zu bringen!

Allerdings musste ich von einem Docker-Image node-alpine zu node-slim wechseln, DuckDB installiert sich nicht gut auf Alpine…

Im Moment wird die Docker-Image-Größe recht groß, aber ich denke, es gibt Optimierungen, die ich vornehmen kann.

In der Zwischenzeit ist die Migration von DuckDB auf den Pi 3 gut verlaufen:

2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:39 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Daten von SQLite migrieren
2024-08-02T16:24:51+0200 <info> index.js:64 (Server.<anonymous>) Server hört auf Port 80
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:47 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: 0 bereits migrierte Gerätefunktionen in DuckDB gefunden.
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:51 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: 3 Gerätefunktionen migrieren
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB: Gerätefunktion = 91f39b3d-d747-4fd0-9880-8bc1e8f9067e migrieren, Offset = 0
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB: Gerätefunktion = 91f39b3d-d747-4fd0-9880-8bc1e8f9067e hat 0 Zustände zu migrieren.
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB: Gerätefunktion = 813c1830-b494-4f01-b339-1f287f621548 migrieren, Offset = 0
2024-08-02T16:24:54+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB: Gerätefunktion = 813c1830-b494-4f01-b339-1f287f621548 hat 34723 Zustände zu migrieren.
2024-08-02T16:24:55+0200 <info> index.js:130 () DuckDB: Chunk 0 für deviceFeature = 813c1830-b494-4f01-b339-1f287f621548 einfügen.
2024-08-02T16:25:00+0200 <info> scene.checkCalendarTriggers.js:25 (SceneManager.checkCalendarTriggers) Überprüfung der Kalenderauslöser am Freitag, 02. August 2024 14:25:00 GMT
2024-08-02T16:25:02+0200 <info> index.js:130 () DuckDB: Chunk 1 für deviceFeature = 813c1830-b494-4f01-b339-1f287f621548 einfügen.
2024-08-02T16:25:09+0200 <info> index.js:130 () DuckDB: Chunk 2 für deviceFeature = 813c1830-b494-4f01-b339-1f287f621548 einfügen.
2024-08-02T16:25:16+0200 <info> index.js:130 () DuckDB: Chunk 3 für deviceFeature = 813c1830-b494-4f01-b339-1f287f621548 einfügen.
2024-08-02T16:25:19+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB: Gerätefunktion = 813c1830-b494-4f01-b339-1f287f621548 migrieren, Offset = 40000
2024-08-02T16:25:19+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB: Gerätefunktion = 813c1830-b494-4f01-b339-1f287f621548 hat 0 Zustände zu migrieren.
2024-08-02T16:25:20+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB: Gerätefunktion = 24e039f2-d497-468a-87ee-517a1e67923d migrieren, Offset = 0
2024-08-02T16:25:20+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB: Gerätefunktion = 24e039f2-d497-468a-87ee-517a1e67923d hat 10272 Zustände zu migrieren.
2024-08-02T16:25:21+0200 <info> index.js:130 () DuckDB: Chunk 0 für deviceFeature = 24e039f2-d497-468a-87ee-517a1e67923d einfügen.
2024-08-02T16:25:27+0200 <info> index.js:130 () DuckDB: Chunk 1 für deviceFeature = 24e039f2-d497-468a-87ee-517a1e67923d einfügen.
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB: Gerätefunktion = 24e039f2-d497-468a-87ee-517a1e67923d migrieren, Offset = 40000
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB: Gerätefunktion = 24e039f2-d497-468a-87ee-517a1e67923d hat 0 Zustände zu migrieren.
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:76 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Migration von DuckDB abgeschlossen.

Meine Aufgabe „Löschen von Zuständen in SQLite“ ist vielleicht zu aggressiv, auf einem Pi 3 mit SD-Karte macht Gladys während der Migration kaum noch nutzbar, danach bleibt es aber ein Setup, das nicht empfohlen wird

@GBoulvin (und die anderen!) Wenn du es dieses Mal testen möchtest, ist das in Ordnung, aber es ist nur auf amd64- oder arm64-Architektur verfügbar (kein Pi Zero also vorerst)

Was ich dir empfehle, wenn du es testen möchtest, ist, es komplett neben deiner Produktion zu machen, am besten auf einer separaten Maschine von deiner Produktion :slight_smile:

:warning::warning: Andernfalls, wenn du nur deinen Pi 4 für die Produktion hast, musst du absolut das auf einem anderen Ordner als deine Produktions-DB machen, dieses Update ist major und das Zurückrollen auf das gladys:v4-Bild, das aktuell in Produktion ist, ist nicht möglich :warning::warning:

:warning: Ich weise darauf hin, dass ich das Betriebssystem für das Docker-Bild geändert habe, einige « native » Integrationen funktionieren möglicherweise nicht mehr (z. B. Bluetooth oder anderes), es gibt QA zu machen, die ich noch nicht gemacht habe ^^

Das Docker-Bild:

gladysassistant/gladys:duckdb

Zögere nicht, wenn du Rückmeldungen hast :wink:

Das Bild funktioniert im Moment gut. Die Migration der Datenbank hat etwa 15 Minuten gedauert.
Meine Produktionsdatenbank sqlite ist 7 GB groß, die duckdb 27 MB.
RPI4 8 GB mit SSD
Erste Rückmeldung, die Werte werden nicht abgeschnitten / abgerundet

Danke für das Feedback @cicoub13! Hast du es laufen lassen oder nur einmal getestet?

Für die Rundungen bin ich mir bewusst, ich hatte einen separaten PR gemacht, weil das Problem bereits in der Produktion auftritt, aber ich denke, ich werde diesen PR in den DuckDB-PR mergen und einen neuen Build erstellen!

Läuft seit Freitag.
Zigbee2Mqtt / MQTT / Enedis / OpenWeather / Kamera und Telegram OK

Ich habe gerade die PR gemerged, um die überflüssigen Nullen aus den Diagrammen zu entfernen und ein Build zu starten

Buildzeit ca. 4h15 :sweat_smile:

Edit: verrückt, mit dem Docker-Cache hat es nur 1 Minute gedauert :slight_smile:

@cicoub13 du kannst dein lokales Image aktualisieren, um die Diagramme ohne Nullen zu haben!

Ich habe versucht, die Größe des Docker-Images zu verkleinern, ich habe einen neuen Build gestartet!