💈

Ubuntu 22.04にシングルノードのApache Hadoop 3.3.4をセットアップする。

2023/06/24に公開

はじめに

この記事では、シングルノード構成で Hadoop を Ubuntu 上の LXD に構築し、分散ファイルシステムを体験してみる。セットアップ方法は以下の公式のセットアップ方法を参考に実施した。

https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html

さらに、以下の 2 つの記事は参考も参考にした。

https://qiita.com/takumi-AandS/items/6783838739e27ab328b2
https://stackoverflow.com/questions/48129029/hdfs-namenode-user-hdfs-datanode-user-hdfs-secondarynamenode-user-not-defined

構築方法

LXD 環境を作成する。

lxc launch images:ubuntu/22.04 hadoop
lxc shell hadoop

ドキュメントを参考に必要なソフトウェアをインストールしていく。

apt install ssh

公式ドキュメントに書いてある pdsh は複数の端末に同じコマンドを打つコマンドらしい。これをインストールすると後のsbin/start-dfs.shでエラーとなるため今回はインストールしない。インストールしなくても最後まで問題はなかった。

Java をインストール。

 apt install openjdk-11-jdk

Hadoop 3.3.4 から Java 11 を完全にサポートしてると書いてある。

バージョンの確認を変数の定義

/usr/lib/jvm/java-11-openjdk-amd64/bin/java -version
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

Hadoop 3.3.4 をダウンロード

wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz

解凍

tar zxvf hadoop-3.3.4.tar.gz

この時点で一応動いてる。

cd hadoop-3.3.4
bin/hadoop version

シングルノードの単一 Java プロセス

Hadoop はシングルノードの単一 Java プロセスでスクリプトを動かせる。

mkdir input
cp etc/hadoop/*.xml input
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar grep input output 'dfs[a-z.]+'
cat output/*

何度も実行したかったら output フォルダを消す。

シングルノードで複数の Java プロセス

Hadoop はシングルノードでも複数の java プロセスでスクリプトを動かせる。

以下ファイルを書き換え。

etc/hadoop/core-site.xml:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

etc/hadoop/hdfs-site.xml:

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

パスワードなしで ssh できる必要があるので公開鍵を生成する。

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys

以下でパスワードなしで ssh できることを確認する。

ssh localhost

HDFS のフォーマット

bin/hdfs namenode -format

環境変数を設定する。
etc/hadoop/hadoop-env.sh:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export HDFS_DATANODE_USER=\root\
export HDFS_SECONDARYNAMENODE_USER=\root\
export HDFS_NAMENODE_USER=\root\
export YARN_RESOURCEMANAGER_USER=\root\
export YARN_NODEMANAGER_USER=\root\

ssh を超えて環境変数を反映させるための設定だと思う。

ノードとなる java プロセスを起動する。

sbin/start-dfs.sh

プロセスを確認すると java プロセスが 3 つ起動している。Hadoop は高可用性のためにデータを 3 つに複製すると聞いたことがある。その 3 個かなぁ。

この状態で http://localhost:9870 にアクセスすると Web UI が確認できる。

今回は LXD 上で行っているのでネットワークインターフェースを追加する。

lxc config device add hadoop c1 proxy listen=tcp:0.0.0.0:9870 connect=tcp:127.0.0.1:9870 bind=host

UI は意外ときれい。Bootstrap 3 だ。
hdfs 上でファイル操作してみる。

bin/hdfs dfs -mkdir /user
bin/hdfs dfs -mkdir /user/root
bin/hdfs dfs -mkdir input
bin/hdfs dfs -put etc/hadoop/*.xml input

UnixLike のコマンドでファイル操作できる。素晴らしい。

テスト用のスクリプトを動かす。

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar grep input output 'dfs[a-z.]+'
bin/hdfs dfs -cat output/*

動かせた。

何度も動かしたかったら以下で output を削除する。

bin/hdfs dfs -rm -r -f output

以下コマンドでノードとなる java プロセスを止めれる。

sbin/stop-dfs.sh

YARN の設定

YARN を使うには以下の設定を書く。

etc/hadoop/mapred-site.xml:

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.application.classpath</name>
        <value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
    </property>
</configuration>

etc/hadoop/yarn-site.xml:

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_HOME,PATH,LANG,TZ,HADOOP_MAPRED_HOME</value>
    </property>
</configuration>

yarn を起動。http://localhost:8088 で WebUI が見れる。

sbin/start-yarn.sh
lxc config device add hadoop c2 proxy listen=tcp:0.0.0.0:8088 connect=tcp:127.0.0.1:8088 bind=host


こっちは無骨なデザイン。Bootstrap とかでもない。

テスト用のスクリプトを動かす。

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar grep input output 'dfs[a-z.]+'

(これってどこに output が保存されてるんだろう。)

yarn を止める。

 sbin/stop-yarn.sh

LXD 環境の後片付け

lxc stop hadoop
lxc delete hadoop

まとめ

  • Hadoop 使えば大量にパソコン用意すれば PB 級のファイルシステムとその計算環境が手に入る。
  • コマンド一発で監視用の WebUI まで手に入る。
  • 今回見ただけでもシングルノードのシングルプロセス、シングルノードのマルチプロセス、Yarn を用いた処理管理など色々な種類で構成できる。
  • Java

感想

  • Hadoop の一番簡単なシングルノード構成を作るならそこまで難しくないことがわかった。(もっともっと難しいのかと思ってた。)
  • Hadoop は PB 級のデータベースが作れるんでしょって理解だったが、ファイルシステムレベルで分散するという理解になった。これだけで結構な収穫かな。構造化データだけじゃなく画像とか動画とかサーバのログとか非構造なデータも突っ込んでおけるのは楽しそう。(結局 S3 に突っ込んでおいて EMR で処理するのが最強なのかもしれんが)
  • MapReduce を用いたプログラミングはまだわかっていない。それがわかった後ぐらいに Yarn の理解が進むのかな。
  • コンテナとの親和性もよくわからない。大量にサーバを管理する以上コンテナは有効な気はするけどね。真面目に k8s の勉強もしないとな。
  • Hadoop の 1 系と 2 系はかなり違うとか聞いたけど、Hadoop の 3 系は何か大きな変化はあったのかな。
  • Hadoop エコシステムはかなり膨大だなぁ。関数型言語が好きなので Scala + Spark は楽しそう。そのへんまでは登りたい。
  • 次は複数コンテナ建ててマルチノード Hadoop クラスタの設定でもしようかな。

追記メモ1

parquet とか Delta Lake とかで、Hadoop 上で表を保存できる。
Delta Lake 使えば ACID の表を使える。

Discussion