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

2019-06-21  本文已影响0人  hongshen

我使用的是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的一些其它功能冲突。
上一篇下一篇

猜你喜欢

热点阅读