Hive UDF の実行

Prev Next

最新のコンテンツが反映されていません。早急にアップデート内容をご提供できるよう努めております。最新のコンテンツ内容は韓国語ページをご参照ください。

VPC環境で利用できます。

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(table)を Outputで返す関数です。
    EXPLODEのような関数が該当します。

本ガイドでは、org.apache.hadoop.hive.ql.exec.UDF Hive UDFインターフェースを実装して Cloud Hadoopで使用する方法を説明します。

Cloud Hadoopで Hive UDFを使用するには、次の手順を順に実行します。

参考

UDFは Javaで実装する必要があり、他のプログラミング言語を使用するには user-definedスクリプト(MapReduceスクリプト)を作成した後、SELECT TRANSFORM構文を使用します。

1. プロジェクト作成

  1. IntelliJを使用して Gradle Projectを作成します。

    • package: com.naverncp.hive

    hadoop-chadoop-use-ex5_1-1_ko

    hadoop-chadoop-use-ex5_1-2_ko

    hadoop-chadoop-use-ex5_1-3_ko

  2. プロジェクト root以下のbuild.gradleに、以下のように dependency設定を追加します。

    • 例では、Cloud Hadoop 2.0にインストールされたコンポーネントと同じバージョンを使用しました。
    plugins {
        id 'java'
    }
    group 'com.naverncp'
    version '1.0-SNAPSHOT'
    repositories {
        mavenCentral()
        maven {
            url "<http://conjars.org/repo>"
        }
    }
    dependencies {
        compile group: 'org.apache.hadoop', name: 'hadoop-client', version: '3.1.1'
        compile group: 'org.apache.hive', name: 'hive-exec', version: '3.1.2'
        compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
    

2. インターフェース実装

  1. 次の条件を満たす UDFを実装します。

    • UDFはorg.apache.hadoop.hive.ql.exec.UDFを継承する。
    • UDFは少なくとも1つのevaluate()メソッドを実装する。

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つ目のメソッド: 文字列の後から指定した文字を削除
  1. UDFを Hiveで使用するには、まず Javaクラスを.jarでパッケージングします。

    • 次の例は、.jarhdfs:///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使用

  1. 次のコマンドを使用して 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>
    
  2. 以下のように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'
    
  3. ビルドしたstrip関数が正しく実行されることを確認します。空白が除去されたことを確認できます。

    hive> select strip('  bee  ');
    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');
    OK
    nan
    Time taken: 0.173 seconds, Fetched: 1 row(s)
    

関数の削除は以下のように実行できます。

DROP FUNCTION strip;
参考

データの特性に応じてよく使用するロジックを UDFで作成しておくと、SQL構文で簡単にデータを照会できます。