Ein Protokoll, das auf keine Platte passt
Eine Supermarktkette speichert für jeden Kassenbon eine Zeile. Nach zwei Jahren ist das Protokoll 60 TB groß. Keine einzelne Festplatte fasst es, und ein einzelner Rechner bräuchte bei 200 MB pro Sekunde mehr als drei Tage, um es nur einmal zu lesen.
Werkzeuge für große Datenmengen zerlegen die Datei. Sie verteilen die Teile auf viele Rechner. Jeder Rechner arbeitet an seinem eigenen Teil.
Am Ende dieser Lektion
Notiz
Ich kann erklären, wie eine Datei zerlegt und parallel verarbeitet wird.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Block | ein Stück fester Größe aus einer großen Datei | 128 MB |
| NameNode | der Rechner, der weiß, wo jeder Block liegt | |
| DataNode | ein Rechner, der Blöcke speichert | |
| Replikat | eine Kopie eines Blocks auf einem anderen Rechner | |
| Map | der Schritt, der jedes Datenstück in Paare verwandelt | |
| Reduce | der Schritt, der die Paare eines Schlüssels addiert |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
HDFS zerlegt eine Datei in Blöcke
HDFS ist das Dateisystem von Hadoop. Es zerlegt jede Datei in Blöcke fester Größe, standardmäßig 128 MB. Der letzte Block nimmt den Rest.
Jeder Block liegt auf einem DataNode und wird zusätzlich kopiert, damit ein Ausfall nichts zerstört. Ein einziger NameNode führt die Liste, aus welchen Blöcken jede Datei besteht und wo sie liegen.
Beispiel: eine Datei mit 520 MB
| Block | Größe | Gespeicherte Kopien | Liegt auf |
|---|---|---|---|
| 1 bis 4 | je 128 MB | je 3 | drei verschiedenen DataNodes |
| 5 | 8 MB | 3 | drei verschiedenen DataNodes |
| Summe | 520 MB | 15 Kopien | Der NameNode führt nur die Liste |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Blöcke einer Datei zählen
# Eine Datei wird in Blöcke fester Größe zerlegt.
groesse_mb = 520
block_mb = 128
volle = groesse_mb // block_mb
rest = groesse_mb % block_mb
bloecke = volle
if rest > 0:
bloecke = bloecke + 1
print("Blöcke:", bloecke)
print("Größe des letzten Blocks:", rest, "MB")
kopien = bloecke * 3
print("Kopien auf den Platten:", kopien)
# Ersetzen Sie 520 durch 900 und starten Sie erneut.
Ihr Lab ist kleiner
Das Lab hat nur einen DataNode. Es hält deshalb nur eine Kopie jedes Blocks und nicht drei. Die Ideen bleiben gleich: Ein echter Cluster fügt einfach Rechner hinzu.
Im Terminal des Labs gibt es den Befehl hadoop nicht. Sie fragen den Cluster mit curl, über die Webadresse des NameNode.
Den Eingabeordner des Labs auflisten
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input?op=LISTSTATUS' | grep -o '"pathSuffix":"[^"]*"'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Blockgröße und Länge der Datei abfragen
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input/sentence.txt?op=GETFILESTATUS' | grep -o '"blockSize":[0-9]*\|"length":[0-9]*'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Fragen, wie viele Kopien HDFS hält
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input/sentence.txt?op=GETFILESTATUS' | grep -o '"replication":[0-9]*'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Fragen, wie viel Platte der Ordner belegt
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input?op=GETCONTENTSUMMARY' | grep -o '"spaceConsumed":[0-9]*'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein häufiger Fehler
Warnung
Viele denken, der NameNode speichere die Datei. Er führt nur die Liste der Blöcke und ihrer Orte. Die Bytes liegen auf den DataNodes. Fragen Sie: Wer hat die Bytes? Die Antwort ist ein DataNode.
MapReduce bringt die Arbeit zu den Daten
60 Terabyte durch ein Netzwerk zu kopieren dauert lange. Hadoop schickt deshalb das kleine Programm zu den Rechnern, die die Blöcke schon haben.
Jeder Rechner führt den Schritt Map auf seinem Block aus, ohne mit den anderen zu sprechen. Danach werden die Paare nach Schlüssel gruppiert: das Mischen (Shuffle). Der Schritt Reduce addiert jede Gruppe.
Beispiel: Wörter im Kassenprotokoll zählen
| Schritt | Was geschieht | Ergebnis |
|---|---|---|
| Eingabe | Zwei Blöcke mit je zwei Zeilen | Brot Milch / Milch Reis und Brot Reis / Brot Milch |
| Map, je Block | Jedes Wort wird ein Paar | Block eins: Brot 1, Milch 1, Milch 1, Reis 1. Block zwei: Brot 1, Reis 1, Brot 1, Milch 1 |
| Mischen (Shuffle) | Gleiche Wörter aus beiden Blöcken kommen zusammen | Brot: 1, 1, 1 / Milch: 1, 1, 1 / Reis: 1, 1 |
| Reduce | Die Einsen werden addiert | Brot 3, Milch 3, Reis 2 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Map und Reduce in einfachem Python
# Zwei Blöcke eines Kassenprotokolls.
block_eins = ["Brot Milch", "Milch Reis"]
block_zwei = ["Brot Reis", "Brot Milch"]
def map_anwenden(zeilen):
# Map: Jedes Wort wird zu einem Paar [Wort, 1].
paare = []
for zeile in zeilen:
for wort in zeile.split():
paare.append([wort, 1])
return paare
def reduce_anwenden(paare):
# Reduce: Die Einsen je Wort werden addiert.
summen = {}
for paar in paare:
wort = paar[0]
if wort in summen:
summen[wort] = summen[wort] + paar[1]
else:
summen[wort] = paar[1]
return summen
alle = map_anwenden(block_eins) + map_anwenden(block_zwei)
print(reduce_anwenden(alle))
# Fügen Sie block_zwei die Zeile "Reis Thymian" hinzu und starten Sie erneut.
Ein Job hinterlässt sein Ergebnis in HDFS
Ein Lauf von MapReduce heißt Job. Der ResourceManager verteilt die Arbeit, und das Ergebnis wird als Dateien in HDFS geschrieben.
Jeder Reducer schreibt eine Datei mit dem Namen part-r- und einer Nummer. Eine leere Datei namens _SUCCESS zeigt, dass der Job fertig ist.
Den Ausgabeordner des Jobs auflisten
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/wordcount-out?op=LISTSTATUS' | grep -o '"pathSuffix":"[^"]*"'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Summe für das Wort „the“ lesen
curl -s -L 'http://namenode:9870/webhdfs/v1/user/lab/wordcount-out/part-r-00000?op=OPEN' | grep '^the'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Fragen, wie der Job geendet hat
curl -s http://resourcemanager:8088/ws/v1/cluster/apps | grep -o '"finalStatus":"[A-Z]*"'Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Weiterführend: vorher im Block addieren
Block zwei schickt vier Paare ins Mischen, und zwei davon sind „Brot 1“. Ein echter Job kann innerhalb jedes Blocks vorher addieren. Diesen Schritt nennt man Combiner.
Ändern Sie map_anwenden im MapReduce-Block so, dass die Funktion die Summen des eigenen Blocks als Paare liefert. Starten Sie den Code. Wie viele Paare verlassen Block zwei jetzt, und bleibt das Endergebnis gleich?