hive-jdbc报出异常java.net.SocketException: Broken pipe

我们这边是通过hive-jdbc,druid连接池连接hiveserver2查询hive数据,但每次hiveserver2重启后,查询程序也得重启,不然会重复使用已经无效的连接,提交的查询报错

java.lang.Exception: ERROR:org.apache.thrift.transport.TTransportException: java.net.SocketException: Broken pipe

查询DruidDataSourceFactory.createDataSource源码,发现创建连接时,super(fairLock)中给定了一些固定配置,

public DruidAbstractDataSource(boolean lockFair) {
    this.validationQuery = DEFAULT_VALIDATION_QUERY;
    this.validationQueryTimeout = -1;
    this.testOnBorrow = false;
    this.testOnReturn = false;
    this.testWhileIdle = true;
    this.testWhileIdle = true;
    ……
}

通过官方文档查询相关参数含义

配置缺省值说明
validationQuery用来检测连接是否有效的sql,要求是一个查询语句,常用select ‘x’。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
validationQueryTimeout单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法
testOnBorrowtruetrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalsefalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。

DEFAULT_VALIDATION_QUERY的值为null,即使testWhileIdle配置了true也无效,druid连接池进行dataSource.init()的时候会根据jdbc类型inti一个ValidConnectionChecker进行连接验证,hive-jdbc没有ValidConnectionChecker

this.initValidConnectionChecker();
this.validationQueryCheck();
private void initValidConnectionChecker() {
    if (this.validConnectionChecker == null) {
        String realDriverClassName = this.driver.getClass().getName();
        if (JdbcUtils.isMySqlDriver(realDriverClassName)) {
            this.validConnectionChecker = new MySqlValidConnectionChecker();
        } else if (!realDriverClassName.equals("oracle.jdbc.OracleDriver") && !realDriverClassName.equals("oracle.jdbc.driver.OracleDriver")) {
            if (!realDriverClassName.equals("com.microsoft.jdbc.sqlserver.SQLServerDriver") && !realDriverClassName.equals("com.microsoft.sqlserver.jdbc.SQLServerDriver") && !realDriverClassName.equals("net.sourceforge.jtds.jdbc.Driver")) {
                if (realDriverClassName.equals("org.postgresql.Driver") || realDriverClassName.equals("com.edb.Driver")) {
                    this.validConnectionChecker = new PGValidConnectionChecker();
                }
            } else {
                this.validConnectionChecker = new MSSQLValidConnectionChecker();
            }
        } else {
            this.validConnectionChecker = new OracleValidConnectionChecker();
        }

    }
}
private void validationQueryCheck() {
    if (this.testOnBorrow || this.testOnReturn || this.testWhileIdle) {
        if (this.validConnectionChecker == null) {
            if (this.validationQuery == null || this.validationQuery.length() <= 0) {
                String errorMessage = "";
                if (this.testOnBorrow) {
                    errorMessage = errorMessage + "testOnBorrow is true, ";
                }

                if (this.testOnReturn) {
                    errorMessage = errorMessage + "testOnReturn is true, ";
                }

                if (this.testWhileIdle) {
                    errorMessage = errorMessage + "testWhileIdle is true, ";
                }

                LOG.error(errorMessage + "validationQuery not set");
            }
        }
    }
}

为解决问题我们自己赋值validationQuery,在hive-jdbc中select 1查询性能比show databases慢很多,为了提高validationQuery查询性能我们使用show databases,为了减少返回数据数量,使用show databases LIKE 'DB_NAME’语句(自己的库名称),测试与show databases查询性能相近。

补充:
hive-jdbc不支持validationQueryTimeout参数,会报Method not supported的异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值