HiveQLにおける初心者狩り


はじめに

HiveQLとはHDFS上のデータ(ファイル)を操作するSQLらいくなデータ操作言語です。
HiveDDLとはHiveQLで構築されたデータ構造定義です。
HDFSとはHadoopが利用している分散ファイルシステムです。
複数のマシンを1つのストレージとして扱い、一部のマシンが故障してもデータが
失われないように設計されており、データ量に応じてスケールアウトすることが可能です。

通常はHiveDDLからテーブルを作成し、HiveQLでテーブルに対して操作を行うと思います。
※dbはデータベース名、tableはテーブル名を表す。

Hive初心者向けのトラブルシューティングがあまり見当たらなかったので記事にしました。

初心者狩りとは

SQLらいくな言語なのに
・UNIONが使えない!
→UNION ALLで頑張りましょう。
・ORDER BYが使えない!
→limit句を使用して頑張りましょう。

……とかではないです。
もっと根本的なところで狩られます。

そして初心者は狩られる

  1. テーブルを作ったけど「select * from table」しても何もない!
  2. テーブルがあるのに「Table not found」でエラーになる!
  3. データベース(スキーマ)が消せない!cascadeで無理やり消したからOK!
  4. HDFSの容量を凄い勢いで大量消費している!

狩られた原因

1:
テーブルを作った(CREATE)、のではなく、テーブルを作り直した(DROP→CREATE)したのではないでしょうか?
DROP TABLEすると、TABLEが参照していたHDFSのデータはディレクトリごと消えます。
その状態でデータを再配置せずにテーブルをCREATEした場合、入力ファイル(ディレクトリ)は無いので、
空のテーブルが出来上がり、「select * from table」しても何も取得できません。
この事象に出会ったときはDROPしてから、データを再配置してCREATEしてください。
なお、DROP TABLEしたテーブルが新規CREATEではなく元々存在するテーブルを使用して
CREATEしたテーブルである場合、大元のHDFS上のデータは消えないことを留意。

2:
データベースの指定を忘れています。
GUI(Hue)とコマンドラインの両方を使用していると陥りやすいです。
use db; select * from table;
のように「use db;」をHiveQLの先頭につけるようにしましょう。
他のDBも同じだと思うのですが、たまにこれが原因の問い合わせを受けます。

3:
データベース(スキーマ)はテーブルが存在するとき、削除できません。
hive -e "drop database DB;"
を実行すると「Database DB is not empty」とエラー出力されます。
hive -e "drop database DB cascade;"
を実行するとテーブルが存在してもDBを削除することができます。
……が、そのDBに存在したテーブルの参照するデータはHDFS上に残り続けます。
消した(DROPした)のはテーブルではなくDBだから。
無暗にcascade指定でDBを消していくとHDFS上にゴミデータが散乱します。
もちろんHDFSの容量は使用したままです。
無暗に消してしまった場合は「hadoop fs -rmr」コマンドでゴミデータを削除しましょう。

4:
間違ったHiveQLを実行して、それを実行したままにしている可能性があります。
コマンドラインでHiveQLを実行したときは、Ctrl+Cで中止できます。
が、GUI(Hue)で実行したときは強制終了しないと中止されません。
例えば、一億レコードと一億レコードのテーブルをユニークで無いキーでJOINした場合、
最大一億×一億のレコードを出力することになり、その分の容量を使用することになります。
そんなHiveQLを放置してしまえばHDFSが数百テラバイトあったとしても長くは持ちません。
実績のないHiveQLの実行放置は極力避けましょう。

他にも……

初心者狩りはある気がするのですが、パッと思い出せませんでした。
(ここまでの紹介は初心者の時に出会ったことのある事例を紹介しています)
何かありましたら、ご指摘・ご教授いただければと思います。