Verteilte Dateisysteme wie das Google-FS jonglieren mühelos mit riesigen Dateien im Giga- und Terabyte-Bereich. Mit dem Kosmos-Filesystem schickt sich ein neuer und freier Vertreter dieser Gattung an, die Konkurrenz das Fürchten zu lehren.
Moderne Computerprogramme gebären und verdauen immer größere Datenmengen. Während sich Datamining-Anwendungen noch mit bestehenden Informationsbergen begnügen, horten Internet-Suchmaschinen alles, was ihnen zwischen die Finger gerät, bekanntestes Beispiel ist Google. Auch Forschung oder Grid-Computing sehen sich regelmäßig mit Dateien konfrontiert, die mehrere GByte auf die Waage bringen.
Die herkömmlichen Dateisysteme stoßen bei diesen Größenordnungen schnell an ihre Grenzen. Folglich muss ein passendes Rückgrat her, das solche großen Datenmengen sicher speichert und einen möglichst schnellen Zugriff gestattet. Die Einlagerung der Dateien sollte dabei möglichst redundant erfolgen – schließlich möchte niemand die womöglich in mehreren Nachtschichten mühsam errechneten Resultate durch einen blöden Plattenfehler verlieren.
Verteilte Dateisysteme erfüllen alle diese Anforderungen. Sie zerlegen die ihnen übergebenen Daten in verdauliche Häppchen und speichern sie in einem beliebig großen Rechnerverbund. Nach außen hin geschieht dies vollkommen transparent. Den Anwendungen gaukelt das verteilte Dateisystem eine riesige Festplatte vor, es virtualisiert den Speicher auf einem Cluster von Computern.
Ab ins All
Ein noch recht junger, aber aufstrebender Vertreter dieser Gattung ist das Kosmos File System, kurz KFS. Entwickelt hat es die namengebende Kosmix Corporation [1], die den gesamten Quellcode unter der Apache-Lizenz freigab. Die erste Alphaversion 0.1 erschien im September 2007. Das jugendliche Alter macht sich am deutlichsten während der Inbetriebnahme bemerkbar: So verlangt KFS nach einem 64-Bit-Linux, das zudem auf allen an der Datenspeicherung beteiligten Computern möglichst identisch sein sollte.
KFS tritt gleich gegen mehrere namhafte Konkurrenten an: Auf der einen Seite steht das Google File System (GFS), das Google als Unterbau für seine Suchmaschine verwendet, während am anderen Ufer HDFS aus dem Hadoop-Projekt wartet [2]. Den grundlegenden Aufbau und die Funktionsweise haben sich die KFS-Entwickler dreist bei Google abgeschaut, das Konzept aber von einigen lästigen Fesseln befreit. Wie sein Vorbild ist KFS auf Szenarien optimiert, in denen immer wieder extrem viele und äußerst große Dateien nur einmal entstehen, dann aber häufig ausgelesen werden.
Arbeitsteilung
Das Kosmos-Dateisystem besteht aus drei Komponenten:
- Einem oder mehreren Chunkservern, die die eigentlichen Daten
auf ihren Festplatten speichern - Einem Metaserver, der den Chunkservern auf die Finger
schaut - Einer Anwendung, die schnell eine große Datei loswerden
möchte
KFS funktioniert damit ähnlich wie eine Datenbank, die sich zwischen ein Computerprogramm und das herkömmliche Dateisystem setzt (Abbildung 1).

Abbildung 1: Das Kosmos File System setzt sich, ähnlich wie eine Datenbank, zwischen die vorhandene Hardware und die Anwendung. Der Zugriff auf das virtuelle Dateisystem erfolgt über eine Client-Bibliothek.
Im ganzen Batzen
KFS zerteilt jede zu speichernde Datei zunächst in handliche, exakt 64 MByte große Blöcke. Diese so genannten Chunks verteilt das Dateisystem gleichmäßig auf alle angeschlossenen Server. Die Endlagerstätten heißen folgerichtig Block- oder Chunkserver. Sie speichern die Blöcke im normalen Dateisystem des jeweils installierten Betriebssystems.
Wenn der Plattenplatz der Chunkserver zur Neige geht, bindet der Administrator einfach einen neuen Computer in den Cluster ein. KFS adaptiert den neuen Speicherknoten automatisch. Das ganze System lässt sich somit mühelos skalieren und wächst bequem mit den jeweils vorliegenden Anforderungen.
Ausfällen beugt KFS vor, indem es die Blöcke jeder Datei redundant auf mehreren Chunkservern parkt. In der Regel existiert damit jede eingelagerte Datei im Verbund mindestens dreimal. Dieses Sicherheitsnetz erlaubt es zudem, günstige handelsübliche PCs als billigen, aber vertrauenswürdigen Datenspeicher zu einzusetzen. Dass dies in der Praxis funktioniert, beweist das Google-FS jeden Tag. Sollte mal eine Platte oder ein Server ausfallen, ist ein neues Modell als Ersatz schnell eingebaut. KFS erkennt den Tausch und bindet den Neuling selbstständig in den Verbund ein.
Als weitere vorbeugende Maßnahme gegen Datenverluste erhält jeder Block sowohl eine Versionsnummer als auch eine Prüfsumme. Letztere wertet KFS bei jedem Lesevorgang aus. Sollten dabei einmal Ungereimtheiten auftauchen, löscht das verteilte Dateisystem den fehlerhaften Chunk und ersetzt ihn unverzüglich durch eine korrekte Kopie (Re-Replication).
Die Versionsnummern helfen schließlich beim Aufspüren von veralteten Chunks: Sollte eine schlechte Internetverbindung einen Server vorübergehend vom übrigen Geschehen abkoppeln, kann er anschließend mit einem Blick feststellen, welche Chunks hoffnungslos veraltet sind, und sich von einem Kollegen automatisch die aktuelle Variante besorgen.
Metastasen
Unglücklicherweise sind die Chunkserver recht egoistisch und merken sich nicht, welche Teile welcher Datei bei welchen Kollegen lagern. Daher erhalten mehrere Chunkserver einen so genannten Metadata-Server, kurz Metaserver, als Partner (das Google File System nennt diese Server Master). Wie ihr Name schon andeutet, notieren solche Aufpasser alle anfallenden Metadaten, darunter beispielsweise welcher Chunkserver welchen Teil einer Datei speichert, die zugehörigen Dateigrößen und Dateinamen, aber auch, welche Prozesse gerade auf diese Datei zugreifen.
In regelmäßigen Abständen kontrolliert der Metaserver die Kapazitäten aller von ihm betreuten Chunkserver. Falls nötig verschiebt er Chunks auch von stark ausgelasteten Servern auf weniger beanspruchte (Rebalancing). Das führt zu gleichmäßiger Kapazitätsauslastung, die sich wiederum in einer besseren Gesamt-Performance niederschlägt.
Klienten
Zugriff auf die so geschaffene Infrastruktur erhält eine Anwendung über die mitgelieferte Client-Bibliothek (Abbildung 2). Sie stellt ein vollständiges Dateisystem-API bereit, über das sich wie gewohnt (große) Dateien im KFS ablegen, manipulieren und lesen lassen. Im Gegensatz zum Konkurrenten HDFS erlaubt es KFS sogar, mehrfach an beliebigen Positionen in eine Datei zu schreiben oder nachträglich Daten an eine bestehende Datei anzuhängen.

Abbildung 2: Möchte eine Anwendung auf ein File zugreifen, bemüht sie zunächst die Client-Bibliothek. Diese fragt beim Metaserver nach, auf welchen Clusterservern die Datei lagert, und holt sie dort anschließend ab.
Leider ist die Client-Bibliothek das einzige Tor zum verteilten Dateisystem, von ein paar Hilfskrücken einmal abgesehen (siehe Kasten “Werkzeugkasten”). Folglich kommt der Admin nicht umhin, die eigenen Programme anzupassen. Das klappt allerdings nur mit C++ oder Python. Java-Programmierer finden noch einen Weg über das Native Interface (JNI). Wohl nicht ganz uneigennützig integrierten die KFS-Entwickler zusätzlich das API des konkurrierenden HDFS-Dateisystems. Die dafür geschriebenen Programme lassen sich deshalb mit wenigen Handgriffen auf KFS portieren.
|
Werkzeugkasten |
|---|
|
Die Client-Bibliothek bietet Anwendungen einen recht komfortablen Zugriff auf die Funktionen des Dateisystems. Um aber schnell die Inhalte eines Verzeichnisses zu kontrollieren, müsste der Admin erst ein kleines Programm schreiben. Für solche Fälle enthält das KFS-Paket eine spezielle Shell, die Pendants der bekannten Unix-Werkzeuge bereithält, darunter auch »ls«, »cp« oder »mv«. Mit ihrer Hilfe navigiert der Anwender wie gewohnt im KFS-Dateibaum. An die Shell gelangt er über ein Skript im Unterverzeichnis »scripts« des Quellcode-Archivs: python kfsshell.py -f Konfigurationsdatei.cfg -b ~/kfs-0.1.1/build/bin/KfsPing Hinter »KfsPing« verbirgt sich ein aufgebohrtes »ping«, das bei der Überwachung der KFS-Server gute Dienste leistet. Seine Bedienung erläutert ein »KfsPing -h«. Weitere nützliche Werkzeuge verstecken sich im Verzeichnis »build/bin/tools«. Wem die Spezialbefehle nicht zusagen, der darf alternativ unter Linux auf eine Fuse-Unterstützung zurückgreifen: Hinter dem Filesystem in Userspace verbirgt sich ein Kernelmodul, das einen Dateisystem-Treiber in den User-Modus verlagert. Mit seiner Hilfe kann ein Benutzer KFS wie eine normale Festplattenpartition mounten und anschließend darin mit der kompletten Palette der bestehenden Linux-Werkzeuge operieren. |
Schnellstart
Das Kosmos-FS kommt als handliches Quellcodepaket, das sich derzeit allerdings nur auf 64-Bit-Systemen übersetzen lässt. Darüber hinaus bleibt es aber erfreulich genügsam: Neben Cmake setzt es lediglich die »log4cpp«- und Boost-Bibliotheken voraus. Wenn alle diese Bedingungen erfüllt sind, entpackt der Administrator das Archiv und bearbeitet die Datei »CmakeLists.txt«.
Standardmäßig übersetzt der Compiler alle KFS-Programme und die Bibliotheken mit Debug-Informationen. Wer dies nicht möchte, setzt hinter »CMAKE_BUILD_TYPE« den Wert in Anführungszeichen von »Debug« auf »Release«. Wer die Fuse-Unterstützung benötigt (mehr dazu im Kasten “Werkzeugkasten”), befreit die Zeile
# set (Fuse_LIBRARY_DIR "")
von ihrer Kommentarraute und setzt in die Anführungszeichen den Pfad zur Fuse-Bibliothek.
Build mit Cmake
Zum Übersetzen und Installieren muss der Admin noch ein paar Befehle eingeben. Zunächst wechselt er in das Verzeichnis mit dem KFS-Quellcode, im Beispiel »~/kfs-0.1.1«. Dort geht es dann weiter per:
mkdir build cd build cmake ~/kfs-0.1.1 gmake gmake install
Der letzte Befehl suggeriert eine Installation im System. Tatsächlich aber schiebt er nur die zuvor erstellten Programme in das Unterverzeichnis »~/kfs-0.1.1/build/bin« und die zugehörigen Bibliotheken nach »~/kfs-0.1.1/build/lib« beziehungsweise nach »~/kfs-0.1.1/build/lib-static«.
Wer eine Java-Anbindung benötigt, wechselt wieder ins KFS-Verzeichnis »~/kfs-0.1.1« und ruft dort »ant jar« auf. Klappt alles, liegt die Datei »kfs.jar« im Unterverzeichnis »build«. Dieses Paket enthält alles Notwendige für die Entwicklung von Java-Programmen, die KFS nutzen.
Eine Python-Anbindung ist dagegen schon etwas aufwändiger. Zunächst wechselt der Admin ins Unterverzeichnis »~/kfs-0.1.1/src/cc/access«, öffnet dort die Datei »kfs_setup.py« mit einem Texteditor und passt die Include-Pfade an. Anschließend setzt er auf der Kommandozeile den Befehl »python kfs_setup.py ~/kfs-0.1.1/build/lib build« ab. Die erstellte »kfs.so« aus dem Unterverzeichnis »build« integriert er abschließend mit »python kfs_setup.py ~/kfs-0.1.1/build/lib/ install« in das Python-System.
KFS anwerfen
Der nächste Schritt verteilt die fertigen Binärdateien auf den Meta- sowie alle Chunkserver. Dabei hilft ein kleines Python-Skript im Unterverzeichnis »~/kfs-0.1.1/scripts«. Es erstellt für jeden Server ein maßgeschneidertes Programmpaket und impft es ihm anschließend per SSH ein.
Damit das reibungslos klappt, sollte auf allen Servern die gleiche Linux-Umgebung laufen, zumindest sollten sich die Distributionen nicht zu stark voneinander unterscheiden. Wer SSH mit Schlüsselpaaren konfiguriert, erspart sich später die wiederholte Eingabe mehrerer Passwörter.
Schließlich fehlt noch die Konfigurationsdatei. Sie teilt dem Skript mit, welche Computer im Cluster-Netzwerk welche Aufgabe übernehmen. Listing 1 zeigt ein praktisches Beispiel für eine entsprechende Konfigurationsdatei.
Dort existiert für jeden beteiligten Server ein eigener Abschnitt, jeweils eingeleitet durch dessen Namen in eckigen Klammern. Mindestens erforderlich ist eine »[metaserver]«-Sektion. Danach erhält jeder Chunkserver einen eigenen Abschnitt, gewöhnlich in der Form »[chunkserver1]« bis »[chunkserverN]«. Im Beispiel besteht der KFS-Cluster aus einem Meta- und zwei Clusterservern.
Netzwerk-Setup
Jeder Abschnitt enthält wiederum die Einstellungen des jeweiligen Servers. Hinter »node:« steht der Name oder die IP-Adresse des Servers. Nach »rundir:« folgt das Verzeichnis, in dem die Binärdateien landen, im Beispiel aus Listing 1 ist dies das Homeverzeichnis des Benutzers »tim«, der auf jedem Server ein Konto besitzt. Die Anweisung »baseport:« legt den TCP-Port fest, über den der Server später mit seinen Kollegen kommuniziert.
|
Listing 1: |
|---|
01 [metaserver] 02 node: 192.168.1.100 03 rundir: /home/tim/kfs/metaserver 04 baseport: 20000 05 [chunkserver1] 06 node: 192.168.1.101 07 rundir: /home/tim/kfs/chunk1 08 baseport: 30000 09 space: 30 G 10 [chunkserver2] 11 node: 192.168.1.102 12 rundir: /home/tim/kfs/chunk2 13 baseport: 30000 14 space: 18000 M |
Die Rechnernamen müssen nicht unbedingt unterschiedlich sein. Kosmos-FS erlaubt es sogar, alle Server auf nur einem Rechner laufen zu lassen – was selbstverständlich auch »localhost« sein darf. In diesen Fällen sind jedoch allen Meta- und Cluster-Servern verschiedene TCP-Ports zuzuordnen.
Jeder Chunkserver kennt darüber hinaus die Option »space:«. Sie regelt, wie viel Plattenplatz der Server für die Speicherung von Daten abknapst. Im Beispiel spendet der erste Chunkserver 30 GByte, der zweite mit 18 000 MByte etwas weniger. Beispiele für weitere Konfigurationsdateien finden sich im Verzeichnis »conf« des Quellcode-Archivs.
Befehlsstand
Mit der fertigen Konfigurationsdatei in der Hand wechselt der Admin in das Unterverzeichnis »scripts« und aktiviert dort:
python kfssetup.py -f Konfigurationsdatei.cfg -b ../build/bin
Auch der Start aller Server klappt dank Konfigurationsdatei und SSH zentral vom aktuellen Rechner aus:
python kfslaunch.py -f Konfigurationsdatei.cfg --start
Das Herunterfahren übernimmt konsequenterweise der Aufruf:
python kfslaunch.py -f Konfigurationsdatei.cfg --stop
Die stets notwendige Angabe der Konfigurationsdatei ist dabei alles andere als überflüssig: So lassen sich mit mehreren Konfigurationsdateien verschiedene KFS-Cluster bequem von nur einer Konsole aus fernsteuern.
Hörtest
Sobald die Server laufen, darf der Anwender seine Daten ins neue große Dateisystem schieben, entweder über die spezielle KFS-Shell (mehr dazu im Kasten “Werkzeugkasten”) oder über das bereitgestellte API. Ein einfaches Beispiel für ein C++-Programm, das seine Daten im Kosmos-FS ablegt, zeigt Listing 2.
Die Headerdateien liegen unglücklicherweise in den Tiefen des Quellcode-Archivs unter »src/cc«. Ähnliches gilt für die Bibliotheken, die sich in »build/lib« finden:
g++ test.cpp -I ~/kfs-0.1.1/src/cc -L ~/kfs-0.1.1/build/lib/ -lkfsClient -lkfsIO -lkfsCommon
Vor dem Aufruf des Ergebnisses ist noch der Linker-Pfad zu setzen:
export LD_LIBRARY_PATH=~/kfs-0.1.1/build
Um dem Linker die Suche nach den dynamischen Bibliotheken zu ersparen, lässt sich die Eigenkreation außerdem direkt mit den statischen Varianten aus dem Unterverzeichnis »~kfs-0.1.1/build/lib-static« linken.
Um ihre großen Datenmengen loszuwerden, öffnet eine KFS-Anwendung einfach eine neue Datei über die Client-Bibliothek. Diese puffert die eingehenden Schreibvorgänge zunächst. Erst wenn der für diese Zwecke reservierte Cache-Speicher voll ist oder wenn die Anwendung dies veranlasst (Flush), wandern die Daten in die Chunkserver. Unmittelbar nachdem sie dort angekommen sind, stehen sie für weitere Operationen zur Verfügung.
Neben den ausgehenden Daten puffert die Client-Bibliothek auch alle angeforderten Metadaten für 30 Sekunden. Auf diese Weise vermeidet sie unnötige wiederholte Serverkontakte. Läuft ein Client sogar auf einem Chunkserver, liest er die Daten lokal und funkt nicht erst wild durch das Netzwerk.
Sollte während eines Lesevorgangs ein Chunkserver plötzlich nicht mehr erreichbar sein, wechselt die Client-Bibliothek automatisch zu einem anderen. Dies alles geschieht vollkommen transparent, sodass die eigentliche Anwendung von diesen Vorgängen gar nichts mitbekommt.
|
Listing 2: Datei |
|---|
01 ...
02 #include "libkfsClient/KfsClient.h"
03
04 using namespace KFS; // KFS Namespace:
05
06 int main(int argc, char **argv)
07 {
08 string serverHost = "localhost";
09 int port = 20000;
10
11 KfsClient *gKfsClient;
12
13 // Zugriff auf Dateisystem holen:
14 gKfsClient = KfsClient::Instance();
15 gKfsClient->Init(serverHost, port);
16
17 // Unterverzeichnis erstellen:
18 gKfsClient->Mkdirs("testdir");
19
20 // Datei öffnen, "fd" ist das Handle:
21 int fd = gKfsClient->Create("testdir/foo.1");
22
23 // Blödsinn reinschreiben:
24 int numBytes=2048;
25 char *buffer = new char[numBytes];
26 gKfsClient->Write(fd, buffer, numBytes);
27
28 // Änderungen "flushen":
29 gKfsClient->Sync(fd);
30
31 // Datei schließen:
32 gKfsClient->Close(fd);
33 }
|
Nicht ganz fertig
Das Kosmos-Filesystem ist eine ambitionierte Alternative zu HDFS und zum Google File System, steckt aber noch in den Kinderschuhen. Einer der größten Schwachpunkte sind derzeit noch die Metaserver. Sie müssen vor allem die Metadaten schnell und zügig liefern. Erst wenn der Client weiß, auf welchen Clustern die gesuchte Datei liegt, kann er weiterarbeiten. Sollte der Metaserver vollständig ausfallen, sind die Dateien auf den von ihm verwalteten Chunkservern nicht mehr erreichbar.
Da der Metaserver zusätzlich noch für eine Lastverteilung sorgt, hängt es von ihm maßgeblich ab, wie leistungsfähig das gesamte, von ihm betreute KFS-Netz ist. Dummerweise existiert derzeit noch kein Replikationsplan für die Metadaten, so wie es die Chunkserver betreiben. Hier muss der Admin also noch selbst Hand anlegen und die Daten auf eigene Faust regelmäßig sichern.
Keine Sicherheit
Ein weiteres, wesentliches Ärgernis sind die fehlenden Zugriffskontrollen des Dateisystems: Derzeit darf jeder Benutzer beliebige Dateien im verteilten Dateisystem ablegen und auch wieder lesen. Aus diesem Grund sollte Kosmos-FS in der jetzigen Form nur in vertrauenswürdigen Umgebungen laufen. (ofr)
|
Infos |
|---|
|
[1] Kosmos File System: [http://kosmosfs.sourceforge.net] [2] HDFS und das Hadoop-Projekt: [http://lucene.apache.org/hadoop] [3] Paper zum Google File System (GSF), auf dem auch KFS aufbaut: [research.google.com/pubs/papers.html] |





