1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Hadoop Cluster Setup(CDHではなく本家)

Posted at

Hadoopの事を理解するために、CDHなどのディストリビューションではなく、本家のHadoopでClusterをセットアップしてみます。
また、データ保存先にHDFSではなくIDCFクラウドのオブジェクトストレージを設定してみます。(hadoop ClusterもIDCFクラウド上に構築します。)
なお、今回のセットアップはNon-Secure Modeとよばれる、認証や暗号化なしのセットアップとなります。(参考: Secure Mode、ケルベロス認証を使うようななので、敷居高いですね。。。私もまだ試せていません。)

私もまだよくわかっていない部分も多く、間違っている部分もあるかもしれませんので、あしからず。(基本的には自分のためのメモです。)

参考URL: Hadoop Cluster Setup
参考URL: Integration with Amazon Web Services

環境準備

  • CentOS 7.2.1511
  • java-1.7.0-openjdk-1.7.0.99-2.6.5.0.el7_2.x86_64 (CentOS付属)
  • hadoop-2.7.2

javaはHadoop Java Versionsにて、Testedバージョンが公開されています。今回は、まぁ、動けばいいや、なのでCentOS付属のOpenJDKで動かしています。

デーモンとサーバ台数

  • HDFSのデーモン
    • NameNode : ファイルシステムのmetadataと実際にデータを格納するDataNodeの管理を行います。
    • SecondaryNameNode : NameNodeのMetaDataのメンテナンスを行います。
    • DataNode : 実際のデータを保持します。データは一定のサイズに分割され、複数のDataNodeへ保存されます。
  • YARNのデーモン
    • ResourceManager : クライアントから受けとったジョブを管理して各NodeManage上で実行します。
    • NodeManager : 実際にジョブを実行する計算ノードです。
    • WebAppProxy : 各WebUIの為のproxy?(あまりちゃんと調べてない。)
  • MapReduceのデーモン
    • MapReduce Job History Server : MapReduceのジョブのヒストリーを管理します。

すべてのデーモンを別々のサーバで動かすこともできます。
今回は、次のようにしようと思います。

  • Server1 : NameNode, SecondaryNameNode
  • Server2 : ResourceManager, WebAppProxy, MapReduce Job History Server
  • Server3 : DataNode1, NodeManager1
  • Server4 : DataNode2, NodeManager2
  • Server5 : DataNode3, NodeManager3
  • Server6 : Client

本来はNameNode, SecondaryNameNodeは分けるべきですが、今回はこれで。
せっかくなので、NodeManagerは3台用意しています。余裕のある方は、全部を個別のサーバにインストールしてみても良いかもしれません。

ところで、NameNodeとDataNodeはIDCFクラウドのオブジェクトストレージを代わりに使うので不要そうですが、現状ではMapReduce Job History Serverがhdfsにしか対応していないようで、NameNodeとDataNodeを完全になくすことはできないようです。どうやら、このバージョンのs3aはAbstractFileSystemとして実装されていないから、という事のようです。(良くわかっていないので、嘘かもしれないが。)こちらに差し替えることで行けるっぽいけど、試していません。

サーバの準備

すべてのサーバで実行する形になります。

CentOS 7.2サーバの準備

まずは、CentOS7.2のサーバを準備してください。IDCF Cloudであれば、テンプレートから5台起動し、yum updateしてください。

JAVAのインストール

次に、Javaのインストールを行います。jpsコマンドを使いたいので、Develも入れましょう。

openjdkインストール
# yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel

hadoopの展開

/usr/localへ展開しておきます。また、/usr/loca/hadoopへリンクを張っておきます。

# cd /usr/local
# tar zxvf ~/hadoop-2.7.2.tar.gz
# ln -s hadoop-2.7.2 hadoop

s3a関連jarファイルのコピー

HDFSの代わりにIDCFクラウドのオブジェクトストレージを利用するためにはs3a(AWS S3)のモジュールを利用します。これらをhdfsのlibディレクトリへコピーしておきます。

# cd /usr/local/hadoop-2.7.2/share/hadoop/tools/lib/
# cp -a hadoop-aws-2.7.2.jar aws-java-sdk-1.7.4.jar jackson-core-2.2.3.jar jackson-databind-2.2.3.jar jackson-annotations-2.2.3.jar /usr/local/hadoop-2.7.2/share/hadoop/hdfs/lib/

環境変数の設定

JAVA_HOME, HADOOP_CONF_DIR, HADOOP_CLASSPATHを設定します。

環境変数の設定
# vi /usr/local/hadoop/etc/hadoop/hadoop-env.sh

# The java implementation to use.
#export JAVA_HOME=${JAVA_HOME}
export JAVA_HOME=/usr/lib/jvm/jre

# The jsvc implementation to use. Jsvc is required to run secure datanodes
# that bind to privileged ports to provide authentication of data transfer
# protocol.  Jsvc is not required if SASL is configured for authentication of
# data transfer protocol using non-privileged ports.
#export JSVC_HOME=${JSVC_HOME}

#export HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-"/etc/hadoop"}
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop

sshの設定

localhostへパスフレーズ無しでsshログイン出きるように、パスフレーズ無しのKeyを作り、authorized_keysへ登録します。

パスフレーズ無しのKeyを作り、authorized_keysへ登録する。
# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/tmp/id_rsa.
Your public key has been saved in /var/tmp/id_rsa.pub.
The key fingerprint is:
c4:38:39:76:d4:c3:5f:d1:29:60:84:a0:32:1f:ea:dc root@hdp1.csdidcfcloud.internal
The key's randomart image is:
+--[ RSA 2048]----+
|       .ooo+. .o.|
|      .= .=  ....|
|   o o* +  o ..  |
|    =..=    .    |
|   . .  S        |
|  o .            |
|   o E           |
|                 |
|                 |
+-----------------+

# cat .ssh/id_rsa.pub >> .ssh/authorized_keys

# ssh localhost    <= パスフレーズ聞かれずにloginできればOK

確認

確認
# hadoop version
Hadoop 2.7.2
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r b165c4fe8a74265c792ce23f546c64604acf0e41
Compiled by jenkins on 2016-01-26T00:08Z
Compiled with protoc 2.5.0
From source with checksum d0fda26633fa762bff87ec759ebe689c
This command was run using /usr/local/hadoop-2.7.2/share/hadoop/common/hadoop-common-2.7.2.jar

Hadoopの設定

基本的には、すべてのサーバで同様の設定を行います。ここでは、クライアントとなるServer6でも同様の設定をしてください。

  • core-site.xml : 全体的な設定
  • hdfs-site.xml : NameNode, DataNodeの設定
  • yarn-site.xml : ResourceManager, NodeManagerの設定
  • mapred-site.xml : MapReduce Applications, MapReduce JobHistory Serverの設定

これらは、/usr/local/hadoop/etc/hadoop/配下に配置してください。(デフォルトで、空の設定ファイルが存在するはずです。)

core-site.xml

core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdp1.csdidcfcloud.internal:9000</value>
    </property>
    <property>
      <name>fs.s3a.access.key</name>
      <value>XXXXXXXXXXXXXXXXXXXX</value>
    </property>
    <property>
      <name>fs.s3a.secret.key</name>
      <value>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</value>
    </property>
    <property>
      <name>fs.s3a.endpoint</name>
      <value>ds.jp-east.idcfcloud.com</value>
    </property>
</configuration>
  • fs.defaultFSにはデフォルトのFSを指定します。NameNodeを指定することになります。IDCFクラウドのオブジェクトストレージを指定したいところですが、前述の通り、MapReduce Job History Serverが起動できなくなります。また、NameNodeやDataNodeもhdfsを指定する必要があります。(これは当たり前かもしれないが。)
  • fs.s3a.access.key,fs.s3a.secret.keyにはIDCFクラウドのオブジェクトストレージのAPI Keyを指定します。
  • fs.s3a.endpointにはIDCFクラウドのオブジェクトストレージのエンドポイントを指定します。

hdfs-site.xml

hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///var/lib/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///var/lib/dfs/data</value>
    </property>
</configuration>
  • dfs.namenode.name.dirにはNameNodeのデータが格納されるディレクトリを指定します。NameNode上で指定したディレクトリにファイルが作成されることになります。
  • dfs.datanode.data.dirにはDataNodeのデータが格納されるディレクトリを指定します。DataNode上で指定したディレクトリにファイルが作成されることになります。

yarn-site.xml

yarn-site.xml
<?xml version="1.0"?>

<configuration>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hdp2.csdidcfcloud.internal</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.web-proxy.address</name>
        <value>hdp2.csdidcfcloud.internal:9046</value>
    </property>
</configuration>
  • yarn.resourcemanager.hostnameにはResourceManagerのアドレスを記載します。DataNodeが接続しに行く先になります。
  • yarn.nodemanager.aux-servicesには、まだ良くわかっていないのですが、Map ReduceアプリケーションにはShuffle serviceなるものが必要らしい。その設定。
  • yarn.web-proxy.addressはWebAppProxyの為の設定で、アドレスを記載します。(すいません、WebAppProxyも良くわかってない。)

mapred-site.xml

mapred-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>
  • mapreduce.framework.nameはMapReduceの処理にYARNを使うという設定(だと思う。)

Hadoop Clusterの起動

hdfsのフォーマット

Server1で実行。(フォーマットはNameNodeの処理なので。)
hdfsは最初にフォーマットする必要があります。

# hdfs namenode -format
16/04/11 11:35:55 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = hdp1.csdidcfcloud.internal/10.13.0.104

<<snip>>

16/04/11 11:35:57 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at hdp1.csdidcfcloud.internal/10.13.0.104
************************************************************/

NameNode, SecondaryNameNodeの起動

Server1で実行。
次にNameNode, SecondaryNameNodeを起動します。

# hadoop-daemon.sh  start namenode
starting namenode, logging to /usr/local/hadoop-2.7.2/logs/hadoop-root-namenode-hdp1.csdidcfcloud.internal.out

# hadoop-daemon.sh  start secondarynamenode
starting secondarynamenode, logging to /usr/local/hadoop-2.7.2/logs/hadoop-root-secondarynamenode-hdp1.csdidcfcloud.internal.out

# jps
16813 SecondaryNameNode
16723 NameNode

DataNodeの起動

Server3,4,5,で実行。
次に、DataNodeを起動します。

# hadoop-daemon.sh start datanode
starting datanode, logging to /usr/local/hadoop-2.7.2/logs/hadoop-root-datanode-hdp3.csdidcfcloud.internal.out

# jps
9349 DataNode

これで、HDFSのデーモンであるNameNodeとDataNodeが起動できたので、HDFSとしては利用可能です。

ResourceManagerの起動

Server2で実行。
次にResourceManagerを起動します。

# yarn-daemon.sh start resourcemanager
starting resourcemanager, logging to /usr/local/hadoop-2.7.2/logs/yarn-root-resourcemanager-hdp2.csdidcfcloud.internal.out

# jps
20402 ResourceManager

NodeManagerの起動

Server3,4,5,で実行。
次にNodeManagerを起動します。

# yarn-daemon.sh start nodemanager
starting nodemanager, logging to /usr/local/hadoop-2.7.2/logs/yarn-root-nodemanager-hdp3.csdidcfcloud.internal.out

# jps
9349 DataNode
9477 NodeManager

WebAppProxyの起動

Server2で実行。
次にWebAppProxyを起動します。

# yarn-daemon.sh start proxyserver
starting proxyserver, logging to /usr/local/hadoop-2.7.2/logs/yarn-root-proxyserver-hdp2.csdidcfcloud.internal.out

# jps
20681 WebAppProxyServer
20402 ResourceManager

MapReduce JobHistory Serverの起動

Server2で実行。
次にMapReduce JobHistory Serverを起動します。

# mr-jobhistory-daemon.sh start historyserver
starting historyserver, logging to /usr/local/hadoop-2.7.2/logs/mapred-root-historyserver-hdp2.csdidcfcloud.internal.out

# jps
20681 WebAppProxyServer
20756 JobHistoryServer
20402 ResourceManager

全デーモン

これで、全てのデーモンをすべてのサーバで起動しました。Hadoop Clusterとして動いているはずです。

Server1
# jps
16813 SecondaryNameNode
16723 NameNode
Server2
# jps
20402 ResourceManager
20681 WebAppProxyServer
20756 JobHistoryServer
Server3
# jps
9349 DataNode
9477 NodeManager
Server4
# jps
19123 DataNode
19243 NodeManager
Server5
# jps
8726 DataNode
8843 NodeManager

ユーザディレクトリの作成

空のバケットの場合アクセスに失敗しまうようなので、dummy.txtなどなんでも良いのでファイルを一つ置いておきます。(重要)

どうやら、相対パスを指定した場合、/user/<username>がデフォルトで使用されるようですので、あらかじめ作成しておきます。(ただ、今回はs3a://を使うので、これ以降の説明では絶対パスを指定しています。)

# hdfs dfs -ls /
Found 2 items
-rw-rw-rw-   1          6 2016-04-11 13:34 /dummy.txt

# hdfs dfs -mkdir /user

# hdfs dfs -mkdir /user/root

# hdfs dfs -ls /user/root

# hdfs dfs -ls /
Found 2 items
-rw-rw-rw-   1          6 2016-04-11 13:34 /dummy.txt
drwxrwxrwx   -          0 1970-01-01 09:00 /user

動かしてみよう

Server6のClientでサンプルのMapReduceアプリケーションを動かしてみましょう。
このアプリケーションは、指定したディレクトリのファイルのワードをカウントするアプリケーションです。

サンプルの実行

それでは、ようやくサンプルのワードをカウントのアプリケーションを実行してみましょう。

インプットファイルの準備

まだでした。ワードカウントするファイル群をIDCFクラウドのオブジェクトストレージへアップロードします。

# hdfs dfs -put /usr/local/hadoop s3a://hadoop-idcf1/user/root/input

# hdfs dfs -ls s3a://hadoop-idcf1/user/root/input/
Found 29 items
-rw-rw-rw-   1       4436 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/capacity-scheduler.xml
-rw-rw-rw-   1       1335 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/configuration.xsl
-rw-rw-rw-   1        318 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/container-executor.cfg
-rw-rw-rw-   1        774 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/core-site.xml
-rw-rw-rw-   1       3670 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hadoop-env.cmd
-rw-rw-rw-   1       4224 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hadoop-env.sh
-rw-rw-rw-   1       2490 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hadoop-metrics.properties
-rw-rw-rw-   1       2598 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hadoop-metrics2.properties
-rw-rw-rw-   1       9683 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hadoop-policy.xml
-rw-rw-rw-   1        775 2016-04-11 14:26 s3a://hadoop-idcf1/user/root/input/hdfs-site.xml
-rw-rw-rw-   1       1449 2016-04-11 14:25 s3a://hadoop-idcf1/user/root/input/httpfs-env.sh
-rw-rw-rw-   1       1657 2016-04-11 14:25 s3a://hadoop-idcf1/user/root/input/httpfs-log4j.properties
-rw-rw-rw-   1         21 2016-04-11 14:25 s3a://hadoop-idcf1/user/root/input/httpfs-signature.secret
-rw-rw-rw-   1        620 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/httpfs-site.xml
-rw-rw-rw-   1       3518 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/kms-acls.xml
-rw-rw-rw-   1       1527 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/kms-env.sh
-rw-rw-rw-   1       1631 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/kms-log4j.properties
-rw-rw-rw-   1       5511 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/kms-site.xml
-rw-rw-rw-   1      11237 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/log4j.properties
-rw-rw-rw-   1        951 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/mapred-env.cmd
-rw-rw-rw-   1       1383 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/mapred-env.sh
-rw-rw-rw-   1       4113 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/mapred-queues.xml.template
-rw-rw-rw-   1        758 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/mapred-site.xml.template
-rw-rw-rw-   1         10 2016-04-11 14:24 s3a://hadoop-idcf1/user/root/input/slaves
-rw-rw-rw-   1       2316 2016-04-11 14:23 s3a://hadoop-idcf1/user/root/input/ssl-client.xml.example
-rw-rw-rw-   1       2268 2016-04-11 14:23 s3a://hadoop-idcf1/user/root/input/ssl-server.xml.example
-rw-rw-rw-   1       2250 2016-04-11 14:23 s3a://hadoop-idcf1/user/root/input/yarn-env.cmd
-rw-rw-rw-   1       4567 2016-04-11 14:23 s3a://hadoop-idcf1/user/root/input/yarn-env.sh
-rw-rw-rw-   1        690 2016-04-11 14:23 s3a://hadoop-idcf1/user/root/input/yarn-site.xml

やっと実行

# hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar grep s3a://hadoop-idcf1/user/root/input s3a://hadoop-idcf1/user/root/output 'dfs[a-z.]
16/04/11 14:34:52 INFO client.RMProxy: Connecting to ResourceManager at hdp2.csdidcfcloud.internal/10.13.0.5:8032
16/04/11 14:35:03 INFO input.FileInputFormat: Total input paths to process : 29
16/04/11 14:35:03 INFO mapreduce.JobSubmitter: number of splits:29
16/04/11 14:35:03 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1460342739299_0002
16/04/11 14:35:03 INFO impl.YarnClientImpl: Submitted application application_1460342739299_0002
16/04/11 14:35:03 INFO mapreduce.Job: The url to track the job: http://hdp2.csdidcfcloud.internal:9046/proxy/application_1460342739299_0002/
16/04/11 14:35:03 INFO mapreduce.Job: Running job: job_1460342739299_0002
16/04/11 14:35:14 INFO mapreduce.Job: Job job_1460342739299_0002 running in uber mode : false
16/04/11 14:35:14 INFO mapreduce.Job:  map 0% reduce 0%
16/04/11 14:35:30 INFO mapreduce.Job:  map 7% reduce 0%
16/04/11 14:35:50 INFO mapreduce.Job:  map 10% reduce 0%

<< snip >>
# hdfs dfs -cat s3a://hadoop-idcf1/user/root/output/part-r-00000
6       dfs.audit.logger
4       dfs.class
3       dfs.server.namenode.
2       dfs.period
2       dfs.audit.log.maxfilesize
2       dfs.audit.log.maxbackupindex
1       dfsmetrics.log
1       dfsadmin
1       dfs.servers
1       dfs.file

雑感とメモ

  • とりあえず、動いたって感じ。Hadoop難しい。
  • MapReduce Job History Serverを起動する為にはHDFSが必要。
  • MapReduce Applicationを動かす時にテンポラリの書き込み?で、HDFSが必要っぽい。
  • これらは、2.8.0で解消されそうなので2.8.0ではNameNodeとDataNodeを停止できるかもしれない。(HDFS使わずにIDCFクラウドのオブジェクトストレージつかうなら、是非止めたい。)
  • s3a経由でIDCFクラウドのオブジェクトストレージを利用すると、かなり遅い気がする。設定で隠蔽できるのかは、まだわからない。
  • そもそもHDFSの代わりにS3ってどうなんでしょう?HDFSで大量のサーバ束ねるのよりも、遅くなってしまうのではないのかな?
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?