Hadoopを動かしてみる

Hadoopの勉強をしとく必要があったので

##Hadoopとは
ビッグデータを複数ノードで分散処理するためのオープンソースソフトウェア

## 目標
hadoopをstandalone,Fully-distributedモデルで起動する

以下参照
https://hadoop.apache.org/docs/r2.8.5/hadoop-project-dist/hadoop-common/SingleCluster.html
https://hadoop.apache.org/docs/r2.8.5/hadoop-project-dist/hadoop-common/ClusterSetup.html

## 基本情報
VirtualBoxで以下を構築

- OS: Ubuntu 18.04
- ノード構成

|ホスト名  |HDFS  |YARN  |MapReduce  |
|:------:|:----:|:----:|:----:|
|node1   |namenode|resourcemanager|job history server|
|node2   |secondary namenode,datanode|nodemanager|-|
|node3   |datanode|nodemanager|-|
|node4   |datanode|nodemanager|-|

- Hadoop: 2.8.5

## 環境構築

### サーバ準備

- VirtualBoxの「ファイル」-「ホストネットワークマネージャ」を開き、新規ホストネットワークアダプタを作成(仮想サーバにホストオンリーアダプタを追加するために必要)
- 仮想サーバを作成
    - 起動ディスク:ubuntu-ja-18.04.1-desktop-amd64.iso
    - 仮想サーバのネットワークアダプタは以下の通り
        - アダプター1:NAT
        - アダプター2:ホストオンリーアダプタ(追加)
- sshインストール
    - `$ sudo apt-get install aptitude`
    - `$ sudo apt-get install aptitude`
    - `$ sudo /etc/init.d/ssh restart`
- IPアドレス固定
    - 修正ファイル：/etc/netplan/01-network-manager-all.yaml
    - sudo netplan applyで変更を有効化 再起動不要

```shell:/etc/netplan/01-network-manager-all.yaml

# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager

  ethernets:
    enp0s8:
      dhcp4: n
      addresses: [192.168.56.10/24]
```

- javaインストール
    - `$ sudo apt-get install default-jre`
    - `$ sudo apt install default-jdk`
- node1をクローンしてnode[2-4]を構築
    - IPアドレス修正
        - /etc/netplan/01-network-manager-all.yaml
    - hostname修正
        - `$ sudo hostnamectl set-hostname ホスト名`

### Hadoopインストール
- Hadoopをダウンロード、展開

`$ wget https://www-eu.apache.org/dist/hadoop/common/hadoop-2.8.5/hadoop-2.8.5.tar.gz`
`$ tar xzvf hadoop-2.8.5.tar.gz`

hadoop-env.shを修正し、JAVA_HOMEにjdkのパスを指定する

```shell:hadoop-2.8.5/etc/hadoop/hadoop-env.sh
# set to the root of your Java installation
  export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
```

- インストール確認
    - `$ hadoop-2.8.5/bin/hadoop`
    - usageが表示されたらOK

### Standalone Operation
まずはnode1のみでhadoopを動かすstandalone operationを試します

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

以下のように表示されればOK

```
1	dfsadmin
```

### Fully distributed operation
次は完全分散モードを試します。

#### HDFSサービス設定

HDFSのNameNodeとしてnode1サーバを指定する

```shell:etc/hadoop/core-site.xml
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://node1:9000/</value>
  </property>
</configuration>
```

HDFSのレプリケーション数を指定する
HDFSのSecondaryNameNodeとしてnode2を指定する

```shell:etc/hadoop/hdfs-site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
　　　　　　　　　<property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>node2:50090</value>
    </property>
</configuration>
```

- すべてのホストにnode1からパスフレーズなしでログインできるよう公開鍵を配置しておく

`$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa`
`$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys`
`$ chmod 0600 ~/.ssh/authorized_keys`
`$ scp -p ~/.ssh/authorized_keys node2:/home/$USER/.ssh/`
`$ scp -p ~/.ssh/authorized_keys node3:/home/$USER/.ssh/`
`$ scp -p ~/.ssh/authorized_keys node4:/home/$USER/.ssh/`

HDFSのdatanodeを起動するサーバを指定する

```shell:etc/hadoop/slaves
node2
node3
node4
```

#### YARN

etc/hadoop/mapred-site.xml.templateをコピーして上記ファイルを作成
MapReduceのフレームワークとしてYARNを指定する

```shell:etc/hadoop/mapred-site.xml 
<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
</configuration>
```

YARNがmapreduceのshuffleを使うよう指定
YARNのResourceManagerとしてnode1を指定

```shell:etc/hadoop/yarn-site.xml
<configuration>
  <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
  </property>
  <property>
      <name>yarn.resourcemanager.hostname</name>
      <value>node1</value>
  </property>
</configuration>
```

- 設定ファイルをnode2,node3,node4にコピーする

`HADOOP_HOME=$(pwd)`
`$ for n in node2 node3 node4 ; do scp \$HADOOP_HOME/etc/hadoop/* \$n:$HADOOP_HOME/etc/hadoop/
done`

#### Hadoop起動

- HDFSフォーマット

`$ bin/hdfs namenode -format`

以下のように聞かれるのでy

```
Re-format filesystem in Storage Directory /tmp/hadoop-$USER/dfs/name ? (Y or N) y
```

- Hadoop各サービス起動

#####HDFS

`sbin/start-dfs.sh`

node1でnamenode
node2でsecondarynamenode
node2,3,4でdatanodeが起動します。

以下のコマンドで実行しているサービスを確認

`$ jps`

```shell:node1
4544 Jps
4300 NameNode
```

```shell:node2
3239 Jps
3032 DataNode
3194 SecondaryNameNode
```

```shell:node3,node4
2643 Jps
2563 DataNode
```

#####YARN

`$ sbin/start-yarn.sh`

node1でResourceManager
node2,3,4でNodeManagerが起動します

`$ jps`

```shell:node1
4871 Jps
4619 ResourceManager
4300 NameNode
```

```shell:node2
3425 NodeManager
3541 Jps
3032 DataNode
3194 SecondaryNameNode
```

```shell:node3,node4
2563 DataNode
2771 NodeManager
2885 Jps
```

#####MapReduce Job History

`sbin/mr-jobhistory-daemon.sh --config etc/hadoop start historyserver`

node1でJobHistoryServerが起動します

`$ jps`

```shell:node1
5073 Jps
5033 JobHistoryServer
4619 ResourceManager
4300 NameNode
```

ここまででサービスが起動するところまできました。
今後実際に構築したHadoopで処理を実行してみます