Alle derzeitigen verteilten Speichersysteme basieren auf Clusterarchitekturen. Daten werden gleichmäßig auf den Knoten des Clusters verteilt. Das ist die Grundidee einer verteilten Datenhaltung. Die Verteilung der Daten ist nicht statisch. Stell dir vor, Knoten verlassen das Cluster oder es kommen neue hinzu. Ein verteiltes Dateisystem muss in diesen Fällen die Daten neu ausbalancieren. Um die Balance zu halten, braucht es zwei wichtige Konzepte; Replikation und Partitionierung.
Replikation
Um den Ausfall einer oder mehrerer Knoten im Cluster verkraften zu können, werden Duplikate der Daten auf unterschiedliche Knoten verteilt. Fällt ein Knoten weg, so können dessen Daten aus anderen Knoten wiederhergestellt werden. Erst dieses Konzept stellt sicher, dass wegfallende Knoten kompensiert werden können (Ausfallsicherheit).
Partitionierung
Filesysteme verschiedener Betriebssysteme (Z. B. Linux) nutzen das Konzept der Blöcke. Blöcke sind die kleinste Einheit, die vom Filesystem verwaltet wird und Daten werden auf Blöcke aufgeteilt. Das Dateisystem weiß, welche Daten in welchen Block gespeichert werden und welche Blöcke frei sind.
Auch ein verteiltes Dateisystem nutzt das Konzept der Blöcke. Daten werden auch hier in Blöcke zerlegt und auf die unterschiedlichen Knoten verteilt. Blöcke werden aus folgenden Gründen genutzt:
- Auf Basis von Blöcken kann das verfügbare Speichervolumen auf den Knoten einfach geschätzt werden.
- Dateien können so parallel gelesen und geschrieben werden, da sie in mehrere Blöcke aufgeteilt werden. Dies gilt insbesondere für die Replikation von Blöcken.
- Es gibt (de facto) keine Begrenzung der Größe einer Datei. Durch die Aufteilung in Blöcke kann das Speichervolumen des ganzen Clusters zur Speicherung genutzt werden.
Um Blöcke nutzen zu können, muss das verteilte Dateisystem eine zentrale Verwaltung der Blöcke bereitstellen. Das Dateisystem weiß, welche Blöcke auf welchem Knoten liegen und welche Blöcke zu einer Datei gehören. Nur mit diesen Informationen lässt sich eine Datei lesen.
Blöcke haben keinerlei Kenntnisse darüber, zu welchen Daten sie gehören, oder Kenntnisse über Informationen wie Zugriffsberechtigungen. Diese Metadaten werden auf der Ebene der Daten und damit ebenfalls zentral vom Dateisystem verwaltet.
Hadoop Distributed Filesystem (HDFS)
Im Ökosystem Hadoop bietet HDFS (Hadoop Distributed Filesystem) ein verteiltes Dateisystem.
In HDFS haben Knoten unterschiedliche Rollen. Datanodes speichern die Blöcke.
Wie oben gesehen, benötigt HDFS eine Verwaltung der Blöcke. Diese wird durch einen Namenode übernommen. Als zentrale Informationen kennt dieser alle Datanodes und weiß, welche Daten diese enthalten. Auch kennt er dazugehörende Metadaten der Daten (wie Berechtigungen der Dateien). Liest ein Client Daten, so ermittelt der Namenode nach Prüfung der Zugriffsrechte die Blöcke. Mit dieser Information lassen sich die Daten zusammensetzen. Schreibt ein Client, so werden die Daten durch den Namenode in Blöcke zerlegt. Er bestimmt, auf welchen Knoten im Cluster diese Blöcke gespeichert werden.
Optimierung des Datentransports
Eine grundlegende Schwäche dieses Ansatzes besteht darin, dass alle Abfragen über den Namenode laufen. Datenblöcke werden erst von Datanode zum Namenode überführt und anschließend von dort zum Client. Die Blöcke werden also zweimal im Cluster transportiert. Es wäre doch viel effizienter, die Blöcke direkt zwischen Datanode und Client auszutauschen.
Diese Optimierung des Datenflusses wird durch den HDFS-Client umgesetzt. HDFS-Client stellt den Zugriff auf HDFS bereit und ist die Schnittstelle zum Dateisystem. Intern optimiert er den Austausch der Blöcke und vermeidet unnötigen Datenfluss.
Werden Daten gelesen, so fragt der HDFS-Client den Namenode nach Blöcken und zugehörigen Datanodes. Nun wendet sich der HDFS-Client direkt an die Datanodes und liest die Inhalte der Blöcke. Mittels dieser Trennung ist der Namenode nicht in die Übertragung der Daten involviert. Das entlastet den Namenode und vermeidet unnötigen Datenfluss zwischen Namenode und Datanodes.
Beim Schreiben einer Datei wird vergleichbar verfahren. Der HDFS-Client informiert den Namenode über die Datei, die zu schreiben ist. Dieser merkt sich Metadaten der Datei und meldet dem Client, wie viele Replikationen anzulegen sind.
Der HDFS-Client zerlegt die Datei in Blöcke und repliziert diese. Vor jeder Übertragung der Blöcke fragt der Client den Namenode nach dem Datanode. Die Übertragung der Daten findet dann zwischen Client und Datanode statt. Auch hier ist der Namenode nicht involviert.
Zum Abschluss quittiert der Client dem Namenode die vollständige Übertragung der Daten und teilt ihm mit, auf welchen Datanodes die Blöcke gelandet sind.
Folgende Graphik skizziert diesen optimierten Datenaustausch.