返回资讯中心
外部精选
软件工程
#开发者实时流

工程师复盘MongoDB与WiredTiger内部机制:一次写入产生两份日志

来源标题:MongoDB: One Write, Two Logs

一位工程师基于运维20TB分片集群(峰值约5.5万次操作/秒、约2.9万次写入)的实践,撰文梳理了他对MongoDB与WiredTiger内部机制的理解。文章以“一次写入、两份日志”为线索,属于个人学习文档,作者提醒技术细节应以MongoDB和WiredTiger官方文档为准。

Hacker News 最新fjelavic2026/11/2 · 3 天前28 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

这篇文章记录了我目前对 MongoDB 和 WiredTiger 的理解,这些理解来自实际操作和持续学习。这是一份学习文档。我尽量保证技术细节准确,但任何错误或过度简化都由我负责。关于正确性和清晰度,应始终查阅 MongoDB 官方文档和 WiredTiger 文档。

当我第一次接触 MongoDB 时,我试图通过我最熟悉的数据库来理解它:PostgreSQL。 我的经历堪称一场烈火洗礼。我当时管理着一个分片集群,数据量达 20 TB,每秒操作数最高约 55k,其中约 29k 是写操作。该集群有六个分片,每个分片都有自己的副本集,还有一个配置服务器副本集和六个路由器。 为了安全地运维那个集群,我不得不停止把 MongoDB 当作 PostgreSQL 来对待,转而学习它的内部工作原理。 有一次,在处理上述集群的流控问题时,一个 AI 模型给出的建议是:增加分配给 WiredTiger 缓存的内存比例。当时这个建议听起来真实且正确,但我不知道模型是基于什么得出结论的。说实话,我也不知道 MongoDB 是如何使用 RAM 的。压垮骆驼的最后一根稻草是官方文档说不要改变 WiredTiger 缓存与 RAM 的比例。 那次经历让我明白了为什么我想学习内部机制。我希望/需要足够的理解,以便将运维建议与某个机制联系起来,识别其所依赖的证据,并做出决定。无论建议来自 AI、同事、文档还是我自己的假设,这都适用。 MongoDB 客户端发送写操作后会发生什么? 该写操作如何经过 MongoDB 和 WiredTiger,何时在磁盘上变得持久? 当有人建议更改某个 WiredTiger 设置时,需要满足什么条件,这个建议才说得通?

当客户端向分片集群发送写操作时,请求首先到达一个名为 mongos 的路由器。路由器会缓存来自配置服务器的关于 chunk 与分片对应关系的数据。利用这些数据,mongos 确定哪个分片拥有相关数据,并将操作转发到该分片的主节点。 然而,本文不比较副本集和分片集群。路由完成后,同样的问题适用于每个分片内部。 主 mongod 进程如何请求、持久化并将其复制到从节点? 为了回答我的问题,我首先必须理解 mongod 在哪里结束,存储引擎 WiredTiger 在哪里开始。 mongod 处理客户端命令、授权、查询执行、事务协调和复制。WiredTiger 是嵌入式存储引擎,存储集合和索引数据。它提供本地事务、MVCC、缓存、压缩、日志、检查点和崩溃恢复。 MongoDB 客户端 │ 写操作 ▼ mongos 查询路由器 │ 路由到所属分片 ▼ 分片主节点(mongod) ├── 授权和命令处理 ├── 查询解析和执行 ├── 事务和会话协调 ├── 复制和 oplog 协调 └── 存储引擎 API │ ▼ WiredTiger ├── 本地事务和 MVCC ├── 内部缓存 ├── 日志 ├── 检查点 └── dbPath 中的集合和索引数据 好,但这如何发挥作用?边界并非绝对。 oplog 属于 MongoDB 的(逻辑)复制模型,但 WiredTiger 将其与其他集合数据一起存储。 此时,我又有了另一个问题。如果 MongoDB 已经有日志,为什么还需要 oplog? WiredTiger 日志最接近 PostgreSQL 的 WAL(预写日志)。它记录崩溃后恢复一个 MongoDB 成员(记住这一点)所需的变化。与 PostgreSQL 的 WAL 不同,MongoDB 不使用日志作为其复制流。 oplog 有不同的用途。它是一个固定集合,存储在 local 数据库中,名为 local.oplog.rs。从节点复制其条目并将其应用到自己的数据。 这引出了一个重要的一致性问题。是什么防止 MongoDB 在提交文档更改时没有相应的 oplog 条目? 让我们检查一个节点上发生的情况,然后通过添加从节点使情况复杂化。 为了理解本地持久性,我首先查看了 MongoDB 成员的 dbPath 内部。一个简化的列表: $ ls /data/mongodb/ collection-<ident>.wt index-<ident>.wt journal/ WiredTiger WiredTigerHS.wt WiredTiger.lock WiredTiger.turtle WiredTiger.wt 确切的文件及其名称取决于 MongoDB 版本和配置,但这些是与本文讨论相关的主要 WiredTiger 文件。 collection-<ident>.wt 和 index-<ident>.wt 文件是 WiredTiger 表,存储集合记录和索引条目。 MongoDB 的持久化目录将逻辑对象(例如集合命名空间)映射到这些存储引擎标识符。WiredTiger 在 WiredTiger.wt 中维护自己的元数据,包括其表、它们的配置以及最新的检查点。 小型 WiredTiger 文本文件标识用于创建数据库的 WiredTiger 版本: WiredTiger WiredTiger 10.0.2: (November 30, 2021) WiredTigerHS.wt 是历史存储。它保存 MVCC 读取器、快照等所需的较旧已提交记录版本。一旦没有活动读取器或快照可能需要这些版本,WiredTiger 就会删除它们。 WiredTiger.turtle 包含足够多的元数据,用于定位并打开 WiredTiger.wt 的最新检查点。它在启动和恢复期间引导元数据表。 WiredTiger 版本字符串 WiredTiger 10.0.2: (November 30, 2021) WiredTiger 版本 major=10,minor=0,patch=2 file:WiredTiger.wt ... checkpoint_lsn=(2248,16291200) ... checkpoint_lsn 使用日志文件编号和字节偏移量标识 WiredTiger 日志中的一个位置。在恢复期间,WiredTiger 打开最后一个一致的检查点,并重放之后的日志记录。

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →