您的位置:首页 > 科技 > IT业 > Impala JDBC/ODBC driver返回不完整数据的解决办法

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

2024/10/5 3:55:14 来源:https://blog.csdn.net/huang_quanlong/article/details/140184422  浏览:    关键词: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 results2: list<string> columns,// A set of results               3: list<string> data,// The starting row of the results4: i64 start_row,// Whether there are more results to fetch5: 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。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com