如何不加锁地将数据并发写入Apache Hudi?
最近一位 Hudi 用户询问他们是否可以在不需要任何锁的情况下同时从多个写入端写入单个 Hudi 表。 他们场景是一个不可变的工作负载。 一般来说对于任何多写入端功能,Hudi 建议启用锁定配置。 但这是一个有趣的问题,我们进行探索并找到了解决方案,因此与更广泛的社区分享。
需要并发写入的锁提供程序
对于某些场景来说可能是必要的,但可能并不适合所有场景。 因此我们首先看看为什么当并发写入Hudi 或任何表格式时我们需要锁提供程序。 如果两个并发写入修改同一组数据,我们只能允许其中一个成功并中止另一个,因为至少与乐观并发控制(OCC)存在冲突。 我们可以尝试设计和实现基于 MVCC 的模型,但当前还没有做到这一点。 因此仅使用纯 OCC,任何两个并发写入重叠数据都无法成功。 因此为了解决冲突和某些表管理服务,我们需要锁,因为在任何时间点只有其中一个可以操作临界区。 因此我们采用锁提供程序来确保两个写入之间协调此类冲突解决和表管理服务。总结如下
- 出于解决冲突的目的,我们不会让两个写入端成功写入重叠的数据。
- 对于清理、归档、聚簇等表管理服务,需要协调不同写入端。
那么如果上述两个原因可以放宽呢?
- 如果工作负载是不可变的,或者不同的写入端写入完全不同的分区,那么真的不需要解决任何冲突。显然声称没有一个写入端重叠这是由用户承担的,因为 Hudi 可能不会做任何冲突解决。
- 禁用除一个写入端之外的所有写入端的表服务。
不可变的工作负载
不可变的工作负载是关键。 因此建议他们使用 bulk_insert作为操作类型,因为它相当于写入Parquet表。 没有索引查找,没有小文件管理,因此两个写入端不会以任何方式发生冲突。
表服务
Hudi 有一个全局配置,可以在需要时禁用表服务("hoodie.table.services.enabled")。 默认情况下配置设置为 true,因此启动的每个写入端都可能正在执行表服务。但我们可以使用此配置来禁用除一个之外的所有写入端。
元数据表
必须禁用元数据表,因为我们有一个先决条件,即如果有多个写入端,需要锁定元数据表。

本质上其中一个写入端将与所有表服务一起进行摄取,而所有其他写入端只会进行摄取,这可能不会与任何其他写入端重叠。如下是两个写入端的配置。
写入端1
忽略典型的必填字段,如记录键、表名等。这些是必须为写入端 1 设置的配置。
option("hoodie.datasource.write.operation","bulk_insert").
option("hoodie.write.concurrency.mode","OPTIMISTIC_CONCURRENCY_CONTROL").
option("hoodie.cleaner.policy.failed.writes","LAZY").
option("hoodie.write.lock.provider","org.apache.hudi.client.transaction.lock.InProcessLockProvider").
option("hoodie.metadata.enable","false").
注意到我们启用了 InProcessLockProvider 并将操作类型设置为"bulk_insert"并禁用了元数据表。
因此写入端将负责清理和归档等表服务。
写入端2
写入端2设置如下
option("hoodie.datasource.write.operation","bulk_insert").
option("hoodie.cleaner.policy.failed.writes","LAZY").
option("hoodie.metadata.enable","false").
option("hoodie.table.services.enabled","false").
注意到我们禁用了表服务和元数据表,并将操作类型设置为"bulk_insert"。 因此写入端2所做的就是将新数据摄取到表中,而无需担心任何表服务。
小文件管理
如果希望利用小文件管理也可以将写入端1的操作类型设置为"insert"。 如果希望将"insert"作为所有写入的操作类型,则应小心。 如果它们都写入不同的分区,那么它可能会起作用。 但如果它们可能写入相同的分区,则可能会导致意想不到的后果,需要避免。
或者我们可以将操作类型保留为"bulk_insert",但使用写入端1启用聚簇来合并小文件,如下所示:
option("hoodie.datasource.write.operation","bulk_insert").
option("hoodie.write.concurrency.mode","OPTIMISTIC_CONCURRENCY_CONTROL").
option("hoodie.cleaner.policy.failed.writes","LAZY").
option("hoodie.write.lock.provider","org.apache.hudi.client.transaction.lock.InProcessLockProvider").
option("hoodie.metadata.enable","false").
option("hoodie.clustering.inline","true").
option("hoodie.clustering.inline.max.commits","4").
为两个并发 Spark 写入端尝试上述一组配置,并使用清理和归档设置进行了 100 多次提交测试。 还进行故障演练并且事物完好无损。 输入数据与两个写入端从 Hudi 读取的快照相匹配。
结论
如果用例符合前面提到的约束,这将非常有助于提高 Hudi 写入的吞吐量。不必为锁提供者管理基础设施也将减轻操作负担。
如何不加锁地将数据并发写入Apache Hudi?的更多相关文章
- 写入Apache Hudi数据集
这一节我们将介绍使用DeltaStreamer工具从外部源甚至其他Hudi数据集摄取新更改的方法, 以及通过使用Hudi数据源的upserts加快大型Spark作业的方法. 对于此类数据集,我们可以使 ...
- 基于Apache Hudi构建数据湖的典型应用场景介绍
1. 传统数据湖存在的问题与挑战 传统数据湖解决方案中,常用Hive来构建T+1级别的数据仓库,通过HDFS存储实现海量数据的存储与水平扩容,通过Hive实现元数据的管理以及数据操作的SQL化.虽然能 ...
- Robinhood基于Apache Hudi的下一代数据湖实践
1. 摘要 Robinhood 的使命是使所有人的金融民主化. Robinhood 内部不同级别的持续数据分析和数据驱动决策是实现这一使命的基础. 我们有各种数据源--OLTP 数据库.事件流和各种第 ...
- 使用Apache Flink 和 Apache Hudi 创建低延迟数据湖管道
近年来出现了从单体架构向微服务架构的转变.微服务架构使应用程序更容易扩展和更快地开发,支持创新并加快新功能上线时间.但是这种方法会导致数据存在于不同的孤岛中,这使得执行分析变得困难.为了获得更深入和更 ...
- Apache Hudi助力nClouds加速数据交付
1. 概述 在nClouds上,当客户的业务决策取决于对近实时数据的访问时,客户通常会向我们寻求有关数据和分析平台的解决方案.但随着每天创建和收集的数据量都在增加,这使得使用传统技术进行数据分析成为一 ...
- 使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失
使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读.数据不丢失. //并发文件操作 function filehandle($filename,$data){ $start = 0; $e ...
- SQLAlchemy并发写入引发的思考
背景 近期公司项目中加了一个积分机制,用户登录签到会获取登录积分,但会出现一种现象就是用户登录时会增加双倍积分,然后生成两个积分记录.此为问题 问题分析 项目采用微服务架构,下图为积分机制流程 ...
- leveldb - 并发写入处理
在并发写入的时候,leveldb巧妙地利用一个时间窗口做batch写入,这部分代码值得一读: Status DBImpl::Write(const WriteOptions& options, ...
- python导出zabbix数据并发邮件脚本
Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...
- C#使用读写锁解决多线程并发写入文件时线程同步的问题
读写锁是以 ReaderWriterLockSlim 对象作为锁管理资源的,不同的 ReaderWriterLockSlim 对象中锁定同一个文件也会被视为不同的锁进行管理,这种差异可能会再次导致文件 ...
随机推荐
- DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍 1. 概述 近日来,ChatGPT及类似模型引发了人工智能(AI)领域的一场风潮. 这场风潮对数字世 ...
- 海思码率控制相关参数调优(CBR/VBR)
1.CBR 海思相关参数调整(在Hisi板,cat /proc/umap/rc 可查看相关参数变化) 1.1 RC参数 1.2 VENC参数 VENC_PARAM_H264_CBR_S/VENC_PA ...
- 用Python语言进行时间序列ARIMA模型分析
应用时间序列 时间序列分析是一种重要的数据分析方法,应用广泛.以下列举了几个时间序列分析的应用场景: 1.经济预测:时间序列分析可以用来分析经济数据,预测未来经济趋势和走向.例如,利用历史股市数据和经 ...
- HTAP for MySQL 在腾讯云数据库的演进
摘要:MySQL在充分利用多核计算资源方面比较欠缺,无法同时满足在线业务和分析型业务的客户需求,而单独部署一套专用的分析型数据库意味着额外的成本和复杂的数据链路.本次主题将介绍腾讯云数据库为满足此类场 ...
- 2021-06-22:现有司机N*2人,调度中心会将所有司机平分给A、B两个区域,第 i 个司机去A可得收入为income[i][0],第 i 个司机去B可得收入为income[i][1],返回所有调
2021-06-22:现有司机N*2人,调度中心会将所有司机平分给A.B两个区域,第 i 个司机去A可得收入为income[i][0],第 i 个司机去B可得收入为income[i][1],返回所有调 ...
- uni-app介绍
"优你"框架 uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.Web(响应式).以及各种小程序(微信/支付宝/ ...
- Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.
问题描述 新建表或者修改表varchar字段长度的时候,出现这个错误 Row size too large. The maximum row size for the used table type, ...
- C语言访问数据对象在内存中真实位模式的一个方法
在判定机器采用大端还是小端存储时,可以按字节输出某数据对象的机器表示的位模式.机器表示的位模式即某数据对象在内存中的二进制串.下面是一个访问数据对象位模式的方法: //传入一个数据对象,从低地址到高地 ...
- 《数据结构(C语言版)》严蔚敏代码实现———顺序表
一.前言 最近在重新学习数据结构啦,网上说这本书挺不错哒,于是我开始啃这本书咯...有一说一,严奶奶的书挺好的,就是有点大量使用指针...需要沉下心来,看一看画一画才能懂,我自己手敲了一遍书上代码,加 ...
- Spring源码:Bean生命周期(终章)
前言 本系列前面讲解了Spring的bean定义.bean实例化.bean初始化等生命周期.这些步骤使我们能够了解bean从创建到准备好使用所经历的过程.但是,除了这些步骤,bean的销毁也是非常重要 ...