Dieser Forum-Thread soll zum Thema ioBroker-Datenbanken und speziell der Option "Redis" als Datenbank zu nutzen informieren und Fragen beantworten. Er soll auch Hintergründe liefern, sodass jeder entscheiden kann ob dies das richtige für sein System ist oder nicht!
ioBroker Datenbank - einige Hintergründe
Ein ioBroker-System lebt von Daten und das diese Daten zwischen den verschiedenen Adaptern ausgetauscht werden. Adapter liefern ständig neue Informationen, in Skripten werden diese verarbeitet und basierend darauf werden neue Aktionen ausgelöst. Die dahinter liegenden Daten und Konfigurationen müssen für alle ioBroker-Komponenten performant und sicher abrufbar sein, damit das System schnell auf Änderungen reagieren kann.
Wenn ioBroker installiert wird, werden in der Standardkonfiguration die Daten in integrierten Datenbanken abgelegt - diese Konfiguration wird "file" genannt.
Diese integrierten Datenbanken sind erprobt, leistungsfähig und benötigen keine zusätzlich zu installierende Software. Das vereinfacht die Einrichtung und Nutzung des Systems.
Konkret bedeutet "file", dass der js-controller die Objects- und States-Daten direkt in seinem RAM-Speicher verwaltet (="In-Memory Data Store"). Der Datenzugriff auf In-Memory-Daten ist extrem schnell. Nachteil ist, dass diese Daten ohne Zwischenspeicherung bei jedem Stopp des js-controllers-Prozesses verloren gehen würden.
Damit die Daten nach einem Neustart des ioBroker-Servers wieder zur Verfügung stehen, werden "file"-Datenbanken bei Änderungen deshalb regelmäßig in das Dateisystem gesichert. Bei der Objects-Datenbank, die sich selten ändert, ist das 5s nach einer Änderung und bei der States-Datenbank sind es 30s nach einer Änderung. Diese Zeiten sind so gewählt, dass Performance, Verschleiß (z.B. SD-Karten) und Datensicherheit ausgewogen sind. Dieser Speichervorgang wird „Persistierung“ genannt.
Die persistierten Datenbanken werden in Form von JSON-Dateien im "iobroker-data"-Ordner gespeichert. Deren Inhalt kann man sich ansehen, aber bitte keinesfalls selbst ändern.
Dieses Setup wird für die meisten Installationen mit State- und Objektanzahlen bis weit in den 5-stelligen Bereich und mehreren 10.000 Ereignissen/15s selbst auf einem aktuellen Raspberrry Pi problemlos funktionieren.
Wenn aber der js-controller-Prozess ständig über 50-70% CPU in Anspruch nimmt oder seine IO-Last im Dateisystem spürbar wird, kann es Zeit werden sich über den Einsatz von Redis Gedanken zu machen
Redis-Datenbank - Was ist das und was bringt es?
Bei Performanceproblemen wegen vieler Datenänderungen bietet ioBroker für große Systeme die Möglichkeit, alternativ zur internen Datenhaltung, die externe Datenbank-Software Redis (https://redis.io/) einzubinden. Diese Konfiguration wird "redis" genannt.
Redis ist genauso wie die im js-controller integrierte "file"-Datenbank ein "In-Memory Data Store". Auch hier werden alle Daten im RAM abgelegt. Im Gegensatz zum js-controller, der in der Programmiersprache JavaScript geschrieben ist, ist Redis zu großen Teilen in C programmiert. Damit kann das für Datenhaltung optimierte Redis z.B. CPU-Ressourcen deutlich besser nutzen.
Der erste Geschwindigkeitsgewinn entsteht üblicherweise, indem man die States-Datenbank auf Redis umstellt, da diese Daten viel öfter geändert werden. Bei einer Umstellung der States-Datenbanken auf Redis bleibt die RAM-Nutzung nahezu gleich. Was der js-controller einspart benötigt jetzt der zusätzliche Redis-Prozess.
ioBroker unterstützte bislang die Möglichkeit, die States-Datenbank alternativ in Redis abzulegen. Neu mit js-controller 2.0 können jetzt neben Objekte auch Dateien im Redis abgelegt werden. Werden Dateien in Redis gespeichert, werden diese dort vollständig im RAM gehalten. Deswegen macht dies nur für Systeme mit mehr als 2GB Speicher Sinn!
Redis muss allerdings als eigener Dienst installiert und konfiguriert werden und auch die Daten wollen beim Backup entsprechend berücksichtigt sein. Das ioBroker System wird also etwas komplexer und jeder Nutzer, der sich für Redis entscheidet, muss sich entsprechend darin einarbeiten.
Redis bietet verglichen mit den internen ioBroker-Datenbanken vor allem Vorteile in den Bereichen Datenzugriffsgeschwindigkeit, IO-Management im Dateisystem und bessere Nutzung von CPU-Ressourcen. Der js-controller wird entlastet. Ein vorher träges System kann wieder schneller werden. Zudem wird damit ioBroker bis hin zu größten professionellen Installationen skalierbar.
Redis einrichten
Diese Anleitung wird vor allem Beispiele für Linux-Systeme wie Ubuntu oder Debian beinhalten. Wer also eine Redis-Datenbank auf einem NAS nutzt, muss bitte schauen was er genau wie anpassen muss. Achtung: Für Windows gibt es keine offiziellen Redis-Builds. Es gibt ältere Versionen die durchaus funktionieren, aber hier sollte man gut überlegen ob das der korrekte Weg ist! (https://github.com/microsoftarchive/redis)
Die Abschnitte weiter unten beschäftigen sich auch damit wo man für welches Szenario den Redis am besten installiert, also bitte vor der Installation weiterlesen 
Unter Ubuntu und Debian sind in den Standard-Repositories meist ältere Redis Versionen enthalten. ioBroker benötigt mindestens Version 2.6.0 von Redis, aktuell ist Version 5.x.
Für Ubuntu gibt es ein PPA (https://launchpad.net/~chris-lea/+archive/ubuntu/redis-server), das aktuelle Versionen bereitstellt.
Mit folgenden Kommandos installiert man damit Redis auf einem Ubuntu-System:
sudo add-apt-repository ppa:chris-lea/redis-server
sudo apt-get update
sudo apt-get install redis-server
Danach ist Redis an sich installiert und auch bereits automatisch gestartet.
Ein sudo systemctl status redis-server
zeigt den Status an. Falls es bei einem Reboot nicht automatisch wieder startet hilft ein sudo systemctl enable redis-server
.
Redis nutzt standardmäßig Port 6379 und bringt auch ein Kommandozeilentool für den Zugriff zur Datenbank mit: redis-cli
öffnet eine Shell. Der Befehl info
zeigt einige Informationen zum System, Speicherverbrauch und zu den gespeicherten Daten ("Keyspace") an, der natürlich aktuell noch leer ist.
Wenn man ein Single-Host -System betreibt bzw. ioBroker auf dem gleichen Host läuft dann war es das auch schon.
Falls auch andere Hosts auf diesen Redis-Server zugreifen sollen (Slaves oder so), dann muss dies noch erlaubt werden. Dazu muss /etc/redis/redis.conf editiert werden und die Zeile bind 127.0.0.1
zu bind 0.0.0.0
geändert werden und direkt darunter der protected_mode
auf no
gesetzt werden.
Danach startet sudo systemctl restart redis-server
den Server mit der aktualisierten Konfiguration neu.
Redis Backup (Persistenz) und Datensicherheits-Optionen
Normalerweise ist Redis eine "In-Speicher-Datenbank". Die Daten lagern also, wie oben schon erwähnt, im RAM. Wenn Redis beendet wird sind diese also weg. Um aber auch ein Update zu ermöglichen, unterstützt Redis zwei Arten der Datenspeicherung auf Festplatte.
Persistenz: RDB Dateien (Redis-Database-Dump-Datei)
Die erste Option ist das Speichern des gesamten Inhalts in einer Datei (RDB), welches beim Start wieder geladen wird. Diese Speicherung kann durch Kommandos angestoßen werden (BGSAVE) oder es kann konfiguriert werden nach wie vielen Datenänderungen pro Zeit die Datei geschrieben wird. Diese Persistenz ist standardmäßig aktiviert und speichert beispielsweise mindestens alle 15 Minuten wenn es eine Änderung gab oder öfter bei mehr Änderungen.
Dies zu konfigurieren sollte eine Mischung aus Datensicherheit (wie viele Daten kann man verkraften bei einem Crash zu verlieren) und Schreiblast für das Speichermedium, da immer der gesamte Inhalt geschrieben wird. Die ioBroker-eigene Datenbank speichert die Daten aktuell öfter als die Redis-Standard-Konfiguration.
Persistenz: AOF Dateien (Append-Only File)
Die zweite Option generiert mehr Schreiblast im Dateisystem, stellt aber sicher das die Daten ganz aktuell sind. Dazu wird fortlaufend eine sog. AOF Datei geschrieben, wo alle Änderungen immer angehängt werden. In regelmäßigen Abständen wird diese Datei dann konsolidiert und verkleinert sich damit wieder. Man erkauft sich also im Crash-Fall aktuelle Daten mit einer höheren Schreiblast. Für SD-Karten ist dies also eher nicht empfohlen. Für die Konfiguration verweise ich auf das kommentierte Konfig-File von Redis oder den untenstehenden Link.
Persistenz RAM-Bedarf
Wichtig ist zu beachten, dass beide Persistenz-Verfahren zum Zeitpunkt der Speicherung bzw. Konsolidierung der Daten zusätzliches RAM benötigen - teilweise das doppelte! Falls dieser RAM nicht verfügbar ist läuft - je nach Einstellungen - alles problemlos weiter. Ein Backup der Daten wird dann allerdings nicht erzeugt! Entsprechende Meldungen stehen nur im Logfile. Das muss also geprüft werden.
Redis - Persistenz Anwendungsgebiete
Beide Dateien kann man grundsätzlich als Backup sichern und kopieren, das Dump File ist dazu allerdings besser geeignet. Es ist allerdings auch möglich generell nur AOF zu nutzen und direkt vor dem Backup ein RDB-Dump File ganz aktuell mittels redis-cli BGSAVE
erstellen lassen und dies nach ein paar Sekunden kopieren.
Beide Optionen helfen allerdings nicht, wenn das Dateisystem des Rechners Fehler hat - dann sind die Daten in jedem Fall weg und man fällt auf das letzte Backup zurück. Eine Option das abzusichern sind Redis-Slaves (siehe nächster Punkt)
Mehr Details zur Persistenz gibt es unter https://redis.io/topics/persistence
Redis Slaves
Eine zweite Möglichkeit immer aktuelle Daten als Sicherung zu haben ist die Einrichtung eines zweiten Redis-Servers, der als Slave mit dem Haupt-Redis verbunden ist. Alle Datenänderungen werden vom Master an diesen Host durchgereicht. Er muss aber auf einem zweiten Rechner (oder mindestens Dateisystem) laufen, weil sonst kein echter Vorteil existiert.
Wenn der Rechner mit dem Master-Redis defekt ist, existieren immer noch die Daten nahezu Echtzeit-aktuell auf dem Slave. Man kann diesen also nutzen um einen Dump zu erstellen um den Master neu aufzusetzen, oder man macht als schnelle Lösung den Slave zum Master und ändert die Datenbank-IPs im ioBroker und ist fast aktuell wieder online.
"Fast aktuell" in den letzten Sätzen bedeutet das Redis keine 100%ige Garantie für die Aktualität der Slaves gibt, da die Synchronisierung erfolgt nachdem eine Änderung schon an das Skript bestätigt wurde. Wenn der Master also abstürzt bevor eine Änderung zum Slave übertragen wurde, so ist diese gegebenenfalls im Slave nicht enthalten. Aber im Normalfall ist dies ein geringes Risiko und betrifft nur sehr wenige Änderungen - wenn überhaupt.
Ein Slave schützt allerdings nicht gegen das versehentliche Löschen von Daten, da diese auf dem Slave auch direkt danach gelöscht sind. Hier helfen nur Backups.
Wer also die Hardware-Möglichkeiten hat sollte, zusätzlich zum Backup einer RDB-Datei in regelmäßigen Abständen, einen Redis-Slave einrichten.
Dazu installiert man Redis auf dem zweiten Host ganz normal, definiert, allerdings im redis.conf
mittels replicaof
den Redis-Master Host und Port. Details siehe z.B. in der kommentierten Konfig-Datei unter https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf
ioBroker-States-Datenbank auf Redis umstellen
Wie oben bereits geschrieben finden die meisten Änderungen und Datenabfragen mit die States-Datenbank statt. Alle Datenänderungen kommen hier an und werden dann wieder auf Adapter verteilt, wenn diese sich für bestimmte Daten angemeldet haben. Eine Umstellung der States auf Redis hat damit mit Abstand den größten und spürbarsten Performance-Effekt.
Wer nur die States-Datenbank umstellt, sollte den Redis-Server idealerweise auf dem gleichen Host installieren wie den ioBroker-Master. Wenn die States-Datenbank nicht verfügbar ist, beendet sich der Controller nach einer gewissen Wartezeit. Wenn der Redis also auf dem gleichen Host ist wie der Master-Controller, gibt es weniger Szenarien die zu Ausfällen führen.
Die Umstellung der States erfolgt dann über:
iobroker stop
iobroker setup custom
Dann für die "Objects" die aktuellen Einstellungen bestätigen ("file" als Typ, IP, Port 9001) und bei "States" jetzt als Typ "redis", die IP des Redis-Hostservers (bzw. 127.0.01 wenn auf dem gleichen Host) und 6379 als Port einstellen. Damit man nicht alle State-Daten verliert bietet es sich an die Daten zu migrieren, was die nächsten Fragen beid er Konfiguration abfragen.
Nach der Migration kann ioBroker mit iobroker start
neu gestartet werden. Falls man auch Slave-Systeme einsetzt, so müssen dort überall die gleichen Einstellungen über iobroker setup custom
vorgenommen werden. Allerdings ist die Frage nach der Migration zu verneinen!
Danach sollte das System problemlos wie vorher funktionieren, der js-controller allerdings weniger CPU und RAM benötigen. Der RAM-Verbrauch insgesamt sollte nahezu identisch sein, weil die State-Daten jetzt im Redis liegen und nicht mehr durch den js-controller verwaltet werden.
Das Risiko bei Datenverlusten ist bei den State-Daten meist nicht so groß, da sich diese über die Zeit meist selbst wieder aktualisieren (außer z.B. bei Zählern). Hier kann man also auch beim Redis-Backup gegebenenfalls pragmatisch sein. Eines haben sollte man aber trotzdem, da Skripte gern davon ausgehen das nötigr States auch Werte haben. Nicht vergessen: Auch ioBroker muss immer noch gesichert werden, da dort immer noch die Objektdefinitionen und Dateien liegen (z.B. mit iobroker backup
).
ioBroker-States-/Objects-/File-Datenbank auf Redis umstellen
Seit js-controller 2.0 kann auch die Objects- UND File-Datenbank durch Redis verwaltet werden. Der Schritt dies zu nutzen sollte sehr gut überlegt sein! Hier muss einiges beachtet werden, damit es im Fehlerfall nicht zu großen Problemen oder Ausfällen kommt.
Welche Auswirkungen hat das?
Der Haupt-Effekt alle Daten (States, Objekte UND Dateien) im Redis abzulegen ist, dass nichts davon mehr auf einzelnen Rechnern im Dateisystem liegt, sondern alles in Datenbanken im RAM vorgehalten wird. Der Zugriff ist damit, vor allem bei Files, etwas schneller - falls das Speichermedium langsam ist.
Eine ioBroker Installation wird damit also sehr unabhängig. Das frühere "Master/Slave"-Denken ändert sich ebenfalls. Alle js-controller und alle Adapter verbinden sich alle zur zentralen Redis-Datenbank, welche damit zum eigentlichen Koordinator - oder in bisherigem Wortgebrauch "Master" wird. Jeder js-controller kennt nur die Adapterinstanzen die zu seinem Host gehören und kümmert sich darum, dass diese gestartet oder beendet werden. Mehr tut er nicht mehr. Falls ein js-controller Prozess ausfällt, hat das keine Auswirkungen auf die anderen js-controller.
Falls jedoch der Redis-Server ausfällt oder neu gestartet wird, ist das gesamte System betroffen - wie früher beim ioBroker-Master-Controller.
Auch der Fakt das sämtliche Daten im Redis liegen bedeutet, dass man sich ein gutes Backup-Konzept ausdenken muss und auf dem Redis-System auch genügend RAM verfügbar haben muss. Da nun auch alle Dateien im RAM abgelegt sind, kann die Redis-Datenbank schnell auch mal einige hundert MB groß werden!
Warum/Wann sollte man das tun?
Diese komplette Umstellung wird (im Vergleich zu rUmstellung der States-Datenbank) nicht so wirklich große Performance-Gewinne mit sich bringen. Also warum ist das sinnvoll?
Es gibt mehrere valide Anwendungsfälle. Einige davon hier als Beispiel. Ihr habt mehr? Berichtet gern unten im Thread.
Vorweg: Wenn Ihr einen ioBroker-Host nutzt und keine Slaves, dann ist diese Option für Euch in meinen Augen nicht sonderlich sinnvoll. Die eigentlichen Stärken werden erst durch ein verteiltes ioBroker-System wirklich ausgenutzt.
-
Wer eine NAS hat, welche sowieso 24/7 läuft, genug verfügbares RAM und die Option hat dort einen Redis-Server laufen zu lassen kann so eine sichere Datenspeicherung erreichen. Durch ein darunter liegendes RAID ggf. sehr sicher. Die ioBroker Server können damit einfache Raspis mit SD Karten sein. Dort werden die Adapter installiert und ausgeführt. Da aber viel weniger Daten im Dateisystem geschrieben werden halten die SD-Karten ggf. um einiges länger. Auf den Raspis aber Redis-Slaves laufen zu lassen mit allen Daten ist wohl nur bei Raspi 4 mit 4GB RAM sinnvoll. In so einem Szenario, und ausgehend von echten HDDs im NAS, eignet sich die AOF-Persistenz mit regelmäßigem RDB-Backup (auf einen anderen Host als die NAS) recht gut. Die NAS wird allerdings zum "Single-Point-of-Failure" - ist Sie defekt ist ioBroker ebenfalls offline. Dies lässt sich nur mit mindestens einem gesonderten Redis-Slave absichern.
-
Wer mehr Flexibilität möchte wie das ioBroker System aufgestellt werden kann und auch einzelne Hosts mal offline nehmen können will, ohne dass der ganze Rest auch betroffen ist, kann ebenfalls diese Option überlegen. Wichtig ist allerdings das genügend RAM verfügbar ist und auch ein Backup bzw. ein Slave verfügbar ist
-
Geplant wurde das Feature in Vorbereitung für die Möglichkeit ein ioBroker System hochverfügbar zu machen. Dazu ist aber noch einiges mehr nötig. Siehe dazu im nächsten Beitrag "Redis Sentinel“.
Die Umstellung
Die Umstellung ist am Ende so einfach wie bei der States-Umstellung:
iobroker stop
iobroker setup custom
Dort bei beiden Datenbanken den Typ "redis" wählen, IP und Port des Redis-Hosts eingeben und ggf. die Daten migrieren. Das wird eine Weile dauern. Bitte alle Hinweise während der Umstellung beachten.
States und Objekte im gleichen oder getrennten Redis-Prozessen?
Am einfachsten ist es natürlich, States und Objekte zusammen in einem Redis-Prozess speichern zu lassen. Dies bedeutet allerdings auch das nur alle Daten zusammen gesichert werden können. Bei der ioBroker File-DB waren States, Objekte und Files getrennt und konnten so selektiv gesichert werden. Auch die Schreiblast ist, wenn alles in einem Redis gespeichert ist, höher, da die Datenbank größer ist.
Um auch mit einem Redis-Setup die sich oft ändernden States und nicht so oft geänderten Objekte und Dateien zu trennen, kann man einfach zwei Redis-Prozesse je Host nutzen. Anleitungen dazu gibt es zB unter https://gist.github.com/inecmc/f40ca0ee622e86999d9aa016c1b15e8c .
Bei iobroker setup custom
werden einfach die jeweiligen unterschiedlichen Ports für States bzw. Objekte/Dateien angegeben.