写点什么

一文读懂 GaussDB(for Mongo) 的计算存储分离架构

  • 2020-08-17
  • 本文字数:2722 字

    阅读完需:约 9 分钟

一文读懂GaussDB(for Mongo)的计算存储分离架构

1.摘要

GaussDB(for Mongo)是华为云自主研发兼容 MongoDB4.0 接口的文档数据库。基于共享存储的存算分离架构,对于传统 MongoDB 社区版有如下优势:


  • 秒级添加 Secondary 节点(相比社区版 Mongo 小时级添加 Secondary 节点)

  • 基于 WAL 复制, Secondary 节点无写 IO,从根本上解决社区版 Seconary 节点 Oplog 脱节问题

  • Primary/Seconary 无任何 IO 交互,Secondary 节点个数理论无上限, 支持百万 OPS 的读事务能力

  • LSMTree Compaction 计算/IO 卸载到 Compaction 统一调度池,集中管理,不浪费用户读写 IO

  • 基于共享存储,Chunk 分裂/迁移动作不引起真实 IO,只更新路由元数据,秒级分裂/均衡

2.GaussDB(for Mongo)技术架构

1)容忍更多 Shard 宕机


与社区版 MongoDB 的Share-Nothing模式不同的是,GaussDB(for Mongo)采用Share-Storage架构,计算存储分离。集群模式下,N 个 Shard 节点,可以容忍 N-1 个 Shard 宕机。



某个 Shard 节点宕机后,其负责的数据由于存在于共享的存储池中,因此不需要物理拷贝数据,只需要修改元数据路由信息,即可被其他分片节点接管。


2)更快的分裂与均衡能力


此外,由于 Chunk 数据在存储池中,Chunk 的分裂与均衡不涉及到数据拷贝,可以做到分钟级分裂与扩容,分裂与扩容对用户的影响也远比社区版 MongoDB 小。



3)百万级读 OPS 能力


GaussDB(for Mongo)副本集模式下,Primary/Secondary 节点之间共享同一份数据库文件。Secondary 节点只复制 Primary 节点的 WriteAheadLog 以及 LSMTree 的结构变更信息,并应用到内存中。Secondary 节点没有 LSMTree 的 Compaction 和 Flush 任务,因此对用户的读业务影响很小。



此外,由于Share-Storage的架构优势,添加 Secondary 节点并不需要拷贝数据,添加 Secondary 节点的动作可以秒级完成。而 Primary/Secondary 之间只传递元数据变更,不传递 WriteAheadLog,因此 Secondary 节点的个数即使变多,也不影响 Primary 节点的写性能。Secondary 节点可以水平扩展,支撑百万级的读 OPS。


4)主节点 IO 卸载


LSMTree 的写压力来源于三部分:


  • 用户的业务写入导致的 Memtable Flush

  • 后台 SST 文件 Compaction

  • WAL 的持续写入


根据线上业务的实际测算,三者的 IO 资源消耗占比为: 1:10:1。后台的 SST 文件 Compaction 占了绝大部分 IO 带宽,通过将 Compaction 任务集中化管理,从计算池卸载到存储池,进一步减少了用户计算节点的 CPU 和 IO 资源消耗。



5)GaussDB(for Mongo) 只读节点设计


  • 传统社区版 MongoDB 副本集基于 Oplog 做数据复制,只读节点需要镜像主节点的所有写 IO 操作。GaussDB(for Mongo) 的只读节点和主节点共享同一份底层数据库文件(LSMTree 的 SST 文件),只读节点并不自己生成 SST 文件。

  • 随着业务数据的写入,Compaction 的不断执行,LSMTree 的当前版本(包含哪些 SST 文件)不断更新,LSMTree 的元数据更新(增删 SST 文件的记录)被同步到只读节点执行。

  • RocksDB 中,数据的变更被持久化到 WAL 里,元数据的变更(增删文件的操作, 叫做 VersionEdit)被持久化到 Mainifest 里。RocksDB 的数据和元数据是分开的,WAL 流和 VersionEdit 流是并行的,没有严格的先后顺序。为了保证只读节点和主节点完全一致的事件回放顺序,WAL 和 VersionEdit 流必须要合并成一个流,在双流合并后,通过 LSN 就可以为每个事件(WAL 的写操作/VersionEdit)定序。



  • 基于 WAL+VersionEdit 复制,而不基于 Oplog 复制

  • 共享文件(sst/wal)的生命周期管理由主节点负责 sst 文件和 wal 的文件的生命周期由主节点负责。RocksDB 中,SST 文件通过层级的引用计数来维持不被删除。如下图,RocksDB 的每个游标会维持 SuperVersion,如下图中的 S0,S1,S2。每个 SuperVersion 会引用一个 Version,一个 Version 代表 LSMTree 在不断变形(通过增删 SST 文件变形)的过程中,某个时间点的形状,最新的 Version 就代表 LSMTree 当前的形状。



  • 在 GaussDB(for Mongo)中,主节点会记录所有只读节点在使用的 Version,并为这些 Version 增加引用计数从而维持 SST 文件的生命周期。对于 WAL,主节点会记录所有只读节点中最老的 LSN(oldestLsn),最老的 LSN 来自于复制最慢的只读节点。并删除比 oldestLsn 还旧的 WAL 文件。

  • 元数据变更通知,无论是 oldestLsn 还是只读节点的当前在用的活跃的 Version,都需要及时推进,这些元数据的变更是通过主从节点的定期心跳上报到主节点上的。主节点利用心跳数据对垃圾版本与 WAL 做清理。如下图所示,在经历一次心跳后,主节点发现 Secondary0 的 Version0 和 Secondary1 的 Version0 不再使用。删除这两个 Version 后,SST0 的引用计数为 0,表示 SST0 可以被删除。OldestLsn 也从 100 推进到了 250,可以清理掉 250 之前的 WAL。



  • 只读节点的 memtable 的释放:主节点的 Memtable 不会实时 Flush 为 SST 文件。如果只读节点不处理主节点的 Memtable 的话,只读节点的数据就不是实时的,且存在数据一致性问题。只读节点通过回放 WAL 到内存的 Memtable 中,来覆盖 SST 文件与主节点的 Memtable 的 Gap。上文介绍了只读节点是不往共享存储写入数据的, 所以只读节点上的 Memtable 最后的结局一定是被丢弃掉。但什么时候丢弃这个 Memtable 就是一个问题。过早的丢弃,会造成 SST 文件与 Memtable 之间的数据不连续,存在 Gap,过晚的丢弃会造成内存的浪费。只有当只读节点识别到 SST 的数据已经完全能够 Cover 某个 Memtable 时,这个 Memtable 才可以被丢弃。

  • GaussDB(for Mongo)的只读节点在每次应用 VersionEdit 后,检查所有 SST 中的最大的 LSN 与 Memtable 的最小的 LSN 的关系,来决定是否要丢弃某个 Memtable。

  • 内存元数据的反向更新:传统的复制,数据流从 Oplog 来,走一遍完整的数据库 Server 层 CRUD 接口,再落到引擎层。这种逻辑和主节点上业务的写入逻辑是一致的,因此 Server 层的一些内存元数据结构,在这个过程中就自然而然的得到更新了。但是当采用基于 WAL 的复制后,整个 WritePath 并不经过只读节点的 Server 层。因此 Server 层的内存元数据更新,就是一个很大的挑战。在这里,只读节点对每一条 WAL 做分析,如果 WAL 的内容会影响 Mongo 内存元数据,就会 reload 对应的元数据模块。


3. 总结

GaussDB(for Mongo) 基于 Share-Storage 架构,实现秒级 Chunk 分裂与均衡,对业务影响更小,水平扩展速度更快,能容忍更多节点宕机。只读节点功能,实现了一份数据多计算节点共用的功能。极大的提升了存储的利用效率,提高了计算节点的读取数据能力。为了让副本节点具有持续的读扩展能力,整个只读方案采用元数据的同步模式,在不降低主节点负载的情况下,极大的提升了整个系统的读数据的处理能力。为 3 节点,5 节点,乃至于 15 节点以上的副本集的工作提供了可能。


2020-08-17 10:142148

评论 2 条评论

发布
用户头像
rocksdb 的WAL应该是逻辑日志,不像mysql 的redo log这种物理日志,就无法做到在存储节点层直接进行recovery 吧
2021-02-01 17:21
回复
用户头像
但是在图3里有4条从计算节点到存储节点的path,oplog, wal, data都下沉? 这还是 log is database 吗?

基于 WAL+VersionEdit 复制,而不基于 Oplog 复制

2021-02-01 17:18
回复
没有更多了
发现更多内容

杰哥教你面试之一百问系列:java中高级多线程concurrent的使用

程序那些事

Java 多线程 并发 程序那些事 面试秘籍

人工智能新范式,创新生产力崛起

百度开发者中心

人工智能 数据分析、 ChatGPT 文心一言

Eplan是电气设计软件吗?Eplan介绍-Eplan官网

智造软件

EPLAN 电气辅助设计 电气设计

2023年大数据平台数据安全厂商汇总

行云管家

大数据 数据安全 大数据平台

EasyPhoto:基于 SD WebUI 的艺术照生成插件来啦!

阿里云大数据AI技术

阿里云 AI

从数据出发,构建可信赖的生成式AI应用

百度开发者中心

人工智能 数据分析 千帆大模型平台

Mac电脑油猴插件 Tampermonkey激活中文版

胖墩儿不胖y

Mac软件 油猴插件 脚本管理

MatrixOne WAL设计解析

MatrixOrigin

分布式数据库 云原生数据库 MatrixOrigin MatrixOne HTAP数据库

GaussDB技术解读丨数据库迁移创新实践

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号9月PK榜

提高生产力,创新工作方式

百度开发者中心

人工智能 ChatGPT 生成式AI 文心一言

云堡垒机收费模式有哪些?哪款更灵活?

行云管家

云计算 网络安全 堡垒机 云堡垒机

用友iuap数据中台,让数据成为企业价值资产,驱动业务持续创新

用友BIP

2023全球商业创新大会 升级数智底座

一体化打通销售到项目交付 项目型营销更在行

用友BIP

项目云 数智营销

创新未来的智能数据生成

百度开发者中心

人工智能 ChatGPT 生成式AI

聊聊Kafka的生产者消费者确认机制

高端章鱼哥

kafka

mac端日程和任务管理 Things3 免激活中文

mac大玩家j

任务管理 Mac软件 任务管理器

一文读懂GaussDB(for Mongo)的计算存储分离架构_数据库_华为云与计算_InfoQ精选文章