概要
Debian 11でCluster ModeのHadoop環境を構築した際のメモです。
環境
Debian 11 bullseye
ノード構成
3台で構成しますが、1台はMaster兼Workerとして利用します。
Hostname | IP address | NameNode | DataNode | ResourceManager | NodeManager |
---|---|---|---|---|---|
kyoto | 192.168.10.111 | Yes | Yes | Yes | Yes |
tokyo | 192.168.10.112 | No | Yes | No | Yes |
osaka | 192.168.10.113 | No | Yes | No | Yes |
Single Clusterによる構築
オフィシャルドキュメントに従って、まずはSingle Clusterで動作を確認します。
実際の環境構築は、オフィシャルドキュメントに加えて以下のサイトを参考にしました。そのため、オフィシャルの奨励から多少ずれてはいますが、動いているので結果OKとしたいと思います。
パッケージインストール
まずはJAVAをインストールします。
root@kyoto:~# apt install default-jdk default-jre
Hadoopを実行するユーザーhadoopを作成します。オフィシャルドキュメントではhdfsとyarnで別ユーザーを勧められていますが、今回は簡略のために同一ユーザーにします。
root@kyoto:~# useradd -r hadoop -m -d /opt/hadoop --shell /bin/bash
以降はhadoopユーザーで行います。
まず、Hadoopが通信のために利用するsshのために鍵を生成します。
root@kyoto:~# su - hadoop
hadoop@kyoto:~$ ssh-keygen -t rsa
hadoop@kyoto:~$ cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
Hadoopのパッケージを展開します。オフィシャルサイトから最新のバージョンをダウンロードし解凍します。
hadoop@kyoto:~$ wget https://dlcdn.apache.org/hadoop/common/hadoop-3.4.0/hadoop-3.4.0.tar.gz
hadoop@kyoto:~$ tar -zxvf hadoop-3.4.0.tar.gz -C /opt/hadoop --strip-components=1
環境変数を設定します。どこまで本当に必要なのかわかりませんが、参考サイトに従って設定しておきます。
export JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64
export HADOOP_HOME=/opt/hadoop
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib"
...
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
最後に、NameNodeとDataNodeの保存先を作成しておきます。
hadoop@kyoto:~$ mkdir -p /opt/hadoop/hadoop_tmp/hdfs/namenode
hadoop@kyoto:~$ mkdir -p /opt/hadoop/hadoop_tmp/hdfs/datanode
サイトの設定
ここからが大変な設定ファイルの編集です。基本的にはオフィシャルドキュメントに沿って設定しますが、そのままでは起動しなかったので、試行錯誤で必要な項目を追加しています。おそらく環境変数等がうまく設定できていないので、正しい解決策はあると思いますが、とりあえず動いているのでこのままにしています。
<configuration>
<property>
<!-- The name of the default file system. -->
<name>fs.defaultFS</name>
<value>hdfs://localhost:8020</value>
</property>
</configuration>
<configuration>
<property>
<!-- Default block replication. -->
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<!-- Determines where on the local filesystem the DFS name node should store the name table(fsimage). -->
<name>dfs.namenode.name.dir</name>
<value>file:///opt/hadoop/hadoop_tmp/hdfs/namenode</value>
</property>
<property>
<!-- Determines where on the local filesystem an DFS data node should store its blocks. -->
<name>dfs.datanode.data.dir</name>
<value>file:///opt/hadoop/hadoop_tmp/hdfs/datanode</value>
</property>
</configuration>
<configuration>
<property>
<!-- A comma separated list of services -->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
<configuration>
<property>
<!-- The runtime framework for executing MapReduce jobs. -->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<!-- CLASSPATH for MR applications. -->
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
</property>
<!-- 起動時に以下の設定がないとエラーになったので追加 -->
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
</configuration>
初期化と起動
hadoop@kyoto:~$ hdfs namenode -format
起動スクリプトを実行します。
hadoop@kyoto:~$ start-all.sh
起動確認は、
を開くことで行います。
サンプルの実行
オフィシャルドキュメントに書かれているMapReduceのサンプルを実行してみます。
hadoop@kyoto:~$ hdfs dfs -mkdir -p /user/hadoop
hadoop@kyoto:~$ hdfs dfs -mkdir input
hadoop@kyoto:~$ hdfs dfs -put etc/hadoop/*.xml input
hadoop@kyoto:~$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.4.0.jar grep input output 'dfs[a-z.]+'
hadoop@kyoto:~$ hdfs dfs -cat output/*
エラーなく実行が完了し、outputが表示できれば成功です。
Cluster Setup (完全分散モード)
Single Clusterでの動作が確認されたら、3台ノードによるCluster Setupに移ります。
既にkyotoにはパッケージをインストールしてあるため、残りの2台(tokyo, osaka)にJAVAのインストール、Hadoopパッケージの展開および環境変数の設定を行っておきます。
SSHの鍵についてはkyotoで作成したものを使うため、再生成は不要です。kyotoで作成した~/.ssh/id_rsa.pubをtokyoとosakaの~/.ssh/authorized_keysに追加しておきます。
SSHで接続できることを確認しておきます。
hadoop@kyoto:~$ ssh tokyo
hadoop@kyoto:~$ ssh osaka
いずれの場合でもパスワード入力無しで接続できることを確認します。
サイトの設定
完全分散モードの設定にするため、再度サイト設定を変更します。本当は個別に設定すべきものもあると思いますが、今回は全てのホスト(kyoto, tokyo, osaka)で同じ設定を行います。
<configuration>
<property>
<!-- The name of the default file system. -->
<name>fs.defaultFS</name>
<value>hdfs://kyoto/</value>
</property>
</configuration>
<configuration>
<property>
<!-- Default block replication. -->
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<!-- Determines where on the local filesystem the DFS name node should store the name table(fsimage). -->
<name>dfs.namenode.name.dir</name>
<value>file:///opt/hadoop/hadoop_tmp/hdfs/namenode</value>
</property>
<property>
<!-- Determines where on the local filesystem an DFS data node should store its blocks. -->
<name>dfs.datanode.data.dir</name>
<value>file:///opt/hadoop/hadoop_tmp/hdfs/datanode</value>
</property>
<property>
<!-- If true (the default), then the namenode requires that a connecting datanode's address must be resolved to a hostname. -->
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property>
<property>
<!-- The actual address the RPC server will bind to. -->
<!-- これがないとworkerからmasterへ接続できず、DataNodeが認識されなかった -->
<name>dfs.namenode.rpc-bind-host</name>
<value>0.0.0.0</value>
</property>
</configuration>
<configuration>
<property>
<!-- The hostname of the RM. -->
<name>yarn.resourcemanager.hostname</name>
<value>kyoto</value>
</property>
<property>
<!-- A comma separated list of services -->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!-- The actual address the server will bind to. -->
<!-- これがないとworkerからmasterへ接続できず、NodeManagerが認識されなかった -->
<name>yarn.resourcemanager.bind-host</name>
<value>0.0.0.0</value>
</property>
</configuration>
<configuration>
<property>
<!-- The runtime framework for executing MapReduce jobs. -->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<!-- MapReduce JobHistory Server IPC host:port -->
<name>mapreduce.jobhistory.address</name>
<value>kyoto:10020</value>
</property>
<property>
<!-- CLASSPATH for MR applications. -->
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=/opt/hadoop</value>
</property>
</configuration>
初期化と起動
Single ClusterのときにDataNodeを使用してしまったので、DataNodeの中身を削除しておきます。
hadoop@kyoto:~$ rm -rf hadoop_tmp/hdfs/datanode/*
NameNodeの初期化と起動を行います。
hadoop@kyoto:~$ hdfs namenode -format
hadoop@kyoto:~$ start-all.sh
サンプルの実行
Single Clusterと同じMapReduceのサンプルを実行してみます。
hadoop@kyoto:~$ hdfs dfs -mkdir -p /user/hadoop
hadoop@kyoto:~$ hdfs dfs -mkdir input
hadoop@kyoto:~$ hdfs dfs -put etc/hadoop/*.xml input
hadoop@kyoto:~$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.4.0.jar grep input output 'dfs[a-z.]+'
hadoop@kyoto:~$ hdfs dfs -cat output/*