Hive JDBC Connection对于超时的处理逻辑
之前我写了一个Spark的SQL Server,可以提供标准JDBC的连接方式去执行SQL,本质上是为了解决Spark Thrift Server带来的一系列问题,当时考虑到迁移成本,整个Server兼容了HiveServer2。
对于使用者来说,就是可以继续使用Hive的JDBC Driver,切换一个端口,就能提交Spark SQL。
但是由于引擎的约束,Hive的SQL Plan是发生在HS2,然后再启动MR作业,而Spark是提交到Yarn上后,在Driver进行SQL的计划生成,所以相对来说,连接HiveServer2的速度会快很多,因为HS2有自己的服务,而对于SparkSQL Server来说,则需要等待Yarn上的作业Ready了,才能收到反馈。
正常来说,这样的设计不会有啥问题,但是对于类似SQL网关服务来说,需要考虑超时机制,也就是假设连接太长,则需要返回timeout,但是对于Yarn来说,本身是不存在超时逻辑的,如果没有资源,就会一直等下去。
Hive的JDBC Driver是提供了超时的设置方式,具体的代码在:org/apache/hive/jdbc/HiveConnection.java
的构造器里面:
public HiveConnection(String uri, Properties info) throws SQLException { |
第一行的setupLoginTimeout();
就设置了超时时间,setupLoginTimeout();
的逻辑是:
// copy loginTimeout from driver manager. Thrift timeout needs to be in millis |
也就是说Hive的connection超时来自于DriverManager.getLoginTimeout(),而DriverManager.getLoginTimeout()是一个全局性的东西,这就导致一旦针对Hive单独设置了超时时间。
对于其他JDBC Driver比如Mysql,Presto都会受影响,Hive这个处理费方式很粗暴,正确的做法是应该透出一个接口支持单独针对Hive处理,社区在https://github.com/apache/hive/pull/1611 这个PR里面提供了一个解决方案。
基本的思路就是支持在JDBC连接的时候进行超时设置,例如这样:
Class.forName("org.apache.hive.jdbc.HiveDriver"); |
目前的PR是合入了Master,在Hive4.0的release里面是有的,但是对于2x和3x就需要自己去cherry-pick了。
扫码手机观看或分享: