腾讯天穹 StarRocks 一站式湖仓融合平台架构揭秘


作者:腾讯大数据 高级工程师 陈九天

小编导读

腾讯天穹是协同腾讯内各 BG 大数据能力而生的 Oteam,作为腾讯大数据领域的代名词,旨在拉通大数据各个技术组件,打造一个具有统一技术栈的公司级大数据平台体系。从底层数据接入、数据存储、资源管理、计算引擎、作业调度,到上层数据治理及数据应用等多个环节,支持腾讯内部近 EB 级数据的存储和计算,为业务提供海量、高效、稳定的大数据平台支撑和决策支持。

本文介绍了目前业内在湖仓融合场景下遇到的问题:湖仓数据如何自由流转、湖仓数据如何做到融合查询、如何优化湖仓建模链路等,同时介绍了天穹 StarRocks 湖仓融合架构是如何解决以上问题,并大规模落地腾讯内部业务的。该架构在兼顾查询性能与存储成本的情况下,大大简化了用户的湖仓建模链路。

当前湖仓融合架构面临的问题

数据湖的核心优势在于开放生态,数据湖通常会采用开放的存储格式,支持各种类型数据,扩展性强、存储成本比较低。而数仓的核心优势在于数据质量高,查询性能比较强,具备实时分析能力,数据治理功能完善等。数据湖和数据仓库各有优势,我们希望通过湖仓融合来充分发挥两者的优势。

图中为 Kappa 架构下使用数据湖和数据仓库的典型方式。我们通常会在湖中进行数据建模,将清洗过后的数据入仓,把冷数据存在湖中、热数据入仓,以此实现降本增效。在湖上的查询对性能可以不太敏感,而仓中则对性能更加敏感,会根据场景选用不同的引擎。

图中的架构已经比较简单,但仍然有两个值得优化的方向:

  • 分析引擎还处于百花齐放的状态,各有优劣,用户经常会遇到选型困难的问题;

  • 数据建模的链路比较长,涉及的组件也比较多;

针对第一个问题,我们在 2.1 版本的时候引入了 StarRocks,StarRocks 当时已经是一款极其优秀的 OLAP 引擎,我们最初是希望用 StarRocks 来替换 ClickHouse,因为两者有着性能相当的单表查询能力,而 StarRocks 还有着更加优秀的多表查询和分布式能力,可运维性也更强。

后来陆续有用户找到我们,希望在 BI 系统中替换一些 MySQL 的指标数据查询,还有一些在线业务希望用 StarRocks 替换有简单聚合场景的 HBase 这种类 KV 系统。这个时候的 StarRocks 其实已经具备在大多数场景下统一查询引擎的能力了。

StarRocks 在 2.5 和 3.0 之后,加强了数据湖查询能力。它提供了极速的湖仓分析、统一的 Catalog 管理以及开放的 lakehouse 架构,为后面进一步的湖仓融合打下了坚实的基础。至此我们已经可以利用 StarRocks 非常方便的查询数据湖中的数据,但是离湖仓融合我们认为还是有距离,所以我们也在思考在现有架构下,还能帮用户做哪些优化来实现真正的湖仓融合。我们总结了以下 3 点:

  • 湖仓之间的数据如何更好的互相流转?

  • 如何在查询时融合湖仓两套系统,不仅仅是用 StarRocks 去查数据湖?

  • 湖仓建模的链路过于复杂,是不是可以进一步简化?

天穹 StarRocks 解决方案

湖仓数据流转

对于湖仓相互流转,其实我们可以拓展出两个场景:

  • 湖入仓的场景,将数据湖中的数据导入到 StarRocks,用来加速查询。

  • 仓出湖的场景,对于一些时效性比较高的数据,用户会希望先进到 StarRocks 进行高时效性的查询分析,数据冷却之后,再通过一些工具来导出到数据湖当中。

湖入仓场景优化

在湖入仓场景下,目前一般通过第三方组件写入,或者采用 StarRocks 内置的离线导入方式来进行湖入仓。但现有工具还存在一些潜在问题,一方面会引入新的组件和任务,给用户的处理链路增加了复杂度,同时这些工具更多的是进行 T+1 离线导入,无法保证实时性。天穹 StarRocks 通过外表物化视图和 Iceberg routine load 的方式解决以上的问题,可以直接从多种湖表导入,同时灵活刷新增量写入,实时性和效率会更高。

外表物化视图

外表物化视图以数据湖上的一张或多张表为基础,在 StarRocks 建立物化视图。物化视图在 StarRocks 中呈现为一张表,可以直接查询,我们可以通过外表物化视图的方式将湖中的表映射到 StarRocks 中,从而达到湖入仓的效果。

Iceberg routine load

目前外表物化视图以分区级别进行刷新,而 Iceberg 的数据一般为分钟级,频繁的数据刷新可能会导致集群负载无法支撑,对此我们采用了 Iceberg routine load 方式来实现增量湖入仓,具体而言,会对 Iceberg 的两个 snapshot 之间的增量文件进行预处理,生成子 task,然后将 task 分发给 BE 执行。它是完全增量式的刷新,可以使用更少的资源,而且持续的流式写入也拥有更高的实时性。

仓出湖场景优化

在仓出湖场景下,通常会采用 export 将 StarRocks 中的数据导出到数据湖中,这种方式存在一定的局限性,只能导出到某个外部目录,无法导出到表。如果希望导出到表,首先要确认这张表的底层存储路径,然后才能进行配置,对用户不太友好。另外它是一个独立的功能,无法做到湖仓联动,部分情况下会导致湖跟仓数据不一致。

我们开发了 cold down 数据降冷功能来解决以上问题,可以支持直接导出到任意一张图表中,并且是一键配置,自动触发,可以贯穿表的整个生命周期。

图中右侧是 cold down 任务创建语句,其中 db1.tbl1 是需要导出的 StarRocks 原表,external table 配置的是在湖上的目标表,同时也支持一些其它配置参数。值得一提的是,这个参数后面跟我们的湖仓融合查询实现了联动。如果在湖上的目标表没有创建出来,我们会帮助用户自动将湖上的表创建出来。如果 StarRocks 中的表出现了 schema change,这个 change 也会被自动 apply 到数据湖的表。同时我们将降冷周期跟 TTL 做了解耦,能够自动感知数据变冷并且触发降冷。

在表类型上,我们支持了 Iceberg、Hudi、Hive ,存储格式包含 Parquet 和 ORC,覆盖了大多数场景。

湖仓融合查询

在湖仓融合场景下,经常会遇到以下这两个问题:

  • 用户将部分热数据导入 StarRocks 加速查询,但不一定清楚哪部分数据已经入仓了,最后还需要检查周期、表名,使用起来不是非常方便。

  • 想要查询的数据已经通过仓出湖的方式导出到数据湖中,并且已经从数仓删除,这种情况下就需要同时查两张表,一张是热表,一张是冷表,然后通过 union all 语句把数据聚合起来。这种方式的缺点显而易见,就是用户需要显示的指定两张表进行查询。

在这里我们可以看到湖仓并未融合,因为用户明确知道一张是仓里的表,一张是湖里的表,同时还需要准确的指定两张表,各自的查询范围有时还可能容易出错。在理想的湖仓融合方案中,用户只需要指定一张表,无论它是热表还是冷表,表视图都是统一。同时用户只需要指定想要查询的范围,不需要区分哪部分数据在湖,哪部分数据在仓,系统会帮用户自动感知查询范围。

采用天穹 StarRocks 实现的解决方案,只需要在建表或修改表属性时增加一个相关属性,该属性会帮助我们将 StarRocks 中的热表跟湖上的冷表进行关联。同时我们开发了一个 session 级别的参数,以便于用户在不同场景下选择是否开启融合查询功能。

湖仓建模体系

有些用户没有复杂的 ETL 流程,也不希望去维护一套冗长的 ETL 链路和任务。在这种情况下,湖仓融合架构应该怎样进一步优化?其实可以通过物化视图的方式在 StarRocks 内部进行湖仓建模,这种方式简化了运维,用户不用再去维护各种组件,只需要 StarRocks 和 Iceberg 就能完成数据分析方案的构建,大大简化数据链路。

天穹 StarRocks 湖仓融合架构

通过解决以上问题,我们构建了天穹 StarRocks 湖仓融合架构的最终形态。在这个架构下,可以通过外表物化视图、Iceberg routine load 的方式进行湖入仓,同时可以通过 cold down 数据降冷功能进行仓出湖,打开隐式融合查询开关,就能进行湖仓融合查询。如果用户希望简化数仓建模链路,则可以直接利用物化视图功能在 StarRocks 内部进行湖仓建模。总体上,这是一个非常简洁高效并且用户友好的湖仓融合架构。

全面融入天穹架构

在前面提到的功能里,假定了冷表跟热表的 table schema 完全一致,但在实际建表过程,不一定会考虑到湖仓融合场景,或者在这个功能开发出来前用户的表已经建好,这种情况下冷表跟热表无法做到完全一致,有可能列名不一致,也有可能列不对齐,或者列的类型因为系统不一样而不一致。

为了将这些类型的表也加到我们的湖仓融合架构中,我们实现了列映射的配置,基于该配置生成执行计划时,会自动根据配置将用户冷热表中的列进行一些转换和校验,确保计划可以顺利执行。我们公司内部有大量的存量表还在使用 RCfile,为了将这些表也能够纳入到天穹架构,我们通过 JNI 的方式支持了 RCfile 数据的读取。

此外,早年在 Oracle 和 Hadoop 迁移过程中,团队进行了很多因地制宜的改造,其中 range 分区也被大量使用,我们主要支持了 range 分区的裁剪。

通过解决以上问题,大量的内部用户可以非常方便地将已有的或者新的数据场景接入到天穹 StarRocks 湖仓架构中来,这个架构能兼顾查询性能跟存储成本,并且大大简化用户的湖仓建模成本。

未来展望

在湖仓场景的功能迭代方面,我们会继续全面兼容 THive 还有 Presto 的语法与函数,让存量表接入更加方便。同时会进一步优化 Iceberg 的查询性能,持续增加各种杂类型的支持。同时我们也会基于天穹 OMS 的元数据更新机制去实现外表物化视图的增量更新。

在产品化的方面,天穹 StarRocks 将借助于 WeDATA 的产品能力,为用户提供更好的湖仓融合服务。

这个功能会在社区版本开源么?