Hive UDF 실행
  • PDF

Hive UDF 실행

  • PDF

VPC 환경에서 이용 가능합니다.

Hive는 사용자가 작성한 processing code를 붙여 hive query 내에서 실행할 수 있게 도와주며, built-in function만으로는 원하는 쿼리를 표현하기 어려울 때 사용합니다.
보통 검색 로그, 거래 내역 등 특정 필드 데이터에 활용할 수 있도록 UDF를 작성하여 사용합니다.

function이 받는 input row, 반환하는 output row 수에 따라 3가지 종류의 UDF로 나눌 수 있습니다. 각 함수의 종류마다 구현해야 하는 interface가 다릅니다.

  • UDF
    single row를 input으로 받아서 single row를 output으로 반환하는 함수입니다.
    ROUND, REPLACE 같은 대부분의 mathematical, string functions이 이런 타입에 해당합니다.

  • UDAF
    multiple rows를 input으로 받아서 single row를 output으로 반환하는 함수입니다.
    COUNT, MAX 같은 aggregate functions이 해당합니다.

  • UDTF
    single rows를 input으로 받아서 multiple rows(table)를 ouput으로 반환하는 함수입니다.
    EXPLODE 같은 함수가 해당합니다.

이 가이드에서는 org.apache.hadoop.hive.ql.exec.UDF Hive UDF 인터페이스를 구현하여 Cloud Hadoop에서 사용하는 방법을 설명합니다.

Cloud Hadoop에서 Hive UDF를 사용하기 위해 다음 단계를 차례대로 진행해 주십시오.
* 1. 프로젝트 생성
* 2. 인터페이스 구현
* 3. Hive 사용

참고

UDF는 java로 구현해야 하며 다른 프로그래밍 언어를 사용하려면 user-defined script(map reduce script)를 만들어 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 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. 인터페이스 구현

  1. 다음 조건을 만족하는 UDF를 구현해 주십시오.

    • UDF는 org.apache.hadoop.hive.ql.exec.UDF를 상속한다.
    • UDF는 적어도 하나의 evaluate() 메소드를 구현한다.

    함수가 몇 개의 argument를 받게 될지, argument가 어떤 타입일지 미리 알기 어려워 org.apache.hadoop.hive.ql.exec.UDF 인터페이스에 evaluate() 메소드가 정의되어 있지 않기 때문입니다.

    // 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;
        }
    }
    

위의 클래스에서는 두 개의 evaluate 메소드를 구현하였습니다.

  • 첫 번째 메소드: 문자열에서 앞, 뒤 공백 제거
  • 두 번째 메소드: 문자열 뒤에서부터, 지정한 문자 제거
  1. UDF를 hive에서 사용하려면 먼저 java class를 .jar로 패키징해 주십시오.

    • 다음 예시는 .jarhdfs:///user/suewoon 아래에 업로드한 것입니다.
    $ ./gradlew clean
    $ ./gradlew build
    $ scp -i ~/Downloads/suewoon-home.pem 
    ~/IdeaProjects/hive/build/libs/hive-1.0-SNAPSHOT.jar sshuser@pub-
    4rrsj.hadoop.ntruss.com:~/
    $ ssh -i ~/Downloads/suewoon-home.pem  sshuser@pub-
    4rrsj.hadoop.ntruss.com
    
    [sshuser@e-001-suewoon-0917-hd ~]$ hadoop fs -copyFromLocal hive-1.0-SNAPSHOT.jar /user/suewoon/
    

3. Hive 사용

  1. 다음 명령어를 사용하여 임의의 hive table을 하나 생성해 주십시오.

    [sshuser@e-001-suewoon-0917-hd ~]$ echo 'dummy' > /tmp/dummy.txt
    [sshuser@e-001-suewoon-0917-hd ~]$ hive -e "CREATE TABLE dummy (value STRING); \\
    LOAD DATA LOCAL INPATH '/tmp/dummy.txt' \\
    OVERWRITE INTO TABLE dummy"
    
  2. 다음 명령어를 사용하여 Hive CLI를 실행해 주십시오.

    • edge 노드에 HiveServer가 설치되어 있기 때문에 별다른 옵션을 주지 않아도 됩니다.
    [sshuser@e-001-suewoon-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>
    
  3. 아래와 같이 metastore에서 함수를 등록해 주십시오.

    • CREATE FUNCTION 구문으로 이름을 설정해 주십시오.
    • Hive metastore: 테이블과 파티션에 관련된 메타정보를 저장하는 장소
    hive> CREATE FUNCTION strip AS 'com.naverncp.hive.Strip'
        > USING JAR 'hdfs:///user/suewoon/hive-1.0-SNAPSHOT.jar';
    converting to local hdfs:///user/suewoon/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/suewoon/hive-1.0-SNAPSHOT.jar]
    OK
    Time taken: 17.786 seconds
    

    또는 metastore에 함수를 영구적으로 저장하지 않고 hive session 동안에만 사용하려면 아래와 같이 TEMPORARY keyword를 사용해 주십시오.

    ADD JAR 'hdfs:///user/suewoon';
    CREATE TEMPORARY FUNCTION strip AS 'com.naverncp.hive.Strip'
    
  4. 빌드한 strip 함수가 제대로 수행되는지 확인해 주십시오. 공백이 제거된 것을 확인할 수 있습니다.

    hive> select strip('  bee  ') from dummy;
    converting to local hdfs:///user/suewoon/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/suewoon/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 구문으로 쉽게 데이터를 조회할 수 있습니다.


이 글이 도움이 되었나요?