Martin Puppe


Hadoop unter Debian Squeeze installieren

Im folgenden Artikel beschreibe ich, wie Hadoop unter Debian Squeeze im sogenannten pseudo-verteilten Modus installiert werden kann. Den Text habe ich im Rahmen meiner Tätigkeit als studentische Hilfskraft beim Leibniz-Zentrum für Psychologische Information und Dokumentation (ZPID) für ein internes Wiki verfasst. Da ich denke, dass diese Anleitung auch für andere nützlich sein könnte, veröffentliche ich sie auch hier im Blog.


Die wichtigsten Bestandteile von Hadoop sind:

Beide folgen einer Master/Slave-Architektur. Der Master-Dienst heißt bei HDFS NameNode, der Slave-Dienst DataNode. Bei HMR ist der sogenannte JobTracker der Master und die TaskTracker sind die Slaves. Typischerweise besteht ein Hadoop-Cluster aus mindestens drei Arten von Maschinen:

Als Einstieg in den Betrieb eines Hadoop-Clusters, und um Programme zu testen, die das HMR-Framework verwenden, bietet es sich an, erst einmal alle Dienste auf einer einzigen Maschine laufen zu lassen. Dieser Operationsmodus wird als pseudo-verteilt bezeichnet.

Wir gehen von folgenden Voraussetzungen aus:

Installation

Download-Links sind unter http://hadoop.apache.org/releases.html zu finden. Wir laden z.B. die aktuelle stabile Version für x86-Systeme und deren Signatur von einem Spiegel-Server herunter:

wget http://mirror.synyx.de/apache/hadoop/common/hadoop-1.0.4/hadoop_1.0.4-1_i386.deb
wget http://mirror.synyx.de/apache/hadoop/common/hadoop-1.0.4/hadoop_1.0.4-1_i386.deb.asc

Außerdem laden wir die Datei KEYS von einem Server der Apache Foundation und importieren die Schlüssel in den GPG-Schlüsselring. Anschließend verifizieren wir die Signatur.

wget http://www.eu.apache.org/dist/hadoop/common/KEYS
gpg --import KEYS
gpg --verify hadoop_1.0.4-1_i386.deb.asc

Schließlich installieren wir das Paket:

sudo dpkg -i hadoop_1.0.4-1_i386.deb

Bei der Installation werden automatisch die Gruppe hadoop und die Benutzer hdfs und mapred angelegt.

Konfiguration

Zunächst müssen unter /etc/hadoop die Dateien core-site.xml, hdfs-site.xml und mapred-site.xml mit folgendem Inhalt angelegt werden:

``` xml core-site.xml

fs.default.name hdfs://localhost:9000

``` xml hdfs-site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.name.dir</name>
        <value>/var/local/lib/hadoop-dfs/name</value>
    </property>
    <property>
        <name>dfs.data.dir</name>
        <value>/var/local/lib/hadoop-dfs/data</value>
    </property>
</configuration>

``` xml mapred-site.xml

mapred.job.tracker localhost:9001 mapred.system.dir /hadoop/mapred/system mapreduce.jobtracker.staging.root.dir /user

Eine Übersicht über alle Konfigurationsoptionen und deren Standardwerte
findet sich unter:

* `core`: <http://hadoop.apache.org/docs/r1.0.4/core-default.html>
* `hdfs`: <http://hadoop.apache.org/docs/r1.0.4/hdfs-default.html>
* `mapred`: <http://hadoop.apache.org/docs/r1.0.4/mapred-default.html>

Zuletzt müssen wir noch sicherstellen, dass die Umgebungsvariable
`JAVA_HOME` korrekt gesetzt wird. Dazu bearbeiten wir die Datei
`/etc/hadoop/hadoop-env.sh` bearbeiten. Wir ersetzen die Zeile

``` sh
export JAVA_HOME=/usr/lib/jvm/java-6-sun

durch

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk

Wichtig! Damit die letzte Änderung wirksam wird, müssen wir uns aus- und wieder einloggen. Mittels echo $JAVA_HOME kann überprüft werden, ob die Variable richtig gesetzt ist.

Erstes Starten der Dienste

Wir werden zuerst das HDFS und dann HMR starten.

HDFS starten

Bevor wir HDFS starten, müssen wir die lokalen Ordner erstellen, in denen die Daten des HDFS abgelegt werden. Es handelt sich dabei, um die Ordner die zuvor in der Konfigurationsdatei hdfs-site.xml festgelegt wurden. Anschließend wirds verteilte Dateisystem formatiert. Einige der Operationen müssen als Benutzer hdfs ausgeführt werden. In diesen Fällen steht am Beginn des Befehls sudo -u hdfs.

sudo mkdir -p /var/lib/local/hadoop-dfs
sudo chown hdfs:hadoop /var/lib/local/hadoop-dfs
sudo -u hdfs mkdir /var/lib/local/hadoop-dfs/name /var/lib/local/hadoop-dfs/data
sudo -u hdfs hadoop namenode -format

Nun können wir den NameNode-Dienst und den DataNode-Dienst starten.

sudo service hadoop-namenode start
sudo service hadoop-datanode start

Nun sollte es möglich sein unter http://localhost:50070 den aktuellen Status des NameNodes und der DataNodes zu einzusehen.

Sollte irgendetwas nicht funktionieren, hilft es bei der Diagnose der Probleme einen Blick in die Log-Dateien zu werfen. Diese werden unter /var/log/hadoop abgelegt. Fehler des NameNode-Dienstes bspw. findet man unter /var/log/hadoop/hadoop--namenode-HOSTNAME.log. Wobei HOSTNAME durch den tatsächlichen Hostnamen bzw. Rechnernamen ersetzt werden muss.

HMR starten

Bevor wir die Dienste für MapReduce starten können, müssen wir im HDFS das Verzeichnis /hadoop/mapred/system anlegen und mapred als Besitzer des Verzeichnisses festlegen.

sudo -u hdfs hadoop fs -mkdir /hadoop/mapred/system
sudo -u hdfs hadoop fs -chown -R mapred:hadoop /hadoop/mapred

Mittels hadoop fs -ls /hadoop/mapred, können wir uns davon überzeugen, dass der Ordner mit den richtigen Rechten erstellt wurde.

Nun können wir die TaskTracker- und JobTracker-Dienste starten:

sudo service hadoop-jobtracker start
sudo service hadoop-tasktracker start

Hat alles geklappt, lässt sich unter http://localhost:50030 der Status des TaskTrackers und der JobTracker einsehen.

Benutzer-Verzeichnis erstellen

sudo -u hdfs hadoop fs -mkdir /user/BENUTZER
sudo -u hdfs hadoop fs -chown BENUTZER:GRUPPE /user/BENUTZER

Ein Beispiel-Programm ausführen

Unsere Hadoop-Installation testen wir mit einem Beispiel-Programm aus, das in der Hadoop-Distribution enthalten ist. Zunächst kopieren wir die Eingabedaten in das verteilte Dateisystem, dann führen wir das Programm aus, und schließlich kopieren wir die Ausgabedaten des Programms auf das lokale Dateisystem.

hadoop fs -put /usr/share/hadoop/templates/conf/ input
hadoop jar /usr/share/hadoop/hadoop-examples-1.0.4.jar grep input output 'dfs[a-z.]+'
hadoop fs -get output output

Mittels cat output/* können wir uns das Ergebnis ansehen.