是这样的,最近公司打算上 impala 来做快查,但是在复杂类型( map 、array 、struct )上面有很大的问题。 impala 和 hive 大部分时候都能兼容,偶尔兼容不了想想办法也能凑合过去,这个问题我实在是没辙了,各位老哥帮忙想想办法。
impala 访问复杂类型的方式过于奇葩,比如 map 吧,他不支持中括号的方式访问通过键访问值,而是必须以这种方式(来自官方文档):
DESCRIBE table_0;
+---------+-----------------------+
| name | type |
+---------+-----------------------+
| field_0 | string |
| field_1 | map<string,int> |
...
SELECT field_0, map_field.key, map_field.value
FROM table_0, table_0.field_1 AS map_field
WHERE length(field_0) = 1
LIMIT 10;
+---------+-----------+-------+
| field_0 | key | value |
+---------+-----------+-------+
| b | gshsgkvd | NULL |
| b | twrtcxj6 | 18 |
| b | 2vp5 | 39 |
| b | fh0s | 13 |
| v | 2 | 41 |
| v | 8b58mz | 20 |
| v | hw | 16 |
| v | 65l388pyt | 29 |
| v | 03k68g91z | 30 |
| v | r2hlg5b | NULL |
+---------+-----------+-------+
同时复杂类型的值不支持出现在任何 select list 中,也就是说在子查询中传递复杂类型给父查询是行不通的,必须展开再传递展开后的基本类型!这个是没法凑合的,一方面公司的数据开发人员肯定不会习惯这种语法,另一方面公司已经有大量的 hive 查询的语句了,本来打算上了 impala 之后写个语法转换器把 hive 的查询转成 impala 的,但由于这个复杂类型的问题,拓扑结构都变了,我甚至觉得理论上很多逻辑都是没法用 impala 这种受限的语法复现的。(这只是我的直觉,当然如果哪位老哥能给资料证明两种形式表达能力相同,有转换的方式,小弟感激不尽~)
我能想到的解决办法就是用 udf,参考 https://blog.csdn.net/yu616568/article/details/79198501 这篇文章,把所有的复杂类型都看成 string,再用自己写的 udf 去解析它、根据键取值啥的,由于是用 C++写的,所以速度上应该也不会慢到哪里去。
但是这样还是有问题没解决,impala 不支持 lateral view,也就是列转行,而我们之前的 hive 查询中有大量此类语句,这个就没法通过 udf 解决了,毕竟 udf 也只能传进去基础类型、传出来基础类型,并没有改变拓扑结构的能力,而我找了半天,impala 中唯一可能成为替代品的就是复杂类型的展开了,可以把列转成行,可是这样又绕回来了,impala 中的复杂类型就是个坑,唉。
各位老哥,求教这个问题有可能解决吗,在不换掉 impala 的情况下,少许对 impala 的二次开发也是可以接受的。
1
azkaban 2020-04-24 11:11:10 +08:00
想要性能不改 sql 可以考虑 tez llap,impala 没啥优势啊,感觉全方位不如 presto,文件是 orc 的话 impala 都读不了
|
2
EmdeBoas 2020-04-24 11:22:59 +08:00
那就上 UDAF 咯,不过我不觉得这个是健康的开发模式;不能把所有的活都丢给 SQL 来干(不要欺负一个图灵不完备的 DSL =-=),离线数据就先做一层 ETL,再入库;实时数据就业务代码里面帮忙处理好,打平了再丢到存储引擎
|
3
leavan OP @azkaban impala 对于 presto 的优势主要在于性能吧,我老大的期望是这次一步到位上个最快的引擎,之后就没必要再做类似的事情了
|
4
leavan OP @EmdeBoas udaf 是用户自定义聚合函数吧,我的理解是多行转一行,这个能做到一行转多行吗?
业务上倒也没有多复杂的需求,基本上 hivesql 的表达能力就都能把需求涵盖了,这次的问题主要还是从 hivesql 到 impala,表达能力又降了一截,太不适应了。 |
6
EmdeBoas 2020-04-24 11:37:55 +08:00
@leavan 可以(不过我只接触过 spark 的);不是说业务需求复杂,是说引擎里面不应该有这么多的复杂数据结构,前置需要打平和结构化,你们初衷就要追求性能,就更加不能整这么多复杂的数据结构了,要把数据做成大宽表
追求性能就应该少用 UDF 或者 UDAF,这玩意对优化器来讲是黑盒,而且对业务侧来讲也不透明 优化空间受限 |
10
levelworm 2020-04-24 11:45:00 +08:00 via Android
@EmdeBoas 我赞同你,这个事情不应该把复杂结构大量的做进来。我们也用 Impala,但是很少碰到这种数据结构,一般都是大平表。
|
11
zeraba 2020-04-24 18:39:46 +08:00 via iPhone
hive 做一层转化 转成传统的表结构 不是有个新的就一根线走到底啊 可以按照场景来
|