Hive UDFを作ったのでメモ
HiveのUDFを仕事で作ったのでメモ
実装
必要なのは以下二つ
org.apache.hadoop.hive.ql.exec.UDF
を継承する。evaluate
メソッドを定義する。
サンプルそのまま
package com.example.hive.udf; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public final class Lower extends UDF { public Text evaluate(final Text s) { if (s == null) { return null; } return new Text(s.toString().toLowerCase()); } }
Q: 状態は持てるのか?
A: 持てる。インスタンスが作られるのは実行時ではないっぽい。
重たい処理(正規表現のコンパイル)とかを変数にキャッシュしておくとUDFの高速化が狙える。
関数の登録
- jar追加
hive> -- add jar ${hdfs上のjarファイル格納パス} hive> add jar /home/hoge/hoge-udf.jar; hive> hive> -- 確認 hive> list jar; /home/hoge/hoge-udf.jar;
- 関数作成
hive> -- create temporary function ${hiveで使用する関数名} as '${Javaのパッケージ}' hive> create temporary function my_lower as 'com.example.hive.udf.Lower'; hive> hive> -- 確認 hive> show functions "my_lower";
なお、上記の方法だと、Hiveとのセッションが切れると関数定義もリセットされてしまう。 (temporaryを外せばいいのかと思ったけど、jarのPATHの方が消えてしまうので実行できない)
Hive 0.13.0以降だと以下の方法で関数定義を永続化できるらしい(確認してない)
hive> CREATE FUNCTION myfunc AS 'myclass' USING JAR 'hdfs:///path/to/jar';
Hive 0.13.0以前の場合は、
hive(またはbeeline)の実行コマンドに-i
オプションをつけてadd .. ~ create..
を記述したscriptを流すのが簡単な解決法なのかなあ
-- initialize.hql add jar /home/hoge/hoge-udf.jar; create temporary function my_lower as 'com.example.hive.udf.Lower'; ...
$ hive -i ./initialize.hql hive>