HDFS-Tutorial: ArchiTektur, Lesen und Schreiben OperaProduktion
⚡ Intelligente Zusammenfassung
HDFS ist die verteilte Speicherschicht von Hadoop, die sehr große Dateien in replizierte Blöcke auf Standardrechnern aufteilt, sodass ein einzelner NameNode tracks-Metadaten, während viele DataNodes Lese- und Schreibanfragen zuverlässig bedienen.
Was ist HDFS?
HDFS ist ein verteiltes Dateisystem zur Speicherung sehr großer Datendateien, das auf Clustern handelsüblicher Hardware läuft. Es ist fehlertolerant, skalierbar und extrem einfach erweiterbar. Hadoop wird standardmäßig mit HDFS (Hadoop Distributed File System) ausgeliefert.
Wenn die Daten die Speicherkapazität einer einzelnen physischen Maschine überschreiten, ist es unerlässlich, sie auf mehrere separate Maschinen zu verteilen. Ein Dateisystem, das speicherspezifische Vorgänge über ein Netzwerk von Maschinen verwaltet, wird als verteiltes Dateisystem bezeichnet. HDFS ist eine solche Software.
HDFS Architektur
Ein HDFS-Cluster besteht im Wesentlichen aus einem NameNode das die Metadaten des Dateisystems verwaltet und Datenknoten die die eigentlichen Daten speichern.
- Namensknoten: Der NameNode kann als zentraler Knoten des Systems betrachtet werden. Er verwaltet die Dateisystemstruktur und die Metadaten aller Dateien und Verzeichnisse im System. Zwei Dateien, das „Namespace-Image“ und das „Edit-Log“, dienen der Speicherung der Metadaten. Der NameNode kennt alle DataNodes, die Datenblöcke einer bestimmten Datei enthalten, speichert die Blockpositionen jedoch nicht dauerhaft. Diese Informationen werden bei jedem Systemstart anhand der DataNodes neu ermittelt.
- Datenknoten: DataNodes sind Slave-Knoten, die auf jedem Rechner in einem Cluster installiert sind und den eigentlichen Speicherplatz bereitstellen. Sie sind für die Bearbeitung von Lese- und Schreibanfragen der Clients zuständig.
Da ein einzelner NameNode einen Single Point of Failure darstellen würde, betreiben aktuelle Cluster einen aktiven NameNode neben einem Standby-NameNode, der das Edit-Log über ein Quorum von JournalNodes teilt, mit automatischem Failover zwischen den beiden.
Lese- und Schreibvorgänge in HDFS erfolgen auf Blockebene. Datendateien in HDFS werden in blockgroße Abschnitte unterteilt, die als unabhängige Einheiten gespeichert werden. Die Standardblockgröße beträgt 64 MB in Hadoop 1.x. Ab Hadoop 2.x beträgt die Standardblockgröße 64 MB. dfs.blocksize beträgt 128 MB.
HDFS basiert auf dem Konzept der Datenreplikation, bei dem mehrere Replikate von Datenblöcken erstellt und auf Knoten in einem Cluster verteilt werden, um eine hohe Datenverfügbarkeit im Falle eines Knotenausfalls zu gewährleisten. Der Standardreplikationsfaktor beträgt drei (dfs.replication), und wenn ein DataNode aufhört, Heartbeats zu senden, repliziert der NameNode seine Blöcke automatisch an anderer Stelle neu.
Weißt du es? Eine Datei in HDFS, die kleiner als ein einzelner Block ist, belegt nicht den gesamten Speicher eines Blocks.
Lesen Sie mehr Operation in HDFS
Eine Datenleseanfrage wird von HDFS, dem NameNode und den DataNodes bearbeitet. Wir nennen den Leser einen „Client“. Das folgende Diagramm veranschaulicht den Dateilesevorgang in Hadoop.
- Ein Client initiiert eine Leseanforderung durch Aufruf der Methode 'open()' des FileSystem-Objekts; es handelt sich um ein Objekt vom Typ DistributedFileSystem.
- Dieses Objekt stellt über RPC eine Verbindung zum NameNode her und ruft Metadaten wie die Speicheradressen der Dateiblöcke ab. Bitte beachten Sie, dass es sich dabei um die Adressen der ersten Blöcke einer Datei handelt.
- Als Antwort auf diese Metadatenanfrage werden die Adressen der DataNodes zurückgegeben, die eine Kopie dieses Blocks enthalten.
- Sobald die Adressen der DataNodes empfangen wurden, wird ein Objekt vom Typ FSDataInputStream an den Client zurückgegeben. FSDataInputStream enthält DFSInputStream, das die Interaktion mit dem DataNode und dem NameNode übernimmt. In Schritt 4 des obigen Diagramms ruft ein Client die Methode „read()“ auf, wodurch DFSInputStream eine Verbindung zum ersten DataNode herstellt, der den ersten Block einer Datei enthält.
- Die Daten werden als Datenströme gelesen, wobei der Client die Methode „read()“ wiederholt aufruft. Dieser Lesevorgang wird so lange fortgesetzt, bis das Ende des Datenblocks erreicht ist.
- Sobald das Ende eines Blocks erreicht ist, schließt DFSInputStream die Verbindung und sucht den nächsten DataNode für den nächsten Block.
- Sobald der Client mit dem Lesen fertig ist, ruft er die Methode close() auf.
Schreiben Operation in HDFS
In diesem Abschnitt werden wir verstehen, wie Daten über Dateien in HDFS geschrieben werden. Das folgende Diagramm veranschaulicht dies. traces, die den Pfad schreiben.
- Ein Client initiiert einen Schreibvorgang durch Aufruf der Methode 'create()' des DistributedFileSystem-Objekts, wodurch eine neue Datei erstellt wird – Schritt Nr. 1 im obigen Diagramm.
- Das DistributedFileSystem-Objekt stellt über einen RPC-Aufruf eine Verbindung zum NameNode her und initiiert die Erstellung einer neuen Datei. Dieser Dateierstellungsvorgang ordnet der Datei jedoch keine Blöcke zu. Es obliegt dem NameNode zu prüfen, ob die zu erstellende Datei bereits existiert und ob der Client über die erforderlichen Berechtigungen zum Erstellen einer neuen Datei verfügt. Existiert die Datei bereits oder besitzt der Client nicht die erforderlichen Berechtigungen, wird eine IOException ausgelöst. Andernfalls ist der Vorgang erfolgreich und der NameNode erstellt einen neuen Datensatz für die Datei.
- Sobald ein neuer Datensatz im NameNode erstellt wurde, wird ein Objekt vom Typ FSDataOutputStream an den Client zurückgegeben. Dieser verwendet es, um Daten in HDFS zu schreiben. Die Datenschreibmethode wird aufgerufen (Schritt 3 im Diagramm).
- FSDataOutputStream enthält ein DFSOutputStream-Objekt, das die Kommunikation mit den DataNodes und dem NameNode übernimmt. Während der Client weiterhin Daten schreibt, erstellt DFSOutputStream fortlaufend Pakete mit diesen Daten. Diese Pakete werden in eine Warteschlange, die sogenannte DataQueue, eingereiht.
- Es gibt eine weitere Komponente namens DataStreamer, die diese DataQueue verarbeitet. DataStreamer fordert außerdem vom NameNode die Zuweisung neuer Blöcke an und wählt so die für die Replikation geeigneten DataNodes aus.
- Nun beginnt der Replikationsprozess mit der Erstellung einer Pipeline mithilfe von DataNodes. In unserem Fall haben wir eine Replikationsebene von 3 gewählt und daher befinden sich 3 DataNodes in der Pipeline.
- Der DataStreamer leitet Pakete an den ersten DataNode in der Pipeline weiter.
- Jeder DataNode in einer Pipeline speichert das von ihm empfangene Paket und leitet es an den nächsten DataNode in der Pipeline weiter.
- Eine weitere Warteschlange, die „Ack Queue“, wird von DFSOutputStream verwaltet, um Pakete zu speichern, die auf eine Bestätigung von den DataNodes warten.
- Sobald von allen DataNodes in der Pipeline eine Bestätigung für ein Paket in der Warteschlange empfangen wurde, wird es aus der „Ack-Warteschlange“ entfernt. Im Falle eines DataNode-Fehlers werden Pakete aus dieser Warteschlange verwendet, um den Vorgang erneut zu starten.
- Nachdem ein Client das Schreiben von Daten abgeschlossen hat, ruft er die Methode `close()` auf (Schritt 9 im Diagramm). Der Aufruf von `close()` führt dazu, dass die verbleibenden Datenpakete in die Pipeline geschrieben werden, woraufhin auf eine Bestätigung gewartet wird.
- Sobald eine abschließende Bestätigung eingegangen ist, wird der NameNode kontaktiert, um ihm mitzuteilen, dass der Schreibvorgang der Datei abgeschlossen ist.
Zugriff auf HDFS über die Java API
In diesem Abschnitt versuchen wir, die Java Schnittstelle für den Zugriff auf das Dateisystem von Hadoop.
Um programmatisch mit dem Dateisystem von Hadoop zu interagieren, bietet Hadoop mehrere Möglichkeiten. Java Das Paket org.apache.hadoop.fs enthält Klassen, die für die Bearbeitung von Dateien im Hadoop-Dateisystem nützlich sind. Zu diesen Operationen gehören Öffnen, Lesen, Schreiben und Schließen. Die Hadoop-Datei-API ist generisch und kann erweitert werden, um mit anderen Dateisystemen als HDFS zu interagieren.
Programmgesteuertes Lesen einer Datei aus HDFS
Objekt java.net.URL wird zum Lesen des Inhalts einer Datei verwendet. Zunächst müssen wir Java Hadoops HDFS erkennen URL Schema. Dies geschieht durch Aufruf der Menge.URLStreamHandlerFactory-Methode auf der URL Objekt und Übergabe einer Instanz von FsUrlStreamHandlerFactory an dieses Objekt. Diese Methode muss nur einmal pro JVM, daher ist es in einem statischen Block eingeschlossen.
Ein Beispielcode ist-
public class URLCat { static { URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); } public static void main(String[] args) throws Exception { InputStream in = null; try { in = new URL(args[0]).openStream(); IOUtils.copyBytes(in, System.out, 4096, false); } finally { IOUtils.closeStream(in); } } }
Dieser Code öffnet eine Datei und liest ihren Inhalt. Der Pfad dieser Datei auf HDFS wird dem Programm als Kommandozeilenargument übergeben.
Zugriff auf HDFS über die Befehlszeilenschnittstelle
Dies ist eine der einfachsten Möglichkeiten, mit HDFS zu interagieren. Die Befehlszeilenschnittstelle unterstützt Dateisystemoperationen wie das Lesen von Dateien, das Erstellen von Verzeichnissen, das Verschieben von Dateien, das Löschen von Daten und das Auflisten von Verzeichnissen.
Wir können laufen '$HADOOP_HOME/bin/hdfs dfs -help' Um detaillierte Hilfe zu jedem Befehl zu erhalten. Hierbei handelt es sich bei „dfs“ um einen Shell-Befehl von HDFS, der mehrere Unterbefehle unterstützt. In aktuellen Hadoop-Versionen hdfs dfs ist die bevorzugte Form, während die ältere Hadoop-Dateisystem Der Befehl führt die gleiche Arbeit für jedes unterstützte Dateisystem aus.
Nachfolgend sind einige der häufig verwendeten Befehle zusammen mit den jeweiligen Einzelheiten aufgeführt.
1. Kopieren Sie eine Datei vom lokalen Dateisystem nach HDFS
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal temp.txt /
Dieser Befehl kopiert die Datei temp.txt vom lokalen Dateisystem nach HDFS, wie die folgende Ausgabe zeigt.
2. Mit dem Befehl -ls können wir die in einem Verzeichnis vorhandenen Dateien auflisten.
$HADOOP_HOME/bin/hdfs dfs -ls /
In der folgenden Auflistung sehen wir die Datei 'temp.txt' (die zuvor kopiert wurde) im Verzeichnis ' / '.
3. Befehl zum Kopieren einer Datei von HDFS in das lokale Dateisystem
$HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt
Dieser Befehl entspricht dem Befehl `-get` und akzeptiert einen expliziten lokalen Zielpfad als zweites Argument. Die folgende Ausgabe zeigt, dass die Datei `temp.txt` in das lokale Dateisystem kopiert wurde.
4. Befehl zum Erstellen eines neuen Verzeichnisses
$HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory
Der Befehl wird im Hintergrund ausgeführt, wie die untenstehende Eingabeaufforderung zeigt.
Prüfen Sie, ob das Verzeichnis erstellt wurde oder nicht. Jetzt wissen Sie, wie das geht 😉




