美文网首页
mlsql通过jdbc链接hive1.1.0版本时遇到的问题

mlsql通过jdbc链接hive1.1.0版本时遇到的问题

作者: hongshen | 来源:发表于2019-06-21 12:23 被阅读0次

    我使用的是mlsql的master分支最新版本,1.3.0-snapshot,编译时选择的是spark2.4.3

    版本不兼容的问题

    通过jdbc的方式load 时,出现了thrift版本不兼容的问题,报错的关键字是client_protocol is unset!
    jdbc连接代码:

    connect jdbc where
    url="jdbc:hive2://192.168.1.133:10000/default"
    and driver="org.apache.hive.jdbc.HiveDriver"
    and user="test"
    and password="test@11/"
    as hive2;
    
    load jdbc.`hive2.dwd.app_conf` as tb1;
    

    这时候我注意到我司的hive数据库版本是1.1.0,而spark2.4.3大版本配套的hive版本是1.2.1
    mlsql中与hive相关的依赖有:hive-thrift-server的profile,这个我在编译的时候是勾选的

           <profile>
                <id>hive-thrift-server</id>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.spark</groupId>
                        <artifactId>spark-hive-thriftserver_${scala.binary.version}</artifactId>
                        <version>${spark.version}</version>
                        <exclusions>
                            <exclusion>
                                <groupId>org.eclipse.jetty.aggregate</groupId>
                                <artifactId>jetty-all</artifactId>
                            </exclusion>
                        </exclusions>
                    </dependency>
                </dependencies>
            </profile>
    

    另外与hive相关的还有spark-hive的直接依赖。

            <dependency>
                <groupId>org.apache.spark</groupId>
                <artifactId>spark-hive_${scala.binary.version}</artifactId>
                <version>${spark.version}</version>
                <scope>${scope}</scope>
            </dependency>
    

    解决这个不兼容的问题

    我的解决办法可能会牺牲掉mlsql直接操作hive的能力
    编译时不要勾选hive-thrift-server,同时去掉spark-hive_${scala.binary.version}的依赖
    加入hive 1.1.0 的jdbc驱动

    <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-jdbc</artifactId>
                <version>1.1.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.httpcomponents</groupId>
                        <artifactId>httpclient</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.httpcomponents</groupId>
                        <artifactId>httpcore</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.zookeeper</groupId>
                        <artifactId>zookeeper</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.curator</groupId>
                        <artifactId>curator-framework</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.hive</groupId>
                        <artifactId>hive-shims</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.hive</groupId>
                        <artifactId>hive-serde</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.hive</groupId>
                        <artifactId>hive-metastore</artifactId>
                    </exclusion>
                    <!--<exclusion>
                        <groupId>org.apache.hive</groupId>
                        <artifactId>hive-service</artifactId>
                    </exclusion>-->
                    <exclusion>
                        <groupId>org.eclipse.jetty.aggregate</groupId>
                        <artifactId>jetty-all</artifactId>
                    </exclusion>
                    <!--<exclusion>
                        <groupId>org.apache.hive</groupId>
                        <artifactId>hive-common</artifactId>
                    </exclusion>-->
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    

    依赖冲突的问题还是比较多的,这个部分要耐心的去调,找一下冲突的部分,如果存在依赖冲突,有2类异常,一类是编译时报错,一类是启动运行时报错,关于如何找依赖冲突,我这边主要是根据前两类异常,通过mvn dependency:tree -Dverbose的结果去找。
    引入新的依赖后,要排除掉一些不需要的依赖、冲突的依赖;去掉一个依赖后,可能还要加上一些新的依赖,因为mlsql用到的一些包可能在你去掉的那个依赖里。
    比如我还必须要加上

            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
                <version>4.4.6</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>apache-log4j-extras</artifactId>
                <version>1.2.17</version>
            </dependency>
    

    到这里,还不算完,还要把spark的jars目录中hive相关的移除掉:


    image.png

    spark JDBC插件和hive驱动的一个小问题

    依赖冲突搞定后,编译和运行都没有了问题,但是这时候一个小问题出现了:


    hive驱动不支持设置查询超时

    这种情况不知道其他朋友有没有遇到过,不管是hive1.1.0还是1.2.1这个代码翻开后都是不支持的。
    那我的一个比较笨的办法就是抄过来改一下,这一点mlsql提供了很大的便利。
    我们先看一下mlsql的jdbc是怎么写的:


    image.png

    这个fullFormat是jdbc,短名字,说明spark知道去哪里找具体的实现,实际上具体的实现是
    JdbcRelationProvider,完整的路径是org.apache.spark.sql.execution.datasources.jdbc.JdbcRelationProvider

    image.png
    这个插件的使用文档在这里哈
    http://spark.apache.org/docs/latest/sql-data-sources-jdbc.html
    跟setQueryTimeout方法相关的有三个scala文件:
    org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD
    org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation
    org.apache.spark.sql.execution.datasources.jdbc.JdbcRelationProvider
    

    抄过来,放在一个包里,比如org.apache.spark.sql.execution.datasources.mlsql.jdbc
    相应的这三个类将包的限制去掉,同时改个名字,比如前面加上MLSQL前缀,里面其它的依赖不用动。
    这时候,我们再把用到statement.setQueryTimeout(options.queryTimeout)的部分注释掉即可

    然后修改MLSQLJDBC的fullformat为org.apache.spark.sql.execution.datasources.mlsql.jdbc.MLSQLJdbcRelationProvider
    override def shortFormat: String = "jdbc"
    这样就解决了hive驱动不能设置setQueryTimeout的问题。

    执行发现没有数据返回

    connect jdbc where
    url="jdbc:hive2://192.168.1.133:10000/default"
    and driver="org.apache.hive.jdbc.HiveDriver"
    and user="test"
    and password="test@11/"
    as hive2;
    
    load jdbc.`hive2.dwd.app_conf` as tb1;
    

    通过debug发现需要设置一个参数fetchsize
    改为:

    connect jdbc where
    url="jdbc:hive2://192.168.1.133:10000/default"
    and driver="org.apache.hive.jdbc.HiveDriver"
    and user="test"
    and password="test@11/"
    and fetchsize="10"
    as hive2;
    
    load jdbc.`hive2.dwd.app_conf` as tb1;
    

    这时候,就可以正常load hive1.1.0的数据了

    小结

      1、解决依赖冲突还是比较麻烦的,基础依赖和功能性依赖最好能分开,否则增减功能性依赖的时候,排查冲突很费劲。
      2、我这样只是解决了用jdbc load hive1.1.0的问题,可能跟mlsql的一些其它功能冲突。

    相关文章

      网友评论

          本文标题:mlsql通过jdbc链接hive1.1.0版本时遇到的问题

          本文链接:https://www.haomeiwen.com/subject/vpfyqctx.html