Impala JDBC/ODBC driver返回不完整数据的解决办法

背景

用户在升级到CDP或Impala-3.4后,可能遇到JDBC/ODBC driver返回不完整数据的情况。比如实际查询结果有100行,但返回90行就结束了,每次的结果不一定相同,只有在时长超过10秒的查询会出现。这可能是遇到了JDBC/ODBC driver的bug,可以尝试以下两种方式解决:

  • Query Option 里 set fetch_rows_timeout_ms=0
  • 升级driver版本,JDBC driver版本至少要到2.6.20,ODBC driver版本至少要到2.6.12

如果以上方法有效,就跟我们要讲的这个bug有关。

客户端流程

客户端与Coordinator交互有两种协议:beeswax和hs2协议。它们都是基于Thrift实现的,各种接口基本上能一一对应。对于一个查询的执行,客户端的请求流程如下,以beeswax协议为例:

Created with Raphaël 2.3.0 executeAndWait fetch finish? close yes no

对应的HS2 RPC如下:

beeswaxhs2
executeAndWaitExecuteStatement
fetchFetchResults
closeCloseOperation

问题出在finish的判定上。

Finish判定

Beeswax 的 fetch RPC 和 HS2 的 FetchResults RPC 的返回类型定义如下:

// beeswax result
struct Results {
  // If set, data is valid.  Otherwise, results aren't ready yet.
  1: bool ready,
  // Columns for the results
  2: list<string> columns,
  // A set of results               
  3: list<string> data,
  // The starting row of the results
  4: i64 start_row,
  // Whether there are more results to fetch
  5: bool has_more
}

// hs2 result
struct TFetchResultsResp {
  1: required TStatus status

  // TRUE if there are more rows left to fetch from the server.
  2: optional bool hasMoreRows

  // The rowset. This is optional so that we have the
  // option in the future of adding alternate formats for
  // representing result set data, e.g. delimited strings,
  // binary encoded, etc.
  3: optional TRowSet results
}

它们除了返回一组数据,还返回一个bool值(has_more、hasMoreRows)标记是否还有更多的数据。理论上用这个值来判断是否要结束就可以了,但如果客户端偷懒,只判断返回的数据是否为空,是否也可行呢?

流水线执行

Impala使用MPP架构设计,区别于MR、Spark、Tez等的一大特点是流水线式执行。查询计划由多段流水线组成,查询的执行由流水线的消费者驱动。客户端就是最后一条流水线的消费者。

客户端开始获取结果时,流水线的另一端可能还在执行。比如一个简单的 select … from tableA where col = ‘A’ 查询,ScanNode是分布式执行的,每个ScanNode内部也是流式执行的,每次读一片数据过滤完就可以返回结果。因此客户端可以开始拉取数据时(即 “Rows Available” 状态),并不代表所有结果都已经生成了。有可能第一批数据被拉取完后,要过10秒或更长的时间才能拉取下一批数据。

IMPALA-7312后 fetch RPC 的变化

在 IMPALA-7312 之前,fetch请求是阻塞式的,会卡住直到有查询结果可返回为止。因此 fetch 返回的结果都有数据。直到所有结果都被拉取完时,fetch 才会返回空集。虽然这是老版本Impala的表现,但这并不是一个定义好的行为,实际上还得用 has_more/hasMoreRows 标记来判定是否还有结果没拉取。

IMPALA-7312 引入了 fetch_rows_timeout_ms 这个查询选项,给 fetch 请求加了超时。服务器端(即coordinator)会在超时前返回一个结果,该结果可能为空,但has_more/hasMoreRows 会标记查询结果是否全返回了。如果客户端没有判断 has_more/hasMoreRows,只看 fetch 返回的结果集是否为空,就可能误判结束标志。此时只能设 fetch_rows_timeout_ms = 0 来绕过这个超时机制。

由于 impala-shell 一直是有判定 has_more/hasMoreRows 这个域的,所以不受影响。这个问题主要出在 Impala JDBC/ODBC driver上。

升级客户端

这个问题在 Impala JDBC/ODBC 的 Release Note 中都有提及,如 JDBC driver 2.6.20:

Released 2020-12-18
The following issues have been resolved in Simba Impala JDBC Driver 2.6.20.

  • [00265194][IMPJ-606] When the server returns 0 rows, the driver stops
    fetching results.

ODBC driver 2.6.12:

Released 2020-12-23
The following issue has been resolved in Cloudera ODBC Driver for Impala 2.6.12.

  • [IMP-806][00265194] When the server returns 0 rows, the driver stops fetching
    results.

总结

Impala JDBC/ODBC driver 使用了未定义的方式来判定查询结束,该方式在 IMPALA-7312 之后不可行。因此解决办法是关闭 IMPALA-7312 引入的超时机制(即 set fetch_rows_timeout_ms = 0)或者升级 JDBC/ODBC driver。

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值