如何不加锁地将数据并发写入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 对象中锁定同一个文件也会被视为不同的锁进行管理,这种差异可能会再次导致文件 ...
随机推荐
- 计算机常用的快捷键以及常用的Dos命令
计算机的常用快捷键有哪些? 今天我重温了Java基础的课程,计算机的快捷键大家肯定不陌生. 计算机的常用快捷键 ctrl+c 复制 ctrl+v 粘贴 ctrl+s 保存 ctrl+x 剪切 ct ...
- rockyLinux 初体验(教程)PostgreSQL15
目录 数据库软件 PostgreSQL 安装 数据库软件 PostgreSQL 配置 数据库软件 PostgreSQL 交互 通用数据库管理软件 DBeaver 彼时,PostgreSQL 已经更新到 ...
- [OpenCV-Python] 24 模板匹配
文章目录 OpenCV-Python:IV OpenCV中的图像处理 24 模板匹配 24.1 OpenCV 中的模板匹配 24.2 多对象的模板匹配 OpenCV-Python:IV OpenCV中 ...
- Selenium 打包为.exe执行
前言:不依赖环境执行,拓展UI自动化使用的场景 一.项目结构介绍 case:测试用例次存放目录 config:主要存放yaml文件配置 ele:元素的定位以及执行动作 tools:HTMLTestRu ...
- Apache ShenYu 学习笔记一
1.简介 这是一个异步的,高性能的,跨语言的,响应式的 API 网关. 官网文档:https://shenyu.apache.org/zh/docs/index 仓库地址:https://github ...
- Java代码读取properties配置文件
读取properties配置文件 package com.easycrud.utils; import java.io.IOException; import java.io.InputStream; ...
- ai问答:使用 Vue3 组合式API 和 TS 封装 echarts 折线图
使用这个组件时,只需要传入合适的chartData数组,就可以渲染一个折线图,并且响应数据变化. <template> <div ref="chart" styl ...
- Vulhub activewq_漏洞复现——源码分析
Vulhub activewq_漏洞复现--源码分析 漏洞简介 Apache ActiveMQ是由美国阿帕奇(Apache)软件基金会开发的开源消息中间件,支持Java消息服务.集群.Spring框架 ...
- 各种远程工具通过ssh连接服务器
开头 最近遇到一个新的连接方式,不能使用日常的本地通过账号连接,要通过私钥和公钥的连接方式,然后连接到服务器之后才能连接到数据库.因为之前没试过这种连接方式,所以很多工具有不同的连接方式.所以现在就记 ...
- 2023-01-05:konradkleine/docker-registry-frontend是registry的web界面工具之一。请问部署在k3s中,yaml如何写?
2023-01-05:konradkleine/docker-registry-frontend是registry的web界面工具之一.请问部署在k3s中,yaml如何写? 答案2023-01-05: ...