프로그래밍/Spring & Maven

Spring 프레임웍 Hadoop-Hive 통합

Terry Cho 2013. 3. 19. 00:46

Spring for Apache Hadoop Project #2

(Hive Integration)

Hive Apache 오픈 소스 프로젝트의 하나로, Hadoop 관련 프로젝트이다.

HDFS에 저장된 데이타를 마치 RDMS SQL처럼 쿼리하기 위한 솔루션으로, 복잡한 데이타 쿼리 연산에 있어서, Hadoop과 함께 사용하면 매우 유용하게 이용할 수 있다.

SHDP에서도 이 Hive를 지원한다. 크게 Hive의 기동과, Hive Script의 실행 그리고, Hive에서 제공하는 API를 수행할 수 있도록 지원하며, Hadoop 지원과 마찬가지로, Tasklet을 제공하여 Spring Batch와의 통합을 지원한다.

Hive Server의 기동

hive-server 엘리먼트로 정의하며, configuration file을 읽어서 기동할 수 있으며, 추가되는 configuration hive-server엘리먼트 안에 value로써 지정이 가능하다.

<hdp:hive-server host="some-other-host" port="10001" properties-location="classpath:hive-dev.properties" configuration-ref="hadoopConfiguration">
  someproperty=somevalue
  hive.exec.scratchdir=/tmp/mydir
</hdp:hive-server>

Thrift Client 를 이용한 Hive Script의 수행

Hive를 사용하기 위해서는 Hive Server에 접속하는 클라이언트를 생성해야 하는데, 첫번째 방법이 Thrift Client를 이용하는 방법이 있다. Thrift Client의 경우에는 Thread Safe 하지 않기 때문에, client factory를 리턴한다.

아래 설정을 보면 hive-client-factory hive서버의 ip,port를 지정하여 client를 생성하였다.

그리고, script 실행을 위해서 runner 를 지정한후에, 앞서 생성한 clientfactory reference하였다. 그리고 hive-runner에서 script location을 지정하여,password-analysis.hal 파일에 정의된 script가 실행되도록 정의하였다.

<hdp:hive-client-factory host="some-other-host" port="10001" />
<hdp:hive-runner id=”hiveRunner”hive-client-ref=”hiveClientFactory” run-at-startup=”false” pre-action=”hdfsScript”>
  <script location=”password-analysis.hal”/>
</hdp:/hiverunner>

실제 위의 Configuration을 가지고 수행하는 자바 코드를 보면 다음과 같다.

public class HiveAppWithApacheLogs {
 
         private static final Log log = LogFactory.getLog(HiveAppWithApacheLogs.class);
 
         public static void main(String[] args) throws Exception {
                 AbstractApplicationContext context = new ClassPathXmlApplicationContext(
                                   "/META-INF/spring/hive-apache-log-context.xml"
, HiveAppWithApacheLogs.class);
                 log.info("Hive Application Running");
                 context.registerShutdownHook();    
 
 
                 HiveRunner runner = context.getBean(HiveRunner.class);                
                 runner.call();
 
         }
}

Hive client를 만들때는 각 client가 생성될때마다 자동으로 initialize script를 실행할 수 있다.

<hive-client-factory host="some-host" port="some-port" xmlns="http://www.springframework.org/schema/hadoop">
   <hdp:script>
     DROP TABLE IF EXITS testHiveBatchTable; 
     CREATE TABLE testHiveBatchTable (key int, value string);
   </hdp:script>
   <hdp:script location="classpath:org/company/hive/script.q">
       <arguments>ignore-case=true</arguments>
   </hdp:script>
</hive-client-factory>

위의 설정은 client가 생성될때 마다 DROP TABLE xx 스크립트와, script.q에 지정된 스크립트 두개를 자동으로 수행하도록 한다.

마찬가지로, runner에서도 순차적으로 여러개의 쿼리가 수행되도록 설정할 수 있다.

JDBC 를 이용한 스크립트 수행

Hive Thrift 이외에도, RDBMS에 사용하는 JDBC 드라이버를 사용할 수 있다. Spring에서도 이 JDBC를 통한 Hive 통합을 지원한다.

사용 방법은 일반적인 JDBC Template을 사용하는 방법과 동일하다.

먼저 hive-driver Hive JDBC 드라이버를 지정한후, 이를 이용하여, hive data source를 정의한후, Jdbc template을 이 data source와 연결하여 사용한다. (아래 예제 참고)

<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:c="http://www.springframework.org/schema/c"
         xmlns:context="http://www.springframework.org/schema/context"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
         
    <!-- basic Hive driver bean -->
    <bean id="hive-driver" class="org.apache.hadoop.hive.jdbc.HiveDriver"/>
 
    <!-- wrapping a basic datasource around the driver -->
    <!-- notice the 'c:' namespace (available in Spring 3.1+) for inlining constructor arguments, 
         in this case the url (default is 'jdbc:hive://localhost:10000/default') -->
    <bean id="hive-ds" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"
       c:driver-ref="hive-driver" c:url="${hive.url}"/>
 
    <!-- standard JdbcTemplate declaration -->
    <bean id=" jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" c:data-source-ref="hive-ds"/>
         
    <context:property-placeholder location="hive.properties"/>
</beans>

위의 Configuration을 수행하는 자바 코드는 다음과 같다.

Hive template을 이용한 Hive API 실행

JDBC Template과 유사하게 Hive 실행도 Template을 제공한다.

다음과 같이 context 파일에서, hive-template을 만든후에, 해당 template SomeClass라는 클래스에 someBean이란 이름으로 생성해서 weaving하였다.

<hdp:hive-client-factory ... />
<!-- Hive template wires automatically to 'hiveClientFactory'-->
<hdp:hive-template />
         
<!-- wire hive template into a bean -->
<bean id="someBean" class="org.SomeClass" p:hive-template-ref="hiveTemplate"/>

SomeClass에서는 template을 받아서, hivetemplate.execute() 메서드를 수행한다.

public class SomeClass {
 
private HiveTemplate template;
 
public void setHiveTemplate(HiveTemplate template) { this.template = template; }
 
public List<String> getDbs() {
    return hiveTemplate.execute(new HiveClientCallback<List<String>>() {
       @Override
       public List<String> doInHive(HiveClient hiveClient) throws Exception {
          return hiveClient.get_all_databases();
       }
    }));
}}

 

Spring Batch Integration

마지막으로 Hadoop integration등과 마찬가지로 Spring Batch 통합을 위하여, tasklet을 제공한다.

<hdp:hive-tasklet id="hive-script">
   <hdp:script>
     DROP TABLE IF EXITS testHiveBatchTable; 
     CREATE TABLE testHiveBatchTable (key int, value string);
   </hdp:script>
   <hdp:script location="classpath:org/company/hive/script.q" />
</hdp:hive-tasklet>