当前的项目中, 涉及到了hive-jdbc/odbc这块, 因此把这几天所调研的资料作一份总结.
本文讲解hive-jdbc/hive-odbc的实现, 以期对jdbc/odbc规范和实现有个较深入的理解和看法.

在具体讲述hive-jdbc之前,首先讲解一下hive的整体架构
*) hive的整体架构
    hive-jdbc/odbc的解读和看法-LMLPHP       
    
    这幅图很清晰的表明了hive的整体架构, 以及各个组件扮演的角色, 这边专注于讲解下hive-jdbc/hive-odbc如何实现,并如何与hiveserver进行交互.    
        
*) 对hive-jdbc的理解和认识
    JDBC/ODBC两者皆是通过hiveclient与hiveserver保持通讯的,借助thrfit rpc协议来实现交互。
    hiveserver里面的session是socket连接级别,不是全局维护的,因此hiveserver的部署属于无状态节点,其HA部署方式简单采用多节点部署即可.
    在hive-0.12源码目录下,odbc是c/c++编写的源码,大致浏览了下,简单易懂,但都是与hiveserver交互的那部分代码,看不到任何与ODBC协议接口相关的内容。
    同时对比了下hive-jdbc的源码, 同一个模块下有两份hive-jdbc源码,分别为org.apache.hadoop.hive.jdbc, org.apache.hive.jdbc, 前者对应hiveserver ,后者对应hiveserver2 实现了tcliservice.thrift接口, hiveserver2加强了并发、认证等功能,同时对open api更友好。                                                                                      
    JDBC是java database connection的规范,它定义了一系列java访问各类db的访问接口,因此hive-jdbc其实本质上是扮演一个协议转换的角色,把jdbc的标准协议转换为访问HiveServer服务的协议. hive-jdbc除了扮演网络协议转化的工作, 并不承担他的工作, 比如sql的合法性校验和解析,一律忽略.
    jdbc的统一接口

public interface Connection extends Wrapper {

        Statement createStatement() throws SQLException;

        void commit() throws SQLException;

        Statement createStatement() throws SQLException;

        void close() throws SQLException;

}

public interface Statement extends Wrapper {

        boolean execute(String sql) throws SQLException;

        ResultSet getResultSet() throws SQLException;

}

public interface ResultSet extends Wrapper {

        Statement createStatement() throws SQLException;

        String getString(int columnIndex) throws SQLException;

}

hive-jdbc里最重要的3个类conection, statement, resultset.
    conection对应hiveclient的创建, statement则对应hiveclient具体sql调用接口执行, resultset对应数据的读取(采用lazy的方式 + 分批批量读取的策略, 对涉及大数据返回结果的查询sql非常友好),因为hiveclient是个长连接, 而thrift rpc是个request/response的服务方式, 一个sql会对应多次rpc访问, 因此session扮演了很重要的角色.
    其对应的服务接口如下所示:

public interface ThriftHiveMetastore.Iface {
// 对应 hive-jdbc, Statement能访问的接口,用于sql的执行
public void execute(String query) throws HiveServerException, org.apache.thrift.TException; // 对应hive-jdbc, ResultSet涉及的数据读取的接口
public String fetchOne() throws HiveServerException, org.apache.thrift.TException; public List<String> fetchN(int numRows) throws HiveServerException, org.apache.thrift.TException; public List<String> fetchAll() throws HiveServerException, org.apache.thrift.TException;
}

*) hive-server的一点看法
    Thrift最常用的还是当作rpc服务使用,请求没有session的概念,这边hiveserver采用thrift是采用worker thread pool来处理,它选用了ThreadPoolServer(One thread per connection)这种thrift提供的服务模型中,最简单的,也是最适合长连接并需要维护session的应用场景。单另一方面, 由于hiveserver没有zookeeper作协调, 而连接方式又是采用长链接, 因此可能会出现集群负载不均衡的情况. 而且,据之前对thrift的认识, thrift对超时控制缺少支持, 这方便在hive-jdbc的实现中,好像也有所体现. 个人的看法.

参考资料:
https://cwiki.apache.org/confluence/display/Hive/HiveClient
www.cnblogs.com/sharpxiajun/archive/2013/06/02/3114180.html

05-08 08:02