woshidan's blog

そんなことよりコードにダイブ。

Hadoop 3.1.1をインストールしてPseudo-Distributed Modeで動かしてみる

Java環境変数のセットアップ

$ sudo yum install java-1.8.0-openjdk

[ec2-user@ip-172-31-16-244 ~]$ sudo update-alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

$ java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
export PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/usr/java/latest/bin
# sudo update-alternatives --config java で出てきたパスに合わせてみる
export JAVA_HOME=/usr/lib/jvm/jre-1.8.0-openjdk.x86_64
export HADOOP_HOME=/home/ec2-user/hadoop

Hadoopのインストール

$ wget http://ftp.jaist.ac.jp/pub/apache/hadoop/common/hadoop-3.1.1/hadoop-3.1.1.tar.gz
$ tar xvfz hadoop-3.1.1.tar.gz
$ ln -s hadoop-3.1.1 hadoop

$ cd hadoop
[ec2-user@ip-172-31-16-244 hadoop]$  ls
bin  etc  include  lib  libexec  LICENSE.txt  NOTICE.txt  README.txt  sbin  share
[ec2-user@ip-172-31-16-244 hadoop]$ bin/hadoop
Usage: hadoop [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS]
 or    hadoop [OPTIONS] CLASSNAME [CLASSNAME OPTIONS]
  where CLASSNAME is a user-provided Java class

Pseudo-Distributed モードで動かすための設定

<!-- etc/hadoop/core-site.xml -->
<!-- fs.defaultFS には マスターノードの設定を行う
<!-- マスターノードがどのファイルシステムを使うのかをスキーマで指定したり、データノードがハートビートを送る先をIP + portで指定したりするらしい
<!-- https://stackoverflow.com/questions/36072890/what-is-the-exactly-use-of-defaultfs https://community.hortonworks.com/questions/185804/difference-between-fsdefaultfs-and-dfsnamenodehttp.html
<configuration>
+  <property>
+    <name>fs.defaultFS</name>
+    <value>hdfs://localhost:9000</value>
+  </property>
</configuration>
<!-- etc/hadoop/hdfs-site.xml -->
<!-- HadoopでHDFSを利用する場合、一つのファイル中のシークに時間がかからないようにデータをそれなりに分けて保存していて、
<!-- そういうクラスタに投入されたデータを保存しておく単位をブロックという。
<!-- そして、HDFSは耐障害性を高めるために、ブロック単位でレプリケーションを行うんですが、今回はテスト用だしレプリケーションいらないよね、という設定 -->
<!-- https://hadoop.apache.org/docs/r3.1.1/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml -->
<configuration>
+  <property>
+    <name>dfs.replication</name>
+    <value>1</value>
+  </property>
</configuration>

ローカルでネームノード、データノードを立ち上げるので、これらのssh通信用の設定

$ ssh localhost # localhostにsshで通信できないことを確認
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:0STL9JFnI81GzdikYqN2DLu4BkdtY1Bb3A7o2zzkbpw.
ECDSA key fingerprint is MD5:c5:c0:cc:69:96:23:27:90:fa:d6:6b:13:1d:cf:16:b9.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Permission denied (publickey).

$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

chmod 0600 ~/.ssh/authorized_keys

ためしにジョブを実行するための準備

$ bin/hdfs namenode -format

$ sbin/start-dfs.sh
Starting namenodes on [localhost]
Starting datanodes
Starting secondary namenodes [ip-172-31-16-244]
ip-172-31-16-244: Warning: Permanently added 'ip-172-31-16-244,172.31.16.244' (ECDSA) to the list of known hosts.

$ bin/hdfs dfs -mkdir /user
$ bin/hdfs dfs -mkdir /user/ec2-user
$ bin/hdfs dfs -put etc/hadoop input
2018-09-18 22:34:53,634 WARN hdfs.DataStreamer: Caught exception
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Thread.join(Thread.java:1252)
    at java.lang.Thread.join(Thread.java:1326)
    at org.apache.hadoop.hdfs.DataStreamer.closeResponder(DataStreamer.java:986)
    at org.apache.hadoop.hdfs.DataStreamer.endBlock(DataStreamer.java:640)
    at org.apache.hadoop.hdfs.DataStreamer.run(DataStreamer.java:810)
    ... # きになる...

exampleのGrep Jobがうまくいかなかった

$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar grep input output 'dfs[a-z.]+'
$ bin/hdfs dfs -cat output/*
$ bin/hdfs dfs -ls output/*
-rw-r--r--   1 ec2-user supergroup          0 2018-09-18 22:36 output/_SUCCESS
-rw-r--r--   1 ec2-user supergroup          0 2018-09-18 22:36 output/part-r-00000
$ bin/hdfs dfs -cat output/_SUCCESS
$ bin/hdfs dfs -cat output/part-r-00000
# 空

Hadoopを操作するユーザーの設定がよくわかってないせいかもしれないです。

exampleの円周率を計算するジョブはうまくいった

$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar pi 2 100
Job Finished in 2.099 seconds
Estimated value of Pi is 3.12000000000000000000

もともとやりたかったことはS3をバックエンドにしてHiveの素振りなので深追いはやめます*1

bin/hdfs dfs コマンドについて

refs: https://hadoop.apache.org/docs/r3.1.1/hadoop-project-dist/hadoop-hdfs/HDFSCommands.html

bin/hdfs スクリプトを利用して、HDFSコマンドを実行することができます。

bin/hdfs dfs -mkdir などで作成しているディレクトリはHDFS上のもので、通常のシェルコマンドでは検索したり開いたりできませんが、 HDFS コマンドで -ls みたいに打ち込むとHDFS上のファイルを操作することができます。

$ bin/hdfs dfs -ls output/*
-rw-r--r--   1 ec2-user supergroup          0 2018-09-18 22:36 output/_SUCCESS
-rw-r--r--   1 ec2-user supergroup          0 2018-09-18 22:36 output/part-r-00000

word-countのexampleは成功した

[ec2-user@ip-172-31-16-244 hadoop]$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar wordcount input/hadoop-env.sh wordcount-output

[ec2-user@ip-172-31-16-244 hadoop]$ bin/hdfs dfs -ls wordcount-output
Found 2 items
-rw-r--r--   1 ec2-user supergroup          0 2018-09-18 23:10 wordcount-output/_SUCCESS
-rw-r--r--   1 ec2-user supergroup      10073 2018-09-18 23:10 wordcount-output/part-r-00000
[ec2-user@ip-172-31-16-244 hadoop]$ bin/hdfs dfs -cat wordcount-output/*
"  3
"AS  1
"License");    1
"log   1
# 310
##    12
###   28
#export   1
$USER 1
${HADOOP_HOME}/logs   1
${HADOOP_OS_TYPE} 1
${HOME}/.hadooprc 1
...
wants 2
way   1
when  13
where 1
which 3
who   1
why....   1
wildcards 1
will  29
with  6
work  1
workers.sh,   1
writing   1
writing,  1
xxx-env.sh.   1
yarn  1
yet/still,    1
you   2
{YARN_xyz|HDFS_xyz}   1
{yarn-env.sh|hdfs-env.sh} 1

動いているHadoop関連のプロセスを止める

$ sbin/stop-all.sh
WARNING: Stopping all Apache Hadoop daemons as ec2-user in 10 seconds.
WARNING: Use CTRL-C to abort.
Stopping namenodes on [localhost]
Stopping datanodes
Stopping secondary namenodes [ip-172-31-16-244]
Stopping nodemanagers
Stopping resourcemanager

現場からは以上です。

*1:2.5.0で Fully-Distributed モードでGrep Jobが動かなかったらしいのでそういうこともあるかもしれないです... http://hadoop.apache.org/docs/r3.1.1/hadoop-project-dist/hadoop-common/release/2.7.0/CHANGES.2.7.0.html