Datenmanagement

Die serverlose Architektur von SQLite ist für das IoT nicht gut geeignet

Actian Germany GmbH

17. Juni 2020

Person, die in Hemd und Krawatte mit Bällen jongliert

Dritter Teil: SQLite, die "Flat File" der Datenbanken

In den letzten Artikeln haben wir uns in unserer SQLite-Blogserie mit der SQLite Serverless Architecture und ihrer Untauglichkeit für IoT beschäftigt. Diejenigen unter Ihnen, die die Serie bereits verfolgt haben, können zum nächsten Abschnitt springen, aber wenn Sie neu in dieser Diskussion sind, sollten Sie sich die vorherigen Teile ansehen.

  • Im ersten Teil, Mobile mag IoT sein, aber IoT ist nicht mobil, wenn es um Daten geht, haben wir die Tatsache untersucht, dass SQLite zwar die beliebteste Datenbank auf dem Planeten ist - größtenteils aufgrund seiner allgegenwärtigen Deployment auf mobilen Smartphones und Tablets, wo es eingebettet Anwendungen für einen einzigen Nutzerunterstützt Nutzernicht die Anforderungen der IoT mit mehreren Verbindungen, Nutzer Nutzern und mehreren Anwendungen unterstützen kann, die sich mit viraler Wildheit in jeder Branche ausbreiten. In einer Welt, in der die Leistung von Geparden und Wanderfalken gefragt ist, ist SQLite eine Bananenschnecke.
  • Im zweiten Teil, Rethinking What Client-Server Means for Edge Datenmanagement, haben wir die Hauptmerkmale und -charakteristika der SQLite Serverless Architecture (Portabilität, wenig bis keine Konfiguration, geringer Platzbedarf, SQL-API und eine anfänglich kostenlose Version, um die Akzeptanz zu fördern) im Hinblick auf die Anforderungen des modernen Datenmanagement betrachtet und die Mängel der SQLite-Architektur in Bezug auf ihre Fähigkeit zur Integration mit kritischen Merkmalen traditioneller Client-Server-Datenbanken (vor allem die oben genannten Mehrpunktqualifikationen) diskutiert.

In unserer abschließenden Analyse dieser serverlosen Architektur würde ich gerne kennenlernen was passiert, wenn ein Entwickler diese Warnhinweise ignoriert und sich auf SQLite als Mittel zur Bewältigung von IoT verlässt.

Verwechseln Sie Multi-Connection und Multi-Threaded nicht mit Client-Server

In den späten 90er Jahren wurden die Anwendungen immer ausgefeilter, erzeugten und erfassten mehr Daten und führten intern komplexere Operationen mit diesen Daten durch. Infolgedessen mussten Anwendungsentwickler eine Menge Workarounds entwickeln, um die Einschränkungen der routinemäßigen, betriebssystembasierten Dateiverwaltungsdienste zu umgehen. Anstatt Zeit für all diese Basteleien aufzuwenden, verlangten Anwendungsentwickler nach einer dedizierten Datenbank, die sie in eine Anwendung einbetten konnten, um ihre spezifischen Datenmanagement zu unterstützen.

Um die Wende zum21. Jahrhundert erschien SQLite und schien wie geschaffen dafür, diese Bedürfnisse kennenlernen . SQLite ermöglichte Indizierung, Abfragen und andere Datenmanagement durch eine Reihe von Standard-SQL-Aufrufen, die in den Anwendungscode eingefügt werden konnten, wobei die gesamte Datenbank als eine Reihe von Bibliotheken gebündelt wurde, die Teil der endgültigen ausführbaren Datei wurden. Dabei ist zu bedenken, dass die meisten dieser Anwendungen monolithische Nutzer waren, die für die einfacheren CPU der damaligen Zeit entwickelt wurden. Sie waren nicht für die Ausführung mehrerer Prozesse, geschweige denn mehrerer Threads ausgelegt. Nutzer und Datensicherheit hatten damals noch nicht die hohe Priorität, die sie heute haben. Und wie sieht es mit der Leistung in einer vernetzten Umgebung aus? Drahtlose Netzwerke waren reaktiv und bestenfalls punktuell. Mehrere externe Datenverbindungen mit hoher Bandbreite waren unüblich.

Es ist daher nicht verwunderlich, dass SQLite bei seiner Entwicklung nicht in der Lage war, gleichzeitige Lese- und Schreibanfragen für eine einzige Verbindung (geschweige denn für mehrere Verbindungen) zu verarbeiten. Die Entwickler waren begeistert von einer einbettbaren Datenbank, die es mehreren Prozessen ermöglicht, innerhalb einer Anwendung sequentiellen Lese- und Schreibzugriff auf eine Datentabelle zu haben. Sie waren nicht auf der Suche nach unternehmenstauglichen Funktionen. Sie wollten keine eigenständigen Datenbanksysteme entwickeln, die mehrere Anwendungen gleichzeitig unterstützen würden. Sie brauchten einfach mehr als einen durch ein Betriebssystem vermittelten Flat-File-Zugriff.

Und hier liegt der Kern des Problems mit SQLite. Es war nie dafür gedacht, mehrere externe Anwendungen oder deren Verbindungen asynchron zu verarbeiten, wie es eine traditionelle Client-Server-Datenbank tun würde. Moderne vernetzte Anwendungen haben in der Regel mehrere Prozesse und/oder mehrere Threads. Wenn Sie SQLite in eine Situation mit mehreren Verbindungen und der Möglichkeit mehrerer gleichzeitiger Lese- und Schreibanfragen bringen, besteht schnell die Möglichkeit von Wettlaufsituationen und Datenbeschädigungen.

Um fair zu sein, hat SQLite versucht, diesen sich entwickelnden Anforderungen Rechnung zu tragen. Die aktuelle Version von SQLite verarbeitet mehrere Verbindungen über die Thread-Modus-Optionen: Single-Thread, Multi-Thread und serialisiert. Single-Thread ist der ursprüngliche SQLite-Verarbeitungsmodus, der jeweils nur eine Transaktion verarbeitet, d. h. entweder einen Lese- oder einen Schreibzugriff über eine einzige Verbindung. Multi-Thread unterstützt mehrere Verbindungen, aber immer noch jeweils eine zum Lesen oder Schreiben. Serialized - der Standardmodus der aktuellsten SQLite-Versionen - kann mehrere gleichzeitige Verbindungen unterstützen (und damit auch eine Multi-Thread- oder Multiprozess-Anwendung), kann aber nicht alle Verbindungen gleichzeitig verarbeiten. SQLite kann gleichzeitig lesende Verbindungen im Multi-Thread- und serialisierten Modus verarbeiten, sperrt aber die Datentabellen, um gleichzeitige Schreibversuche zu verhindern. SQLite kann auch nicht mit der Orchestrierung von Schreibvorgängen aus mehreren Verbindungen umgehen.

Vergleichen Sie dies mit der Architektur einer echten Client-Server-Datenbank, die für die verwalten gleichzeitiger Schreibvorgänge ausgelegt ist. Die Client-Server-Datenbank wertet jede Schreibdienstanforderung aus, und wenn versucht wird, auf dieselben Daten innerhalb einer Tabelle zu schreiben, blockiert sie die Anforderung, bis der aktuelle Vorgang für diese Daten abgeschlossen ist. Bei Versuchen, in verschiedene Teile der Datentabelle zu schreiben, lässt der Server diese zu. Das ist echte Orchestrierung. Das Sperren der gesamten Tabelle und das Zurückhalten von Schreibvorgängen (oder das Vortäuschen von sequentiellen Schreibvorgängen neben mehreren Lesevorgängen mit WAL) ist nicht dasselbe.

Warum ist dies ein Hindernis für SQLite in einer IoT ? Einer der grundlegendsten Vorgänge bei IoT und -Gateways besteht darin, Daten von einer Vielzahl von Geräten in Ihr Lager zu schreiben, und die Schreibsperren, die bei Multi-Thread-/Multi-Verbindungsvorgängen auferlegt werden, machen dies in einer Produktionsumgebung nicht praktikabel. Ein zweiter grundlegender Vorgang, der in einer IoT stattfindet, ist die Datenverarbeitung und Analyse von zuvor gesammelten Datensätzen. Auch wenn es sich hierbei um leseintensive Operationen handelt, die unabhängig (entweder als separate Prozesse oder als separate Threads) von den gerade beschriebenen schreibintensiven Operationen ausgeführt werden, können sie in einer SQLite-Umgebung nicht gleichzeitig stattfinden und die ACID-Konformität aufrechterhalten.

Wenn Sie Ihre Bereitstellungen erweitern oder die Systemkomplexität zunimmt - z. B. wenn Sie mehr und mehr Instrumente in einer Umgebung einsetzen möchten, sei es ein autonomes Auto oder ein intelligentes Gebäude -, werden Sie unweigerlich mehr Datenverbindungspunkte nachgelagert oder innerhalb Ihrer lokalen Umgebung hinzufügen. Jede dieser Einheiten wird eine oder mehrere zusätzliche Datenbankverbindungen haben, wenn nicht sogar ihre eigene Datenbank, die eine Verbindung benötigt. Sie könnten versuchen, diese Verbindungen herzustellen, aber sie müssen durch zusätzliche Anwendungslogik gehandhabt werden, was wahrscheinlich zu Antwortzeiten führen wird, die außerhalb der Entwurfseinschränkungen für Ihr IoT liegen.

Behelfslösungen zur Verleugnung (oder Verweigerung) der Realität

SQLite-Partisanen werden mit abweisender Nonchalance mit den Händen winken und Ihnen sagen, dass SQLite schnell genug ist (ist es nicht; wir haben bereits erörtert, wie langsam SQLite ist) und dass Sie Ihre eigenen Funktionen erstellen können, um gleichzeitige Lese- und Schreibvorgänge über mehrere Verbindungen hinweg zu handhaben - und zwar durch manuelle Synchronisierung speziell für den jeweiligen use case . Eine Methode zur verwalten dieses Szenarios besteht darin, den oben erwähnten serialisierten Modus zu verwenden und Funktionen zur Synchronisierung und Orchestrierung innerhalb der Anwendungsthreads zu erstellen. Mit diesem Ansatz wird versucht, die Übertragung von Lese- und Schreibanforderungen auf mehreren Kanälen zu vermeiden (und damit Race Conditions und die Möglichkeit der Datenbeschädigung zu vermeiden). Allerdings erfordert dieser Ansatz auch ein hohes Maß an Fachkenntnis, die Übernahme langfristiger Verantwortung für den Code und die Notwendigkeit umfangreicher Tests und Validierungen, um sicherzustellen, dass die Operationen ordnungsgemäß ablaufen.

Ein alternativer Ansatz wäre, das Äquivalent eines Orchestrierung zu bauen und die Single-Thread-Option innerhalb von SQLite zu verwenden, was Race Conditions oder Datenbeschädigung ausschließen würde. Aber der Rückgriff auf die Single-Thread-Option wäre so, als würde man dieser Bananenschnecke dabei zusehen, wie sie sich in noch langsamerer Bewegung bewegt. Angesichts der schnellen, parallelen Schreibvorgänge, die erforderlich sind, um mehrere hochauflösende Dateneinspeisungen oder große Sensorgitter unterzubringen, ist das kein gangbarer Weg. Außerdem haben Sie nur die Schwächen der Datenbankarchitektur ausgeglichen, indem Sie die Anwendung zwangen, etwas zu tun, was die Datenbank tun sollte. Und das müssen Sie für jede Anwendung in Ihrem IoT wieder und wieder tun.

Es gibt mehrere Codesätze und einige kleine Unternehmen, die versucht haben, diesen Ansatz zu verwirklichen, allerdings mit begrenztem Erfolg. Sie funktionieren nur mit bestimmten Entwicklungsplattformen auf einigen wenigen von SQLite unterstützten Plattformen. Selbst wenn diese Plattformen für Ihren use case geeignet sind, können die Leistungsprobleme das Risiko und die Schwierigkeiten bei der Programmierung dieses Workarounds in Ihrer Anwendung erhöhen.

Wir haben diesen Eisberg schon einmal gesehen

Bei diesem abschreckenden Beispiel geht es nicht nur um die Menge an Heimwerkerarbeiten, die durch die unbestrittene Abhängigkeit von SQLite für eine bestimmte Anwendung entstehen. Wie das IoT selbst geht es um viel mehr als das. Wenn Sie sich zum Beispiel verpflichten, dies in Ihrem eigenen Code zu handhaben, wie werden Sie dann die Bewegung von Daten von einem Gerät zum Edge On-Premises handhaben? Wie werden Sie das Verschieben von Daten in die oder aus der Cloud handhaben? Die Anforderungen für die Interaktion mit Servern auf beiden Ebenen können unterschiedlich sein, so dass Sie mehr Code schreiben müssen, um Datenumwandlungen durchzuführen (erinnern Sie sich an den Blog über SQLite und ETL?). Sie könnten versuchen, den ETL-Engpass zu vermeiden, indem Sie SQLite auf beiden Seiten verwenden, aber das wäre nur ein virtueller Tropfen auf den heißen Stein. Sie müssten immer noch Code schreiben, um SQLite als serverbasierte Datenbank auf dem Gateway und in der Cloud zu verwenden.

Letztlich kommen Sie nicht umhin, mehr Code zu schreiben, damit SQLite in jedem dieser Szenarien funktioniert. Und das ist nur die Spitze des Eisbergs. Sie müssten Kompromisse zwischen DIY und partiellem DIY plus Code-Module/Bibliotheken für andere Funktionen - von der Datenverschlüsselung und der Verwaltung öffentlicher Schlüssel bis zur Bearbeitung von Anfrage und mehr - eingehen. Die Liste der Funktionen, die eine echte Client-Server-Infrastruktur mit sich bringt und die in SQLite fehlen, ließe sich beliebig fortsetzen.

Damals ermöglichte SQLite den Entwicklern, einen Großteil der Bastelei zu vermeiden, die bei der Verwaltung von Flachdateien erforderlich war. Für die damals aufkommenden Anwendungsfälle war es eine ideale Lösung. Für die heutigen Anwendungsfälle wäre jedoch noch mehr Eigenarbeit erforderlich, damit SQLite funktioniert - und selbst dann würde es nicht so gut funktionieren. Die überwiegende Mehrheit der IoT erfordert ein Maß an Client-Server-Funktionalität, das SQLite nicht bieten kann, ohne erhebliche Kosten zu verursachen - in Bezug auf Leistung, Entwicklungszeit und Risiko. Kurz gesagt, es ist ein Déjà-vu, aber jetzt ist SQLite die flache Datei, deren Unzulänglichkeiten wir der Vergangenheit angehören lassen müssen.

Und wenn Sie glauben, dass all dies nur ein Problem für Entwickler ist, dann irren Sie sich. Im nächsten und letzten Blog dieser Reihe werden wir den Blickwinkel etwas erweitern und uns ansehen, was dies für das Unternehmen und den Endgewinn bedeutet.

Wenn Sie bereit sind, SQLite zu überdenken und mehr über Actian Zen zu erfahren, können Sie Zen Core kostenlos testen, das für Entwicklung und Vertrieb lizenzfrei ist.

actian avatar logo

Über Actian Corporation

Actian macht Daten einfach. Unsere Datenplattform vereinfacht die Verbindung, Verwaltung und Analyse von Daten in Cloud-, Hybrid- und lokalen Umgebungen. Mit jahrzehntelanger Erfahrung in den Bereichen Datenmanagement und -analyse liefert Actian leistungsstarke Lösungen, die es Unternehmen ermöglichen, datengesteuerte Entscheidungen zu treffen. Actian wird von führenden Analysten anerkannt und wurde für seine Leistung und Innovation mit Branchenpreisen ausgezeichnet. Unsere Teams präsentieren bewährte Anwendungsfälle auf Konferenzen (z. B. Strata Data) und tragen zu Open-Source-Projekten bei. Im ActianBlog behandeln wir Themen wie Echtzeit-Dateneingabe, Datenanalyse, Data Governance, Datenmanagement, Datenqualität, Datenintelligenz und KI-gesteuerte Analysen.