Lakehouse数据湖并发控制陷阱分析


Posted in Oracle onMarch 31, 2022

1. 概述

如今数据湖上的事务被认为是 Lakehouse 的一个关键特征。 但到目前为止,实际完成了什么? 目前有哪些方法? 它们在现实世界中的表现如何? 这些问题是本博客的重点。

有幸从事过各种数据库项目——RDBMS (Oracle)、NoSQL 键值存储 (Voldemort)、流数据库 (ksqlDB)、闭源实时数据存储,当然还有 Apache Hudi, 我可以肯定地说,工作负载的不同深刻地影响了不同数据库中采用的并发控制机制。本博客还将介绍我们如何重新思考 Apache Hudi 数据湖的并发控制机制。

首先,我们直截了当点,RDBMS 数据库提供了最丰富的事务功能集和最广泛的并发控制机制,不同的隔离级别、细粒度锁、死锁检测/避免等其他更多机制,因为它们必须支持行级变更和跨多个表的读取,同时强制执行键约束并维护索引。而NoSQL 存储提供了非常弱的保证,例如仅仅提供最终一致性和简单的行级原子性,以换取更简单的工作负载的更好的扩展性。传统数据仓库基于列存或多或少提供了您在 RDBMS 中可以找到的全套功能,强制执行锁定和键约束,而云数据仓库似乎更多地关注存算分离架构,同时提供更少的隔离级别。作为一个令人惊讶的例子,没有强制执行键约束。

2. 数据湖并发控制中的陷阱

从历史看来,数据湖一直被视为在云存储上读取/写入文件的批处理作业,有趣的是看到大多数新工作如何扩展此视图并使用某种形式的“乐观并发控制”(OCC)来实现文件版本控制。 OCC 作业采用表级锁来检查它们是否影响了重叠文件,如果存在冲突则中止操作,锁有时甚至只是在单个 Apache Spark Driver节点上持有的 JVM 级锁,这对于主要将文件附加到表的旧式批处理作业的轻量级协调来说可能没问题,但不能广泛应用于现代数据湖工作负载。此类方法是在考虑不可变/仅附加数据模型的情况下构建的,这些模型不适用于增量数据处理或键控更新/删除。 OCC 非常乐观地认为真正的冲突永远不会发生。将 OCC 与 RDBMS 或传统数据仓库的完全成熟的事务功能进行比较的开发人员布道是完全错误的,直接引用维基百科——“如果频繁地争用数据资源,重复重启事务的成本会显着损害性能,在这种情况下,其他并发控制方法可能更适合。” 当冲突确实发生时,它们会导致大量资源浪费,因为你有每次尝试运行几个小时后都失败的批处理作业!

想象一下两个写入进程的真实场景:一个每 30 分钟生成一次新数据的摄取写入作业和一个执行 GDPR 的删除作业,需要 2 小时才能完成删除。这些很可能与随机删除重叠文件,并且删除作业几乎可以保证每次都饿死并且无法提交。 在数据库方面,将长期运行的事务与乐观混合会导致失望,因为事务越长,它们重叠的可能性就越高。

Lakehouse数据湖并发控制陷阱分析

那么有什么替代方案呢?锁?维基百科还说 - “但是,基于锁(“悲观”)的方法也可能提供较差的性能,因为即使避免了死锁,锁也会极大地限制有效的并发性。”。这就是 Hudi 采用不同方法的地方,我们认为这种方法更适合现代数据湖事务,这些事务通常是长期运行的,甚至是连续的。与数据库的标准读/写相比,数据湖工作负载与高吞吐量流处理作业共享更多特征,这就是我们借鉴的地方。在流处理中,事件被序列化为单个有序日志,避免任何锁/并发瓶颈,用户可以每秒连续处理数百万个事件。Hudi 在 Hudi 时间线上实现了一个文件级、基于日志的并发控制协议,而该协议又依赖于对云存储的最低限度的原子写入。通过将事件日志构建为进程间协调的核心部分,Hudi 能够提供一些灵活的部署模型,与仅跟踪表快照的纯 OCC 方法相比,这些模型提供更高的并发性。

3. 模型 1:单写入,内联表服务

并发控制的最简单形式就是完全没有并发。 数据湖表通常在其上运行公共服务以确保效率,从旧版本和日志中回收存储空间、合并文件(Hudi 中的Clustering)、合并增量(Hudi 中的Compaction)等等。 Hudi 可以简单地消除对并发控制的需求,并通过支持这些开箱即用的表服务并在每次写入表后内联运行来最大化吞吐量。

执行计划是幂等的,持久化至时间线并从故障中自动恢复。对于大多数简单的用例,这意味着只需写入就足以获得一个不需要并发控制的管理良好的表。

Lakehouse数据湖并发控制陷阱分析

4. 模型2:单写入,异步表服务

我们上面的删除/摄取示例并不是那么简单。虽然摄取/写入可能只是更新表上的最后 N 个分区,但删除甚至可能跨越整个表,将它们混合在同一个工作负载中可能会大大影响摄取延迟,因此Hudi 提供了以异步方式运行表服务的选项,其中大部分繁重的工作(例如通过压缩服务实际重写列数据)是异步完成的,消除了任何重复的浪费重试,同时还使用Clustering技术。因此单个写入可以同时使用常规更新和 GDPR 删除并将它们序列化到日志中。鉴于 Hudi 具有记录级索引并且 avro 日志写入要便宜得多(与写入 parquet 相比,后者可能要贵 10 倍或更高),摄取延迟可以持续,同时享受出色的可回溯性。事实上我们能够在 Uber 将这个模型扩展到 100 PB数据规模,通过将所有删除和更新排序到同一个源 Apache Kafka 主题中,并发控制不仅仅是锁,Hudi 无需任何外部锁即可完成所有这一切。

Lakehouse数据湖并发控制陷阱分析

5. 模型3:多写入

但是并不总是可以将删除序列化到相同的写入流中,或者需要基于 sql 的删除。 对于多个分布式进程,某种形式的锁是不可避免的,但就像真正的数据库一样,Hudi 的并发模型足够智能,可以将实际写入表的内容与管理或优化表的表服务区分开来。 Hudi 提供了类似的跨多个写入器的乐观并发控制,但表服务仍然可以完全无锁和异步地执行。 这意味着删除作业只能对删除进行编码,摄取作业可以记录更新,而压缩服务再次将更新/删除应用于基本文件。 尽管删除作业和摄取作业可以像我们上面提到的那样相互竞争和饿死,但它们的运行时间要低得多,浪费也大大降低,因为压缩完成了parquet/列数据写入的繁重工作。

Lakehouse数据湖并发控制陷阱分析

综上所述,在这个基础上我们还有很多方法可以改进。

首先,Hudi 已经实现了一种标记机制,可以跟踪作为活动写入事务一部分的所有文件,以及一种可以跟踪表的活动写入者的心跳机制。这可以由其他活动事务/写入器直接使用来检测其他写入器正在做什么,如果检测到冲突,则尽早中止,从而更快地将集群资源返回给其他作业。

虽然在需要可序列化快照隔离时乐观并发控制很有吸引力,但它既不是最佳方法,也不是处理写入者之间并发性的唯一方法。我们计划使用 CRDT 和广泛采用的流处理概念,通过我们的日志合并 API 实现完全无锁的并发控制,这已经被证明可以为数据湖维持巨大的连续写入量。

谈到键约束,Hudi 是当今唯一确保唯一键约束的湖事务层,但仅限于表的记录键。我们将寻求以更通用的形式将此功能扩展到非主键字段,并使用上述较新的并发模型。

最后,要使数据湖成功转型为Lakehouse,我们必须从“Hadoop 仓库”愿景的失败中吸取教训,它与新的“Lakehouse”愿景有着相似的目标。 设计人员没有密切关注与数据仓库相关的缺失技术差距,并且对实际软件产生了不切实际的期望。 随着事务和数据库功能最终成为数据湖的主流,我们必须应用这些经验教训并对当前的缺点保持坦率。 如果您正在构建一个 Lakehouse,我希望这篇文章能鼓励您仔细考虑围绕并发控制的各种操作和效率方面。 

https://hudi.apache.org/blog/2021/12/16/lakehouse-concurrency-control-are-we-too-optimistic

以上就是Lakehouse数据湖并发控制陷阱分析的详细内容,更多关于Lakehouse数据湖并发控制的资料请关注三水点靠木其它相关文章!

Oracle 相关文章推荐
Oracle笔记
Apr 05 Oracle
Oracle设置DB、监听和EM开机启动的方法
Apr 25 Oracle
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
Jun 04 Oracle
快速学习Oracle触发器和游标
Jun 30 Oracle
Oracle以逗号分隔的字符串拆分为多行数据实例详解
Jul 16 Oracle
使用Oracle命令进行数据库备份与还原
Dec 06 Oracle
Oracle中update和select 关联操作
Jan 18 Oracle
详解SQL的窗口函数
Apr 21 Oracle
Oracle中DBLink的详细介绍
Apr 29 Oracle
oracle数据库去除重复数据
May 20 Oracle
Oracle锁表解决方法的详细记录
Jun 05 Oracle
Oracle数据库中通用的函数实例详解
详细聊聊Oracle表碎片对性能有多大的影响
Mar 19 #Oracle
oracle删除超过N天数据脚本的方法
Feb 28 #Oracle
oracle重置序列从0开始递增1
Feb 28 #Oracle
Oracle 触发器trigger使用案例
Feb 24 #Oracle
Oracle中update和select 关联操作
Jan 18 #Oracle
使用Oracle命令进行数据库备份与还原
Dec 06 #Oracle
You might like
php实现webservice实例
2014/11/06 PHP
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
Javascript入门学习资料收集整理篇
2008/07/06 Javascript
jQuery弹出层插件简化版代码下载
2008/10/16 Javascript
javaScript Array(数组)相关方法简述
2009/07/25 Javascript
js将当前时间格式转换成时间搓(自写)
2013/09/26 Javascript
再谈javascript原型继承
2014/11/10 Javascript
node.js中的path.resolve方法使用说明
2014/12/08 Javascript
javascript中this关键字详解
2016/12/12 Javascript
微信小程序 地图map详解及简单实例
2017/01/10 Javascript
webpack入门必知必会
2017/01/16 Javascript
基于jQuery实现一个marquee无缝滚动的插件
2017/03/09 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
2017/03/29 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
浅谈在Vue-cli里基于axios封装复用请求
2017/11/06 Javascript
使用Python编写提取日志中的中文的脚本的方法
2015/04/30 Python
Python实现文件复制删除
2016/04/19 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
python面试题小结附答案实例代码
2019/04/11 Python
Python内置函数property()如何使用
2020/09/01 Python
使用django自带的user做外键的方法
2020/11/30 Python
广告宣传策划方案
2014/05/21 职场文书
承诺书范文
2014/06/03 职场文书
学校运动会广播稿100条
2014/09/14 职场文书
法人委托书范本格式
2014/09/15 职场文书
幼儿园教师的自我评价范文
2014/09/17 职场文书
医院领导班子整改方案
2014/10/01 职场文书
党员个人查摆剖析材料
2014/10/16 职场文书
教师师德师风整改措施
2014/10/24 职场文书
2014年检验科工作总结
2014/11/22 职场文书
2015教师见习期工作总结
2014/12/12 职场文书
钢琴师观后感
2015/06/12 职场文书
详解JavaScript中的执行上下文及调用堆栈
2021/04/29 Javascript
mysql事务对效率的影响分析总结
2021/10/24 MySQL
Java实现学生管理系统(IO版)
2022/02/24 Java/Android
小程序自定义轮播图圆点组件
2022/06/25 Javascript