Hadoop/Hive SQLライクなクエリを使ってビッグデータ解析(前編)

Hadoop/Hive SQLライクなクエリを使ってビッグデータ解析(前編)

先日、先輩のkoglenさんがHadoopに関する記事を書かれていましたので、
流れにのって今回は同じHadoopプロダクトのHiveについてご紹介したいと思います。

前編は、基礎編としてHiveに関する概要を簡単に解説させていただき、
後編は、実践編として本サイトのアクセスログを解析してみたいと思います。
※インストールなどの導入編は割愛させていただきます。

Hiveとは?

Hadoopによるビッグデータ解析では一般的にJavaを使い、MapReduceの実装をすることになるのですが、
解析方法を考えたり、それを実際にロジックにするのは結構大変な作業だと思います。
そこで登場したのがHiveです。
http://hadoop.apache.org/hive/

HiveはHDFS上に保存されたデータをテーブルとして見做し、
HiveQLと呼ばれる、SQLライクなDSL言語を使うことで、
MapReduceを意識することなく、データを操作することができます。

同様のプロダクトとしては、「Pig」と呼ばれるDSL言語も存在しますが、
「Hive」はSQLライクな言語であるという点が、大きな魅力です。
ちなみに「Hive」はFacebookが、「Pig」はYahoo!によって開発されました。

HiveQL(DDL)

HiveQLは何度も述べていますように、SQLに似ています。
本記事では必要最低限の紹介に留めさせて頂きます。
完全なリファレンスは下記をご参照ください。
https://cwiki.apache.org/confluence/display/Hive/LanguageManual

指定できるデータ型

型の種類データ型名内容
プリミティブ型整数型TINYINT1Byteの整数
SMALLINT2Byteの整数
INT4Byteの整数
BIGINT8Byteの整数
浮動小数点型FLOAT単精度の浮動小数点
DOUBLE倍精度の浮動小数点
論理型BOOLEANTRUEとFALSE
文字列型STRING文字列
配列型ARRAY < データ型 >データ型を配列として扱う
マップ型MAP <プリミティブ型, データ型>Key, Value形式でデータを扱う
構造型STRUCT<カラム名:データ型 ,,,>複数のデータ型を構造化する

テーブル作成

[sql]
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] テーブル名
 [(項目名 型 [COMMENT コメント], …)]
 [ROW FORMAT row_format ]
[/sql]

テーブル作成の一番簡単な形式です。
他にも格納時のファイル形式やパーテションの設定など様々なオプションがありますが、ここでは割愛をさせていただきます。

  • ROW FORMAT句行フォーマットの指定です。データファイルを読み込む時に、ここで指定したフォーマットに従って項目値を分割し、テーブルに格納します。
  • サンプル
    TSVファイルをタブで区切った値として1行ごとに格納した例[sql] CREATE TABLE logs ( id INT, created_at STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,‘ [/sql]

テーブル操作

  • テーブル削除
    dropするとデータファイル自体が消えます。[sql] DROP TABLE [IF EXISTS] テーブル名; [/sql]
  • テーブル名変更[sql] ALTER TABLE テーブル名 RENAME TO 新テーブル名; [/sql]

テーブル情報参照

  • テーブルの一覧を表示[sql] SHOW TABLES; [/sql]
  • パテーション表示[sql] SHOW PARTITIONS テーブル名; [/sql]
  • テーブルの内容を表示[sql] DESCRIBE [EXTENDED] テーブル名; — 省略形のDESCも使用可能 — EXTENDEDを付けると詳細情報を表示 [/sql]

HiveQL(DML)

SELECT文

[sql]
SELECT [ALL | DISTINCT] カラム名1,カラム名2, ...
FROM テーブル名
[WHERE 条件]
[GROUP BY col_list]
[LIMIT number]
[/sql]

データの集計処理

  • GROUP BY句(グループ化)[sql] SELECT * FROM テーブル名 GROUP BY カラム名; [/sql]
  • HAVING句(グループ化後の条件)[sql] SELECT * FROM テーブル名 GROUP BY カラム名 HAVING 条件; [/sql]
  • LIMIT句[sql] SELECT * FROM テーブル名 LIMIT Number; — 以下のようなクエリは、MapReduceしないので高速 — SELECT * FROM table_name LIMIT 3 [/sql]

テーブルの結合

FROM句でのテーブル名の羅列不可のため、結合する場合は、JOIN句を使用する。

[sql]
SELECT * FROM テーブル名1 t1
{LEFT|RIGHT|FULL} [OUTER] JOIN テーブル名2 t2 ON t1.c1 = t2.c1;
[/sql]

データの格納

ここが一般的なSQLと違うところですが、作成したテーブルへのデータの格納には、INSERT文ではなくLOAD文を使用します。
LOAD文ではHDFS上、ローカルディスク上からそれぞれデータを格納することができます。

[sql]
LOAD DATA [LOCAL] INPAT 'ファイルパス' [OVERWRITE] INTO TABLE テーブル名
[/sql]
  • LOCALオプション
    ローカルディスク上のデータをHiveのテーブルに格納する場合につけます。
  • OVERWRITEオプション
    OVERWRITEを付けた場合、上書き(新しいデータのみ)
    付けない場合は、データ追加

データの保存

別テーブルとして保存

テーブル(SELECT文)から別のテーブルに対し、データを入れるのに使用します。
この際テーブルのデータはすべて上書きされます。

[sql]
INSERT OVERWRITE TABLE テーブル名 SELECT文 FROM ~
[/sql]

ファイルに保存

HDFS上やローカルディスク上にもファイルとして保存をします。

[sql]
INSERT OVERWRITE [LOCAL] DIRECTORY 'ファイルパス' SELECT文 FROM ~
[/sql]
  • LOCAL
    LOCALオプションを付けた場合、ローカルディスク上にクエリ結果を出力します。

【動作サンプル】Word Count

それでは前編の仕上げにおなじみのWord Countを試してみたいと思います。

データはせっかくですので、Koglenさんが生のHadoopで利用したファイルを使ってみましょう。
ちなみにHiveを利用する都合、単語ごとに改行をしてあります。

[bash]
cat /tmp/hoge.txt
hoge
abc
def
ghi
jkl
mno
pqe
stu
vwx
yz
hoge
hoge
[/bash]

テーブル作成

[sql]
CREATE TABLE hoge (
  word string
);
[/sql]

データ格納

[sql]
LOAD DATA LOCAL INPATH '/tmp/hoge.txt'
OVERWRITE INTO TABLE hoge;
[/sql]

ワードカウント実行

[sql]
SELECT word, count(*) FROM hoge GROUP BY word;
[/sql]

実際にHiveQLを実行した際のコンソールログです。
SELECT文からHadoopのMap Reduceが呼び出されているのが確認できます。
結果もKoglenさんのWord Countの結果と同じです。

まとめ

以上、簡単ではありましたがHiveの概要を紹介させていただきました。
プログラミング言語でMapReduceを書く必要がなく、
慣れしたんだSQLを使ってMapReduceを操作できるのは大変魅力的だと思います。
最近は日本語の解説も増えてきましたので、これを機に触れてみてはいかがでしょうか?

後編ではApacheのログを用いて、解析をしてみたいと思います。 

コメントを残す

メールアドレスが公開されることはありません。