- 印刷する
- PDF
Hive UDF の実行
- 印刷する
- PDF
Classic環境で利用できます。
Hive UDF(User-Defined Functions)はユーザーが作成したコードをHiveクエリ内で実行できるようサポートし、Built-in Functionsだけでは希望するクエリの表現が困難な場合に使用します。
一般に、検索ログ、取引内訳などの特定のフィールドデータに活用するようにUDFを作成して使用します。
関数が受けるInput row、返すOutput row数によって3種類のUDFに区分できます。 各関数の種類ごとに実装するインターフェースが異なります。
UDF
Single rowをInputに受けてSingle rowをOutputに返す関数です。
ROUND、REPLACEなどのほとんどのMathematical、String FunctionsがUDFタイプに該当します。UDAF
Multiple rowsをInputに受けてSingle rowをOutputに返す関数です。
COUNT、MAXなどのAggregate Functionsが該当します。UDTF
Single rowsをInputに受けてMultiple rows(テーブル)をOuputに返す関数です。
EXPLODEのような関数が該当します。
このガイドでは、org.apache.hadoop.hive.ql.exec.UDF
Hive UDFインターフェースを実装してCloud Hadoopで使用する方法を説明します。
Cloud HadoopでHive UDFを使用するには、以下の手順に従います。
UDFはJavaで実装する必要があり、他のプログラミング言語を使用するにはuser-definedスクリプト(MapReduceスクリプト)を作成してSELECT TRANSFORM構文を使用します。
1. プロジェクトの作成
IntelliJを用いてGradle Projectを作成します。
- package:
com.naverncp.hive
- package:
プロジェクトrootの下位の
build.gradle
に以下のようにdependency設定を追加します。- 例はCloud Hadoop 1.2にインストールされたコンポーネントと同じバージョンを使用しました。
plugins { id 'java' } group 'com.naverncp' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() maven { url "<http://conjars.org/repo>" } } dependencies { compile group: 'org.apache.hadoop', name: 'hadoop-client', version: '2.7.3' compile group: 'org.apache.hive', name: 'hive-exec', version: '1.2.2' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9' testCompile group: 'junit', name: 'junit', version: '4.12' }
2. インターフェースの実装
以下の条件を満足するUDFを実装します。
- UDFは
org.apache.hadoop.hive.ql.exec.UDF
を継承する。 - UDFは少なくとも一つの
evaluate()
メソッドを実装する。
- UDFは
org.apache.hadoop.hive.ql.exec.UDF
インターフェースにevaluate()
メソッドは定義されていないため関数がいくつのargumentを受けるかわからず、argumentがどんなタイプなのか前もって知ることはできません。
// Strip.java
package com.naverncp.hive;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
@Description(
name = "Strip",
value = "returns a stripped text",
extended = "stripping characters from the ends of strings"
)
public class Strip extends UDF {
private Text result = new Text();
public Text evaluate(Text str){
if (str == null){
return null;
}
result.set(StringUtils.strip(str.toString()));
return result;
}
public Text evaluate(Text str, String stripChar){
if (str == null){
return null;
}
result.set(StringUtils.strip(str.toString(), stripChar));
return result;
}
}
上記のクラスでは2つのevaluate
メソッドを実装しました。
- 1番目のメソッド:文字列で前後のスペースを除去
- 2番目のメソッド:文字列の後ろから指定した文字を除去
UDFをHiveで使用するには、まずJavaクラスを
.jar
にパッケージングする必要があります。- 以下の例は、
.jar
をhdfs:///user/example
の下にアップロードしたものです。
$ ./gradlew clean $ ./gradlew build $ scp -i ~/Downloads/example-home.pem ~/IdeaProjects/hive/build/libs/hive-1.0-SNAPSHOT.jar sshuser@pub- 4rrsj.hadoop.ntruss.com:~/ $ ssh -i ~/Downloads/example-home.pem sshuser@pub- 4rrsj.hadoop.ntruss.com [sshuser@e-001-example-0917-hd ~]$ hadoop fs -copyFromLocal hive-1.0-SNAPSHOT.jar /user/example/
- 以下の例は、
3. Hiveを使用する
以下のコマンドを使用して任意の
hive table
を1つ作成します。[sshuser@e-001-example-0917-hd ~]$ echo 'dummy' > /tmp/dummy.txt [sshuser@e-001-example-0917-hd ~]$ hive -e "CREATE TABLE dummy (value STRING); \\ LOAD DATA LOCAL INPATH '/tmp/dummy.txt' \\ OVERWRITE INTO TABLE dummy"
以下のコマンドを使用してHive CLIを実行します。
- エッジノードにHiveServerがインストールされているため、別途のオプションは不要です。
[sshuser@e-001-example-0917-hd ~]$ hive 20/11/06 16:04:39 WARN conf.HiveConf: HiveConf of name hive.server2.enable.doAs.property does not exist log4j:WARN No such property [maxFileSize] in org.apache.log4j.DailyRollingFileAppender. Logging initialized using configuration in file:/etc/hive/2.6.5.0-292/0/hive-log4j.properties hive>
以下のように
metastore
で関数を登録します。- CREATE FUNCTION構文で名前を設定します。
- Hive Metastore:テーブルとパーティションに関連したメタ情報を保存する場所
hive> CREATE FUNCTION strip AS 'com.naverncp.hive.Strip' > USING JAR 'hdfs:///user/example/hive-1.0-SNAPSHOT.jar'; converting to local hdfs:///user/example/hive-1.0-SNAPSHOT.jar Added [/tmp/99c3d137-f58e-4fab-8a2a-98361e3e59a1_resources/hive-1.0-SNAPSHOT.jar] to class path Added resources: [hdfs:///user/example/hive-1.0-SNAPSHOT.jar] OK Time taken: 17.786 seconds
または、metastoreに関数を永続的に保存せずにHiveセッション中のみ使用するには、以下のように
TEMPORARY keyword
を使用します。ADD JAR 'hdfs:///user/example'; CREATE TEMPORARY FUNCTION strip AS 'com.naverncp.hive.Strip'
ビルドした
strip
関数が正常に実行されるのかを確認します。 空白が除去されたことが確認できます。hive> select strip(' bee ') from dummy; converting to local hdfs:///user/example/hive-1.0-SNAPSHOT.jar Added [/tmp/70e2e17a-ecca-41ff-9fe6-48417b8ef797_resources/hive-1.0-SNAPSHOT.jar] to class path Added resources: [hdfs:///user/example/hive-1.0-SNAPSHOT.jar] OK bee Time taken: 0.967 seconds, Fetched: 1 row(s) hive> select strip('banana', 'ab') from dummy ; OK nan Time taken: 0.173 seconds, Fetched: 1 row(s)
関数の削除は、以下のように実行できます。
DROP FUNCTION strip
データの特性に応じてよく使うロジックをUDFに作成しておくと、SQL構文で簡単にデータを照会できます。