前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何不加锁地将数据并发写入Apache Hudi?

如何不加锁地将数据并发写入Apache Hudi?

作者头像
ApacheHudi
发布2023-09-04 12:37:37
4940
发布2023-09-04 12:37:37
举报
文章被收录于专栏:ApacheHudi
最近一位 Hudi 用户询问他们是否可以在不需要任何锁的情况下同时从多个写入端写入单个 Hudi 表。他们场景是一个不可变的工作负载。一般来说对于任何多写入端功能,Hudi 建议启用锁定配置。但这是一个有趣的问题,我们进行探索并找到了解决方案,因此与更广泛的社区分享。

需要并发写入的锁提供程序

对于某些场景来说可能是必要的,但可能并不适合所有场景。因此我们首先看看为什么当并发写入Hudi 或任何表格式时我们需要锁提供程序。如果两个并发写入修改同一组数据,我们只能允许其中一个成功并中止另一个,因为至少与乐观并发控制(OCC)存在冲突。我们可以尝试设计和实现基于 MVCC 的模型,但当前还没有做到这一点。因此仅使用纯 OCC,任何两个并发写入重叠数据都无法成功。因此为了解决冲突和某些表管理服务,我们需要锁,因为在任何时间点只有其中一个可以操作临界区。因此我们采用锁提供程序来确保两个写入之间协调此类冲突解决和表管理服务。总结如下

  1. 1. 出于解决冲突的目的,我们不会让两个写入端成功写入重叠的数据。
  2. 2. 对于清理、归档、聚簇等表管理服务,需要协调不同写入端。

那么如果上述两个原因可以放宽呢?

  • • 如果工作负载是不可变的,或者不同的写入端写入完全不同的分区,那么真的不需要解决任何冲突。显然声称没有一个写入端重叠这是由用户承担的,因为 Hudi 可能不会做任何冲突解决。
  • • 禁用除一个写入端之外的所有写入端的表服务。

不可变的工作负载

不可变的工作负载是关键。因此建议他们使用 bulk_insert作为操作类型,因为它相当于写入Parquet表。没有索引查找,没有小文件管理,因此两个写入端不会以任何方式发生冲突。

表服务

Hudi 有一个全局配置,可以在需要时禁用表服务("hoodie.table.services.enabled")。默认情况下配置设置为 true,因此启动的每个写入端都可能正在执行表服务。但我们可以使用此配置来禁用除一个之外的所有写入端。

元数据表

必须禁用元数据表,因为我们有一个先决条件,即如果有多个写入端,需要锁定元数据表。

本质上其中一个写入端将与所有表服务一起进行摄取,而所有其他写入端只会进行摄取,这可能不会与任何其他写入端重叠。如下是两个写入端的配置。

写入端1

忽略典型的必填字段,如记录键、表名等。这些是必须为写入端 1 设置的配置。

代码语言:javascript
复制
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设置如下

代码语言:javascript
复制
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启用聚簇来合并小文件,如下所示:

代码语言:javascript
复制
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 写入的吞吐量。不必为锁提供者管理基础设施也将减轻操作负担。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ApacheHudi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需要并发写入的锁提供程序
  • 不可变的工作负载
  • 表服务
    • 元数据表
      • 小文件管理
      • 结论
      相关产品与服务
      混沌演练平台
      混沌演练平台(Chaotic Fault Generator)提供高效便捷、安全可靠的故障演习服务,除可视化故障注入服务外,还提供行业经验模板,监控护栏等核心功能,致力于帮助用户及时发现业务容灾隐患、验证高可用预案的有效性,从而提高系统的可用性和韧性。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档