基于数据湖格式构建数据湖仓架构 ——毕岩 阿里巴巴技术专家

本文涉及的产品
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: ——毕岩阿里巴巴技术专家

一、数据湖&数仓&湖仓

image.png

新架构的提出往往是为了解决老架构存在的问题,而数据湖的出现也是为了解决传统数仓架构遗留的问题。

阿里云对数据湖的定义为:数据湖是统一存储池,可对接多种数据输入方式,可以存储任意规模的结构化、半结化、非结化数据也可以无缝对接到多种计算分析处理的引擎和平台,可以直接对数据做处理和分析,打破数据孤岛,洞察业务价值等。同时,阿里云还提供了冷热分层转换能力,覆盖数据全生命周期

定义可以提炼出数据湖的公共能力:

第一,具备统一中心化的存储和数据管理。

第二,支持非结构化、半结化和结构化等各类型数据

第三,支持 SQL ML等各类查询、计算、分析。

第四,支持大规模的数据

第五,开放开源的格式比如ParquetORC

传统的数仓架构仅支持结构化和半结构化,只能提供 SQL 语法导致对于音频视频图等非结构化数据的处理能力较弱,也无法直接对接到机器学习和深度学习框架。

为了解决数仓引入问题,数据湖架构被提出。而数据湖本身存在一些问题

第一,安全数据湖将所有数据都做了统一存储,缺乏完备的操作审计,且只能做到文件级别的权限控制,因此存在安全性问题。

第二,质量。数据湖天然支持同一份数据同时被数据分析师、数据科学家等不同的角色使用同时还引入了批流两种方式的写入如果没有合适的方法保证事务的质量,保证其一致性,则会带来可靠性问题。

第三,性能。不同于数仓可以使用索引缓存以及优化后特定的存储格式加速查询原生的数据湖查询性能较弱,

第四,成本。数仓的数据格式是封闭自定义的,因此在机器在学习和深度学领域无法很好地应用。

基于以上挑战,数据湖引入了存储层。而引入新的引擎组件必然带来一系列学习和使用成本,以及后续的运维和管理成本等。因此,最终从数据湖衍生出数据湖仓架构。

image.png

仓架构是在数据湖上拓展了原本仓的能力,融合了两者的优势,弥补劣势,达到了灵活性、安全和高性能的统一。

湖仓架构的底层继承了数据湖架构统一存储数据的能力,使能够承载结构化和非结化数据,同时允许 BI AI 的任务直接在上面运行。湖仓架构的关键在于中间层封装了数据湖的存储层,包括数据湖管理和元数据服务的能力。

通过权限审计工作解决安全问题以及降低部分数据湖管理成本的工作,可以借助中间层的数据湖管理和元数据服务模块。性能和质量上多流读写的事务性保证可以借助于数据湖格式本身解决。

另外,数仓架构能够支持数据湖的数据增加或删除字段等schema 变更来适配数据的变更,支持数据的审计和回溯。存算分离的特性也更加有利于企业做细粒度的成本控制,同时也利于比如在EMR环境下集群的版本升级或管理等。然而存算分离之后会引发数据读取 IO开销增加,可以通过引入大数据缓存Alluxio以及阿里云的JindoFS 来解决。

image.png

上图展示了传统的数仓数据湖和数据湖仓的区别。可以看到原本数据湖在成本数据可靠性监管安全以及性能上问题都可以通过数仓的方式得以解决。

二、数据湖格式

数据湖格式是作用在数据湖仓架构之下、在数据真实的存储层之上元数据管理之下的一层数据存储

image.png

数据湖的很多特性都由数据湖格式来承载,这DeltaLakeHudiIceberg这两年兴起的主要原因和背景。

DeltaLakeDatabricks公司提出,近期宣布了将全功能开源,一次性放出很多大家期待的featureIcebergNetflix开源,其设计更开放,在国外的场景上应用更佳Hudi Uber开源当前在国内社区比较活跃,其社区风格较为激进,会进行快速功能迭代,因此功能丰富。Hudi只是将自己作为数据湖的存储层,而是一个平台,内置了很多管理的服务。

image.png

数据湖格式的关键实现是:表的元数据不再存放在比如 HiveMetaStore服务里,而是和数据一起放在本地的 filesystem针对于每一次表的变更都会提交新的事务日志记录对湖格式表的修改schema的变化和数据文件的变化等。基于以上设计,再结合并发控制协议,能够更好地实现并发控制,拓展 TimeTravel等能力。

image.png

经过了几年的发展,三个湖格式的整体功能已经基本一致。

其中HudiIceberg支持的Merge on Read主要解决写数据时遇到的写放大现象。比如想要更新某包含 1 万条数据的文件里的 1000 条数据需要将 1000 条更新之后的值连同 9000 条没有被修改的数据一起再写回到新的文件数据湖格式会将一个版本标记为废弃,将最新版本标记为生效。新版本内9000数据原封不动被保留下来,这就是写放大现象。

 Hudi能够 1000 条新增的数据通过行存的形式写入增量文件,在查询时合并增量文件和 base 文件,得到全视图最新版本的数据。

 DeltaLake 220可以delta表作为 CDC source 产生changedata 给下游交付,再做使用。湖管理功能比如合并小文件,用户无需用户再另起任务,能够减少用户的使用和管理成本。Hudi以及 EMR 版本的 DeltaLake都已实现该功能,社区版目前尚未跟进。

image.png

生态上,三个格式也在持续布局和完善。三者都已具备基于 Spark Flink 的读写功能在查询引擎支持上略有不同,比如 icebergprestoJindo上已经支持写的功能。DeltaLake在云厂商的支持以及云catalog 支持上推动比较好。

不管哪一种湖格式,能够实现实时 Sync 实时入湖和入仓,后续可以进一步做 ETL 处理,比如 ODS 层到 DWD DWS 层的数据的转换。支持 Spark OLAP 引擎查询提供近实时的 OLAP 能力。

image.png

湖格式场景一:SCD

SCD保存随着时间缓慢变化的维度值的变更信息。举个例子,用户和常驻地,用户可能隔几天几小时会变更所在地信息随着时间变化。在此类场景,可能有些数仓无法只提取最新数据只能提取到某个历史时刻用户在何地

SCD根据对新值的处理方式,定义了多种类型TypeType0指只保留原来的值,新值丢弃;Type1只保留最新值,将历史值全部丢弃;Type2以行存的形式保存所有记录Type3增加新的字段来保留前版本和当前版本。

本示例使用Type2增加两个字段,用于标识某条记录生效范围,或者也可以通过布尔值直接表示是否生效。

初始表格如最上方表格所示,需要将原有 ID 标记为无效,新数据标记为有效如果 ID 不存在原表里,则以新增的方式插入。基于以上策略得到的表入上图最下方表格所示。

针对上述示例,传统数仓的实现逻辑比较复杂,很难保证其事务性。而数据湖格式通过语法在一次事务中完成对数据的删除修改新增插入。

上图右侧为具体语法实现。Using部分的数据通过 when mached()when not mached then()部分语法,按照逻辑写入到 target 表里when mached语法表示:当匹配到某条记录之后,会对这条记录做删除或修改when not mached then后面可以加谓词,对数据做插入。

image.png

湖格式场景二:G-SCD

另一类场景,比如只需要知道用户某天内最后在什么地方,即只需知道固定时间段内用户最新值,可以通过湖格式的TimeTravel解决。我们基于 EMR 胡格式的TimeTravel能力实现了G-SCD解决方案,是基于固定粒度缓慢变化

此前基于 Hive 的解决方案如下:首先一条实时流通过不断获取增量的数据写入到增量表里。再将T+1的增量表和原始表的 T 分区数据作合并,产生离线表的 T+1分区。通过分区值查询 T+1分区即可获知这一天用户最新的值。该方案存在较重的数据冗余以及资源浪费,因为 TT+1 的数据大量重复。

G-SCD的解决方案如下:首先通过 MySQL 将变量信息拖至 Kafka 消费Kafka数据,通过 Spark Streaming batch 的形式做提交。该方案会要求每一个被提交到 Delta commit 只包含业务快照数据,让每一个业务快照和delta版本做关联。比如先提交了一个 T 时刻的版本,又提交了一个T时刻,后面提 T+1时刻可以通过查询第二个 T时刻的 TimeTravel得到 T时刻数据。 此外,我们对Spark Streaming做了升级,可按照业务快照做拆分,比如按天级别拆成两天数据,一天一天提交,保证提交秩序

该方案无需添加辅助字段只需原生的表结构即可解决。同时不存在大量数据冗余,能够借助于 Spark Delta本身的查询优化提升查询效率。

image.png

湖格式场景三:CDC

上图定义了流式的 ETL 其中表中包含userIDnamecity三个字段。通过 user_city 表和 user_name 表做 join name 字段接入并产生下游的表。再按照 city 表做聚合得到所在的城常州人口数据。

针对以上需求,此前常用的方案为:首先获取全量的 user_city 表,将它user_name 表做 join ,以 override 的形式写到 user_name_city 表。然后按照 city group by 重写后面的 city_population表,每一步都全量数据

CDC方案如下:首先通过 user_name_city表的次变更提取出其change data,将其与user_name 表做 join 更新到 user_name_city 表。user_name_city 表在这次变更中产生以下变更:用户 1 从北京变杭州用户 5 新增数据,位于武汉。因此,再往下游到 city_population 表里,需要对于北京-1,对杭州和武汉+1,得到其新的常驻人口。

CDC方案需要user 信息操作还需要表里的其他字段信息,比如 city 字段等以及获取该记录完整的前和后才能下游做处理。

银行场景下,比如有A B 两个账户 A 账户全天没有任何变化, B 账户全天操作了几百次但最终金额没有变化。此类场景需要追溯每一次变更才有意义。

image.png

EMR内部,HudiDelta都是基于 CDLF 的思路实现CDC充分权衡了读写两端的性能结合了数据湖格式的事务性特点以及变更的有效映射关系提出的CDLF方案,其核心在于必要时会持久化 CDC数据类似于数据湖触发器的形式,数据湖可以通过 create trigger 语法来对insertdelete update 操作做触发,将前和旧写到一张insert表里后续可直接查询insert表得到其 CDC 数据。

以上方案增加了写开销但在查询时避免了表 diff ,具有较高的传输效率而该方案依然存在可优化的点:

首先,尽可能复用已有的数据,避免所有场景所有写操作都持久化举个例子,首次表的 insert 每一条数据都是先插入才进行操作因此没必要双写一份数CDC数据集只需下载原有的数据并进行拼接,将其标记为 insert 或前值为空然后返回即可再比如删除分区场景,整个分区的数据都被删除,因此只需将所有数据加载进来,拼接上删除操作,并置新值空返回即可

其次,针对主键场景,仅持久化主键(和操作类型),查询时再提取旧值和新值。

image.png

当前,湖格式的使用还存在一些挑战:

第一,学习和使用成本。不同的数据湖格式有不同的实现,在读写场景上会有不同,会带来较大的学习成本和后续调优成本。

第二,湖格式统一了批和流,因此必然会有小文件过期文件清理问题,管理成本增加

第三,湖格式依然处于发展阶段,迭代较快前后版本无法能保证完全兼容。

第四,无法真正地满足OLAP场景的查询性能要求。

第五,引擎之间并不互通,元数据也没有打通,生态集成不够成熟。

第六,业务和客户对于数据湖格式的引入依然持保守观望的态度,更多的使用场景有待挖掘打磨

三、阿里云EMR+DLF构建湖仓架构

image.png

上图为DLF数据湖仓架构图。

最底层由OSS存储作为数据的统一存储层往上是关键的由 DLF 数据湖构建开放开源的数据湖格式数据湖缓存加速JindoFS 三者共同提供的数据湖管理和优化层再往上是由开源和阿里云自研的产品组成的弹性计算引擎层,提供了基于 BI AI 能力最上阿里云数据开平台 DataworksEMR提供的开发层,提供了完备的数据开发体系和数据治理平台。

image.png

DLF数据湖构建是阿里云提出的全托管数据湖服务,提供了湖仓架构下必需的能力。它提供了全托管的统一元数据,借助于该能力可以无缝对接到 EMR 上的各类开源引擎阿里云的数据集成平台以及阿里云的数仓产品等,实现湖仓一体,避免数据孤岛现象。

统一的权限服务能够帮助适配到多个查询引擎和多个产品,为数据的访问和操作提供了安全的保证。标准的入湖模板可以对接到 MySQL BinlogKafka等多个 source 实现一键入湖,可直接保存成湖格式的表后续再在 EMR 或其他产品上做处理和查询。元数据发现能力可以直接扫描底层的filesystem ,发掘未被管理和记录的数据来消除沉没数据。

据湖管理能力直接针对于数据湖格式提供的管理能力,包括自动化解决小文件以及历史过期文件带来的一系列管理和运营。

DLF会监听湖格式每一次提交 commit 感知每一次变化,实时分析各种维度的指标包括文件数平均文件大小有效/无效文件占比等。

image.png

EMR的数据湖格式提供了丰富的SQL语法,包括 Partition相关、DPOOptimizeTimeTravel等,支持SavepointRollBack等,拓展了Spack SQL支持Streaming SQL语法。EMR解决了湖格式存在的问题,保证了格式和普通的 Hive 表的功能和场景性能一致。即使在存在schema 变更的情况下也能够保证正确实时地同步到相关元数据服务。三种湖格式都可对接到 DLF 支持阿里云其他产品的查询。

我们也在积极拥抱社区,向社区贡献了很多关键 feature比如Spark3.0 Merge Into语法Delta支持Hive查询的delta-connectors以及HudiSpark SQL支持和Hudi CDC

Q&A

Q:湖格式产品支持 CDC也是通过 Binlog 实现的吗?

A湖格式产品支持CDC是将自己的表作为 CDC source 提供服务。主要用于构建完整的一套增量场景。此前通过 SQL Binlog 只是将数据库changedata做入湖而已,并不能继续支持下游的场景。

Q请问 Hudi 现在支持使用 Java reader读取数据吗?

A:支持,可以通过 Java 的方式读写数据,性能上不如Flink Spark大数据引擎。

相关实践学习
AnalyticDB MySQL海量数据秒级分析体验
快速上手AnalyticDB MySQL,玩转SQL开发等功能!本教程介绍如何在AnalyticDB MySQL中,一键加载内置数据集,并基于自动生成的查询脚本,运行复杂查询语句,秒级生成查询结果。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
相关文章
|
13天前
|
监控 安全 API
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
本文详细介绍了PaliGemma2模型的微调流程及其在目标检测任务中的应用。PaliGemma2通过整合SigLIP-So400m视觉编码器与Gemma 2系列语言模型,实现了多模态数据的高效处理。文章涵盖了开发环境构建、数据集预处理、模型初始化与配置、数据加载系统实现、模型微调、推理与评估系统以及性能分析与优化策略等内容。特别强调了计算资源优化、训练过程监控和自动化优化流程的重要性,为机器学习工程师和研究人员提供了系统化的技术方案。
133 77
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
|
8天前
|
Serverless 决策智能 UED
构建全天候自动化智能导购助手:从部署者的视角审视Multi-Agent架构解决方案
在构建基于多代理系统(Multi-Agent System, MAS)的智能导购助手过程中,作为部署者,我体验到了从初步接触到深入理解再到实际应用的一系列步骤。整个部署过程得到了充分的引导和支持,文档详尽全面,使得部署顺利完成,未遇到明显的报错或异常情况。尽管初次尝试时对某些复杂配置环节需反复确认,但整体流程顺畅。
|
14天前
|
DataWorks 数据挖掘 大数据
方案实践测评 | DataWorks集成Hologres构建一站式高性能的OLAP数据分析
DataWorks在任务开发便捷性、任务运行速度、产品使用门槛等方面都表现出色。在数据处理场景方面仍有改进和扩展的空间,通过引入更多的智能技术、扩展数据源支持、优化任务调度和可视化功能以及提升团队协作效率,DataWorks将能够为企业提供更全面、更高效的数据处理解决方案。
|
16天前
|
缓存 Kubernetes 容灾
如何基于服务网格构建高可用架构
分享如何利用服务网格构建更强更全面的高可用架构
|
26天前
|
弹性计算 持续交付 API
构建高效后端服务:微服务架构的深度解析与实践
在当今快速发展的软件行业中,构建高效、可扩展且易于维护的后端服务是每个技术团队的追求。本文将深入探讨微服务架构的核心概念、设计原则及其在实际项目中的应用,通过具体案例分析,展示如何利用微服务架构解决传统单体应用面临的挑战,提升系统的灵活性和响应速度。我们将从微服务的拆分策略、通信机制、服务发现、配置管理、以及持续集成/持续部署(CI/CD)等方面进行全面剖析,旨在为读者提供一套实用的微服务实施指南。
|
24天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
78 5
|
22天前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
38 2
|
22天前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####
|
26天前
|
监控 持续交付 API
深入理解微服务架构:构建高效、可扩展的系统
深入理解微服务架构:构建高效、可扩展的系统
46 3
|
26天前
|
消息中间件 监控 安全
构建高效微服务架构:最佳实践与挑战
在现代软件开发中,微服务架构因其高度的可扩展性、灵活性和敏捷性而受到青睐。本文深入探讨了构建高效微服务架构的关键策略,包括服务的划分、通信机制、数据管理、部署与监控等方面的最佳实践。同时,文章也分析了在实施过程中可能遇到的挑战,如服务间的依赖管理、数据一致性问题、安全考量及性能优化等,并提出了相应的解决方案。通过实际案例分析,本文旨在为开发者提供一套实用的指南,帮助他们在构建微服务系统时能够有效规避风险,提升系统的健壮性和用户体验。