首先,附上Github链接
LakeSoul:https://github.com/meta-soul/LakeSoul
一、导语
从 Hadoop 诞生至今,大数据系统开源生态已经走过了近 15 个年头。在这 15 年里,大数据领域不断涌现出各类计算、存储框架。但整体上在大数据架构领域,仍然没有到达一个收敛的状态,面对云原生、流批一体、湖仓一体的大趋势,还有很多问题需要解决。
LakeSoul 是数元灵研发并开源的流批一体表存储框架,围绕大数据架构体系新趋势做了大量的设计优化。本文从总体设计理念出发,为大家详解 LakeSoul 的核心概念和设计原理。
二、大数据系统架构的演进趋势
近年来,大数据领域涌现出一批新的计算、存储框架。例如,计算框架出现了以Spark、Flink 为代表的通用计算引擎、以Clickhouse 为代表的 OLAP 系统。存储方面,对象存储成为新的存储标准,代表了数据湖、湖仓一体的重要底座,同时也出现了 Alluxio、JuiceFS 等本地缓存加速层。我们可以看到大数据领域业内的几个重点演进方向:
1.云原生。无论是公有云还是私有云,都提供了对计算和存储硬件的抽象,将传统的 IaaS 层的管理运维抽象出来。云原生的一个重要特点是计算和存储都提供了弹性的能力,而怎样用好弹性能力,在提升资源利用率的同时降低成本,是计算和存储框架都需要考虑的问题。
2.实时化。传统 Hive 为代表的离线数仓,提供 T+1 的数据处理流程,已经很难适应新的业务需求。传统的 LAMBDA 架构引入复杂性和数据不一致性也无法满足业务需求。那么怎样构建一个高效的实时数仓体系,以及怎样在低成本的云存储上实现实时或准实时的写入更新和分析,对于计算和存储框架来说都是新的挑战。
3.计算引擎多样化。大数据领域的计算引擎呈现百花齐放的状态,虽然 MapReduce 已经逐渐没落,但是 Spark、Flink 和各类 OLAP 框架仍在蓬勃发展。每个框架都有自己设计上的侧重点,有一些深耕垂直场景,另一些功能特性在互相融合,而大数据框架的选型也变得越来越繁多。
4.湖仓一体。在湖仓一体上,维基没有给出具体定义,我们认为:它兼顾了数据湖和数据仓库两者的优势,即在开放式格式的低成本云存储之上,实现与数据仓库中的数据结构和数据管理功能类似的功能。具体包含如下几个特性:并发读取和写入数据、具有数据治理机制的架构支持、直接访问源数据、存储和计算资源分离、开放存储格式、支持结构化和半结构化类型(音频、视频)数据以及端到端流式传输等。
从技术成熟度发展来看,数据湖处于稳步爬升复苏期,而湖仓一体还处于期望膨胀期,技术上还未完全收敛,在具体的业务场景上仍然存在着多种问题。
结合大数据领域最新的演进方向,怎样在云原生架构体系内打通多种引擎和存储之间的衔接、适配上层快速变化的数据智能业务的需求,是当前大数据平台架构需要解决的问题。我们认为,解决以上各类问题,首先需要有一套完善的存储框架,在云上提供数据高并发、高吞吐读写的能力和完整的数仓管理能力,并且将这样的存储能力以通用的方式暴露给多种计算引擎访问。这也是我们开发 LakeSoul 的初衷。
三、LakeSoul设计理念详解
LakeSoul是一个流批一体表存储框架。LakeSoul 在设计上具备如下几个核心特性:
1.高可扩展的 Catalog 元数据服务。随着数据量的快速增长,数据仓库需要能够处理快速增加的分区和文件。LakeSoul 通过使用分布式去中心化数据库来存储 Catalog 信息,大幅提升元数据可扩展性。
2.支持并发写入。LakeSoul 通过元数据服务实现了并发控制,在同一分区支持多个作业并发更新,通过智能区分写入类型来控制合并或回退机制。
3.支持增量写入和 Upsert。LakeSoul 提供了增量追加和行列级别 Upsert 的功能,支持 Merge on Read 模式,提升数据摄入的灵活性和性能。LakeSoul 在多种更新类型下都实现了 Merge on Read,从而在写入时不需要读取并合并数据,提供了很高的写入性能。而高度优化的 Merge Reader 保证了读性能不受损失。
4.实时数仓功能。LakeSoul 支持流式和批量的写入,行列级别更新,框架无关的 CDC、SCD ,多版本回溯等常用的数仓功能。结合流批一体的能力,能够支撑常见的实时数仓构建的需求。
LakeSoul 的总体架构示意如下:
LakeSoul总体架构
接下来我们详细介绍以上几个设计要点和实现机制。
2.1 高可扩展的Catalog元数据服务
在表分区级别,LakeSoul 支持多级的分区管理,支持多个 range 分区,以及最多一个哈希分区。在实际业务场景中,较大规模的数据仓库,在长时间更新后,会提交大量的分区信息到元数据层。对于实时或准实时更新的场景,提交会更为频繁。这时往往会面临元数据膨胀的问题,造成元数据访问效率低下。由于在数据查询时需要访问元数据中的分区信息以及其他数据分布的基本信息,元数据的性能会对查询性能有着较大的影响。因此,一个高性能、高可扩展的元数据服务对一个数据仓库是非常重要的。
为提升元数据的性能和可扩展性,LakeSoul 使用 Cassandra 分布式数据库来管理元数据。Cassandra 是一个去中心化的分布式 NoSQL 数据库,提供了丰富的数据建模方式,能够提供很高的读写吞吐能力。同时,Cassandra 也能够比较方便地进行水平扩容。使用 Cassandra 作为元数据服务的存储,还能够获得可调节的可用性和一致性级别,能够方便地实现元数据操作的并发控制和 ACID。
LakeSoul 通过精心组织元数据层表的主键和索引,对一个叶子级别分区只需要做一次主键操作就可以获得这个分区的所有信息,以及读写当前版本的 snapshot 等。一个分区的 snapshot 中包含了全量写入和增量更新的文件完整路径和提交类型。通过对 snapshot 中文件提交进行顺序的遍历,就可以构建出该分区读取计划。这样一方面分区信息访问很高效,另一方面也避免了对文件目录的遍历,对于 S3、OSS 这样的对象存储系统是比较重要的优化手段。LakeSoul 的分区管理机制示意:
作为对比,Hive 使用 MySQL 作为元数据存储层,除了扩展性问题,自身分区信息查询的效率也存在瓶颈,难以管理单表数千以上的分区。而相比 Iceberg、Delta Lake 等使用文件系统来存储元数据方式,LakeSoul 也能够支持更大规模的分区数。
2.2ACID事务和并发写
为保证数据并发写入和读取一致性,LakeSoul 支持 ACID 事务和并发更新。不同于 OLTP 的场景,湖仓的更新是文件级粒度的。LakeSoul 使用 Cassandra 的轻量级事务(Light Weight Transaction)来实现分区级别更新。Cassandra 自身虽然不是完整的关系型事务数据库,但是可以通过 LWT 来提供更新的原子性和隔离性。而可用性和一致性,则可以通过 Cassandra 的一致性级别来控制。可以根据业务场景的需要来选择一致性级别,提供了较好的灵活性。
具体来说,当计算引擎产出要提交的各个分区的文件后,会首先提交分区文件更新的信息,例如全量更新或增量更新,然后通过 LWT 来更新读者可见的版本。在检测到并发更新发生的场景,LakeSoul 会自动区分写入类型判断是否属于有冲突情形,并决定是直接重新提交还是回退数据计算。
2.3增量更新和Upsert
有了高效的元数据层的支持,LakeSoul 可以很方便地实现增量更新的机制。LakeSoul 支持多种更新机制,包括 Append、Overwrite 和 Upsert。对于一般的日志流写入,通常是 Append 模式。这种情况下,元数据层只需要记录各分区追加的文件路径,而读数据作业将分区内所有追加的文件统一读出,即可完成读时合并(Merge on Read)。对于 Overwrite 的情形,即任意条件的 Update/Delete,或者 Compaction,LakeSoul 采用 Copy on Write 机制进行更新。
在存在哈希分区,并且 Upsert 操作作用于哈希键的情况下,LakeSoul 支持了更为高效的 Upsert 机制。在每个哈希分桶内,LakeSoul 将文件根据哈希键进行排序。执行多次 Upsert 后,就获得了多个有序的文件。对于读取作业,只需要将这些有序文件进行归并,即可完成 Merge on Read。Upsert 的示意如下:
通过这样的方式,LakeSoul 可以获得很高的写入吞吐能力,同时通过高度优化的有序文件归并,也能够保证读取速度不受损失。
2.4 实时数仓功能
LakeSoul 致力于简化大数据数仓的落地应用,希望为数据开发提供简洁高效的实时数仓能力。为此,LakeSoul 针对实时数仓常用的业务场景,专门开发、优化了若干实用的功能,包括 CDC、SCD、TimeTravel 等。
LakeSoul CDC 提供了一套独立的 CDC 语义表达。通过在 CDC 承接表中指定一个操作列作为 CDC 语义列,可以对接 Debezium、Flink、Canal 等多种 CDC 采集源。只需要将采集源的操作列转换为 LakeSoul CDC 操作列即可。对于在线 OLTP 数据库同步到 LakeSoul 的场景,由于在线数据库大部分场景都是通过主键对数据进行操作,LakeSoul 承接表同样可以采用哈希分桶的方式,并将 CDC 写入转为对哈希键的 Upsert,从而获得很高的 CDC 同步速度。
四、LakeSoul应用场景举例
CDC实时同步大屏报表
为了实时分析在线数据库中的数据,我们通常需要将在线数据同步到数仓中,然后在数仓中进行数据分析、创建 BI 报表、展示大屏等。例如,在电商促销节期间,我们希望能够实时大屏展示分省份、地区、人群的消费金额、订单数、库存数等,而这些交易数据又来自于线上的交易数据库,我们需要将数据导入到数仓中进行多维报表分析。这类场景如果使用周期 dump 数据库的方式,延迟和存储开销都太高,无法满足时效性要求,而使用 Flink 实时计算又存在开发运维繁琐的问题。
通过使用 LakeSoul CDC 实时同步,在主键操作的情况下转为 Upsert,可以获得极高的写吞吐,以接近实时的方式将在线数据库中的数据变化同步到数仓中,随后通过 SQL 查询就可以快速进行线上数据的 BI 分析。通过 Debezium,可以支持多种在线数据库,包括 MySQL、Oracle 等,应用CDC 入湖的方式可以大幅简化数仓数据实时摄入更新的架构。
我们提供了一个 LakeSoul CDC MVP 验证文档:https://github.com/meta-soul/LakeSoul/blob/main/examples/cdc_ingestion_debezium/README-CN.md,包含了完整的 CDC 实时同步入湖的示例,感兴趣的朋友可以参考。
推荐算法系统实时样本库构建
在推荐算法场景中,一个常见的需求是需要将多个表合并到一起,包括用户特征、商品特征、曝光标签、点击标签,从而构建模型训练的样本库。通过离线的方式进行大表 Join 拼接,同样存在时效性低和计算资源消耗量大的问题。而通过实时流的方式,之前很多方案是使用 Flink 进行多流 Join。然而在时间窗口较大的情况下,Flink 同样也占用较高的资源。
我们可以使用 LakeSoul 来构建实时样本库,将多流 Join 转换为多流并发 Upsert。由于不同流都会有同一个主键,我们可以将这个主键设置为哈希分区键,通过哈希键来实现高效的 Upsert。这种方式可以支持大跨度的时间窗口的 Upsert,同时保证了很高的写入吞吐。
五、结束语
这篇文章我们详细介绍了 LakeSoul 的设计理念和一些关键特性的实现原理。LakeSoul 针对云原生的架构,以及实时数仓的业务需求,做了大量针对性设计和改进。在未来,LakeSoul 还将增加更完整的全语义 Merge on Read,云存储加速,以及更多实时数仓功能。欢迎关注元灵数智公众号,我们将定期更新干货文章分享。