MacにhiveをセットアップしてS3上のファイルにアクセスするまで
Mac上にhadoop/hiveを入れて、 S3上のファイルをhiveでアクセスするまでの手順のメモを残しておきます。
- Hadoopとhiveのセットアップ
- S3上のファイルへのアクセス設定
- S3上のTSVファイルへのクエリ実行
- S3上にクエリの実行結果を保存
Hadoopとhiveのセットアップ
homebrewを使ってhadoopとhiveのインストール、 その後必要となる設定を行います。
インストール
jdk及びhomebrewはセットアップ済みとして、
以下のコマンドでhadoopとhiveをインストールします。
$ brew install hadoop
$ brew install hive
以下のコマンドで、インストール出来たことを確認します。
$ hadoop version
$ hive -H
HADOOP_HOMEの設定
環境変数「HADOOP_HOME」「HADOOP_CONF_DIR」を設定しておきます。
hadoop version
の出力結果を見て、以下のように設定します。
以下は私の環境の場合の設定です。
$ hadoop version
Hadoop 2.7.2
※省略※
This command was run using /usr/local/Cellar/hadoop/2.7.2/libexec/share/hadoop/common/hadoop-common-2.7.2.jar
$ echo 'export HADOOP_HOME=/usr/local/Cellar/hadoop/2.7.2' >> ~/.bash_profile
$ echo 'export HADOOP_CONF_DIR=$HADOOP_HOME/libexec/etc/hadoop' >> ~/.bash_profile
$ . ~/.bash_profile
localhostへのssh接続設定
localhostにsshで接続できるように設定します。
システム環境設定 → 共有 から、「リモートログイン」にチェックを入れます。
以下のコマンドでauthorized_keysを追加します。
※まだ公開鍵を作成していない場合はssh-keygen
で作成します。
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
以下のコマンドでlocalhostにsshで接続できることを確認します。
$ ssh localhost
HDFS設定とnamenodeの起動
次に、疑似分散モードでHDFSを構成します。
参考: Hadoop: Setting up a Single Node Cluster.
https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html
core-site.xml/hdfs-site.xmlを以下のように変更します。
$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.replication</name>
<value>1</value>
</property>
</configuration>
以下のコマンドでnamenodeを初期化します。
$ hadoop namenode -format
以下のコマンドでHDFSを起動します。
※停止する場合は $HADOOP_HOME/sbin/stop-dfs.sh
$ $HADOOP_HOME/sbin/start-dfs.sh
以下のコマンドでHDFSを参照できることを確認します。
※まだHDFS上にファイルが無いので一覧には何も表示されません。
$ hadoop fs -ls /
S3上のファイルへのアクセス設定
Mac上のhadoopからS3にアクセスできるように設定を行います。
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/*
S3AFileSystemとアクセスキーを設定
「yarn-site.xml」を以下のように編集し、hadoopがS3にアクセス出来るようにします。
$HADOOP_CONF_DIR/yarn-site.xml
<?xml version="1.0"?>
<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>
S3へのアクセス確認
hadoopコマンドでS3のbucketにアクセスできることを確認します。
$ hadoop fs -ls s3a://※ここにS3のbucket名※/
S3上のTSVファイルへのクエリ実行
次に、S3上に配置したTSVファイルに対してhiveでクエリを投げてみます。
hiveの起動
以下のコマンドでhiveを起動します。
$ hive
S3上のtsvファイルへのアクセス
とりあえず、以下のように「日時」「支店」「金額」がタブ区切りで入力された、
店舗別の売り上げデータがあるとします。
2012-11-20 10:35:00 東京店 1000
2012-12-05 19:07:00 大阪店 1200
2012-12-07 12:42:00 京都店 2200
2012-12-10 13:05:00 東京店 1800
このファイルをS3 bucketの以下のパスに配置します。
/hive/external/sales/sales001
次のように、配置したtsvファイルを外部テーブルとして定義します。
hive> create external table sales (
saletime timestamp,
shop string,
amount int
)
row format delimited
fields terminated by '\t' lines terminated by '\n'
stored as textfile location 's3a://※ここにS3のbucket名※/hive/external/sales';
テーブルを定義できたら、
hiveで該当のテーブルにクエリを投げることができます。
例えば、次のようにして店舗別の売り上げ集計を行うことができます。
hive> select shop, sum(amount) from sales group by shop;
京都店 2200
大阪店 1200
東京店 2800
S3上にクエリの実行結果を保存
ここまででクエリを実行できたので、今度はクエリの実行結果をS3上に保存してみます。
出力先テーブルの作成
次のようにして、出力先のテーブルを作成します。
hive> create external table sales_by_shop(shop string, amount int)
partitioned by (ym string)
stored as textfile location 's3a://※ここにS3のbucket名※/hive/external/sales_by_shop';
クエリの実行と登録
以下のクエリを実行して、実行結果を先ほど作成したテーブルに保存します。
hive> alter table sales_by_shop add partition (ym=201211);
hive> insert into sales_by_shop partition(ym=201211)
select shop, sum(amount) from sales where saletime between '2012-11-01' and '2012-11-30' group by shop;
hive> alter table sales_by_shop add partition (ym=201212);
hive> insert into sales_by_shop partition(ym=201212)
select shop, sum(amount) from sales where saletime between '2012-12-01' and '2012-12-31' group by shop;
保存されたデータの確認
クエリの実行後、以下のコマンドでpartitionができていることを確認できます。
$ hadoo fs -ls s3a://※ここにS3のbucket名※/hive/external/sales_by_shop
drwxrwxrwx - 0 1970-01-01 09:00 s3a://※ここにS3のbucket名※/hive/external/sales_by_shop/ym=201211
drwxrwxrwx - 0 1970-01-01 09:00 s3a://※ここにS3のbucket名※/hive/external/sales_by_shop/ym=201212
また、以下のようにすると、保存されたファイルの中身を確認できます。
$ hadoop fs -cat s3a://※ここにS3のbucket名※/hive/external/sales_by_shop/ym=201212/*
京都店2200
大阪店1200
東京店1800
以上で、Mac上のhiveからS3のファイルにアクセスできるようになりました。
S3を使う場合は、EC2やEMR上のhadoopから処理をした方が(ネットワーク的に)有利ですが、
手元で環境変更したり、UDFを開発したりなどの用途で、
このようにMac上のhadoopからS3にアクセスできると便利かもしれないです。