通過HiveServer2訪問Hive

Hive系列文章

  1. Hive表的基本操作
  2. Hive中的集合數據類型
  3. Hive動態分區詳解
  4. hive中orc格式表的數據導入
  5. Java通過jdbc連接hive
  6. 通過HiveServer2訪問Hive
  7. SpringBoot連接Hive實現自助取數
  8. hive關聯hbase表
  9. Hive udf 使用方法
  10. Hive基于UDF進行文本分詞
  11. Hive窗口函數row number的用法
  12. 數據倉庫之拉鏈表

先解釋一下幾個名詞:

  • metadata :hive元數據,即hive定義的表名,字段名,類型,分區,用戶這些數據。一般存儲關系型書庫mysql中,在測試階段也可以用hive內置Derby數據庫。
  • metastore :hivestore服務端。主要提供將DDL,DML等語句轉換為MapReduce,提交到hdfs中。
  • hiveserver2:hive服務端。提供hive服務??蛻舳丝梢酝ㄟ^beeline,jdbc(即用java代碼鏈接)等多種方式鏈接到hive。
  • beeline:hive客戶端鏈接到hive的一個工具??梢岳斫獬蒻ysql的客戶端。如:navite cat 等。

其它語言訪問hive主要是通過hiveserver2服務,HiveServer2(HS2)是一種能使客戶端執行Hive查詢的服務。HiveServer2可以支持對 HiveServer2 的嵌入式和遠程訪問,支持多客戶端并發和身份認證。旨在為開放API客戶端(如JDBC和ODBC)提供更好的支持。

會啟動一個hive服務端默認端口為:10000,可以通過beeline,jdbc,odbc的方式鏈接到hive。hiveserver2啟動的時候會先檢查有沒有配置hive.metastore.uris,如果沒有會先啟動一個metastore服務,然后在啟動hiveserver2。如果有配置hive.metastore.uris。會連接到遠程的metastore服務。這種方式是最常用的。部署在圖如下:

Python連接Hive

Python3訪問hive需要安裝的依賴有:

  • pip3 install thrift
  • pip3 install PyHive
  • pip3 install sasl
  • pip3 install thrift_sasl

這里有一個Python訪問Hive的工具類:

# -*- coding:utf-8 -*-

from pyhive import hive

class HiveClient(object):
    """docstring for HiveClient"""
    def __init__(self, host='hadoop-master',port=10000,username='hadoop',password='hadoop',database='hadoop',auth='LDAP'):
        """ 
        create connection to hive server2 
        """  
        self.conn = hive.Connection(host=host,  
            port=port,  
            username=username,  
            password=password,  
            database=database,
            auth=auth) 

    def query(self, sql):
        """ 
        query 
        """ 
        with self.conn.cursor() as cursor: 
            cursor.execute(sql)
            return cursor.fetchall()

    def insert(self, sql):
        """
        insert action
        """
        with self.conn.cursor() as cursor:
            cursor.execute(sql)
            # self.conn.commit()
            # self.conn.rollback()

    def close(self):
        """ 
        close connection 
        """  
        self.conn.close()
SQL

使用的時候,只需要導入,然后創建一個對象實例即可,傳入sql調用query方法完成查詢。

# 拿一個連接
hclient = hive.HiveClient()

# 執行查詢操作
...

# 關閉連接
hclient.close()
Python

注意:在insert插入方法中,我將self.conn.commit()self.conn.rollback()即回滾注釋了,這是傳統關系型數據庫才有的事務操作,Hive中是不支持的。

Java連接Hive

Java作為大數據的基礎語言,連接hive自然是支持的很好的,這里介紹通過jdbc和mybatis兩種方法連接hive。

1. Jdbc連接

java通過jdbc連接hiveserver,跟傳統的jdbc連接mysql方法一樣。

需要hive-jdbc依賴:

<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>
    <version>1.2.1</version>
</dependency>
XML

代碼跟連接mysql套路一樣,都是使用的DriverManager.getConnection(url, username, password)

@NoArgsConstructor
@AllArgsConstructor
@Data
@ToString
public class HiveConfigModel {

    private String url = "jdbc:hive2://localhost:10000";
    private String username = "hadoop";
    private String password = "hadoop";

}

@Test
public void test(){
    // 初始化配置
    HiveConfigModel hiveConfigModel = ConfigureContext.getInstance("hive-config.properties")
            .addClass(HiveConfigModel.class)
            .getModelProperties(HiveConfigModel.class);

    try {
        Connection conn = DriverManager.getConnection(hiveConfigModel.getUrl(),
                hiveConfigModel.getUsername(), hiveConfigModel.getPassword());

        String sql = "show tables";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        ResultSet rs = preparedStatement.executeQuery();
        List<String> tables = new ArrayList<>();
        while (rs.next()){
            tables.add(rs.getString(1));
        }

        System.out.println(tables);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
Java

hive-jdbc-1.2.1.jarMETA-INF下有個services目錄,里面有個java.sql.Driver文件,內容是:

org.apache.hive.jdbc.HiveDriver

java.sql.DriverManager使用spi實現了服務接口與服務實現分離以達到解耦,在這里jdbc的實現org.apache.hive.jdbc.HiveDriver根據java.sql.Driver提供的統一規范實現邏輯??蛻舳耸褂胘dbc時不需要去改變代碼,直接引入不同的spi接口服務即可。

DriverManager.getConnection(url, username, password)
Java

這樣即可拿到連接,前提是具體實現需要遵循相應的spi規范。

2. 整合mybatis

通常都會使用mybatis來做dao層訪問數據庫,訪問hive也是類似的。

配置文件sqlConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="production">
        <environment id="production">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="org.apache.hive.jdbc.HiveDriver"/>
                <property name="url" value="jdbc:hive2://master:10000/default"/>
                <property name="username" value="hadoop"/>
                <property name="password" value="hadoop"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/hive/test/test.xml"/>
    </mappers>
</configuration>
XML

mapper代碼省略,實現代碼:

public classTestMapperImpl implements TestMapper {

    private static SqlSessionFactory sqlSessionFactory = HiveSqlSessionFactory.getInstance().getSqlSessionFactory();

    @Override
    public int getTestCount(String dateTime) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);

        int count = testMapper.getTestCount(dateTime);

        sqlSession.close();

        return count;
    }
}



作者:柯廣的網絡日志

微信公眾號:Java大數據與數據倉庫