LoginSignup
1
2

More than 5 years have passed since last update.

hadoop & hive & metastore on mysql & S3AFileSystem をMac上にて動かすまで

Last updated at Posted at 2017-02-19

各種バージョン

この記事の時点でのAmazon EMRは
Hadoop ディストリビューションは、Amazon 2.7.3となっていてhadoop 2.7.3で
アプリケーションは、Hive 2.1.1, Tez 0.8.4 なので極力これに近付ける

  • MacOS Sierra 10.12.3
  • Java 1.8
  • hadoop 2.7.3
  • hive 2.1.1
  • mysql 5.5.49

EMRのバージョンと関連バージョンの確認はこちら
https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-release-components.html

alt


インストール作業

1.java

# javaをインストール
$ brew cask install java

# JAVA_HOMEを設定
$ echo 'export JAVA_HOME=`/usr/libexec/java_home -v 1.8`' >> ~/.bash_profile
$ echo 'export PATH="PATH=$JAVA_HOME/bin:$PATH"' >> ~/.bash_profile

# バージョンを確認
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)

2.mysql

# 既に入っていたら消す my.cnfとかも消す方が吉
$ brew uninstall mysql

# インストール
$ brew tap homebrew/versions
$ brew install mysql55

# パスを追加
$ echo 'export PATH="/usr/local/opt/mysql@5.5/bin:$PATH"' >> ~/.bash_profile

# mysql起動
$ brew services start mysql@5.5

# バージョンを確認
$ mysql -u root
Server version: 5.5.49 Homebrew
  • ハマりポイント
# 5.5系でないと、hive 2.1.0のmetastoreの作成が、
# InnoDBでPK・Uniqueカラムのフィールド長の制限に引っ掛かる
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

3.hadoop

# インストール
$ brew install hadoop

# 環境変数を設定
$ echo 'export HADOOP_HOME="/usr/local/Cellar/hadoop/2.7.3"' >> ~/.bash_profile
$ echo 'export HADOOP_CONF_DIR="$HADOOP_HOME/libexec/etc/hadoop"' >> ~/.bash_profile

# バージョンを確認
$ hadoop version
Hadoop 2.7.3

4.hive

# brewでは、2.1.0までしかないので、本家からダウンロードする
$ curl -O http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/hive/hive-2.1.1/apache-hive-2.1.1-bin.tar.gz

# 解凍
$ tar xvzf apache-hive-2.1.1-bin.tar.gz 

# インストール (今回わかりやすくするため、/usr/local/Cellar/hive/2.1.1へ配置)
$ sudo mv apache-hive-2.1.1-bin /usr/local/Cellar/hive/2.1.1

# 環境変数を設定
$ echo 'export HIVE_HOME="/usr/local/Cellar/hive/2.1.1"' >> ~/.bash_profile
$ echo 'export PATH="PATH=$HIVE_HOME/bin:$PATH"' >> ~/.bash_profile

# バージョンを確認
$ hive -H
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/Cellar/hive/2.1.1/lib/log4j-slf4j-impl-2.4.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]

2.1.1でないと、パーティショニング MSCK REPAIR TABLEがエラーになる。

ここまでで、インストールと環境設定が終わり、次は各種設定


設定作業

1.localhostへのssh接続できるようにする設定

Macの場合
システム環境設定 → 共有 から、「リモートログイン」にチェックを入れます。

以下のコマンドでauthorized_keysを追加します。
※まだ公開鍵を作成していない場合はssh-keygenで作成します。

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

以下のコマンドでlocalhostにsshで接続できることを確認します。

$ ssh localhost

2.HDFS設定

疑似分散モードでHDFSを構成します。

$HADOOP_CONF_DIR/core-site.xml
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
</configuration>
$HADOOP_CONF_DIR/hdfs-site.xml
<configuration>
  <property>
    <name>dfs.name.dir</name>
    <value>/var/lib/hdfs/name</value>
  </property>
  <property>
    <name>dfs.data.dir</name>
    <value>/var/lib/hdfs/data</value>
  </property>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
</configuration>

3.S3上のファイルへのアクセス設定

hadoopがS3にアクセス出来るようにします。

3.1.awsのjarにパスを通す

S3AFileSystemを使えるようにするため、「hadoop-aws-2.7.2.jar」にCLASSPATHを通します。
hadoop-env.shに以下を追記します。

$HADOOP_CONF_DIR/hadoop-env.sh
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/libexec/share/hadoop/tools/lib/*

3.2.S3AFileSystemとアクセスキーを設定

$HADOOP_CONF_DIR/yarn-site.xml
<configuration>
  <property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
  </property>
  <property>
    <name>fs.s3a.access.key</name>
    <value>※ここにAWSのアクセスキー※</value>
  </property>
  <property>
    <name>fs.s3a.secret.key</name>
    <value>※ここにAWSのシークレットキー※</value>
  </property>
</configuration>

4.mysqlをmetastore用のデータベースとして設定

4.1.データベースを作成

$ mysql -u root
# databaseのcharactersetはlaten1にしておく必要があります。
# 以下を参照
# http://tagomoris.hatenablog.com/entry/20110310/1299738606
mysql> create database metastore default character set 'latin1';
mysql> use metastore;
mysql> create user 'hive'@'localhost' identified by 'hive';
mysql> grant select, insert, update, delete, alter, create, index, references on metastore.* to 'hive'@'localhost';

4.2.jdbcドライバをhiveのライブラリへ追加

# ダウンロード
$ curl -O https://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-5.1.40.tar.gz

# 解凍
$ tar xvzf mysql-connector-java-5.1.40.tar.gz

# hiveのライブラリディレクトリに配置
$ mv mysql-connector-java-5.1.40/mysql-connector-java-5.1.40-bin.jar $HIVE_HOME/lib

4.3.mysqlのmetastoreデータベースをhadoopのメタストアとして使用するための設定

$HIVE_HOME/conf/hive-site.xml
<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost/metastore?useSSL=false</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>hive</value>
  </property>
  <property>
    <name>datanucleus.fixedDatastore</name>
    <value>false</value>
  </property>
  <property>
    <name>hive.exec.local.scratchdir</name>
    <value>/tmp/hive</value>
  </property>
  <property>
    <name>hive.downloaded.resources.dir</name>
    <value>/tmp/hive</value>
  </property>
  <property>
    <name>hive.querylog.location</name>
    <value>/tmp/hive</value>
  </property>

<!-- hiveでdynamodbを利用する場合の設定 -->
  <property>
    <name>dynamodb.endpoint</name>
    <value>http://localhost:8000</value>
  </property>
  <property>
    <name>dynamodb.awsAccessKeyId</name>
    <value>hoge</value>
  </property>
  <property>
    <name>dynamodb.awsSecretAccessKey</name>
    <value>hogehoge</value>
  </property>
</configuration>

4.4.metastoreの初期化

# schematoolで初期化を実行します。
$ schematool -dbType mysql -initSchema -verbose

5.HDFSのフォーマット

$ hdfs namenode -format

6.namenodeの起動とhdfsとS3への接続確認

以下のコマンドでHDFSを起動します。
YARN (Yet-Another-Resource-Negotiator)も起動したいので、 $HADOOP_HOME/sbin/start-all.shを実行する。

※停止する場合は $HADOOP_HOME/sbin/stop-all.sh

# パスワード聞かれたら、入力する
$ $HADOOP_HOME/sbin/start-all.sh

# hdfsへの接続確認(この時点では、まだHDFS上にファイルが無いので一覧には何も表示されません。)
$ hadoop fs -ls /

# s3のバケットが見れるかも確認
$ hadoop fs -ls s3a://※ここにS3のbucket名※/

お疲れ様です。
ここまでで、各種設定が終わりました。
次は、S3上に配置したTSVファイルに対してhiveでクエリを投げてみます。


S3上に配置したTSVファイルに対してhiveでクエリを投げてみます!

1.S3バケットの状態

# S3バケットには、カレンダーマスターを年でパーティショニングした状態で、TSVファイルを置いてある
$ hadoop fs -ls s3a://hivelocal/input/calendar_master/
Found 2 items
drwxrwxrwx   -          0 1970-01-01 09:00 s3a://hivelocal/input/calendar_master/year=2016
drwxrwxrwx   -          0 1970-01-01 09:00 s3a://hivelocal/input/calendar_master/year=2017

# こんな感じ
$ hadoop fs -ls s3a://hivelocal/input/calendar_master/year=2016/
Found 1 items
-rw-rw-rw-   1       5855 2017-02-19 14:06 s3a://hivelocal/input/calendar_master/year=2016/calendar_master.csv
$ hadoop fs -ls s3a://hivelocal/input/calendar_master/year=2017/
Found 1 items
-rw-rw-rw-   1       5840 2017-02-19 14:06 s3a://hivelocal/input/calendar_master/year=2017/calendar_master.csv

2.hiveQLを準備

データベース作って、テーブル作って、ロードして、パーティショニングするスクリプト

/src/hive/create_calendar_master.q
-- データベースを作成
CREATE DATABASE IF NOT EXISTS HIVE_TEST;

USE HIVE_TEST;

-- カレンダーマスタテーブルを削除
DROP TABLE IF EXISTS calendar_master;

-- カレンダーマスタテーブルを作成
CREATE EXTERNAL TABLE IF NOT EXISTS calendar_master (
  dt date,                  -- 日付
  yobi tinyint,             -- 曜日
  shukujitsu_code tinyint   -- 祝日コード
)
PARTITIONED BY (`year` string)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '\t'
  LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '${INPUT}/calendar_master/';

-- テーブルにすべてのパーティションを挿入
MSCK REPAIR TABLE calendar_master;

3.テスト用のシェルを用意

/test.sh
#!/bin/sh

# hiveコマンドのオプション debug
OPTS=-v
# hiveQLソースがあるフォルダ
SRC=./src/hive
# INPUTデータがある、S3バケット指定
INPUT=s3a://hivelocal/input
# OUTPUTデータの出力先S3バケット指定
OUTPUT=s3a://hivelocal/output

hive $OPTS -f $SRC/create_calendar_master.q -dINPUT=$INPUT || { echo oops!; exit 1; }

4.いざ実行!

$ sh test.sh 
CREATE DATABASE IF NOT EXISTS HIVE_TEST
OK
Time taken: 1.738 seconds


USE HIVE_TEST
OK
Time taken: 0.019 seconds


DROP TABLE IF EXISTS calendar_master
OK
Time taken: 0.127 seconds


CREATE EXTERNAL TABLE IF NOT EXISTS calendar_master (
  dt date,                  -- 日付
  yobi tinyint,             -- 曜日
  shukujitsu_code tinyint   -- 祝日コード
)
PARTITIONED BY (`year` string)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '\t'
  LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '${INPUT}/calendar_master/'
OK
Time taken: 1.667 seconds


MSCK REPAIR TABLE calendar_master
OK
Partitions not in metastore:    calendar_master:year=2016   calendar_master:year=2017
Repair: Added partition to metastore calendar_master:year=2016
Repair: Added partition to metastore calendar_master:year=2017
Time taken: 3.469 seconds, Fetched: 3 row(s)

お! Partitionも作られてるね〜イイね!

5.確認してみる

$ hive
# データベースあった!
hive> use HIVE_TEST;
OK
Time taken: 1.254 seconds

# テーブルもあった!
hive> show tables;
OK
calendar_master
Time taken: 0.283 seconds, Fetched: 1 row(s)

# パーティションもあった!
hive> show partitions calendar_master;
OK
year=2016
year=2017
Time taken: 0.266 seconds, Fetched: 2 row(s)

# TSVのデータも取り込まれている!
hive> select * from calendar_master;
OK
2016-01-01  6   1   2016
2016-01-02  7   0   2016
2016-01-03  1   0   2016
2016-01-04  2   0   2016
2016-01-05  3   0   2016
〜省略

2016-12-30  6   0   2016
2016-12-31  7   0   2016
2017-01-01  1   1   2017
2017-01-02  2   9   2017
2017-01-03  3   0   2017
2017-01-04  4   0   2017
2017-01-05  5   0   2017

Time taken: 0.251 seconds, Fetched: 731 row(s)
hive> 

やった〜!

お次は、S3上に出力できるか試せたら、追記します。

終わりに

hadoop,hiveは、構成がいろいろ出てて、初心者にはかなりハードル高い感じでした。

CDH? EMR なんだかんだ・・・

docker使えば一発じゃんとかあるかもしれませんが

今回は、理解を進める上でも、オールインワンは使わずやってみました。

1
2
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
2