前回の記事では、手元のマシン上にHadoop環境を構築してHiveを導入し、基本的な操作を確認しました。今回は同じ環境を使って、より実践的なデータ操作についてみていきます。
今回は少し凝ったテーブルを定義をしてみましょう。
郵便番号データは毎月更新されるので、テーブル指定時にバージョンも指定できるようにします。このような場合、Hiveではパーティションを使います。
以下に郵便番号を保存するテーブル「zip」を定義しますが、日付型DATEのパーティションverを設定するようにします。
hive> CREATE TABLE zip (zip STRING, pref INT, city STRING, town STRING)
> PARTITIONED BY (ver DATE)
> ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
> LINES TERMINATED BY '\n';
OK
Time taken: 0.128 seconds
ここで、テーブルzipに2008年11月28日版の郵便番号データzip20081128.csvと2008年12月26日版のzip20091226.csvを読み込みます。
hive> LOAD DATA LOCAL INPATH '/home/hiveuser/localfiles/zip20081128.csv'
> OVERWRITE INTO TABLE zip PARTITION (ver = '2008-11-28');
Copying data from file:/home/hiveuser/localfiles/zip20081128.csv
Loading data to table zip partition {ver=2008-11-28}
OK
Time taken: 1.582 seconds
hive> LOAD DATA LOCAL INPATH '/home/hiveuser/localfiles/zip20081226.csv'
> OVERWRITE INTO TABLE zip PARTITION (ver = '2008-12-26');
Copying data from file:/home/hiveuser/localfiles/zip20081226.csv
Loading data to table zip partition {ver=2008-12-26}
OK
Time taken: 1.788 seconds
データが本当に読み込まれたかどうか確認しましょう。次に説明するSELECT文でもいいですが、ここでは直接HadoopのHDFSシステムのうえで、どのようにデータが保存されているか確認します。
HadoopのコマンドでHDFSシステムのディレクトリ「/user/hive/warehouse」以下を表示させます。Hiveのデータはこのディレクトリに保存されます。
hiveuser> $HADOOP_HOME/bin/hadoop dfs -lsr /user/hive/warehouse drwxr-xr-x - hiveuser supergroup 0 2009-01-01 12:22 /user/hive/warehouse/pref -rw-r--r-- 3 hiveuser supergroup 611 2009-01-01 12:21 /user/hive/warehouse/pref/pref.csv drwxr-xr-x - hiveuser supergroup 0 2009-01-01 12:24 /user/hive/warehouse/zip drwxr-xr-x - hiveuser supergroup 0 2009-01-01 12:24 /user/hive/warehouse/zip/ver=2008-11-28 -rw-r--r-- 3 hiveuser supergroup 4541673 2009-01-01 12:24 /user/hive/warehouse/zip/ver=2008-11-28/zip20081128.csv drwxr-xr-x - hiveuser supergroup 0 2009-01-01 12:24 /user/hive/warehouse/zip/ver=2008-12-26 -rw-r--r-- 3 hiveuser supergroup 4541979 2009-01-01 12:24 /user/hive/warehouse/zip/ver=2008-12-26/zip20081226.csv
テーブル名と同じ名前のディレクトリが作成され、それ以下に読み込まれたファイルが存在していることが分かります。パーティションが設定されたテーブルには、サブディレクトリが作成されていることも分かります。
ここでは省略しますが、WebブラウザでHDFSの状態を表示させることもできます。
Webブラウザで「localhost:50070」にアクセスし、「Live Datanodes」の「Node = localhost」をクリックすると、HDFSのルートディレクトリが表示されます。
HiveはHadoopの機能であるMapReduce操作もできます。そもそもHive自体がMapReduceで実行されるわけですが、ここではHiveからMapReduceスクリプトを実行する方法を説明します。MapReduceの構文は、下記URLで紹介されています。
ここではテーブルprefについて、prefカラムの「青森県」や「岩手県」から「県」という文字を削除して、新しいテーブルpref_newに挿入するMap操作を行います。
はじめにテーブルpref_newを定義します。
hive> CREATE TABLE pref_new (id int, pref STRING)
> ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
> LINES TERMINATED BY '\n';
次にMap操作を行います。まずは簡略版で実行してみましょう。
hive> FROM (
> FROM pref
> SELECT TRANSFORM(pref.id, pref.pref) AS (oid, opref)
> USING '/bin/sed s/県//'
> CLUSTER BY oid
> ) tmap
> INSERT OVERWRITE TABLE pref_new SELECT tmap.oid, tmap.opref;
Mapスクリプトを書き込むUSING句には、UNIXのコマンドであるsedが書き込まれているだけです。この操作を行うと、テーブルが1行ずつsedコマンドに渡され、「県」という文字列を削除してINSERT文に渡されます。
sedコマンドは1行ごとにすべてのカラムに対して変換を行うので、目的とするカラム以外のデータも変換してしまい、汎用的ではありません。そこで、きちんと目的のカラムだけに変換を施すperlスクリプトを使って同様の作用を起こしてみましょう。
#!/usr/bin/perl
while (<>) {
chop;
my(@w) = split('\t', $_);
$w[1] =~ s/県$//;
printf("%d\t%s\n", $w[0], $w[1]);
}
hiveuser> chmod +x /home/hiveuser/test.pl
区切り文字が「\t」であることに注意してください。HDFSの通常の区切り文字は「^A」ですが、Hiveが生成したテーブルにデータを書き込む場合は、ファイルの区切りが「\t」となるようです。
あとは、同様に実行するだけです。
hive> FROM (
> FROM pref
> SELECT TRANSFORM(pref.id, pref.pref) AS (oid, opref)
> USING '/home/hiveuser/test.pl'
> CLUSTER BY oid
> ) tmap
> INSERT OVERWRITE TABLE pref_new SELECT tmap.oid, tmap.opref;
Copyright © ITmedia, Inc. All Rights Reserved.