V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leavan
V2EX  ›  程序员

有没有用 Impala 的老哥,复杂类型好难处理啊

  •  
  •   leavan · 2020-04-24 10:59:54 +08:00 · 3110 次点击
    这是一个创建于 1674 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是这样的,最近公司打算上 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 的二次开发也是可以接受的。

    11 条回复    2020-04-24 18:39:46 +08:00
    azkaban
        1
    azkaban  
       2020-04-24 11:11:10 +08:00
    想要性能不改 sql 可以考虑 tez llap,impala 没啥优势啊,感觉全方位不如 presto,文件是 orc 的话 impala 都读不了
    EmdeBoas
        2
    EmdeBoas  
       2020-04-24 11:22:59 +08:00
    那就上 UDAF 咯,不过我不觉得这个是健康的开发模式;不能把所有的活都丢给 SQL 来干(不要欺负一个图灵不完备的 DSL =-=),离线数据就先做一层 ETL,再入库;实时数据就业务代码里面帮忙处理好,打平了再丢到存储引擎
    leavan
        3
    leavan  
    OP
       2020-04-24 11:23:43 +08:00
    @azkaban impala 对于 presto 的优势主要在于性能吧,我老大的期望是这次一步到位上个最快的引擎,之后就没必要再做类似的事情了
    leavan
        4
    leavan  
    OP
       2020-04-24 11:29:33 +08:00
    @EmdeBoas udaf 是用户自定义聚合函数吧,我的理解是多行转一行,这个能做到一行转多行吗?
    业务上倒也没有多复杂的需求,基本上 hivesql 的表达能力就都能把需求涵盖了,这次的问题主要还是从 hivesql 到 impala,表达能力又降了一截,太不适应了。
    miaoever
        5
    miaoever  
       2020-04-24 11:36:27 +08:00   ❤️ 1
    @EmdeBoas 楼主需要的是 UDTF. SQL (with recursive CTE) 是图灵完备的。
    EmdeBoas
        6
    EmdeBoas  
       2020-04-24 11:37:55 +08:00
    @leavan 可以(不过我只接触过 spark 的);不是说业务需求复杂,是说引擎里面不应该有这么多的复杂数据结构,前置需要打平和结构化,你们初衷就要追求性能,就更加不能整这么多复杂的数据结构了,要把数据做成大宽表

    追求性能就应该少用 UDF 或者 UDAF,这玩意对优化器来讲是黑盒,而且对业务侧来讲也不透明 优化空间受限
    EmdeBoas
        7
    EmdeBoas  
       2020-04-24 11:40:45 +08:00
    @miaoever 学习了,蟹蟹老哥
    leavan
        8
    leavan  
    OP
       2020-04-24 11:43:30 +08:00
    @miaoever 学习了,感谢。遗憾的是刚才查了一下,impala 不支持 udtf,唉。
    leavan
        9
    leavan  
    OP
       2020-04-24 11:44:12 +08:00
    @EmdeBoas 你说得很有道理,我如果从头设计肯定不让他这么搞...
    levelworm
        10
    levelworm  
       2020-04-24 11:45:00 +08:00 via Android
    @EmdeBoas 我赞同你,这个事情不应该把复杂结构大量的做进来。我们也用 Impala,但是很少碰到这种数据结构,一般都是大平表。
    zeraba
        11
    zeraba  
       2020-04-24 18:39:46 +08:00 via iPhone
    hive 做一层转化 转成传统的表结构 不是有个新的就一根线走到底啊 可以按照场景来
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2836 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:08 · PVG 15:08 · LAX 23:08 · JFK 02:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.