使用jdbc查询impala时的超时问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用jdbc查询impala时的超时问题相关的知识,希望对你有一定的参考价值。

参考技术A 项目中应用服务直接通过jdbc连接impala做数据查询,其他遇到一个问题,查询impala时因为没有设置查询超时,有些大sql一直占用连接,同时这个sql在impala集群中执行着,也占用了impala集群的资源,这样挤压了其他sql的响应。所以这时候设置查询超时,让连接断开,空闲出集群资源能够很大程度上提升服务的稳定性。

连接impala的jdbc主要有cloudera jdbc和hive jdbc。因为需要使用kerberos认证来连接impala,最开始同事为了简单话选择了hive jdbc,配置kerberos也方便( 官方推荐 Cloudera JDBC Connector )。开始用的很爽,但后面发现并不能设置查询超时(Statement.setQueryTime()无效,但是如果通过hive jdbc连接查询hive的话是能够生效的--- HIVE-4924 ,查询impala却不行)。最后想查询下hive jdbc是否还有其他参数能够设置,通过几天的寻找,最终却无果。
后来把目光放在了cloudera jdbc上,通过文档中的参数,发现一个SocketTimeout参数,并在本地尝试了cloudera jdbc配置上SocketTimeout这个参数,在自测过程上都出现了大的查询没有执行完,因为SocketTimeout时间到了而断开并抛出socket timeout exception,当时很开心,以为问题解决了,当把这个拿给同事时,同事试了几次,有时候会timeout断开,有时候却根本不断开,直到sql执行成功返回,基本宣布这个参数失败。
再一次失败后,都快觉得这个问题搞不定了,我觉得不太可能是官方定义了一个不靠谱的参数,更可能是自己理解上面的错误,后来又反复查看了这个参数的解释(The number of seconds after which Impala closes the connection with the client application if the connection is idle),一旦连接空闲超过这个时长,impala就会关闭应该客户端的连接。什么叫connection is idle,以及它为何叫socketTimeout却不是查询超时的英文呢?socket是网络层,而且在参数定义中,说连接空闲,而不是连接占用的时间。有了这些疑问后,又搜索查询了一番,最终在一篇文章中,很详细的解释了jdbc中的 各种timeout 。

通过这篇文章的讲解,我知道我之前在hive jdbc配置的Statement.setQueryTime()是statement timeout,它是依赖于更低基本的socket timeout, impala没有生效的原因很大可能是对于impala的查询statement并没有去处理超时(Statement Timeout Execution Process for JDBC Driver),而对hive查询却做了处理。
而cloudera jdbc提供了socket timeout参数,也在statement timeout提供了超时的处理,即statement查询超时后会中断查询并抛出java.sql.SQLTimeoutException。所以配置上Statement.setQueryTime(),就能够在查询超过timeout值后抛出异常,关闭连接。
最后讲queryTimeOut配置入DataSource,与orm结合,查询超时问题算告一段落。

cloudera jdbc: https://www.cloudera.com/documentation/enterprise/5-11-x/topics/impala_jdbc.html#jdbc_driver_choice
query timeout: https://www.cubrid.org/blog/understanding-jdbc-internals-and-timeout-configuration
带有kerberos验证连接impala: http://blog.csdn.net/tlqfreedom/article/details/75220058

Impala 通过 JDBC 流式传输真的很慢

【中文标题】Impala 通过 JDBC 流式传输真的很慢【英文标题】:Impala streaming over JDBC is really slow 【发布时间】:2017-05-16 01:44:19 【问题描述】:

我使用 impala-shell 运行了几个大型查询,发现性能令人满意。这些查询通常将 100k-1m 行写入磁盘。但是,当我使用 JDBC 以编程方式运行相同的查询时,将结果写入磁盘需要更长的时间。例如,从 impala-shell 需要 5 分钟的查询在 JDBC 上最多需要 30 分钟。

我已经尝试过 Hive 和 Cloudera JDBC 驱动程序,但性能同样很差。我尝试了各种获取大小,但没有任何区别。 Impala 通过 JDBC 进行流式传输从根本上来说很慢,还是我可以做其他事情来加速流式传输?

这是在 CDH 5.9.1 上。

【问题讨论】:

“流媒体”是什么意思?你能举一个你正在运行的查询的例子吗? 基本上,如果您正在运行INSERT SELECT 查询,则数据不会由您的客户端应用程序传输,因此“获取大小”无效。而按顺序运行 1000 个小查询意味着创建至少 1000 个 HDFS 文件(复制 x3),这与运行一个大查询不同。 【参考方案1】:

结果证明这是一个客户端问题。我正在使用 curl 来测试一个进行 Impala 查询的 Web 应用程序。从 curl 切换到使用 Scala 代码编写的客户端消除了延迟。

【讨论】:

以上是关于使用jdbc查询impala时的超时问题的主要内容,如果未能解决你的问题,请参考以下文章

使用本地 Impala 连接执行单元测试用例

Parquet 支持的 Hive 表:Impala 中不可查询的数组列

Impala 通过 JDBC 流式传输真的很慢

无法使用 Impala JDBC 驱动程序通过 Java 应用程序连接到 Impala

Impala动态资源池及放置规则使用

Impala 的问题。 “查询等待关闭”