Protocol Buffers, Etch, Avro und Thrift im Vergleich

Thomas Bayer

Von: Thomas Bayer
Datum: 15.03.2010

Die Unzufriedenheit mit SOAP basierten Web Services, REST, CORBA und anderen Technologien hat dazu geführt, dass eine ganze Reihe von neuen Projekten entstanden ist. Diese Technologien werden von großen Web 2.0 Konzernen wie Facebook und Google für die Verteilung von gigantischen Datenmengen in Echtzeit eingesetzt. Dieser Artikel beschreibt diese Entwicklung und vergleicht die einzelnen Frameworks.

1. Weshalb keine Web Services?

Mit SOAP und der Familie der WS-Standards können Anwendungen unterschiedlichster Technologie miteinander verbunden werden. Die Komplexität des Web Services Stacks hat es allerdings in sich. Für viele sind daher Web Services zu aufgebläht und der Lernaufwand ist zu groß. Ein weiterer Kritikpunkt ist die Verwendung von XML und der damit verbundene Overhead.
Heutige Web Services Stacks, die moderne STAX Parser verwenden erreichen eine beachtliche Performance. Beispielsweise ist die Roundtripzeit für einfache Aufrufe auf unter 1 ms gefallen. Diese Geschwindigkeit reicht für Geschäftsanwendungen in der Regel vollkommen aus. Große Web 2.0 Anbieter oder Betreiber von Clustern für verteiltes Rechnen haben jedoch andere Anforderungen. Transaktionssicherheit, die bei Bestellungen und Überweisungen entscheidend ist, ist für eine Internet Suche oder ein soziales Netzwerk vollkommen irrelevant. Dafür müssen aber gigantische Datenmengen in kurzer Zeit, möglichst in Echtzeit ausgetauscht werden. Daher verwundert der Wunsch nach einem einfachen und schnellen Kommunikationsframework, das einfach einzusetzen ist, nicht.

2. Eigenschaften der Serialisation Frameworks

Die Frameworks zur Serialisierung besitzen gemeinsame Eigenschaften, wie z.B. die Verwendung eines binären Formats für die Codierung von Nachrichten. Diese Eigenschaften werden in den nächsten Abschnitten beschrieben, bevor die einzelnen Frameworks vorgestellt werden.

2.1 Beschreibung von Schnittstellen

Web Services Schnittstellen werden mit der Web Service Definition Language beschrieben. WSDL ist wie auch SOAP eine Sprache, die auf XML basiert. Die neuen Frameworks verwenden eigene Sprachen, die nicht auf XML basieren. Die neuen Sprachen zur Schnittstellen und Typbeschreibung ähneln der von CORBA bekannten Interface Definition Language.

message Book {
 required int32 id = 1;
 required string title = 2;
 repeated string author = 3;

 message Author {
   required string name = 1;
 }
}
Listing 1: Beschreibung einer Schnittstelle mit Protocol Buffers

Mit Codegeneratoren können aus den Beschreibungen Code für die unterschiedlichsten Programmiersprachen erzeugt werden. Neben den Enterprise Sprachen C# und Java werden oft auch die bei den Web Entwicklern beliebten Skiptsprachen Perl, PHP, Python oder Ruby unterstützt.

Library.Book book =
           Library.Book.newBuilder()
           .setId(1234)
           .setTitle("Meine Geschichten")
           .addAuthor("Ich")
           .build();
   FileOutputStream fos = new FileOutputStream(new File("book.ser"));
   book.writeTo(fos);
 }
Listing 2: Objekt Erzeugung und Serialisation mit Java und Protocol Buffers

Gerade diese Sprachen hat die Web Services Community sträflich vernachlässigt. Für fast jede Programmiersprache gibt es SOAP Bibliotheken. WSDL Unterstützung dagegen ist in vielen Skiptsprachen nicht vorhanden oder nur unvollständig implementiert. Mit nur wenigen Zeilen kann mit Hilfe des generierten Codes ein Objekt serialisiert oder ein Service aufgerufen werden.

2.2 Versionierung

Werden Datentypen, die in einer remote Schnittstelle verwendet werden, um zusätzliche Felder erweitert, so führt dies bei vielen Middleware Technologien zu einer Inkompatibilität. Selbst bei XML basierten Web Services ist dies häufig der Fall, falls nicht der Service Designer dafür Vorsorge getroffen hat. Beispielsweise durch optionale Elemente mittels minoccurs=0 oder anyType. Die neuen Bibliotheken und Frameworks für die Serialisierung wurden bereits mit dem Ziel der evolutionären Erweiterung entwickelt. Bei den meisten Tools können einer Datenstruktur zusätzliche Felder hinzugefügt werden, ohne dass bestehende Clients Fehler verursachen.
Protocol Buflers, Thrift und die meisten der hier beschriebenen Technologien verwenden dynamisch typisierte Metaprotokolle, die mit den Daten Metainformationen versenden. Mit diesen Metainformationen kann der Empfänger eine Zuordnung der Felder durchführen, selbst wenn Felder hinzugefügt oder gelöscht werden. Ein erneutes Kompilieren ist dafür nicht notwendig. Diese Art der Versionierung hat natürlich ihre Grenzen, erspart aber beispielsweise das Ausrollen neuer Clients, nachdem der Server ein zusätzliches Feld akzeptiert. Statistisch typisierte Systeme wie z. B. CORBA oder RMI erfordern bei solchen Änderungen auch ein Update aller Clients.

2.3 Binär Format

Um einen möglichst großem Datendurchsatz zu erzielen wird auf Binärformate zurückgegriffen. Beim Übertragen von Strukturen fehlt im Binärformat die Information über den Datentyp und den Feldnamen. Damit die Felder trotzdem zugeordnet werden können wird von einigen Tools eine Parameternummer verwendet. Um auch das letzte Byte zu sparen verwendet Googles Protocol Buffers für ganzzählige Werte einen variablen Integer Typ, der für kleine Zahlen nur so viel Platz wie nötig beansprucht.

2.4 Footprint

Die Größe der zur Laufzeit benötigten Bibliotheken ist recht klein und liegt meist unter 1 Megabyte. Apache CXF hat zum Vergleich eine Größe von ungefähr X Megabyte.

2.5 Performance

Bei den neuen Frameworks wird auf vieles verzichtet. Die geniale Erweiterbarkeit von XML mittels Namespaces fehlt ebenso wie die Aufsplittung in Metadaten (Header) und Nutzlast (Body). Auch auf HTTP wird meist verzichtet. Dafür verbessert sich die Performance ungefähr um den Faktor 10 verglichen mit Axis2, .NET oder der JAX-WS Referenzimplementierung. Die Performance hängt natürlich von den verwendeten Betriebssystemen, Sprachen und vom Netzwerk ab und soll nur eine ungefähre Größenordnung angeben.

3. Die Frameworks

Im Folgenden werden die einzelnen Frameworks mit ihren Besonderheiten kurz vorgestellt.

3.1 BSON

Ausgesprochen wird BSON wie der GNU Parser Gengerator Bison und bedeutet so viel wie „Binary JSON“. Bei BSON handelt es sich auch um ein Binärformat für Daten, die in JavaScript Object Notation vorliegen oder ähnlich strukturiert sind.
Die Dokument-orientierte Datenbank MongoDB verwendet BSON als Speicherformat für Dokumente und Objekte. BSON kann aber auch losgelöst von MongoDB für die Serialisation verwendet werden.

3.2 Etch

Etch ist ein Framework für das Erstellen und konsumieren von Diensten im Netzwerk. Die Firma Cisco, die Etch entwickelt hat, hat das Project an die Apache Software Foundation übergeben. Etch verwendet zur Beschreibung von Schnittstellen die Network Service Describtion Language, kurz NSDL. Mit NSDL können außer Datentypen auch Dienste, Timeouts und Authentifizierung beschrieben werden. Entfernte Funktionen können über TCP, UDP oder SOAP aufgerufen werden.

3.3 Hadoop Avro

Das Apache Hadoop Projekt unterscheidet sich von den anderen dadurch, dass es viele Funktionen für verteiltes Rechnen bietet. Hadoop beschränkt sich daher nicht auf die Serialisierung von Objekten und auf RPC Funktionalität. Das Projekt beinhaltet u. a. folgende Bausteine:

Baustein Beschreibung
Avro Serialisierung von Daten
Chukwa Data Collection System
HBase Verteilte Datenbank für große Tabellen
HDFS Verteiltes Dateisystem
Hive Infrastruktur für Data Warehousing
MapReduce Framework für die Verarbeitung von großen Data Sets
Pig Sprache für die Datenfluss Modellierung und Framework für paralleles Rechnen
ZooKeeper Koordinator für verteilte Anwendungen

Vergleichbar mit den anderen Frameworks ist die Avro Komponente, welche von Hadoop für das Serialisieren verwendet wird. Wie leistungsfähig das in Java realisierte Framework für verteiltes Rechnen ist zeigt der Sieg von Hadoop beim Terabyte Sort Benchmark 2008. Ein Hadoop Cluster bei Yahoo benötigte für die Sortierung nur 209 Sekunden.

3.4 Hessian

Hessian ist ein binäres Protokoll für Web Services. Entwickelt wurde es von Caucho Technology, die bekannt sind für Ihren Resin Application Server. Hessian ist dynamisch typisiert und unterstützt daher dynamisch typisierte Programmiersprachen ohne dass dafür eine Schnittstellenbeschreibung nötig wäre. Für das Hessian Protokoll gibt es Implementierungen für viele Programmiersprachen und Plattformen. Mit hessdroid steht auch ein Port für Googles Android zur Verfügung.

3.5 Protocol Buffers

Protocol Buffers ist ein Format für die Serialisierung von Daten. Google hat Protocol Buffers entwickelt, um Probleme mit der Versionierung von Schnittstellen zu lösen. Google verwendet heute Protocol Buffers für das Speichern und den Austausch von Daten in vielen Google-internen Anwendungen. Implementierungen des Protocol Buffers Format für C++, Java und Python hat Google unter einer BSD Lizenz als open source Software veröffentlicht.

3.6 Thrift

Thrift stammt ursprünglich von Facebook und ist mittlerweile bei Apache im Inkubator. Neben einer sprachenunabhängigen Serialisierung von Objekten bietet Thrift einen Stack für RPC Aufrufe. Wie beispielsweise Googles Protocol Buffer erlaubt Thrift das evolutionäre Verändern von Datentypen.

4. Vergleich

In Tabelle 2 finden Sie Features und Eigenschaften der Frameworks.

BSON Etch Hadoop Avro Hessian ICE Protocol
Buffers
Thrift
Initiator MongoDB Cisco Apache ZeroC Google Facebook
License ASF 2.02 ASF 2.0 ASF ASF BSD ASF
Versionierung soft6 soft3 soft3
Interface
Description
Yes
NSDL
Annotations
Language Code
Generator
optional5 ✔︎
Output Format Binary4 Binary Binary Binary,
JSON
RPC
Functionality
Only
Interfaces
Exceptions No
Cyclic Structs No
Type Inheritance No
Authentification No
Security Yes
SSL/TLS
Transport TCP, UDP,
SOAP
No
Asynchronous
Messaging
Yes,
Oneway
Callbacks
No
Impementation Language Java
Minimal Footprint1 288 k <400k

Tabelle 2: Vergleich der Frameworks

Fußnoten

1 Für den Vergleich dienten die Java Versionen
2 Die BSON Bibliotheken sind in den MongoDB Client Treibern enthalten.Fürdie Treiber gilt die ASF 2.0
3 Erlaubt die Evolution der Schnittstelle
4 Über Extensions sind weitere Ausgabeformate möglich
5 Generierung von Code ist nicht notwendig, auch nicht für RPC. Code Generierung kann für die Optimierung bei statisch typisierten Sprachen verwandt werden.
6 Avoro verwendet ein Schema, das die Struktur der Daten beschreibt. In Schema sind Feldnamen spezifiziert über die Unterschiede ermittelt werden können.

Unterstützte Programmiersprachen

Tabelle 3 gibts Aufschluss über die unterstützten Programmiersprachen.

Framework/
Sprache
BSON Etch Hessian Avro ICE Protocol
Buffers
Thrift
C
C++
C#
Cocoa
D
Erlang
Flash/Flex
Haskell
Java
OCAML
Perl
PHP
Python
Ruby
Smalltalk

Tabelle 3: Unterstützte Sprachen

5. Quellen

Protocol Buffers - Developer Guide - code.google.com
Metaprotocol Taxonomy - Caucho Technology
Thrift Protobuf Compare - Benchmarking - code.google.com
Hessian Binary Web Service Protocol - Caucho Technology
BSON - mongoDB
Apache Hadoop - The Apache Software Foundation
hessdroid - android hessian library - code.google.com
Etch Project Incubation Status - The Apache Software Foundation
Etch - Overview - The Apache Software Foundation
Thrift: Scalable Cross-Language Services Implementation - Mark Slee, Aditya Agarwal and Marc Kwiatkowski, Facebook
Welcome to Avro - The Apache Software Foundation