乐趣区

关于spark:实时数据湖在字节跳动的实践

导读:明天分享的主题是实时数据湖在字节跳动的实际。
将围绕上面四点开展:

  • 对实时数据湖的解读
  • 在落地实时数据湖的过程中遇到的一些挑战和应答形式
  • 联合场景介绍实时数据湖在字节外部的一些实际案例
  • 数据湖倒退的一些布局

    1. 对实时数据湖的解读

    数据湖的概念是比拟宽泛的,不同的人可能有着不同的解读。这个名词诞生以来,在不同的阶段被赋予了不同的含意。

    数据湖的概念最早是在 Hadoop World 大会上提出的。过后的提出者给数据湖赋予了一个十分形象的含意,他认为它能解决数据集市面临的一些重要问题。其中最次要的两个问题是:首先,数据集市只保留了局部属性,只能解决事后定义好的问题;另外,数据集市中反映细节的原始数据失落了,限度了通过数据解决问题。从解决问题的角度登程,心愿有一个适合的存储来保留这些明细的、未加工的数据。因而在这个阶段,人们对数据湖的解读更多的是聚焦在中心化的存储之上。
    不同的云厂商也把本人的对象产存储产品称为数据湖。比方 AWS 在那个阶段就强调数据湖的存储属性,对应的就是自家的对象存储 S3。在 Wiki 的定义中也是强调数据湖是一个中心化存储,能够存海量的不同品种的数据。然而当对象存储满足了大家对存储海量数据的诉求之后,人们对数据湖的解读又产生了变动。
    第二阶段,对数据湖的解读更多的是从开源社区和背地的商业公司发动的。比方 Databricks 作为一个云中立的产品,它将云厂商的这个对象存储称为 data lakes storage,而后把本人的重心聚焦在如何基于一个中心化的存储构建一个数据分析、数据迷信和机器学习的数据湖解决方案,并且把这个计划称之为 lake。他们认为在这个中心化的存储之上构建事务层、索引层,元数据层,能够去解决数据湖上的可靠性、性能和平安的问题。
    与此同时,Uber 最后也将 Hudi 对外称为一个事务型的数据湖,名字实际上也是由 Hadoop Updates and Incrementals 缩写而来,最早也是被用于解决 Uber 外部离线数据的合规问题。当初他们更偏向的定义是一个流式数据湖平台,Iceberg 也经常被人们纳入数据湖的探讨。只管 Ryan Blue 始终声称 Iceberg 是一个 Open Table Format。这三者有一些共同点,一个是对 ACID 的反对,引入了一个事务层,第二是对 streaming 和 batch 的等同反对,第三就是聚焦在如何能更快的查问数据。国内也有人将 Hudi、Iceberg、Delta Lake 称为数据湖的三剑客。
    讲完了业界的解读,来看一下字节跳动对数据湖的解读。咱们是联合字节的业务场景来解读的。通过实际总结,咱们发现数据湖须要具备六大能力:

    第一是高效的并发更新能力。因为它可能扭转咱们在 Hive 数仓中遇到的数据更新老本高的问题,反对对海量的离线数据做更新删除。
    第二是智能的查问减速。用户应用数据湖的时候,不心愿感知到数据湖的底层实现细节,数据湖的解决方案应该可能主动地优化数据分布,提供稳固的产品性能。
    第三是批流一体的存储。数据湖这个技术呈现以来,被数仓行业给予了厚望,他们认为数据湖能够最终去解决一份存储流批两种应用形式的问题,从而从根本上晋升开发效率和数据品质。
    第四是对立的元数据和权限。在一个企业级的数据湖当中,元数据和权限必定是不能少的。同时在湖仓共存的状况下,用户不心愿元数据和权限在湖仓两种状况下是割裂的。
    第五是极致的查问性能。用户对于数据湖的冀望就是可能在数据实时入湖的同时还能做到数据的秒级可视化。
    第六是 AI + BI。数据湖数据的对外输入,不只局限于 BI,同时 AI 也是数据湖的一等公民,数据湖也被利用在了字节的整个举荐体系,尤其是特色工程当中。实时数据湖其实是数据湖之上,更加重视数据的实时属性或者说流属性的一个数据湖倒退方向。当然,正如业界对于数据湖的解读始终在演变,咱们对数据湖的解读也不会局限于以上场景和性能。

    2. 落地实时数据湖过程中的挑战和应答形式

    接下来介绍数据湖落地的挑战和应答。字节外部的数据湖最后是基于开源的数据湖框架 Hudi 构建的,抉择 Hudi,最简略的一个起因就是因为相比于 Iceberg 和 Delta Lake,Hudi 原生反对可扩大的索引零碎,可能帮忙数据疾速定位到所在的地位,达到高效更新的成果。
    在尝试规模化落地的过程中,咱们次要遇到了四个挑战:数据难治理,并发更新弱,更新性能差,以及日志难入湖。
    接下来会一一介绍这些挑战背地呈现的起因以及咱们应答的策略。

    (1)数据难治理
    下图是一个典型的基于中心化存储构建数仓机器学习和数据迷信的架构。这里将加工过后的数据保留在数仓中,通过数仓的元数据进行组织。数据科学家和机器学习框架都会间接去这个中心化的存储中获取原始数据。因而在这个中心化存储之上的数据对用户来说是齐全扩散的,没有一个全局的视图。

为了解决这个数据难治理的问题,Databricks 提出了一个 Lakehouse 的架构,就是在存储层之下来构建对立的元数据缓存和索引层,所有对数据湖之上数据的应用都会通过这个对立的一层。在这一点上和咱们的指标是很类似的,然而事实是比拟残暴的,咱们面临的是海量存量数据,这些存量数据不论是数据格式的迁徙,还是应用形式的迁徙,亦或是元数据的迁徙,都意味着微小的投入。因而在很长一段时间里,咱们都会面临数仓和数据湖共存这样一个阶段。在这一阶段,两者的连通性是用户最为关怀的。
咱们在数据湖和数仓之上,构建了一层对立的元数据层,这层元数据层屏蔽了上层各个系统的元数据的异构性,由对立的元数据层去对接 BI 工具,对接计算引擎,以及数据开发、治理和权限管控的一系列数据工具。而这一层对外裸露的 API 是与 Hive 兼容的。只管 Hive 这个引擎曾经逐步被其余的更新的计算引擎代替了,比方 Spark、Presto、Flink,然而它的源数据管理仍旧是业界的事实标准。另外一些云厂商即便抉择构建了本人的元数据服务,也都同时提供了和 HMS 兼容的元数据查问接口,各个计算引擎也都内置了 Hive Catalog 这一层。

解决了下层的拜访对立的问题,但仍旧没有解决数据湖和数仓元数据自身的异构问题。这个异构问题是如何导致的呢?为什么 Hive Matestore 没有方法去满足元数据管理的这个诉求?
这就波及到数据湖治理元数据的特殊性。以 Hudi 为例,作为一个典型的事务型数据湖,Hudi 应用工夫线 Timeline 来追踪针对表的各种操作。比方 commit compaction clean,Timeline 相似于数据湖里的事务管理器,记录对表的更改状况。而这些更改或事务记录了每次更新的操作是产生在哪些文件当中,哪些文件为新增,哪些文件生效,哪些数据新增,哪些数据更新。

总结下来,数据湖是通过追踪文件来治理元数据。治理的力度更细了,天然也就防止了有效的读写放大,从而提供了高效的更新删除、增量生产、工夫旅行等一系列的能力。但这其实也就意味着另外一个问题,就是一个目录中能够蕴含多个版本的文件,这与 Hive 治理元数据的形式就产生了一致,因为 Hive Metastore 是通过目录的模式来治理元数据的,数据更新也是通过笼罩目录来保障事务。因为对元信息的治理力度不同,基于 Hive Metastore 的元数据管理其实是没有方法实现数据湖刚刚提到的一系列能力的。针对这个问题,Hudi 社区的解决方案是应用一个分布式存储来治理这个 Timeline。Timeline 外面记录了每次操作的元数据,也记录了一些表的 schema 和分区的信息,通过同步到 Hive Metastore 来做元数据的展现。这个过程中咱们发现了三个问题。
第一个问题就是分区的元数据是扩散在两个零碎当中的,不足 single source of true。第二个是分区的元数据的获取须要从 HDFS 拉取多个文件,没有方法给出相似于 HMS 这样的秒级拜访响应。服务在线的数据利用和开发工具时,这个提早是没有方法满足需要的。第三个是读表的时候须要拉取大量的目录和 Timeline 上记录的表操作对应的元数据进行比对,找出最新的这个版本蕴含的文件。元数据读取自身就很重,并且不足裁剪能力,这在近实时的场景下带来了比拟大的 overhead。
Hudi Metastore Server 交融了 Hive Metastore 和 Hudi MetaData 治理的劣势。首先,Hudi Metastore Server 提供了多租户的、中心化的元数据管理服务,将文件一级的元数据保留在适宜随机读写的存储中,让数据湖的元数据不再扩散在多个文件当中,满足了 single source of true。其次,Hudi Metastore Server 针对元数据的查问,尤其是一些变更操作。比方 Job position 提供了与 Hive Metastore 齐全兼容的接口,用户在应用一张数据湖上的表的时候,享受到这些减少的高效更新、删除、增量生产等能力的同时,也能享受到一张 Hive 表所具备的性能,例如通过 Spark、Flink、Presto 查问,以及在一些数据开发工具上在线的去获取到元数据以及一些分区 TTL 清理的能力。此外,Hudi Metastore Server 还解决了一个关键性的问题,就是多任务并发更新弱的问题。
(2)并发更新弱
咱们最早是基于 Hudi 社区的 0.7 版本的内核进行研发的,过后 Hudi 的 Timeline 中的操作必须是齐全程序的,每一个新的事务都会去回滚之前未实现的事务,因而无奈反对并发写入。后续社区也实现了一个并发写入的计划,整体是基于分布式锁实现的,并且只反对了 Spark COW 表的并发写,并不适用于 Flink 或者实时的 MOR 表。然而多任务的并发写入是咱们外部实际当中一个十分通用的诉求。因而咱们在 Hudi Metastore Server 的 Timeline 之上,应用乐观锁去从新实现了这个并发的更新能力。同时咱们这个并发管制模块还能反对更灵便的行列级别并发写策略,为后续要介绍到的实时数据关联的场景的落地提供了一个可能。

除了多任务的并发写入之外,咱们在单个 Flink 工作的并发写入也遇到了瓶颈。因为 Hudi 设计之初重大依赖 Spark。0.7.0 的版本才刚刚反对 Flink。不论是在稳定性还是在性能上都和 Spark On Hudi 有十分大的差距。因而在进行高 QPS 入湖的状况下,咱们就遇到了单个 Flink 工作的扩展性问题。
咱们通过在 Flink 的 embedding term server 上反对对以后进行中的事务元信息进行一下缓存,大幅晋升了单个工作可能并发写入的文件量级,基本上是在 80 倍的量级。联合分区级别的并发写入,咱们整体撑持了近千万 QPS 的数据量的增量入湖。
下一步的并发问题是批流并发抵触的问题。批流并发抵触问题相似于一个咱们在传统数据湖中遇到的场景,就是有一连串的小事务和一个周期比拟长的长事务,如果这两者发生冲突,应该如何解决。

如果让短事务等长事务实现之后再进行,那对一个实时的链路来说,就意味着数据的可见性变低了。同时如果在期待过程中失败了,还会有十分高的 fail over 老本。然而如果咱们让这个长事务失败了,老本又会很高,因为这个长事务往往须要消耗更多的资源和工夫。而在批流并发抵触的这个场景下,最好是两都不失败,但这从语义上来讲又不合乎咱们认知中的隔离级别。
为了解决批流抵触的问题,咱们的思路是提供更灵便的抵触检查和数据合并策略。最根底的就是行级并发,首先两个独立的 writer 写入的数据在物理上就是隔离的,借助文件系统的租约机制也可能保障对于一个文件同时只有一个 writer。所以这个抵触实际上不是产生在数据层面的,而是产生在元数据层面。那数据的抵触与否,就能够交由用户来定义。很多时候入湖的数据实际上并不是一个事实中正在产生的事件,而是一个事实操作的回放。比方图中的这个场景,咱们假如删除的作业是针对一个特定的 Snapshot。即便有抵触,咱们能够认为整个删除的过程是刹时实现的,后续的新事物能够追加的产生在这次删除作业之后。

第二就是列级并发。比方接下来在实际理论案例中,咱们要介绍的这个实时数据关联场景,每个 writer 实际上只是依据主键去更新局部的列。因而这些数据其实在行级别看起来是抵触的,然而从列的角度来看是齐全不抵触的。配合咱们的一些确定性索引,数据能被写入到同一个文件组中,这样就不会呈现一致性的问题。
最初就是抵触合并。如果两个数据真的是在行级别和列级别都产生了抵触,那真的只能通过 fail 掉一个事务能力实现吗?我感觉是不肯定的,这里咱们受到了 git 的启发。如果两次 commit 抵触了,咱们是不是能够提供 merge 值的策略,比方数据中带有工夫戳,在合并时就能够依照工夫戳的先后顺序来做合并。
(3)更新性能差
咱们最早抉择基于 Hudi 也是因为可扩大的索引零碎,通过这个索引零碎能够疾速地定位到须要跟新的文件。这带来了三点益处,一个是防止读取不须要的文件;二是防止更新不必要的文件;三是防止将更新的数据和历史的数据做分布式关联,而是通过提前将文件分好组的形式间接在文件组内进行合并。

在晚期的落地过程当中,咱们尝试尽可能去复用 Hudi 的一些原生能力,比方 Boom Filter index。然而随着数据规模的不停增长,当达到了千亿的量级之后,upsert 的数据随着数据量的增长逐步放缓,到了数千亿的量级后,生产的速度甚至赶不上生产者的速度。即便咱们去为它裁减了资源,而这时的数据总量其实也只是在 TB 级别。咱们剖析了每个文件组的大小,发现其实文件组的大小也是一个比拟正当的值,基本上是在 0.5g 到 1g 之间。进一步剖析,咱们发现随着数据量的增长,新的导入在通过索引定位数据的这一步破费的工夫越来越长。
根本原因是 Bloom Filter 存在假阳性,一旦命中假阳性的 case,咱们就须要把整个文件组中的主键链读取上来,再进一步地去判断这个数据是否曾经存在。通过这种形式来辨别这个到底是 update 还是 insert。upsert 自身就是 update 和 insert 两个操作的联合,如果发现雷同组件数据不存在,就进行 insert。如果存在,咱们就进行 update。而 Bloom Filter 因为假阳性的存在,只能减速数据的 insert 而没有方法去减速 update。这就和咱们察看到的景象很统一。因为这个 pipeline 在运行初期,大部分数据都是第一次入湖,是 insert 操作,因而能够被索引减速。然而规模达到一定量级之后,大部分数据都是更新操作,没有方法再被索引减速。为了解决这个问题,咱们急需一个更稳固更高效的索引。
Bloom Filter 索引的问题,根因是读取历史数据进行定位,导致定位的工夫越来越长。那有没有什么方法是无需读历史数据,也能够疾速定位到数据所在位置呢?很天然的,咱们就想到了相似于 Hive 的 bucket,也就是哈希的办法来解决这个问题。

Bucket Index 原理比较简单,整个表或者分区就相当于是一张哈希表,文件名中记录的这个哈希值,就相当于哈希表中这个数组的值。能够依据这个数据中的主键哈希值疾速地定位到文件组。一个文件组就相似于哈希表中的一个链表,能够将数据追加到这个文件组当中。Bucket Index 胜利地解决了流式更新性能的问题。因为极低的定位数据的老本,只有设置了一个适合的 bucket 桶大小,就能解决导入性能的问题。将流式更新能笼罩的场景从 TB 级别扩大到了百 TB 级别。除了导入的性能,Bucket Index 还减速了数据的查问,其中比拟有代表性的就是 bucket Pruning 和 bucket join。
当然这种索引形式咱们也遇到了一些扩展性的问题,用户须要提前一步做桶数的容量布局,给一个比拟平安的值,防止单个桶扩充,以便应答接下来的数据增长。在数据歪斜的场景下,为了让歪斜值尽可能扩散在不同的 bucket,会将 bucket 的数量调到很大。而每个 bucket 均匀大小很小,会带来大量的小文件,给文件系统带来冲击的同时也会带来查问侧性能下滑和写入侧的资源节约。同时在一线快速增长的业务,很难对容量有一个精准的预估。如果估算少了,数据量飞速增长,单个的 bucket 的均匀大小就会很大,这就会导致写入和查问的并发度有余,影响性能。如果估算多了,就会和歪斜的场景一样呈现大量的小文件。整体的 rehash 又是一个很重的运维操作,会间接影响业务侧对数据的生产和应用。因而不论从业务的易用性登程,还是思考到资源的使用率和查问的效率,咱们认为兼具高效导入和查问性能,也能反对弹性扩大的索引零碎是一个重要的方向。
这时咱们就想到了可扩大 hash 这个数据结构。利用这个构造,咱们能够很天然地去做桶的决裂和合并,让整个 bucket 的索引从手动驾驶进化到主动驾驶。在数据写入的时候,咱们也能够疾速地依据现有的总数,推断出最深的无效哈希值的长度,通过一直地对 2 的桶深度次方进行取余的形式,匹配到最靠近的分桶写入。咱们将 Bucket Index 这个索引奉献到了社区,已在 Hudi 的 0.11 版本对外公布。
(4)日志难入湖
实质起因也是因为 Hudi 的索引零碎。因为这个索引零碎要求数据依照组件汇集,一个最简略的形式就是把这个组件设成 UUID。但这样就会带来性能上的问题以及资源上的节约。因而咱们在 Hudi 之内实现了一套新的机制,咱们认为是无索引。就是绕过 Hudi 的索引机制,去做到数据的实时入湖。同时因为没有主键,Upsert 的能力也生效了。咱们提供了用更通用的 update 能力,通过 shuffle hash join 和 broadcast join 去实现数据实时更新。

3. 联合场景介绍实时数据湖在字节外部的一些实际案例

接下来具体介绍实时数据湖在字节的实际场景。电商是字节倒退十分疾速的业务之一,数据增长十分快,这也对数仓的建设提出了较高的要求。目前电商业务数据还是典型的 lambda 架构,分为是离线数仓和实时数仓建设。在理论场景中,lambda 架构的问题置信大家都曾经比拟理解了,我就不多做赘述了。这次的场景介绍是围绕一个主题,通过数据湖来构建实时数仓,使实时数据湖切入到实时数仓的建设当中。这不是欲速不达的,是分阶段一步一步渗透到实时数仓的建设当中。而实时数据湖的终极目标也是在存储侧造成一个真正意义上的批流一体的架构。

咱们切入的第一个阶段是实时数据的近实时可见可测。坦白说,在实时数据湖的落地初期,对于数据湖是否能在实时数仓中真正胜任,大家都是存疑的。因而最早的切入点也比拟激进,用在数据的验证环节。在电商的实时数仓中,因为业务倒退快,上游零碎变更,以及数据产品需要都十分多。导致实时数仓开发周期短,上线变更频繁。以后这个实时的数据的新增字段和指标逻辑变更,或者在工作重构优化时,都要对新版本的作业生成的指标进行验证。验证的指标次要有两点,一是原有指标,数据是否统一,二是新增指标的数据是否正当。
在采纳数据湖的计划之前,数据湖的验证环节须要将后果导入到 Kafka 而后再 dump 到 Hive。进行全量数据校验。这里存在的一个问题就是数据无奈实时或者近实时可见可检的,基本上都是一个小时级的提早。在很多紧急上线的场景下,因为延时的问题,只能去抽测数据进行测试验证,就会影响数据品质。实时数据湖的计划,是通过将实时数据低成本的增量导入到数据湖中,而后通过 Presto 进行查问,而后进行实时计算汇总,计算的后果做到近实时的全面的可见可测。

当然在这个阶段中,咱们也暴露出了很多数据湖上易用性的问题。业务侧的同学反馈最多的问题就是数据湖的配置过于简单。比方要写一个数据湖的工作,Hudi 本身就存在十多个参数须要在写入工作中配置。这减少了业务侧同学的学习老本和引擎侧同学的解释老本。同时还须要在 Flink SQL 里定义一个 sync table 的 DDL,写一个残缺的 schema。很容易会因为页的程序或者拼写错误导致工作失败。
咱们借助了 Hudi Metastore Server 的能力,封装了大量的参数。同时应用 Flink Catalog 的能力,对 Meta Server 进一步封装,让用户在配置一个 Fink SQL 工作的时候,从最后的写 DDL 配置十多个参数,到当初只有写一条 create table like 的语句,配置一张长期表,用户对这种形式的接受度广泛是比拟高的。
第二个阶段,也就是第二个利用场景是数据的实时入湖和实时剖析。数据湖能够同时满足高效的实时数据增量导入和交互式剖析的需要,让数据分析师能够自助地去搭建看板,同时也能够进行低成本的数据回刷,真正做到一份数据批流两种应用形式。在这个阶段,因为数据实际上曾经开始生产了,用户对于数据入湖的稳定性和查问性能都有很高的要求。咱们通过将 Compaction 工作与实时导入工作拆分,首先解决了资源抢占导致的入湖时效性比拟低的问题,同时设计了 compaction service,负责 compaction 工作的调度,整个过程对业务侧同学齐全屏蔽。咱们在服务层面也对报警和监控进行了增强,可能做到先于业务去发现问题,解决问题,进一步晋升了工作的稳定性,也让咱们的应用方可能更有信念地去应用实时数据湖。

在查问的优化下面,咱们优化了读文件系统的长尾问题,反对了实时表的列裁剪。同时咱们对 Avro 日志进行了短序列化和序列化的 case by case 的优化,还引入了列存的 log 进一步晋升查问性能。除了实时数据分析之外,这种能力还能够用于机器学习。在特色过程当中,有些 label 是能够疾速地从日志中实时获取到的。比方对一个视频点了个赞,和特色是能够关联上的。而有些 label 的生成则是长周期的。比方在抖音上买了一个货色,或者把一个货色退出购物车,到最初的购买,这整个链路是很长的,可能波及到天级别或者周级别的一个不定周期。然而在这两种状况下,它的特色数据基本上都是雷同的,这也使底层的存储有了批流两种应用形式的诉求,以往都是通过冗余的存储和计算来解决的。通过数据湖能够将短周期的特色和标签实时地入湖,长周期的每天做一次调度,做一个批式入湖,真正能做到一份数据去实用多个模型。
第三个阶段的利用场景是数据的实时多维汇总。在这个阶短最重要的指标是实时数据的普惠。因为很多的实时数据应用方都是通过可视化查问或者是数据服务去生产一个特定的汇总数据。而这些重度汇总过后的实时数据使用率相对来说是比拟低的。因而咱们和数仓的同学独特推动了一个实时多维汇总的计划落地。数仓的同学通过实时计算引擎实现数据的多维度的轻度汇总,并且实时地更新入湖。上游能够灵便地按需获取重度汇总的数据,这种形式能够缩短数据链路,晋升研发效力。

在理论的业务场景中,对于不同的业务诉求,又能够细分成三个不同的子场景。第一个场景是外部用户的可视化查问和报表这一类场景。它的特点就是查问频率不高,然而维度和指标的组合灵便,同时用户也能容忍数秒的提早。在这种场景下,下层的数据利用间接调用底层的 Presto 引擎行为实时入库的数据进行多维度的重度聚合之后,再做展示。另外一个次要的场景就是面向在线的数据产品,这种场景对高查问频率、低查问提早的诉求比拟高,然而对数据可见性的要求反而不那么高。而且通过重度汇总的数据量也比拟小,这就对数据分析工具提出了比拟大的挑战。因而在以后阶段,咱们通过减少了一个预计算链路来解决。
上面一个问题,多维重度汇总的多维计算结果是从咱们湖里批量读出来,而后定时地去写入 KV 存储,由存储去间接对接数据产品。从长期来看,咱们下一步打算就是对实时数据湖之上的表去进行主动地构建物化视图,并且加载进缓存,以此来兼顾灵活性和查问性能,让用户在享受这种低运维老本的同时,又能满足低延低查问提早、高查问频率和灵便应用的诉求。
第四个典型的场景是实时数据关联,数据的关联在数仓中是一个十分根底的诉求。数仓的同学须要将多个流的指标和维度列进行关联,造成一张宽表。然而应用维表 join,尤其是通过缓存减速的形式,数据准确性往往很难保障。而应用多流 join 的形式又须要维持一个大状态,尤其是对于一些关联周期不太确定的场景,稳定性和准确性之间往往很难取舍。

基于以上背景,咱们的实时数据湖计划通过了这个列级的并发写入和确定性的索引。咱们反对多个流式工作并发地去写入同一张表中,每个工作只写表中的局部列。数据写入的 log 件在物理上其实是隔离的,每个 log 文件当中也只蕴含了宽表中的局部列,实际上不会产生相互影响。再异步地通过 compaction 工作定期的对之前对 log 数据进行合并,在这个阶段对数据进行真正的理论的关联操作。通过这种形式,提供一个比较稳定的性能。应用这一套计划,实时关联用户也不必再关注状态大小和 TTL 该如何设置这个问题了,宽表的数据也能够做到实时可查。
最初一个阶段。咱们认为是实时数据湖的终极阶段,目前仍在摸索中。咱们只在局部场景开启了验证。在这个架构外面,数据能够从内部的不同数据源中实时或者批量的入湖和出湖,而流批作业实现湖内的数据实时流转,造成真正意义上的存储层批流一体。

同时在这套架构中,为了解决实时数据湖从分钟级到秒级的最初一公里,咱们在实时引擎与数据湖的表之间减少了一层数据减速服务。在这层数据减速服务之上,多个实时作业能够做到秒级的数据流转。而这个服务也会解决频繁流式写入频繁提交导致的小文件问题,为实时数据的交互查问进一步提速。除此之外,因为流批作业的个性不同,批计算往往会须要更高的刹时吞吐。因而这些批计算工作也能够间接地去读写底层的池化文件系统,来做到极强的扩展性,真正意义上做到批流写入的隔离,批作业的写入不会受限于减速服务的带宽。在这个批流一体的架构中,数据湖之上的用户,不论是 SQL 查问,还是 BI、AI,都能够通过一个对立的 table format 享受到数据湖之上数据的开放性。

4. 数据湖倒退的一些布局

最初来看一下将来布局。次要聚焦于三个维度:性能层面的布局,开源层面的布局,以及商业化输入相干的一些布局。
(1)性能层面
首先是性能维度,咱们认为一个更智能的实时数据湖的减速零碎是咱们最重要的指标之一。

首先是元数据层面的减速,数据湖托管了文件级别的元数据,元数据的数据量,相比数仓有了几个量级的增长,但同时也给咱们带来了一些优化的机会。比方咱们将来打算将查问的谓词间接下推到元数据系统当中,让这个引擎在 scan 阶段无需拜访零碎,间接去跳过有效文件来晋升查问的性能。
其次就是数据的减速。以后的实时数据湖因为其 serverless 架构对文件系统的重度依赖,在生产实践中还是处于分钟级,秒级仍旧处于验证阶段。那咱们接下来打算将这个数据湖减速服务一直地去打磨成熟,用来做实时数据的替换和热数据的存储,以解决分钟级到秒级的最初一公里问题。智能减速层面临的最大的挑战是批流数据写入的一致性问题,这也是咱们接下来重点要解决的问题。例如在这种端到端的实时生产链路中,如何在提供秒级延时的前提下解决相似于跨表事务的问题。
第三是索引减速。通过 bucket, zorder 等一系列的主键索引,来进一步地晋升数据湖之上的数据的查问性能,过滤掉大量的原始数据,防止有效的数据交换。同时咱们接下来也会十分重视二级索引的反对,因为二级索引的反对能够延长湖上数据的更新能力,从而去减速非主线更新的效率。
第四是智能优化。咱们接下来会通过一套表优化服务来实现智能优化,因为对于两个相似的查问是否去提供一个稳固的查问性能,表的数据分布是一个关键因素。而从用户的角度来看,用户只有查问快、写入快,像相似于 compaction 或 clustering、索引构建等一系列的表优化的形式,只会晋升用户的应用门槛。而咱们的打算是通过一个智能的表优化服务剖析用户的查问特色,去同时监听这个数据湖上数据的变动,自适应的去触发这个表的一系列的优化操作,能够做到在用户不须要理解过多细节的状况下,做到智能的互减速。
(2)开源层面
第二个维度是开源奉献。咱们当初始终在踊跃地投入到 Hudi 的社区奉献当中。参加了多个 Hudi 的外围 feature 的开发和设计。其中 Bucket index 是咱们合入到社区的第一个外围性能,而当下咱们也在同时奉献着多个重要的性能,比方最早提到的解决数据难治理的 Hudi MetaStore Server,咱们曾经奉献到社区了,去普惠到开源社区。因为咱们发现 Hudi MetaStore Server 不止解决咱们在生产实践中遇到的问题,也是业界广泛遇到的一个问题。当初也在跟 Hudi 社区的 PMC 独特探讨数据湖的元数据管理系统制订规范。

其它一些性能咱们也打算分两个阶段奉献到社区。比方 RPC 42,将咱们的湖表治理服务与大家共享,长期来看可能做到数据湖上的表的主动优化。还有 Trino 和 Presto DB 的 Hudi Connector,目前也是在和 Hudi 背地的生态公司独特推动投入到开源社区当中。
(3)商业化输入
以后在火山引擎之上,咱们将外部的数据湖技术实际同时通过 LAS 和 EMR 这两个产品向内部企业输入。其中 LAS 湖仓一体剖析服务是一个整体面向湖仓一体架构的 Serverless 数据处理剖析服务,提供一站式的海量数据存储计算和交互剖析能力,齐全地去兼容 Spark、Presto 和 Flink 生态。同时这个产品具备了残缺的字节外部的实时数据湖的成熟能力,可能帮忙企业轻松实现湖仓的构建和数据价值的洞察。
另外一个产品 EMR 是一个 Stateless 的云原生数仓,100% 开源兼容,在这个产品当中也会蕴含字节数据湖实际中一些开源兼容的优化,以及一些引擎的企业级加强,以及云上便捷的运维能力。
最初,欢送大家关注字节跳动数据平台公众号,在这里有十分多的技术干货、产品动静和招聘信息。
立刻跳转理解火山引擎 LAS 和火山引擎 EMR 产品。

退出移动版