Suche

Binäre Austauschformate: Kompakte Daten nicht nur im Internet of Things

Maik Wojcieszak

© Shutterstock/Kotkoa

Das Internet der Dinge bringt eine Entwicklung auf die Tagesordnung, die dem Trend immer schnellerer Hardware und immer größerem Arbeitsspeicher diametral entgegensteht: Sensoren mit geringen Ressourcen, die stromsparend arbeiten müssen, werden im Netz in großer Anzahl miteinander verbunden und müssen ihre Daten effizient liefern.

Textbasierte Datenaustauschformate wie JSON oder XML benötigen Parser, die auf den jeweiligen Geräten ausgeführt werden. Binäre Daten, wie Bilder oder Audiodateien, werden für die Übertragung als Text aufwändig kodiert. Nicht nur der eigentliche Vorgang der Datenumwandlung benötigt dabei Rechenzeit und Speicher, sondern auch die Menge der zu übertragenen Daten steigt merklich an. Binäre Austauschformate wie Binary JSON (BSON) oder binäre, an XML orientierte Formate wie WBXML wurden für diesen Zweck entwickelt.

Wo sind die Grenzen für die Anwendung binärer Austauschformate? Warum sind binäre Formate nicht nur für das Internet der Dinge interessant?

Lange Zeit war XML das bevorzugte Austauschformat für Daten im Netz. Syntaktisch angelehnt an HTML, einfach strukturiert und mit der Möglichkeit versehen, beliebig neue Datenstrukturen und Tags zu kreieren, bot XML eine Flexibilität, die bisher in keinem anderen Datenformat zu finden war. Es ist möglich, tief verschachtelte Datenmodelle zu entwickeln, und die Darstellung der Daten ist frei wählbar. Auf SOAP basierende Netzdienste verwenden XML für den Austausch von Nachrichten. Viele Schnittstellen wurden im Laufe der Jahre, basierend auf den Möglichkeiten von XML, geschaffen und in unterschiedlichsten Systemen erfolgreich eingesetzt.

REST-basierte Netzdienste verwenden bevorzugt JSON als Datenformat. Es hat sich die Meinung durchgesetzt, JSON sei die bessere Wahl, verglichen mit XML. Ein Pro-Argument ist das geringere Datenvolumen von JSON gegenüber XML. Ob diese zusätzlichen Bytes jedoch eine Rolle spielen, hängt vom jeweiligen Anwendungsfall ab. Für die Verbreitung von JSON spielt sicher ebenfalls eine Rolle, dass JavaScript in Verbindung mit einem Browser JSON problemlos erzeugen und auswerten kann.

XML unterscheidet keine Datentypen, weshalb es der Anwendung überlassen bleibt, die enthaltenen Zeichenketten zu interpretieren. Das macht XML zwar flexibel, jedoch für klassische Daten auch aufwändiger in der Anwendung. Im Gegensatz dazu sind für JSON die möglichen Datentypen und ihre Formatierung festgelegt. Bei der Entwicklung von Schnittstellen erweist sich diese Festlegung als Vorteil, da eine Spezifikation nur die Struktur der Daten festlegt, nicht aber deren Darstellung. Auch die Implementierung wird vereinfacht: Die String-Konvertierung einer Gleitkommazahl ist beispielsweise in vielen Fällen sprachabhängig, was beim Austausch der Daten zwischen Systemen mit unterschiedlichen Sprachen zu Problemen führen kann. JSON erlaubt für Gleitkommazahlen keine sprachabhängige Darstellung und ist somit nicht anfällig für dieses Problem.

Auch wenn die Festlegung auf bestimmte Datentypen Vorteile mit sich bringt und verteilte Systeme stabiler macht, birgt dieses Vorgehen auch den Nachteil, sich auf diese Datentypen beschränken zu müssen.

JSON erweitern

Da JSON nicht erweiterbar ist, werden in der Praxis Daten, zu denen kein existierender  Datentyp passt, zum Beispiel als String angegeben. Es ist dann die Aufgabe der Anwendung, diese Daten korrekt zu interpretieren.

Datum und Zeitangaben sind ein Beispiel für dieses Vorgehen. In der Praxis werden sie häufig als String dargestellt. Alternativ findet auch die numerische UNIX-Zeit oder ein Array mit Einträgen für Jahr, Monat, Tag usw. Verwendung. Wie diese speziellen Daten von einer Anwendung auszuwerten sind, legt eine Schnittstellenbeschreibung fest. Wie bei XML wird die Interpretation der Datentypen dabei in die Ebene der Anwendung verschoben, was Mehraufwand bei der Implementierung und möglicherweise geringere Flexibilität bei zukünftigen Änderungen bedeutet.

Binäre Daten

Binäre Daten wie Bilder oder Multimediadateien nehmen in textbasierten Austauschformaten  eine Sonderstellung ein. Für ihren Transport werden zwei unterschiedliche Vorgehensweisen verwendet:

  1. Binäre Daten im Austauschformat einbetten: Binäre Daten werden beispielsweise base64-kodiert und zusammen mit der Nachricht übertragen. Eine Kodierung ist für den Transport in allen textbasierten Formaten erforderlich. Die Datenmenge wird dabei um den Faktor 33 vergrößert, und es entsteht zusätzlicher Aufwand bei der Konvertierung. Dieses Vorgehen wirkt sich nachteilig auf die Performance der Anwendung aus.
  2. Verweise auf Dateien: Eingebettete URIs verweisen auf binäre Daten auf einem FTP- oder HTTP-Server. Eine Kodierung der Dateien ist nicht erforderlich und die Nachricht bleibt klein, da sie nur den Verweis enthält. Das Ziel des Verweises muss allerdings für den Empfänger erreichbar sein. Ad hoc erstellte Binärdaten, wie zum Beispiel dynamisch erzeugte Diagramme, müssen vor dem Senden der Nachricht auf den Fileserver transportiert werden. Der Server ist dafür verantwortlich, veraltete Daten automatisch zu entfernen.

Für binäre Daten, die nicht als Datei auf einem Server liegen, sondern für eine Anfrage explizit erstellt und anschließend nicht mehr gebraucht werden, bietet sich das Einbetten in eine Nachricht an. Nachrichten und Dateien auf unterschiedlichen Wegen zu übertragen, birgt darüber hinaus Sicherheitsrisiken, da unterschiedliche Protokolle und Verbindungen gesichert werden müssen, anstatt eine bereits gesicherte Verbindung für die gesamte Kommunikation zu nutzen.

Für Geräte im Netz, denen nur eingeschränkte Rechenleistung zur Verfügung steht, ist jede zusätzliche Verbindung, jede temporär gespeicherte Datei und zusätzlicher Aufwand für Aufräumarbeiten und Verwaltung zu vermeiden.

Binäre Formate erlauben einen effizienten Austausch eingebetteter Daten. Das macht sie nicht nur für das Internet der Dinge interessant, sondern bietet auch Möglichkeiten bei der Anwendung in Web-APIs und Systemen, die über andere Protokolle als HTTP kommunizieren.

Ein logischer Schritt

Netzwerkprotokolle für das Internet der Dinge wie CoAP und MQTT verwenden binäre Frames. Auch der kürzlich von der Internet Engineering Steering Group (IESG) zur Standardisierung freigegebenen Entwurf des HTTP/2-Protokolls setzt auf eine binäre Formatierung für mehr Effizienz bei der Übertragung. Der logische Schritt ist also, die von diesen Protokollen transportierten Daten ebenfalls binär darzustellen.

Es ist kein Wunder, dass immer neue binäre Datenformate auftauchen. Sie orientieren sich wahlweise an JSON oder XML. Daten hierarchisch verschachtelt zu strukturieren, hat sich in der Praxis bewährt. Neben der Möglichkeit, binäre Daten ohne Kodierung einzubetten, wird auch für klassische Datentypen die Menge der notwendigen Bytes für deren Darstellung reduziert. So kann der Wert 18446744073709551615 binär mit 8 Bytes dargestellt werden. JSON und XML sind Textdateien, die Unicode verwenden. Je nach Kodierung werden also für die Darstellung statt 8 mindestens 20 Bytes benötigt. Ist die Kodierung der Textdatei UTF32, werden daraus 80 Bytes, da jedes Zeichen 4 Bytes benötigt.

Was für ein Typ?

Daten abhängig von ihrem Datentyp binär darzustellen, spart Platz und Rechenzeit; Parsen und umwandeln von Strings ist nicht erforderlich. Fehler werden vermieden, weil sichergestellt ist, dass zum Beispiel ein Zahlenwert vom Empfänger korrekt gelesen wird.

Klingt soweit gut, aber welche Datentypen werden benötigt? Natürlich ist davon auszugehen, dass klassische Datentypen auf jeden Fall dabei sind. Abstufungen wie 16, 32 und 64 Bit erlauben der Anwendung, nur so viel Speicher zu nutzen, wie unbedingt nötig.

Bei Strings zeigt sich ein weiterer Vorteil des binären Datenformats. Für reine Feldbezeichnungen wie Spaltennamen aus Datenbanktabellen werden ASCII-Strings mit nur einem Byte pro Zeichen verwendet. Unicode-Strings werden wie gewünscht kodiert, wobei in einem einzigen Dokument verschiedene Kodierungen möglich sind. Im Gegensatz dazu bezieht sich die Kodierung eines textbasierten Datenformats auf das gesamte Dokument. Umwandlungen erfordern auch hier wieder Rechenzeit und müssen sehr sorgfältig durchgeführt werden.

Weniger als nichts

Datenbanken haben eine lange Geschichte, und die verwendeten Datentypen sind eine solide Grundlage für die Modellierung realer Zusammenhänge. Der Wert NULL spielt in diesem Zusammenhang eine wichtige Rolle und kennzeichnet ein leeres Datenfeld in einer Tabelle. Ein Vergleich mit dem Wert null im JSON-Format zeigt jedoch einen wesentlichen Unterschied. JSON null hat einen eigenen Datentyp, während in einer Datenbank NULL den Typ der jeweiligen Tabellenspalte trägt. In der Praxis wird ein Null aus einer Datenbank auch mit speziellen Werten wie 0 oder „“ (leerer String) dargestellt, um den Typ des Felds zu transportieren. Eine Unterscheidung von NULL mit Datentyp für leere Werte und VOID für Felder, deren Typ unbekannt ist und die keine Daten enthalten, hilft hier genauer zu unterscheiden.

1. Jan. 1970 00:00 Uhr UTC

Bei der Entwicklung des UNIX-Betriebssystems wurde bekanntlich entschieden, Zeit als 32-Bit-Integer mit Vorzeichen festzulegen. Der Wert gibt die Anzahl der Sekunden seit dem 1. Jan. 1970 00:00 Uhr UTC (The Epoch) an. Im Jahre 2038 wird der Zahlenraum in dieser Definition erschöpft sein, daher verwenden moderne Systeme einen 64-Bit-Integer. Negative Zahlen geben Zeiten vor der Epoche an. Diese Darstellung eignet sich gut für binäre Datenformate und lässt sich leicht in ein Datum und eine Uhrzeit umrechnen.

Eine Zeit kann auch als String ausgedrückt werden („1971-08-23 15:32:12:000“), was für binäre Austauschformate zwar möglich ist, jedoch wie bei textbasierten Formaten aufwändige Konvertierungen erfordert.

Eine Darstellung der Zeit als Folge von ganzen Zahlen, die als Jahr, Monat, Tag, Stunde, Minute, Sekunde und Millisekunde interpretiert werden, bietet die Möglichkeit, eigene Typen für ein Datum oder eine Zeit zu definieren. Auch ein Zeitstempel mit einer Auflösung von einer Millisekunde ist so möglich.

Gut verpackt

Die Stärke von Austauschformaten wie XML und JSON ist die Möglichkeit, Datenfelder in Containern zusammenzufassen. Objekte, wie sie in JSON genannt werden, sind eine Sammlung von benannten Werten. Sie eignen sich gut für die Darstellung einzelner Tabellenzeilen. Ein Array ist eine Reihe von Werten in einer bestimmten Reihenfolge. Jeder Wert in JSON kann ein Array oder ein Objekt enthalten. Für die Darstellung von Tabellen eignet sich deshalb ein Array mit Objekten. Nachteil dieser Art der Darstellung ist die Wiederholung von Spaltenbezeichnungen vor jedem Wert, was unnötigen Platz verschwendet.

Für binäre Datenformate ist ein eigener Typ für Tabellen daher eine denkbare Erweiterung. Neben einer besseren Nutzung des Speicherplatzes bietet dieser Weg auch die Sicherheit, dass Spalten und Zeilen konsistent sind und keine Werte fehlen.

Sowohl XML als auch JSON sehen für ein Objekt nur Namen vor. Abhängig von Kodierung und XML-Spezifikation sind jedoch Rahmenbedingungen, wie erlaubte Zeichen, vorgegeben. Auch in einem binären Datenformat würde ein Objekt key/valuePaare enthalten. Der Schlüssel (key) sollte jedoch nicht auf Strings beschränkt sein. Jeder Wert ist als Schlüssel geeignet. Natürlich muss dabei der Datentyp berücksichtigt werden. Der Wert 0 ist nicht identisch mit 0.0 oder „0“. Bei Namen sind Unicode-Bezeichnungen in diesem Fall kein Problem mehr. Wegen ihrer Komplexität eignen sich Objekte und Arrays nicht als Schlüssel, da sie miteinander verglichen werden müssen.

Version und Erweiterbarkeit

Je spezieller ein Datenformat ist, desto besser kann es optimiert werden. Binäre Formate legen  Datentypen fest. Einige bieten die Möglichkeit, eigene Datentypen zu definieren und das Format damit zu erweitern. Anwendungen, die diese Erweiterungen nicht kennen, würden sie nicht verstehen. Das gilt selbstverständlich auch für textbasierte Formate. Natürlich kann in der Praxis ein vorhandener Datentyp von einer Anwendung interpretiert werden. Wie im Beispiel des Datums in JSON werden dann die Daten entsprechend ausgewertet. Eine Anwendung, die ein solches Feld auswertet und dessen Bedeutung nicht kennt, kann zumindest den Datentyp verstehen, auch wenn der Inhalt möglicherweise keinen Sinn ergibt.

Ein Datenformat, das allgemeingültig ist und über einen langen Zeitraum in unterschiedlichen Anwendungen verwendet wird, benötigt sicher die eine oder andere Erweiterung. Auch wenn es etwas Speicherplatz kostet, sollte ein Binärformat deshalb eine Version enthalten. Anwendungen können so prüfen, wie eine Nachricht auszuwerten ist oder ob sie ausgewertet werden kann, ohne vorher eine Version mit dem Sender auszuhandeln. Eine Version am Anfang des Dokuments erlaubt, falls nötig, umfangreiche Änderungen am Datenformat.

Lesbarkeit

Eines der Argumente gegen die Verwendung binärer Datenformate ist die Lesbarkeit. Wer bereits versucht hat, ein textbasiertes Format wie JSON oder XML zu lesen oder zu editieren, hat möglicherweise drei Dinge festgestellt:

  1. Bevor die Datei lesbar ist, muss sie in einem Texteditor geöffnet werden. Es wird also ein Werkzeug benötigt.
  2. Das Lesen und Verstehen haben nur wenig miteinander zu tun.
  3. Nachdem die Datei editiert und gespeichert wurde, stellt sich die Frage, ob es sich noch um ein gültiges Format handelt.

Ein Editor für ein standardisiertes Binärformat macht die Daten ebenfalls lesbar und verhindert darüber hinaus Fehler bei der Bearbeitung. Ob ein Austauschformat in jedem beliebigen Texteditor zu öffnen ist, sollte nicht die Grundlage für eine Entscheidung gegen binäre Formate sein. Vielmehr sollten geeignete Werkzeuge die Verwendung von Binärformaten, beispielsweise als Konfigurationsdateien, ermöglichen.

Die Qual der Wahl

Binäre Formate unterscheiden sich stark voneinander und sind nur schwer vergleichbar. Sich für ein bestimmtes Format zu entscheiden, fällt daher nicht leicht. Die im Kasten „Binäre Austauschformate“ gezeigte Aufstellung und die in Tabelle 1 dargestellten Eigenschaften mögen als grobe Übersicht dienen. Die Liste der Formate ist auf typisierte Formate, die sich strukturell an JSON anlehnen, beschränkt. Ob ein Format für eine bestimmte Anwendung geeignet ist, hängt natürlich vom jeweiligen Einzelfall ab.

Vollständig ist die Liste sicher nicht. Eine eigene Recherche lohnt daher in jedem Fall. Sicher sind aber nützliche Anhaltspunkte dabei, wo mit der Suche zu beginnen ist und welche Eigenschaften eines Binärformats für die eigene Anwendung nötig sind.

Binäre Austauschformate
Binary JSON (BSON) wurde für die Speicherung JSON-ähnlicher Objekte (Maps) entwickelt. Inhalte einer Datei können nachträglich geändert werden, ohne sie komplett neu schreiben zu müssen. Diese Funktion unterscheidet BSON von anderen Formaten. BSON wird in der Datenbank MongoDB zur Datenspeicherung eingesetzt.
Concise Binary Object Representation (CBOR) ist definiert im 2013 veröffentlichten RFC 7049. Durch die extreme Kompaktheit der Daten eignet es sich gut für Anwendungen im Internet der Dinge. CBOR erlaubt Erweiterungen ohne eine Versionierung. Ziel dabei ist, in langlebigen Anwendungen auf veränderte Anforderungen reagieren zu können. Als Startpunkt diente das JSON-Datenmodell, das die Migration bestehender Systeme erleichtert. Darüber hinaus werden jedoch weitere Datentypen unterstützt.
MessagePack wurde 2011 das erste Mal veröffentlicht und ähnelt CBOR in vielen Eigenschaften. Seitdem wurde das Format kaum verändert. Lediglich durch den Wunsch der Benutzer getrieben, wurde kürzlich ein binärer Datentyp eingeführt. Diese Stabilität ist vermutlich der Grund für den Einsatz von MessagePack zur dauerhaften Speicherung von Daten. Implementierungen für eine Vielzahl von Programmiersprachen, die über die Jahre entstanden sind und von einer großen Community gepflegt werden, sind vorhanden. Viele RPC-Anwendungen setzen MessagePack für den Nachrichtentransport ein.
Universal Binary JSON (UBJSON) orientiert sich – mit dem Ziel, eine breite Akzeptanz zu erreichen – bewusst eng an JSON. Datentypen, die JSON nicht unterstützt, sind deshalb auch nicht enthalten. UBJSON ist optimiert für leichte Lesbarkeit und nicht für die kompakte Darstellung nativer Typen, wie zum Beispiel von half precision-Kommawerten.
UJO Binary Data Object Notation ist das jüngste der hier aufgeführten Austauschformate. Die Spezifikation der ersten Version ist noch in Arbeit und kann im Internet kommentiert werden. Der Name UJO ist Esperanto und bedeutet „Container“. Ziel ist die Verwendung von UJO als Alternative zu XML im TML/SIDEX SDK. Der Austausch von Daten zwischen existierenden Datenbanken und GUI-Anwendungen prägt die vorhandenen Datentypen. Es werden beispielsweise Datum und Zeit sowie typisierte NULL-Werte und Tabellen unterstützt.
Tabelle 1: Vergleich binärer Austauschformate

Tabelle 1: Vergleich binärer Austauschformate

wojcieszak_binaer1

Schlussbemerkung

Im Internet der Dinge stoßen textbasierte Austauschformate an ihre Grenzen. Speicher und Rechenleistung stehen nicht für Parser und Datenkonvertierungen oder aufwändige String-Operationen zur Verfügung. Die Vorteile binärer Formate liegen in ihrer Effizienz, weshalb sie sich für Anwendungen im Internet der Dinge besonders eignen.

Auch herkömmliche verteilte Anwendungen können von einer binären Darstellung der ausgetauschten Daten profitieren: Multimediadateien, Grafiken und Unicode-Strings können ohne Sonderbehandlung wie einfache Datenfelder in die Nachricht eingebettet werden. Freie Ressourcen stehen für zusätzliche Sicherheit zur Verfügung, und eine Infrastruktur für referenzierte Dateien ist überflüssig.

Bisher ist das Angebot an binären Formaten unübersichtlich und die Verfügbarkeit von Werkzeugen für deren Bearbeitung dürftig bis nicht vorhanden. Implementierungen und Bibliotheken existieren jedoch meist für viele Plattformen und Programmiersprachen. Dennoch ist die Unterstützung bei Weitem nicht mit der von JSON vergleichbar.

Neue Netzwerkprotokolle wie CoAP und HTTP/2 zeigen den Beginn einer Entwicklung weg von textbasierten Formaten, die für Maschinen nur mit hohem Aufwand lesbar sind, hin zu maschinenfreundlichen, binären Formaten. Nötig wird diese Entwicklung sowohl durch Anwendungen im Internet der Dinge als auch die Nutzung von Web-APIs für den Zugriff auf Daten und Datenbanken.

Aufmacherbild: Abstract binary code von Shutterstock / Urheberrecht: Kotkoa

Geschrieben von
Maik Wojcieszak
Maik Wojcieszak
Maik Wojcieszak ist Gründer, Geschäftsführer und Entwicklungsleiter der Kieler Firma wobe-systems GmbH. Er entwickelt seit mehr als fünfzehn Jahren zusammen mit seinem Team verteilte Systeme für höchste Anforderungen bezüglich Geschwindigkeit und Ausfallsicherheit in der grafischen Industrie. Neben effizienten Nachrichtenformaten beschäftigen ihn dabei Netzwerkprotokolle der nächsten Generation, Parallel Computing und verteilte Datenbanken.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: