实时湖仓一体在腾讯的落地实践

本文根据邵赛赛老师在〖中国数据智能管理峰会-上海站〗现场演讲内容整理而成。

作者介绍

邵赛赛,前腾讯实时湖仓团队负责人,现Co-FounderCTOofDatastrato。Apache基金会成员,ApacheSparkInlongLivyPMC成员,曾就职于Hortonworks、Intel,10年的大数据从业经验,专注于分布式流批计算引擎的研发和优化。

分享概要

一、湖仓一体技术诞生的背景和现状

二、湖仓一体技术现存的问题

三、腾讯在湖仓一体上的工作

四、后续规划

一、湖仓一体技术诞生的背景和现状

1.湖仓的演进

1)数据仓库(90s)

需要进行数据处理的公司在湖仓演进的架构选择上都十分相似。起初,首选方式是数仓架构,比如teradata、greenplum或Oracle等。通常数据处理的流程是把一些业务数据库,如TransactionalDatabase等,通过ETL的方式加载到DataWarehouse中,再在前端接入一些报表或者BI的工具去展示。

自BillInmon提出数仓概念以来,从90年代的美国到国内,数仓架构一直是一个比较经典的架构,它可以高效处理结构化的数据,而且性能好、速度快。尤其是teradata,它是存算一体的架构。

但是随着业务类型增多,我们需要扩展更多的业务场景,如数据科学或机器科学领域等。数据类型和数量也随之增多,结构化数据在互联网领域只占很小的一部分,还有很多半结构化、非结构化的埋点日志和音视频数据等。

我们的数仓已经无法处理更多数据,一些新技术,尤其是开源等多个领域的大数据技术开始涌现。

2)数据湖——数仓两层架构(10s)

我们逐渐将架构划分为数仓和数据库的双层架构,把数据先加载到数据湖中,通常我们会选择Hadoop数据库作为自建数据湖。如果要做高效的查询或者报表的输出,我们会对数据再加工,放入高性能的数仓中,如ClickHouse或Doris等。

大概从年开始,随着Hadoop的盛行,绝大多数互联网公司都在用这样的架构。大家如果使用过Hadoop,相信也能感知到它可以支持各种不同的场景,基本上能够满足所有业务场景。

缺点:

在效率方面存在较大缺陷,比如数据要来回导,以ETL或者反向ETL的方式导进导出,会出现多份;

一致性很难保证。

3)仓、湖、流——孤岛式架构(15s)

这个架构整体偏离线处理,随着流式框架的引入,大公司整体的数据处理架构在年后就变成了仓、湖、流三种架构。

根据不同的场景选择不同的架构,比如我要做一些Ad-hoc的场景,我们会选择在仓里面进行;如果要做一些定时的报表或业务报表,则用Spark;如果想要做一些流式数据的查询和分析,则可以用Flink之类的工具。

这个架构存在几个问题:

一致性:数据分成了三路,彼此之间天然割裂,在这种割裂的情况下,一致性是一个大问题。如果大家在公司里做一些数据处理的架构如Lambda架构等,流和批数据的对齐是一个绕不开的问题,因为数据是多份的,本质上仍是一致性问题。

受限的进阶分析:如果我们在湖上做数据分析,我们缺乏一些更高阶的分析能力,比如更新、快照、ACID等语义存在缺失。

数据成本:每一个通路的底层存储不同,计算也不一样,因为计算需要对应的存储来决定计算的性能,所以我们需要拷贝多份数据,成本也随之上升。

2.解决之道——湖仓一体

大概于20年左右提出了湖仓一体的架构,试图用一个统一的湖上建仓或湖仓一体的存储架构,解决数仓和数据库的问题。

针对传统意义的数据湖,若在对象存储或者Hadoop上能够构建出具备数仓语义的一个格式,使得我们在湖上的格式有更强的能力去做数仓,则需要具备几个条件:

湖上可靠的数据管理:即需要一种开放的高性能的数据组织方式。采用传统方式定义表时,缺乏一种高效的表的组织方式。我们通常用Hive表,它就是一个目录,没有特殊的能力。我们需要一种更高效的组织能力,兼顾一些仓的特性。

支持机器学习和数据科学:湖仓一体的技术需要有一套开放的标准或者开放的接口。大家在用数仓的时候,会发现它是存算一体的数仓,存储就是为了计算所定制。虽然性能很好,但不开放,也就是所有的生态都要建立在上面,但数据湖则是天然开放,Flink和Spark等其他引擎都能使用这些数据。

最先进的SQL性能:若湖仓一体只是湖,那么很轻易就能办到,但是它的性能会比较差。如果要使表具备仓的性能,比如能够匹敌类似Snowflake或者Redshift这样的性能,则需要一个高性能的SQL引擎,这也是Databricks做了Photon引擎的原因,有了这些,我们就可以真正在湖上构建出一个高性能的数仓,也就是“湖仓一体”。

3.三种主流开源技术

前文讲述了湖仓一体技术所要具备的几个特性,如今在开源领域主要有三种技术拥有这些特性,分别是:Hudi、Iceberg和DeltaLake。

它们的功能整体上比较接近,都是一种数据的组织方式,即定义了一种表的格式,这个格式主要是定义数据的组织方式,而不是确定一种数据的存储格式。与一些纯粹的数据格式或Hive表(Hive3.0版本前)相比,它提供了ACID事务能力,这样就具备了仓的能力,它可以提供一些事务的特性和并发能力,还可以做行级数据的修改、表结构的修改和进化,这些都是传统大数据格式难以完成的事项。湖仓一体技术出现后被业界迅速采用,从21年开始就进入了Gartner技术成熟度曲线的评估。

4.湖仓一体技术的优势

优化数据入湖流程:相比传统的成熟形态,比如T+1的入仓形态或者入湖的形态,它可以用T+0的高效的流式入湖形态,大大降低了数据的可见时延。

支持更多的分析引擎:它是开放的,所以能够支持很多引擎。我们内部也对接了很多不同的引擎,包括Flink、Spark、Presto和StarRocks等。

统一数据存储和灵活的文件组织:采用比较灵活的文件组织方式,具备了一些额外的特性,使得流和批都可以用这种文件组织方式进行消费。

增量读取处理能力

5.湖仓一体落地场景

1)加速数据入湖

下图左侧是我们一个旧的数据管道。举个例子,要收集一些Spark的审计日志以观察每天的情况,那么我们就可以把Spark日志都导入到消息队列中。在腾讯内部使用的是TubeMQ,然后我们有一个服务TDSort用于归档,把数据按照小时或者天的时间格式分类,紧接着保存至HDFS上,再启动一个Hive的命令,把它添加到分区内。

前面是通过流式进入,后面是批的落盘,整体设计比较复杂。为了保证exactly-once以及保证流转批的可见性,我们在原子性上花了很多心思,因为在原先的架构上我们缺乏事务的能力,所以我们通常依赖HDFS的原子性来保证可见性。

之后我们把整体架构迁到了以数据湖格式为体系的另一套架构中,选择用Flink来做流式的入湖,把它写到HDFS上,这样整体链路就变得更为简单。对于Flink写下的数据,我们主要选择的是Iceberg,在Flink读取把它写到Iceberg中,下游就能直接可见。

至此,原先T+1的可见性就变成T+0,这个是最典型、最常见的一种使用方式。这也是我们内部像广告和视频号等业务的主要使用方式,把小时级的数据可见性降低到分钟级的可见性。

2)构建CDCPipeline

CDC在腾讯内部不算是非常大的场景,但原本通过拉链表方式去构建,会带来一些问题:一是延迟,二是后续的处理流程非常复杂。

我们现在改成了另一种方式,使用Flink的CDCConnector,再加上Hudi。因为针对CDC而言,Hudi在这方面的能力比Iceberg更成熟,所以选用Hudi而不是Iceberg。

有两种方案,一种方案是直连MySQL或PostgreSQL等类似的数据库,另一种是通过消息队列的方式,通常都是使用第一种方式,这也是比较常见的一种内部形态,与前面相比FlinkCDCconnector与MySQL直连获取binlog。

3)近实时的流批一体架构

在业务侧使用整套湖仓一体技术后,从原先的Lambda架构转换成了湖仓一体的架构。在原先的架构中,流和批分离,流主要是用消息队列来做流式的Pipeline的构建,还有一条离线链路做数据的回补和对账等。但是离线存在于HDFS上,这样就会导致两条链路要做同一份数据的处理。

使用湖仓一体就相当于把它们合并,我们在ODS、DWD或者DWS层统一用Iceberg来进行流式写入。在流式写入后,可以在每一层中做离线或者批的分析,也可以一直做流式分析,因此同一份数据既做到了流式的读和写,又做到了批的读和写,一份数据就可以适配整个场景,不需要存多份数据或者接多条ETLPipeline。这就是我们比较典型的一个架构,腾讯视频也是在这个架构基础上做演进。

4)更好的Hive表

回到湖仓一体的本质,即使我们不需要上述的特性,相比传统的Hive表,它也带来了很多新的特性和能力。用于取代离线的场景化,也会有更好的效果。

数据治理:

支持表结构进化:Hive的其中一个特性就是分区,在建表的时候就需要指定分区字段,同时在查询时也必须加上分区的过滤条件,否则它有可能去查所有的分区,造成大量数据的误读取。分区一旦定下来就很难变动,但Iceberg是隐式的分区,通过它的表达式来做分区的映射和转换,就可以对分区做出调整,比如原先是按月来分区,你可以把它更改成按天分区。

支持行级数据的修正:原先Hive表的一个常见思路是用覆盖写的方式,要做数据修正时就要覆盖一个分区,但你可能只有一行数据需要调整。湖仓一体的格式提供了行级的修正能力。提供两种修正,一种是CopyOnWrite的修正,还有一种是MergeOnRead的修正,降低了修正的代价,大大提高了它的实时性。

数据查询:

ACID能力:Hive依靠HDFS的原子性来保证它的可见性。比如你Insert到多个分区时,Insert涉及到跨多目录复制,则无法原子性,这时你一边Insert一边去查询的时候就会读到脏数据,Iceberg、Hudi都是通过快照机制进行查询,快照只有被


转载请注明:http://www.180woai.com/afhhy/7980.html


冀ICP备2021022604号-10

当前时间: