hive-jdbc的默认超时时间被mysql超时时间覆盖

现象

hive-jdbc.2.1.1版本

在循环遍历查询数据,并且同时处理发现偶尔会出现SocketException异常,推测异常是由于超时导致的,结果验证果然超时时间被设置为了mysql的30s

Error retrieving next row
java.sql.SQLException: Error retrieving next row
        at org.apache.hive.jdbc.HiveQueryResultSet.next(HiveQueryResultSet.java:396)
        .....
Caused by: org.apache.thrift.transport.TTransportException: java.net.SocketException: Connection reset
        at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:129)
        at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
        at org.apache.thrift.transport.TSaslTransport.readLength(TSaslTransport.java:376)
        at org.apache.thrift.transport.TSaslTransport.readFrame(TSaslTransport.java:453)

原因

  1. org.apache.hive.jdbc.HiveConnection的setupLoginTimeout方法可以看出超时时间默认取的是DriverManager.getLoginTimeout(),loginTimeout最终就是Socket的setSoTimeout时间
  
  private void setupLoginTimeout() {
    long timeOut = TimeUnit.SECONDS.toMillis(DriverManager.getLoginTimeout());
    if (timeOut > Integer.MAX_VALUE) {
      loginTimeout = Integer.MAX_VALUE;
    } else {
      loginTimeout = (int) timeOut;
    }
  }
    private TTransport createUnderlyingTransport() throws TTransportException {       
     ...
            transport = HiveAuthFactory.getSocketTransport(this.host, this.port, this.loginTimeout);
            ...
    }

// 下面是HiveAuthFactory类中的方法
  public static TTransport getSocketTransport(String host, int port, int loginTimeout) {
    return new TSocket(host, port, loginTimeout);
  }

// 下面是thrift的TSocket类中的方法
  private void initSocket() {
    socket_ = new Socket();
    try {
      socket_.setSoLinger(false, 0);
      socket_.setTcpNoDelay(true);
      socket_.setKeepAlive(true);
      socket_.setSoTimeout(socketTimeout_);
    } catch (SocketException sx) {
      LOGGER.error("Could not configure socket.", sx);
    }
  }
  1. 在DriverManager.setLoginTimeout方法上打断点调试可以看到DriverManager.getLoginTimeout()的超时时间被覆盖
    HikariDataSource.getConnection()---->new HikariPool(this)------>PoolBase.initializeDataSource()----->PoolBase.setLoginTimeout----->DriverDataSource.setLoginTimeout()----->DriverManager.setLoginTimeout

HikariDataSource extends HikariConfig

private static final long CONNECTION_TIMEOUT = SECONDS.toMillis(30);
 public HikariConfig()
   {
      connectionTimeout = CONNECTION_TIMEOUT;
   }

PoolBase.setLoginTimeout

   private void setLoginTimeout(final DataSource dataSource)
   {
      if (connectionTimeout != Integer.MAX_VALUE) {
         try {
            dataSource.setLoginTimeout(Math.max(1, (int) MILLISECONDS.toSeconds(500L + connectionTimeout)));
         }
         catch (Throwable e) {
            LOGGER.info("{} - Failed to set login timeout for data source. ({})", poolName, e.getMessage());
         }
      }
   }

Issue-HIVE-22196 有进行说明

修复方案

  • 重写org.apache.hive.jdbc.HiveConnection的setupLoginTimeout方法,打包上传到自己的maven仓库, 最新版本hive-jdbc-3.1.2中这个问题仍然存在
  • 在使用hive前手动调用 DriverManager.setLoginTimeout

Hive任务超时报错 Invalid OperationHandle

Hive-JDBC Uber Jar 是一个包含了所有依赖项的单一 JAR 文件,使得使用 Hive JDBC 连接数据库更加方便。为了下载 hive-jdbc-uber-jar,您可以按照以下步骤进行操作: 1. 打开您的网络浏览器并访问 Apache Hive 的官方网站(https://hive.apache.org/)。 2. 在页面的顶部菜单栏中,您会找到一个"Downloads"(下载)的选项。单击这个选项。 3. 在下载页面上,您可以看到不同的 Hive 版本和相关的下载链接。根据您的需求选择适合的版本。一般建议选择最新版本。 4. 找到并单击下载链接,以启动 hive-jdbc-uber-jar 文件的下载。可以选择一个合适的下载镜像,点击相关链接即可开始下载。 5. 下载完成后,您可以在您指定的下载文件夹中找到 hive-jdbc-uber-jar 文件。可以通过文件管理器打开文件夹并查看文件。 在您下载了 hive-jdbc-uber-jar 文件后,您可以将其添加到您的项目中,并使用 HiveJDBC API 连接到 Hive 数据库。您可以在项目的构建路径中添加该 JAR 文件,并在代码中引入相关的类和方法。确保在代码中正确配置 JDBC 连接参数,如 Hive 服务器的 URL、用户名和密码等。 总结起来,您可以通过在 Apache Hive 官方网站下载页面上选择适当的 Hive 版本并点击相关的下载链接,从中直接下载 hive-jdbc-uber-jar 文件。这个 JAR 文件是使用 Hive JDBC 连接到 Hive 数据库时所需的所有依赖项的集合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值