今天有空聊聊大数据技术。Project Tardigrade是今年大数据技术里面值得聊几句的东西。不知道有多少人听说过?
我想写这个话题有段时间了,但是一直都比较懒,没写。
这个项目是Trino,也就是以前分裂出来的Presto和它背后的大数据初创公司做的。
具体的介绍可以参考这篇博客文章:https://trino.io/blog/2022/05/05/tardigrade-launch.html
很不幸的是,如果你去读这篇文章,你会读得云里雾里。比如说标题:Project Tardigrade delivers ETL at Trino speeds to early users
什么叫做ETL at Trino speeds。我一开始以为这个项目是增强ETL功能和速度的,比如说,增加对UDF UDA的支持。很不幸,一点关系都没有。这方面还是佩服databricks的文档功底。确实一堆教授和PhD就是不一样。
Project Tradigrade最核心干的一件事情是:当Trino的一个query的某些节点fail了或者慢了,能不能不要把整个query都fail了,而是对这些节点进行retry。
这东西听起来不是什么新鲜事。远的10多年前微软的Dryad就能做,近一点的Spark节点fail了,在DAG上retry也是司空见惯。
Trino这个MPP架构的计算引擎,做这个事情难在哪里呢?这个问题我觉得可以从这两方面看。
要能够retry,首先scheduler要能够监视这个query有没有failure,有的话是在哪个节点挂了。其次是能够有reschedule那些需要retry的节点的功能。这个基础功能今天在Trino里面是没有的。
第二个方面,整个执行引擎要有retry的基础。Retry的基础是什么呢?还是两个方面的事情:
1.operator每次run的时候,出的结果是deterministic的。
2.前一次的fail不会对,后一次的retry产生副作用。
先聊聊deterministic的事情,举个例子,Trino在做Table Scan的时候,会随机分配一些文件chunk给不同的节点去读,这个决定是在runtime做的。这样一来下一次如果运行某个节点之后,它被分配到的文件chunk和上一次可能不一样,然后,就没有然后了。
再聊聊第二个,举个例子,如果第一次retry产生了一些partial result,第二次又产生了一堆result,而第二次的result没有覆盖掉第一次的那些partial result,那么最后的output就莫名其妙多了一些数据。
大家可能看起来很奇怪,但是这些都是Trino在Project Tardigrade中面临的真实问题。
总之Trino的execution engine有很多需要修补的地方。
这些都考虑进去之后,事情完了吗?没有。Trino以前就是一个纯内存是streaming方式的MPP引擎。但是retry的话,就需要选择合适的节点,对这个节点下面的partial result先存到永久存储里面去。
否则的话,就意味着一个query上面任何一个地方坏了,可能导致整个query都要重新跑过,这个代价无法接受。但是这个合适的节点怎么选择呢?这是Trino在这个project里面遇到的另外一个问题。简单来说,选择在exchange operator附近做这个事情是比较合适的,具体的大家还是去阅读技术文档我就不展开了。
Project Tardigrade做的事情大概就是这些,得到的是一个更稳定的query engine,可以retry,也可以在某些节点慢了的时候schedule another copy run。
那么这个project也不是没有代价,新增的东西可以导致查询变慢,尤其是原来不需要这些能跑成功的查询,也会更慢。这个代价的大和小,取决于Project Tardigrade的实现水平如何。
大概来说,这个项目离成熟还是有不少距离。但是大概的意思就是我上面说的。当然,大家肯定还会问我,这个项目做得怎么样。
我的经验判断,有些东西没毛病,还有一些东西,不好说。举个例子,这种deterministic的operator核心问题很多时候还是什么东西应该compile time决定,什么时候runtime决定。
基于已经公开的资料判断,我并不觉得他们对这个问题的理解足够深刻了。我随便举个例子,如果query里面有random函数,而random需要实现deterministic random才可以retry,至少我并没有看到他们认真讨论过这个问题。
即使有这样那样的缺陷,将来都可以修补。无论如何,我们都不能否定这个项目对Trino发展的意义。