1 Apache Zookeeper Ein Überblick Philipp Abraham Seminararbeit Software Systems Engineering - WS 2012 / 2013 Zusammenfassung—In dieser Ausarbeitung soll Apache ZooKeeper beschrieben werden. ZooKeeper ist ein Dienst, der es vereinfacht Prozesse in verteilten Systemen zu koordinieren. Dabei wird eine Dateisystem-ähnliche Schnittstelle geboten, die zentral und repliziert verfügbar ist. Mit den Garantien, dass Anfragen eines Clients in FIFO-Manier ausgeführt werden und dass Veränderungen am Zustand des ZooKeeper Dienstes linearisierbar sind, lassen sich Standard-Konstrukte – wie beispielsweise Locks, Barriers, Leader-Election – schnell und weniger fehleranfällig implementieren. Leseanfragen von Clients können dabei aus lokalen Servern gelesen werden und Clients können Daten cachen, da eine Invalidierung über Events vom Server möglich ist. Die getroffenen Design-Entscheidungen ermöglichen High-Performance Applikationen mit mehreren hunderttausend Anfragen pro Sekunde. I. E INF ÜHRUNG In Verteilten Systemen ist es oft nötig bestimmte Prozesse zu koordinieren. Beispielweise könnten feste oder dynamische Konfigurationsparameter unter verschiedenen Servern synchronisiert werden müssen. Gruppen von gleichartigen Prozessen müssen oft gebildet werden, um zum Beispiel festzustellen, welche Server noch verfügbar oder gerade mit einer bestimmten Aufgabe beschäftigt sind. Häufig ist es auch nötig einen “Master-Server” zu bestimmen unter allen verfügbaren. Sich dynamisch auf solch einen zu einigen wird als Leader-Election bezeichnet. Ein Leader kann dann auch verwendet werden um Locks zu realisieren. Also exklusive Zugriffsrechte auf eine bestimmte Ressource. Da die Programmierung solche Koordinierungsdienste nicht immer trivial ist und schnell RaceConditions und Deadlocks entstehen können, bietet es sich an ein Framework wie Apache ZooKeeper zu benutzen, dass diese Dienste anbietet. ZooKeeper entstand ursprünglich als Teil von Apache Hadoop [1], ist jetzt aber ein eigenes Projekt, dass auch von großen Firmen wie Yahoo und Rackspace und Projekten wie Eclipse und Solr genutzt wird [2]. Im Folgenden soll zunächst die Grundlegende Struktur des ZooKeeper Dienstes erläutert werden um dann mithilfe der durch ZooKeeper gegebenen Garantien und der Client-API beispielhafte Strukturen zur Prozesskoordinierung zu beschreiben. Diese Arbeit basiert zu größten Teilen auf Informationen aus der Apache ZooKeeper Dokumentation [3] und einem von Yahoo Mitarbeitern 2010 publiziertem Paper [4]. II. AUFBAU DES Z OOKEEPER D IENSTES ZooKeeper ist ein Dienst, der auf einem oder mehreren Servern läuft und eine Client API anbietet um Koordinierungsaufgaben zu realisieren. Mehrere Server werden unter dem Begriff “Ensemble” zusammengefasst und automatisch untereinander abgeglichen. Ein Server im Ensemble muss der so genannte “Leader” sein. Die anderen sind dann Follower und senden zur globalen Linearisierung jeden Schreibzugriff an den Leader (siehe Abbildung 1). Um alle Replikas synchron zu halten und auf Ausfall von Servern zu reagieren, wird der Ansatz der “State Machines” verwendet ähnlich wie er 1990 von Schneider [5] beschrieben wurde. Dieser besagt, dass ein Dienst einen Zustand hat, der bei allen Replikaten gleich zu halten ist, indem alle zustandsverändernden Operationen auf allen Replikaten gleich angewendet werden. Dazu wird hier eine abgewandelte Form des Paxos Algorithmus von Lamport [6] verwendet um einen Konsens zu erreichen. Will ein Client den Zustand des ZooKeeper Dienstes ändern, so ist, um Fehler zu vermeiden, ein Konsens der Mehrheit des Ensembles nötig (weshalb es sich auch anbietet eine ungerade Anzahl an Servern bereitzustellen). Um den Zustand des Systems auch bei totalem Ausfall wiederherstellen zu können wird ein “writeahead” Log benutzt. Es werden also alle Zustandsänderungen in dieses Log geschrieben, bevor sie im System angewendet und verteilt werden. Aus Performance-Gründen sollte dieses Log-File auf einem separaten Speichermedium liegen. Abbildung 1. Aufbau des ZooKeeper Dienstes ZooKeeper Ensemble Leader Server Client Client Server Client Server Client Server Client Client Datenstruktur Über die Client-API können Clients auf die abstrakte Datenstruktur des ZooKeeper Dienstes zugreifen. Diese ist als hierarchischer Namensraum in Baumstruktur realisiert ähnlich eines UNIX-Dateisystems. Knoten in diesem Baum (auch “data-tree” genannt) werden als zNodes bezeichnet. Der Pfad zu einem zNode wird dabei wie in UNIXSystemen angegeben, beginnend mit dem Wurzelelement /. Beispielsweise wird ein Pfad zu Knoten C über B und A notiert als /A/B/C (siehe auch Abbildung 2). ZooKeeper benötigt zudem immer absolute Pfadangaben. Im Unterschied zu UNIX kann hier jeder zNode auch Daten enthalten. Da ZooKeeper nur für die Koordinierung von Prozessen und nicht für die Verwaltung von Anwendungsdaten konzipiert wurde, ist die Menge an Daten für zNodes auf 2 jeweils 1 Megabyte begrenzt. Diese Grenze sollte in der Praxis jedoch nicht ausgereizt werden, da die Performance des ZooKeeper Dienstes maßgeblich von der Menge der Daten in den zNodes abhängt. zNodes Grundlegend gibt es zwei Arten von zNodes: Persistent zNodes können vom Client explizit erzeugt, verändert und gelöscht werden. Sie können Subknoten/-bäume haben und Daten beinhalten. Ephemeral zNodes unterscheiden sich durch die Tatsache, dass sie mit Beenden der Session des Clients, der sie erzeugt hat, automatisch gelöscht werden. Außerdem können ephemeral zNodes keine Kind-Elemente haben. Abbildung 2. Visualisierung eines ZooKeeper Namensraums Außerdem kann ein Client bei der Erzeugung eines Knotens ein sequential Flag setzen, welches automatisch eine Sequenznummer an den Namen des Knotens hängt. Es wird garantiert, dass alle Knoten auf der gleichen Ebene (also alle Knoten mit dem selben Eltern-Knoten) keine größere Sequenznummer im Namen haben können. Die Sequenznummern werden als 10 Stellige Zahl mit ZeroPadding dargestellt. Beispiel: /myApp/sequence/element-0000000001 Zusätzlich zu den optionalen Nutzdaten speichert ZooKeeper automatisch einige Meta-Daten (genannt Stat) zu jeder zNode; dazu gehören Zeitstempel (in Sekunden seit der letzten Epoche), ACLs (siehe nächster Absatz) und Versionsinformationen. Diese werden standardmäßig beispielsweise dazu genutzt, statusverändernde Operationen auf zNodes nur dann durchzuführen wenn sich zwischenzeitlich die Versionsnummer nicht geändert hat. Außerdem ermöglichen sie Lock-freies Lesen von Daten - selbst wenn andere Transaktionen auf diesem Datum gerade laufen - nach dem MVCC (Multiversion Concurrency Control) Prinzip welches erstmals von Reed 1978 beschrieben wurde [7]. Access Control Lists Um den Zugriff auf einzelne zNodes zu beschränken hat jeder Knoten eine so genannte Access Control List (ACL) ähnlich der in UNIX verwendeten Zugriffskontrolle für Dateien. Im unterschied zu Unix existieren aber keine festen Rollen wie Owner und Group. Stattdessen besteht ein ACL aus einer Menge IDs mit zugeordneten Rechten. Für die Authentifizierung von Benutzen steht ein modulares System zur Verfügung, dass es ermöglicht eigene Authentifizierungsmechanismen einzubinden. Folgende Rechte können dabei verändert werden: CREATE: Kindknoten dürfen erzeugt werden. READ: Daten des Knotens dürfen gelesen und die Kinder aufgelistet werden WRITE: Daten des Knoten dürfen geschrieben werden DELETE: Kindknoten dürfen gelöscht werden ADMIN: Rechte dürfen gesetzt werden Sobald sich ein Client mit ZooKeeper verbindet, authentifiziert er sich gegenüber dem Server und bekommt alle zugehörigen IDs zugeordnet. Will der Client nun auf einen zNode zugreifen werden dessen ACLs mit der ID des Clients überprüft. Eine ACL ist aufgebaut als Tupel (scheme:expression, perms). Das Format der expression ist dabei spezifisch zum gewählten Authentifizierungsschema scheme. Einige Mechanismen sind bereits eingebaut; beispielweise die Authentifizierung mittels IP, Hostname oder einer einfachen Benutzername:Passwort Kombination. Es existieren jedoch Projekte die sicherere Methoden nutzen; beispielsweise Anbindung an ein Kerberos [8] System mittels SASL [9]. Watches Damit Clients über Änderungen am Datenmodell informiert werden ist kein Polling nötig. Stattdessen bietet ZooKeeper mit dem Prinzip der “Watches” einen event-basierten PublishSubscribe Mechanismus um vom Server informiert zu werden. Wird ein Watch auf einen Knoten gesetzt, wird der Client einmalig informiert, wenn sich der Zustand eines Knotens geändert hat. Wie sich ein Knoten geändert hat wird jedoch nicht übergeben. Um fortlaufend bei Änderungen eines bestimmten zNodes informiert zu werden muss also bei der Verarbeitung eines Events ein neues Watch gesetzt werden. Dabei ist zu beachten, dass nicht garantiert werden kann, dass der Client über alle Änderungen zwischen dem Empfang eines Events und dem Neu-setzen einer Watch informiert wird. zNodes werden im Hauptspeicher des Servers gehalten, um Lesezugriffe zu beschleunigen. Trotzdem sollten Daten für eine Optimale Geschwindigkeit auf den Clients gecached werden. Beispielsweise könnte der aktuelle Leader lokal beim Client gespeichert sein. Wird im System der aktuelle Leader immer in einem bestimmten zNode notiert, können Clients ein Watch auf diesen setzen, um dann ihre zwischengespeicherte Version zu invalidieren sollte sich der Wert ändern. Sessions Baut ein Client eine Verbindung zu einem Server auf, wird eine Session erstellt. Sessions besitzen einen Timeout. Wird dieser überschritten gilt der Client als fehlerhaft. Dazu Innerhalb der Session kann ein Client mittels Watches und synchronen Operationen den Zustand des Systems beobachten und beeinflussen. Sessions sind persistent innerhalb des ZooKeeper Dienstes und ermöglichen somit die transparente 3 Weitergabe an andere Server sollte der aktuell zu einem Client zugeordnete ausfallen. Diese Übergabe an einen Server des Ensembles geschieht automatisch im Fehlerfall und benötigt in der Regel nur wenige Millisekunden und stört somit den operativen Betrieb im besten Fall nicht. III. G ARANTIEN Um mit ZooKeeper verteilte Anwendungen zu koordinieren, ist wichtig die Garantien innerhalb des ZooKeeper Protokolls zu kennen. Linearisierbare Schreibvorgänge: Alle Vorgänge die den Zustand des ZooKeeper Dienstes verändern werden unter Beachtung der Reihenfolge (am Leader) linearisiert. Realisiert wird dies durch ein Atomic “Broadcast Protocol” names Zab [10]. FIFO Client Abarbeitung: Alle Anfragen eines Clients werden in der Reihenfolge bearbeitet in der sie abgesandt wurden. Atomare Operationen Lese- und Schreiboperationen in ZooKeeper sind atomar. Das heißt, es wird immer der gesamt Inhalt gelesen bzw. verändert. Da nur Updates linearisiebar sind können Lesevorgänge aus dem lokalen Server geliefert werden. Damit skaliert ZooKeeper linear in Bezug auf die Anzahl der Server (Replikate). Watches • Watches sind geordnet bezüglich anderen Events, Watches und asynchronen Antworten. ZooKeeper sorgt für die Einhaltung der Reihenfolge. • Setzt ein Client ein Watch auf ein zNode, so bekommt dieser Client im Falle einer Datenänderung das Watch Event bevor er die neuen Daten sieht. • Die Reihenfolge der Watch-Events korrespondiert zu der Reihenfolge der Updates auf dem ZooKeeper Server. Um die Bedeutung dieser Garantien zu verdeutlichen soll folgendes Beispiel betrachtet werden: Ein verteiltes System, bestehend aus vielen Prozessen, soll einen Leader wählen. Dieser muss dann einige Konfigurationen anpassen und danach alle anderen Prozesse informieren, damit diese die neuen Parameter nutzen können. Wichtig sind für diesen Vorgang zwei Anforderungen: • Andere Prozesse sollen die neuen Parameter erst nutzen sobald der Leader vollständig mit seinen Änderungen fertig ist. • Falls der neue Leader aufgrund eines Fehlers vor Beendigung der Parameteranpassungen stirbt, sollen andere Prozesse die unvollständigen Änderungen nicht nutzen. Mit ZooKeeper könnte ein ready zNode eingeführt werden, welcher anzeigt, dass die Konfigurationsparameter von allen Prozessen genutzt werden können. Wird ein neuer Leader bestimmt löscht er diesen Knoten, sendet asynchron alle Änderungswünsche ab und erzeugt wieder einen ready Knoten. Angenommen jede Anfrage würde 5ms dauern und es müssten 4000 Knoten geändert werden, dann würde dieser Vorgang bei synchroner Abarbeitung 20 Sekunden dauern. Durch die von ZooKeeper geleisteten Garantien kann das absetzen der Änderungen asynchron erfolgen und Clients können alle Änderungen sehen sobald der ready Knoten verfügbar ist. Was jedoch wenn ein Client einen alten ready Knoten sieht und anfängt die Konfigurationsparameter zu lesen während der neue Leader den ready zNode entfernt und die Konfiguration ändert? Da jedoch garantiert ist, dass Clients in der Reihenfolge der Updates Benachrichtigungen erhalten, sieht auch ein Client der ein Watch auf ready hat, die Änderung dieses Knotens bevor er geänderte Konfigurationsparameter einlesen würde. Abbildung 3. Schreibzugriffe werden an einen lokalen Server gesendet. Von dort zum Leader, in das Transaktionslog und über einen atomaren Broadcast zur Mehrheit des Ensembles. Erst dann kann eine Antwort herausgegeben werden. Weitere anfragen können dann wieder aus der im Speicher liegenden lokalen Datenbank der Server beantwortet werden. IV. C LIENT API Die wichtigsten Methoden der Client API [11] sollen hier kurz vorgestellt werden um spätere Beispiele nachvollziehen zu können. Die Client APIs sind in den von Apache ZooKeeper angebotenen Bindings als C oder Java Variante verfügbar. Es werden jeweils blockierende oder asynchrone Varianten von allen Operationen angeboten. Außerdem existieren weitere inoffizielle Bindings beispielsweise für Ruby [12], Node.js [13], PHP [14], Scala [15] und Weitere. create(path, data, acl, flags): Erzeugt einen neuen zNode mit Namen path und Inhalt data. Der Parameter flags bestimmt den Knoten-Typ (ephemeral oder persistent) und ermöglicht setzen des sequence Flags. acl ist die “Access Control List” für den neuen Knoten. delete(path, version): Löscht den Knoten path insofern die Version übereinstimmt und keine Kind-Knoten vorhanden sind. exists(path, watch): Gibt ein Meta-Daten Objekt (Stat) zurück falls ein Knoten mit angegebenem Pfad existiert und null sonst. Wird watch auf true gesetzt wird der Client über eine Änderung an diesem Knoten informiert. getData(path, watch): Liefert ein Byte-Array der Daten im angegebenen Knoten. setData(path, data, version): Setzt den Inhalt des angegebenen Knotens auf data falls die Version übereinstimmt. getChildren(path, watch): Liefert eine Liste der Pfade aller Kind-Knoten des angegebenen Knotens. sync(path, callback): Wartet auf eine Synchronisierung und benachrichtigt dann über den callback . 4 Jede dieser Operationen ist noch in einer asynchronen Variante verfügbar, welcher dann zusätzlich ein Callback-Objekt übergeben werden muss. Operationen die nur bei übereinstimmender Versionsnummer ausgeführt werden, können durch Übergabe der Versionsnummer -1 dazu gezwungen werden immer ausgeführt zu werden. Falls ein Watch gesetzt werden soll kann meist entweder einfach true übergeben werden und der bei Initiierung der Session angegebene default Watcher wird benutzt. Alternativ lässt sich auch ein Objekt vom Typ Watcher angeben, welches lediglich die Methode process(WatchedEvent event) implementieren muss. Ein WatchedEvent kann dabei vom Typ NodeChildrenChanged, NodeCreated, NodeDataChanged, NodeDeleted oder None sein. V. P RIMITIVES In diesem Abschnitt sollen exemplarisch Ansätze gezeigt werden, wie in ZooKeeper komplexere Primitive für die Koordination von Prozessen implementiert werden können. Der ZooKeeper Dienst selbst weiß nichts von der Existenz dieser Konstrukte. Eine Realisierung erfolgt in den Clients mithilfe der API. A. Group Membership Für die Bildung von Gruppen können ephemeral zNodes ausgenutzt werden. Zunächst muss ein persistenter zNode mit dem Namen der Gruppe erstellt werden. Jedes Mitglied erstellt nun ein ephemeral zNode unterhalb dieses GruppenKnotens und vergibt als Namen seine ID (falls keine eindeutigen Namen garantiert sind kann auch das sequence Flag genutzt werden). Verlässt ein Mitglied die Gruppe (sei es durch Verbindungsabbruch oder freiwillig) so existiert auch kein Knoten mehr für public void join(String groupName, String memberName) throws KeeperException, InterruptedException { String path = "/" + groupName + "/" + memberName; String createdPath = zk.create(path, null/*data*/, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); System.out.println("Created " + createdPath); } Um alle Mitglieder einer Gruppe aufzulisten muss dann lediglich getChildren() aufgerufen werden: public void list(String groupName) throws KeeperException, InterruptedException { String path = "/" + groupName; try { List<String> children = zk.getChildren(path, false); if (children.isEmpty()) { System.out.printf("No members in group %s\n", groupName); return; } for (String child : children) { System.out.println(child); } } catch (KeeperException.NoNodeException e) { System.out.printf("Group %s does not exist\n", groupName); } } B. Service Directory Service Directories könnten mit ZooKeeper wie folgt realisiert werden: Ein Dienst registriert sich beim Server, indem er einen ephemeral zNode mit seinem Namen erstellt und eventuell Konfigurationsdaten in diesen Knoten einträgt. Über den gleichen Ansatz wie beim Group Membership könnten auch Kategorisierungen vorgenommen werden. Ein Client kann nun mit getChildren(’/category’,true) die angebotenen Dienste abrufen und wird automatisch informiert wenn neue Dienste hinzukommen. Durch die gewählte Repräsentation werden Dienste im data-tree gelöscht, sobald sie nicht mehr erreichbar sind und Clients werden umgehend informiert falls sie ein entsprechendes Watch gesetzt hatten. C. Barriers Barrieren werden beispielsweise genutzt, um die Verarbeitung von mehreren Prozessen zu blockieren bis eine bestimmte Bedingung erfüllt ist. Dieses Prinzip wird beispielsweise verwendet um Schleifen in parallelen Sprachen zu realisieren. Der Code nach der Schleife darf erst ausgeführt werden, wenn alle beteiligten Prozesse die Schleifenabbruchbedingung erfüllt haben. Analog dazu werden Doppel-Barrieren genutzt um Prozesse zu starten wenn eine gewisse Anzahl an Knoten die Barriere betritt und folgende Operationen erst erlaubt wenn alle Prozesse die Barriere verlassen haben. In ZooKeeper könnte ein zNode b eine Barriere repräsentieren und Prozesse darunter jeweils Knoten pi erzeugen wenn sie die Barriere betreten möchten. Bei Betreten setzt jeder Prozess ein Watch auf b. Ist die gewünschte Anzahl an Prozessen bereit (hat also Subknoten erstellt), beginnt die Operation. Ist ein Prozess mit der Verarbeitung fertig, löscht er seinen Knoten. Sind alle Knoten gelöscht, können alle Prozesse die Barriere verlassen. D. Locks Mit Locks können exklusive Zugriffe auf Ressourcen realisiert werden. Lediglich ein Prozess darf zeitgleich Zugriff auf den kritischen Bereich haben. Eine einfache Realisierung wäre, ein ephemeral zNode zu erstellen wenn man einen exklusiven Bereich betritt. Vorher wird geschaut, ob solch ein zNode bereits existiert. Wollen nun Zeitgleich mehrere Prozesse das Lock, setzen sie ein Watch und werden benachrichtigt wenn dies frei wird. Problematisch bei dieser Implementierung ist das Auftreten des so genannten “Herd Effects”. Es werden nämlich alle Prozesse, welche auf das Lock warten zeitgleich informiert und der Kommunikationskanal geflutet mit Benachrichtigungen. Um diesen Effekt zu vermeiden könnten sich wartende Prozesse mit ephemeral sequence zNodes registrieren. Statt ein Watch auf den Besitzer des Locks zu setzen wird ein Watch auf 5 den wartenden Knoten gesetzt, der sich zuvor eingereiht hat. Damit wird bei Übergabe des Locks nur jeweils ein Prozess benachrichtigt. Stirbt ein Prozess in der Warteschlange so bekommt der Nachfolgende dies mit und kann ein Watch auf den Vorgänger des fehlerhaften Prozesses setzen. VI. E VALUATION Das Yahoo Research Center hat Benchmarks durchgeführt um die Performance des ZooKeeper Dienstes unter möglichst realen Bedingungen zu erproben [4]. Dabei wurde die Anzahl der Server des Ensembles variiert, die Anzahl der Clients jedoch konstant bei 250 gehalten. Das ZooKeeper System wird unter Sättigung analysiert, wobei verschiedene Verhältnisse von Schreiben zu Lesen betrachtet werden. Jeder Client hat mindestens 100 ausstehende Anfragen. Eine Anfrage ist dabei eine Leseoperation oder eine Schreiboperation mit jeweils 1K an Daten. Abbildung 4. müssen, wurden Abstraktionsebenen entwickeln, die auf die ZooKeeper API aufsetzen. Hauptsächlich vereinfachen diese das Error-Handling. Beispielsweise verbindet sich ein Client mit dem ZooKeeper Server durch einen Handshake. Dies geschieht asynchron. Werden nun synchrone Befehle an den Server gesendet bevor der Handshake abgeschlossen ist, liefern diese Operationen eine Fehlermeldung. Es muss also immer sichergestellt werden, dass synchrone Operationen erst abgesetzt werden, wenn dieser Handshake abgeschlossen ist. Auch muss oft die Funktionalität implementiert werden, nach einem Timeout die aktuelle Operation nochmals zu Wiederholen. Dabei ist es unter Umständen auch wichtig, nicht permanent erneute Versuche zu starten, da dies die anderen Clients potenziell auch tun und so das Netz möglicherweise zu stark belasten. Verschiedene Strategien wie eine Obergrenze an Neuversuchen, ein Zeitlimit oder auch Neuversuche mit zufälligen Zeitabständen könnten implementiert werden. Die Java Bibliothek Curator von Netflix [16] ist eine Möglichkeit, solche Fehlerfälle leichter zu behandeln. Curator ist ein Framework, dass auf die auf die ZooKeeper API aufsetzt und sie mit häufig verwendeten Helfer-Methoden und vielen bereits implementieren Rezepten für Primitive komplettiert. Die im vorigen Absatz genannten Beispiele für wiederkehrende Implementierungen zur Fehlerbehandlung werden durch die Curator API stark vereinfacht. VIII. Der Durchsatz steigt dabei mit dem Prozentsatz an Leseoperationen, da jede schreibende Operation durch den Leader gesendet wird und ein Konsens über das Atomic Broadcast Protocol erreicht werden muss. Es ist auch erkannbar, dass mehr Server im Ensemble den Durchsatz negativ beeinflussen bei schreibenden Vorgängen. Ursächlich dafür ist, dass jeder Server einen Abstimmenden Kandidaten für das Konsensprotokoll darstellt und somit mehr Stimmen eingeholt werden müssen bei Schreiboperationen. Des Weiteren konnte ermittelt werden, dass falls der aktuelle Leader ausfällt, ein neuer Leader binnen 200ms gewählt ist. Typische Koordinierungsaufgaben in Verteilten Systemen erfordern jedoch meist deutlich mehr Lese- als Schreibvorgänge und können somit von mehreren hunderttausend Operationen pro Sekunde profitieren. VII. Apache ZooKeeper ermöglicht die Koordination verteilter Prozesse. Bei Anwendungen die durch Leseoperationen dominiert werden, sind Durchsätze mit hunderttausenden von Operationen pro Sekunde durch die Nutzung von lokalen Replikas mit im Hauptspeicher gehaltenen Datenbanken möglich. Eine Dateisystem-ähnliche Schnittstelle ermöglicht schnelle Implementierungen verschiedenster Koordinierungskonstrukte. ZooKeeper bietet transparente Synchronisierung eines ServersClusters und ermöglicht fehlertolerante verteilte Applikationen mit wenig Programmieraufwand. L ITERATUR [1] [2] [3] [4] [5] Z US ÄTZLICHE A BSTRAKTION Um ZooKeeper noch leichter benutzbar zu machen und immer wiederkehrende Konzepte nicht neu implementieren zu Z USAMMENFASSUNG [6] “Apache hadoop (abgerufen am 16. jan ’13),” http://hadoop.apache.org/. “Applications and organizations using zookeeper (abgerufen am 16. jan ’13),” http://wiki.apache.org/hadoop/ZooKeeper/PoweredBy. “Zookeeper: Because coordinating distributed systems is a zoo (abgerufen am 16. jan ’13),” http://zookeeper.apache.org/doc/trunk/. P. Hunt, M. Konar, F. P. Junqueira, and B. Reed, “Zookeeper: wait-free coordination for internet-scale systems,” in Proceedings of the 2010 USENIX conference on USENIX annual technical conference, ser. USENIXATC’10. Berkeley, CA, USA: USENIX Association, 2010, pp. 11–11. [Online]. Available: http://dl.acm.org/citation.cfm? id=1855840.1855851 F. B. Schneider, “Implementing fault-tolerant services using the state machine approach: a tutorial,” ACM Comput. Surv., vol. 22, no. 4, pp. 299–319, Dec. 1990. [Online]. Available: http://doi.acm.org/10.1145/ 98163.98167 L. Lamport, “The part-time parliament,” ACM Trans. Comput. Syst., vol. 16, no. 2, pp. 133–169, May 1998. [Online]. Available: http://doi.acm.org/10.1145/279227.279229 6 [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] D. P. Reed, “Naming and synchronization in a decentralized computer system,” Cambridge, MA, USA, Tech. Rep., 1978. “The mit kerberos consortium (abgerufen am 19. jan ’13),” http://www. kerberos.org/. “Zookeeper and sasl (abgerufen am 19. jan ’13),” https://cwiki.apache. org/ZOOKEEPER/zookeeper-and-sasl.html. B. Reed and F. P. Junqueira, “A simple totally ordered broadcast protocol,” in Proceedings of the 2nd Workshop on Large-Scale Distributed Systems and Middleware, ser. LADIS ’08. New York, NY, USA: ACM, 2008, pp. 2:1–2:6. [Online]. Available: http://doi.acm.org/10.1145/1529974.1529978 “Apache zookeeper 3.4.5 api (abgerufen am 16. jan ’13),” http:// zookeeper.apache.org/doc/r3.4.5/api/index.html. “Zk ruby interface (abgerufen am 16. jan ’13),” https://github.com/ slyphon/zk. “Node-zookeeper (abgerufen am 16. jan ’13),” https://github.com/ yfinkelstein/node-zookeeper. “Php-zookeeper (abgerufen am 16. jan ’13),” http://pecl.php.net/ package/zookeeper. “Scala-zookeeper (abgerufen am 16. jan ’13),” https://github.com/ twitter/scala-zookeeper-client. “Netfilx curator: Zookeeper client wrapper and rich zookeeper framework (abgerufen am 18. jan ’13),” https://github.com/Netflix/curator.