Apache Hive には、データ処理用の多数のビルトイン関数が備わっています。ただし、カスタム文字列変換、データ暗号化、またはドメイン固有の計算など、ビルトイン関数で対応できないロジックが必要な場合は、代わりにユーザー定義関数 (UDF) を作成してください。
UDF の種類
Apache Hive では、以下の 3 種類の UDF をサポートしています。
| 種類 | 正式名称 | 動作 |
|---|---|---|
| UDF | ユーザー定義スカラー関数 | 1 対 1 のマッピング:1 行を入力として読み取り、1 つの値を返す |
| UDTF | ユーザー定義テーブル値関数 | 入力 1 件に対して複数行を返す。複数のフィールドを返すことができる唯一の種類 |
| UDAF | ユーザー定義集計関数 | 多対 1 のマッピング:複数行を 1 つの出力値に集計する。GROUP BY |
前提条件
開始する前に、以下の環境が整っていることを確認してください。
SSH アクセス可能な E-MapReduce (EMR) クラスター。詳細については、「クラスターへのログイン」をご参照ください。
Java 開発キット (JDK) のインストール
Apache Maven のインストールおよび設定
Java 開発用の統合開発環境 (IDE)
UDF コードの開発
このセクションでは、文字列入力に :HelloWorld を追加するシンプルな UDF の作成手順を説明します。
1. Maven プロジェクトの作成
IDE で、以下の座標を指定して新しい Maven プロジェクトを作成します。groupId および artifactId は、ご使用の組織およびプロジェクト名に合わせて調整してください。
<groupId>org.example</groupId>
<artifactId>hiveudf</artifactId>
<version>1.0-SNAPSHOT</version>2. Hive 依存関係の追加
pom.xml に、以下の依存関係を追加します。
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.7</version>
<exclusions>
<exclusion>
<groupId>org.pentaho</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>3. UDF クラスの実装
org.apache.hadoop.hive.ql.exec.UDF を継承するクラスを作成し、evaluate() メソッドを実装します。クラス名は任意ですが、本例では MyUDF を使用しています。
package org.example;
import org.apache.hadoop.hive.ql.exec.UDF;
public class MyUDF extends UDF {
public String evaluate(final String s) {
if (s == null) { return null; }
return s + ":HelloWorld";
}
}4. JAR ファイルのビルド
pom.xml を含むディレクトリで、以下のコマンドを実行します。
mvn clean package -DskipTests出力された JAR ファイル hiveudf-1.0-SNAPSHOT.jar は、target ディレクトリに配置されます。
UDF のデプロイおよび登録
1. JAR のクラスターへの転送
SSH Secure File Transfer Client を使用して、hiveudf-1.0-SNAPSHOT.jar を EMR クラスターのルートディレクトリにアップロードします。
2. JAR の HDFS へのアップロード
SSH モードでクラスターにログインします。
Hadoop 分散ファイルシステム (HDFS) に JAR をアップロードします。
hadoop fs -put hiveudf-1.0-SNAPSHOT.jar /user/hive/warehouse/アップロードが正常に完了したかを確認します。
hadoop fs -ls /user/hive/warehouse/期待される出力:
Found 1 items -rw-r--r-- 1 xx xx 2668 2021-06-09 14:13 /user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar
3. Hive への UDF の登録
Hive CLI を起動します。
hiveUDF を永続関数として登録します。
create function myfunc as "org.example.MyUDF" using jar "hdfs:///user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar";このコマンドでは、
| パラメーター | 説明 |
|---|---|
myfunc | クエリ内で使用する関数名 |
org.example.MyUDF | JAR 内の完全修飾クラス名 |
hdfs:///user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar | JAR の HDFS 上のパス |
登録が成功した場合、次のような出力が表示されます。
Added [/private/var/folders/2s/wzzsgpn13rn8rl_0fc4xxkc00000gp/T/40608d4a-a0e1-4bf5-92e8-b875fa6a1e53_resources/hiveudf-1.0-SNAPSHOT.jar] to class path
Added resources: [hdfs:///user/hive/warehouse/myfunc/hiveudf-1.0-SNAPSHOT.jar]4. UDF のテスト
UDF を、ビルトイン関数と同様にクエリ内で呼び出します。
select myfunc("abc");期待される出力:
OK
abc:HelloWorld関数が正しく登録されているかを確認するには、以下のコマンドを実行します。
SHOW FUNCTIONS LIKE '*myfunc*';トラブルシューティング
create function コマンドが「クラスが見つかりません」というエラーで失敗する
create function 文内のクラス名が、JAR 内の完全修飾クラス名(パッケージプレフィックスを含む)と一致しているかを確認してください。たとえば、クラスが MyUDF で、パッケージが org.example の場合、参照は org.example.MyUDF でなければならず、MyUDF では不十分です。
UDF がすべての入力に対して null を返す
evaluate() メソッドの null 処理ロジックを確認してください。本例の実装では、入力が null の場合に null を返します。関数が null 入力を異なる方法で処理する必要がある場合は、該当メソッドを適宜更新してください。