ラズパイでHadoopの疑似分散モードを試してみる

8 min read読了の目安(約7400字

環境構築周りはこちらの記事を参考

https://zenn.dev/yassh_i/articles/33d00fb94e7adb

HadoopサーバーにSSHする

1. SSHキーを作成

hadoopのサーバーアドレスの設定を記述する

下記2つのファイルに,記述内容を追記する

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>

こうなっていればよい

ここでタイプミスなどをしていると,NameNode起動の際にUnexpected~でエラーが出る

hadoop用のJAVA_HOMEを設定する

sudo vi hadoopのディレクトリ/etc/hadoop/hadoop-env.sh

文字がたくさん書かれたファイルが開かれるはず
下記を追記する

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-armhf/jre/
export PATH=$PATH:$JAVA_HOME/bin

NameNode起動

# ログがたくさん出る.SHUTDOWN_MSG: Shutting down NameNode at raspberrypi/127.0.1.1みたいなのが出ればOK
hadoopのディレクトリ/bin/hdfs namenode -format

# 出力結果は下記
hadoopのディレクトリ/sbin/start-dfs.sh
hadoop@raspberrypi:~/hadoop-3.2.2 $ sbin/start-dfs.sh
Starting namenodes on [localhost]
Starting datanodes
Starting secondary namenodes [raspberrypi]
OpenJDK Client VM warning: You have loaded library /home/hadoop/hadoop-3.2.2/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
2021-01-26 22:00:35,106 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

NameNodeにアクセス

SSHしているなら,同じWiFiに接続している状態でhttp://ラズパイのローカルIP(192.168.~):9870にアクセスする.
ラズパイ本体でブラウザを使用できる場合は,http://localhost:9870でOK

アクセスできました

Tips:Hadoopのログ

Hadoopのディレクトリのlogs/に入っています
こんな感じ

hadoop@raspberrypi:~/hadoop-3.2.2 $ head logs/hadoop-hadoop-namenode-raspberrypi.log
2021-01-26 22:00:22,140 INFO org.apache.hadoop.hdfs.server.namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = raspberrypi/127.0.1.1
STARTUP_MSG:   args = []
STARTUP_MSG:   version = 3.2.2
STARTUP_MSG:   classpath = /home/hadoop/hadoop-…たくさん(改行されていないからheadが意味なかった)
STARTUP_MSG:   build = Unknown -r 7a3bc90b05f257c8ace2f76d74264906f0f7a932; compiled by 'hexiaoqiao' on 2021-01-03T09:26Z
STARTUP_MSG:   java = 1.8.0_212
************************************************************/

MapReduceジョブに必要なHDFSディレクトリを作成する

下記コマンドで作成可能

hadoop@raspberrypi:~/hadoop-3.2.2 $ bin/hdfs dfs -mkdir /user
hadoop@raspberrypi:~/hadoop-3.2.2 $ bin/hdfs dfs -mkdir /user/hadoop

こんな警告がいちいち出てきます.OpenJDKを入れたのが原因がわかりませんが,デバッグレベルなら気にしなくていい警告みたいです

OpenJDK Client VM warning: You have loaded library /home/hadoop/hadoop-3.2.2/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
2021-01-26 22:18:34,110 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

Userフォルダにジョブ用のフォルダを作成する

先頭の記事で作成済みのものを,Userフォルダの中に作成します

hadoop@raspberrypi:~/hadoop-3.2.2 $ bin/hdfs dfs -mkdir input
hadoop@raspberrypi:~/hadoop-3.2.2 $ bin/hdfs dfs -put etc/hadoop/*.xml input
この段落をスルーして,前のコマンドでええんやろ!てやるとこういうエラーが出ます
2021-01-26 22:25:05,242 INFO impl.MetricsConfig: Loaded properties from hadoop-metrics2.properties
2021-01-26 22:25:05,443 INFO impl.MetricsSystemImpl: Scheduled Metric snapshot period at 10 second(s).
2021-01-26 22:25:05,443 INFO impl.MetricsSystemImpl: JobTracker metrics system started
2021-01-26 22:25:06,003 INFO mapreduce.JobSubmitter: Cleaning up the staging area file:/tmp/hadoop/mapred/staging/hadoop541450179/.staging/job_local541450179_0001
org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input path does not exist: hdfs://localhost:9000/user/hadoop/input
        at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:332)
        at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:274)
        at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits(FileInputFormat.java:396)
        at org.apache.hadoop.mapreduce.JobSubmitter.writeNewSplits(JobSubmitter.java:310)
        at org.apache.hadoop.mapreduce.JobSubmitter.writeSplits(JobSubmitter.java:327)
        at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:200)
        at org.apache.hadoop.mapreduce.Job$11.run(Job.java:1565)
        at org.apache.hadoop.mapreduce.Job$11.run(Job.java:1562)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1762)
        at org.apache.hadoop.mapreduce.Job.submit(Job.java:1562)
        at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1583)
        at org.apache.hadoop.examples.Grep.run(Grep.java:78)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76)
        at org.apache.hadoop.examples.Grep.main(Grep.java:103)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.util.ProgramDriver$ProgramDescription.invoke(ProgramDriver.java:71)
        at org.apache.hadoop.util.ProgramDriver.run(ProgramDriver.java:144)
        at org.apache.hadoop.examples.ExampleDriver.main(ExampleDriver.java:74)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:323)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:236)

ユーザーを作成したらそのユーザーの場所にいろいろ作るようにされるんですかね,,,

実行成功すると以下のようなログが出ます

できたファイルを見る

HDFSシステムの中にOutputが作られているので,それをローカルに持ってきて,見ます.
下記コマンドでできます

hadoop@raspberrypi:~/hadoop-3.2.2 $ bin/hdfs dfs -get output output
hadoop@raspberrypi:~/hadoop-3.2.2 $ cat output/*
cat: output/output: ディレクトリです
1       dfsadmin

outputの中身はこうなっていました

hadoop@raspberrypi:~/hadoop-3.2.2/output $ ls
_SUCCESS  output  part-r-00000

動いている形跡

NameNode informationはこんな画面に

DataNodeがひとつできているのでそこにアクセスすると,

このようになっています.

次回は完全分散モード!と行きたいところですが,丸1日かかりそう(ハードウェア等も調達,セットアップしないとなので)です.気長にお待ちください