CentOSでHadoopとHiveを試してみる（2015年秋編）


###やりたいこと

Hadoopファミリーは日々進化しますが、とはいえ、MapReduceとHiveのニーズは不滅です。現行（最新）かつ素のHadoopとHiveをCentOS上に構築して動作確認してみます。

##環境

* CentOS6.7（7でも基本同じ:手元にイメージがあっただけ・・・）
* Hadoop 2.7.1
* Hive 1.2.1

##準備

###OS

CentOS6.7をMinimal構成でインストールした後、

* yum update
* yum groupinstall 'Development tools'
* yum install wget

を実行した状態。テスト自体は、VMWareFusion8上で行っているが、多分依存などは無い。

###ssh

疑似分散モードを利用するためには、ssh localhostでパスフレーズ無しでログインできるようにしておく必要があります。

```bash
mkdir .ssh
chmod 700 .ssh
cd .ssh
ssh-keygen -t rsa
cp id_rsa.pub authorized_keys
chmod 600 *
```
とでもしておけばよいでしょう。

###Java

HadoopはJavaアプリなのでJava(JDK)のインストールが必要。
ここでは、OracleのJava8を入れた。wgetでrpmを取得し、インストール。

```bash
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.rpm

rpm -ivh jdk-8u66-linux-x64.rpm
```
Javaは、/usr/java/jdk1.8.0_66にインストールされる。PATHはインストーラが通してくれるみたいだが、JAVA_HOMEの設定はされないので手動で行う。

JAVA_HOMEに設定は、Hadoopの事項において必須のようだ。

.bashrcをいじり、sourceで反映させておく。

```bash
export JAVA_HOME=/usr/java/jdk1.8.0_66
source .bashrc
```

>.bash_profileではなく、.bashrcに書くほうが無難なようです。

##Hadoop

Hadoopは疑似分散モードで構成します。

###インストール
ここでは、Apache Hadoopサイトから最新版を取得してインストールしてみます。

```bash
wget http://ftp.riken.jp/net/apache/hadoop/common/hadoop-2.7.1/hadoop-2.7.1.tar.gz 
tar -xzvf hadoop-2.7.1.tar.gz 
mv hadoop-2.7.1 /usr/
```

解凍したものを、/usr/hadoop-2.7.1としてmvします。

###HADOOP_HOMEとPATHの設定
.bashrcに、下記を追加し、反映させます。

```bash
export HADOOP_HOME=/usr/hadoop-2.7.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$JAVA_HOME/bin:$PATH
source .bashrc
```

ここまでの設定で、一応hadoop（クライアント）自体は動きます。

```bash
hadoop version
```
バージョンが表示されればOKです。

###設定ファイルの編集
設定ファイルを編集します。編集するファイルは、

* core-site.xml
* hdfs-site.xml
* yarn-site.xml

の３つです。
場所は、$HADOOP_HOME/etc/hadoop以下にあります。
yarn-site.xmlは用途によります。

設定は、Apache Hadoopサイトの例のまんま。

core-site.xml

```xml
<configuration>
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://localhost:9000</value>
        </property>
</configuration>
```
hdfs-site.xml

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

yarn-site.xml

```xml
<configuration>
	<property>
		<name>yarn.nodemanager.aux-services</name>
		<value>mapreduce_shuffle</value>
	</property>
	<property>
		<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
		<value>org.apache.hadoop.mapred.ShuffleHandler</value>
	</property>
</configuration>
```

以上で、設定は終わりました。
###Namenodeの初期化

準備ができたので、初期化処理をします。HDFS等が設定されます。

```bash
hadoop namenode -format
```

起動のための準備が整いました。

###諸々起動

```bash
start-dfs.sh
```

>起動時にワーニング出ますが、動作には問題ないようです。
WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform...
あと、start-all.shは非推奨とのこと。


起動しているかの確認は、

```bash
jps

4290 SecondaryNameNode
4131 DataNode
4533 NodeManager
4440 ResourceManager
4013 NameNode
4847 Jps
```

停止は、

```bash
stop-dfs.sh
```
でできます。

###WordCountを実行してみる（動作確認）

まず、カウント用のテストファイルを生成し、それをローカルファイルシステムからHDFSにコピーしてみます。

```bash
echo "a b c a" > test.txt
```
コピーする先のディレクトリをHDFS上に作成します。

```bash
hadoop fs -mkdir /input
hadoop fs -ls /
drwxr-xr-x   - root supergroup          0 2015-11-13 20:51 /input
```

inputディレクトリができています。

>ここでも、WARN util.NativeCodeLoader: Unable to ...というワーニングが出ますが、動作には問題無いようです。

test.txtをコピーします。

```bash
hadoop fs -put test.txt /input
hadoop fs -ls -R /
drwxr-xr-x   - root supergroup          0 2015-11-13 20:53 /input
-rw-r--r--   1 root supergroup          8 2015-11-13 20:53 /input/test.txt
hadoop fs -cat /input/test.txt
a b c a
```
どうやらうまくコピーできたようです。

>-ls　-Rとすると再帰的にフォルダの中身が表示されます。

では、WordCountを実行してみます。

```bash
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar wordcount /input /output

hadoop fs -ls -R /
drwxr-xr-x   - root supergroup          0 2015-11-13 20:53 /input
-rw-r--r--   1 root supergroup          8 2015-11-13 20:53 /input/test.txt
drwxr-xr-x   - root supergroup          0 2015-11-13 20:55 /output
-rw-r--r--   1 root supergroup          0 2015-11-13 20:55 /output/_SUCCESS
-rw-r--r--   1 root supergroup         12 2015-11-13 20:55 /output/part-r-00000
```

/output/part-r-00000が出力ファイルです。中身を見てみます。

```bash
hadoop fs -cat /output/part-r-00000

a	2
b	1
c	1
```
期待の結果が得られました。

##Hive

HadoopファミリーのコアであるHadoopやHDFSが問題無く動いているようなので、Hiveもセットアップしてみます。

###インストール

Hadoopと同じくHiveのサイトからwgetと取得します。

```bash
wget http://ftp.riken.jp/net/apache/hive/hive-1.2.1/apache-hive-1.2.1-bin.tar.gz
tar -xzvf apache-hive-1.2.1-bin.tar.gz
apache-hive-1.2.1-bin /usr/hive-1.2.1
```

HIVE_HOMEとPATHの設定をします。

```bash
export HIVE_HOME=/usr/hive-1.2.1
export PATH=$PATH:$HIVE_HOME/bin
souce .bashrc
```

動作の確認をしてみます。hiveと入力し、hive>プロンプトがでれば基本OKです。

```bash
hive

hive>show databases;
OK
default
Time taken: 0.825 seconds, Fetched: 1 row(s)
```

###簡単なテスト

####データの準備

ビックデータと呼ぶには程遠い、下記のようなファイル(data.csv)を用意ます。

```text
新橋店,100
新宿店,340
池袋店,874
渋谷店,400
```

>Hiveは問題なく日本語を処理できますが、形式はUTF-8が良いでしょう。

####データベースとテーブルの準備

これを扱うデータベースとテーブルをHive上に作成します。

```bash
hive> create database testdb;
hive> use testdb;
hive> create table sales(shop string,sales int) row format delimited fields terminated by ',';
desc sales;
OK
shop                	string
sales               	int
Time taken: 0.471 seconds, Fetched: 2 row(s)
```
MySQLを利用しているのとほぼ感覚は変わりませんね。

####データの読込

```bash
hive> load data local inpath "/root/data.csv" into table sales;
```

うまくいったら、selectをしてみましょう。

```bash
select * from sales;
OK
新橋店	100
新宿店	340
池袋店	874
渋谷店	400
	NULL
Time taken: 0.311 seconds, Fetched: 5 row(s)
```

いいですね。日本語もバッチリです。
likeもOK。

```bash
select * from sales where shop like '新%';
OK
新橋店	100
新宿店	340
Time taken: 0.155 seconds, Fetched: 2 row(s)
```

SumもOK。

```bash
select sum(sales) from sales;

OK
1714
Time taken: 2.21 seconds, Fetched: 1 row(s)
```
この程度のデータとSQLなら、普通のRDBの方が高速ですが、ひとまず動作確認ということで。

####処理結果のファイルへの出力

Hiveはインタラクティブに利用するというよりも、最終的な処理を担うDWHやSparkなどに値を渡してやることが多いと思うので、結果をファイルに出力してみます。

```bash
hive>
    > insert overwrite directory '/output/'
    > select * from sales;
```

insert~分で出力先を指定した後、クエリを実行します。
出力結果を見てみます。

```bash
hadoop fs -cat /output/000000_0
新橋店100
新宿店340
池袋店874
渋谷店400
\N
```
いちおう出力はされています。

####Update, Delete

HiveQLには、UpdateやDeleteは存在しない。

####hiveを終了させる

```bash
hive> exit;
```
で、コンソールから抜けられます。