Hive UDFを作ったのでメモ

HiveのUDFを仕事で作ったのでメモ

実装

必要なのは以下二つ

  1. org.apache.hadoop.hive.ql.exec.UDFを継承する。
  2. 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の高速化が狙える。

関数の登録

  1. jar追加
hive> -- add jar ${hdfs上のjarファイル格納パス}
hive> add jar /home/hoge/hoge-udf.jar;
hive>
hive> -- 確認
hive> list jar;
/home/hoge/hoge-udf.jar;
  1. 関数作成
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> 

参考

HivePlugins - Apache Hive - Apache Software Foundation