
作者:赵师的工作日(赵明中)
现役Oracle ACE、MySQL 8.0 ocp、TiDB PCTA\PCTP、Elasticsearch Certified Engineer
微信公众号:赵师的工作日
CSND:赵师的工作日
MongoDB 早在 3.2 版本就引入了 WiredTiger 作为默认存储引擎,取代了之前的 MMAPv1 引擎。WiredTiger 引擎是 MongoDB 的核心组成部分,它为数据存储提供了更加高效的性能和更强的并发处理能力。
一、WiredTiger 存储引擎概述
WiredTiger 是一个开源的、事务性键值存储引擎,设计用于支持高并发和高性能的数据存储。它为 MongoDB 提供了以下几个关键特性:
- 1.多版本并发控制(MVCC): WiredTiger 通过多版本并发控制(MVCC)来管理读写操作的并发性,允许读操作与写操作并发执行。
- 2.写时复制(Copy-on-write, COW): 写时复制使得每次数据修改都生成一个新的数据版本,而不是直接修改原数据,这样可以避免并发写入时的锁争用。
- 3.压缩与缓存: WiredTiger 使用内存中的缓存来加速读操作,同时支持数据压缩,减少存储空间的需求。
二、WiredTiger 的读写模型
WiredTiger 存储引擎的读写模型在高并发场景下表现得尤为重要,特别是对于读写隔离性和事务管理的控制。WiredTiger 主要通过以下几个机制来管理读写操作:
1、多版本并发控制(MVCC)
WiredTiger 使用多版本并发控制(MVCC)来保证数据的一致性和隔离性。在 MVCC 模型下,数据库会为每个写操作创建一个新的数据版本,同时保留旧版本,以允许读操作在不被写操作阻塞的情况下继续执行。
读操作
- 读取旧版本数据: 在执行读操作时,WiredTiger 会根据当前事务的快照来读取数据,即使数据正在被写入。这样,读操作会看到数据的某个稳定版本,而不是写操作正在进行的版本。
- 事务一致性: 如果一个读操作和写操作发生在同一时间,读操作会读取到写操作之前的数据版本。WiredTiger 的 MVCC 确保了在并发环境下的读一致性。
写操作
- 写时复制(Copy-On-Write, COW): 每次写操作都会创建一个新的数据版本,而不会覆盖原有数据。通过这种方式,WiredTiger 避免了多个写操作之间的冲突,同时可以让多个事务并发进行。
- 提交事务: 当写操作完成并提交时,新的数据版本会成为当前版本,而旧的数据版本会被标记为过期,等待清理。
2、锁机制和并发控制
WiredTiger 使用细粒度的锁机制来支持高并发的数据访问。与 MMAPv1 存储引擎不同,WiredTiger 不会为整个数据库或集合加全局锁,而是通过以下方式控制并发:
- 文档级别锁: MongoDB 通过文档级别锁来控制对特定文档的访问。这样,在进行更新或删除操作时,WiredTiger 会锁定受影响的文档,从而允许其他文档并发处理。
- 表级锁: 对于一些跨文档的操作,如创建索引,WiredTiger 会使用表级锁,但这种锁的粒度较粗,不会影响数据库的整体并发性。
- 写入冲突: 在并发写操作中,如果两个事务尝试修改相同的文档或同一组数据,WiredTiger 会通过回滚事务来避免数据冲突。WiredTiger 支持 优化的锁管理,大大提高了数据库的吞吐量。
3、事务支持
WiredTiger 支持 ACID 事务(原子性、一致性、隔离性和持久性),确保数据操作在出现系统故障时能够保持一致性。WiredTiger 支持以下几种事务:
- 单文档事务: MongoDB 默认的操作通常是单文档事务,即每个文档操作都是独立的事务。对于大多数应用场景来说,单文档事务足够满足需求。
- 多文档事务: MongoDB 从 4.0 版本开始支持多文档事务,WiredTiger 存储引擎通过 两阶段提交协议(2PC) 实现了多文档事务的支持。这意味着在多个文档更新时,WiredTiger 会通过事务日志(Write-Ahead Logging, WAL)确保所有操作要么成功提交,要么完全回滚,保持数据的一致性。
事务隔离级别
WiredTiger 提供 读已提交(Read Committed) 隔离级别,这意味着事务只会读取已经提交的数据版本,而不会读取正在进行的写操作。WiredTiger 使用 快照隔离 来确保读操作和写操作之间不会产生不一致的数据读取。
4、写入与日志
WiredTiger 使用写时复制和事务日志来确保数据的一致性和持久性。每次修改都会记录到 WAL(Write-Ahead Log) 中,这使得在系统崩溃时可以通过恢复日志来回滚到事务提交之前的状态。
- 写时复制(COW):写入操作不会立即覆盖旧数据,而是复制数据并写入新的位置。这减少了锁的争用并提高了并发性能。
- 事务日志(WAL):每次事务操作都会记录到事务日志中。即使在发生崩溃时,WAL 可以保证在恢复时数据的完整性。
5、缓存管理
WiredTiger 使用 内存映射缓存 来提高数据访问的速度。缓存存储的是最新的活跃数据和索引,确保频繁访问的数据能够快速从内存中获取,而不是每次都从磁盘读取。
- 内存管理: WiredTiger 会管理其缓存池,并根据负载动态调整。默认情况下,WiredTiger 分配了最大可用内存的 50% 用于缓存,但可以通过配置进行调整。
- 磁盘与内存的平衡: 当缓存池的大小超过内存限制时,WiredTiger 会将不常用的数据从内存交换到磁盘,以便腾出空间来存储热数据。
三、WiredTiger 的读写性能优化
WiredTiger 提供了一些优化选项,可以根据不同的使用场景调整性能:
- 压缩: WiredTiger 支持多种数据压缩算法(如 Snappy、Zlib、zlib+),可以在减少磁盘空间占用的同时,提高 I/O 性能。
- 缓存管理: 通过调整缓存大小和内存使用比例,可以根据应用的负载类型进行性能优化。
- 并发控制: 使用合适的事务隔离级别和文档级别锁,可以在保证数据一致性的同时,提高并发性能。
此外,针对高写负载的场景,可以采用 批量写入 或者使用 MongoDB 的写入关注级别(Write Concern) 配置,以减少写入时的延迟。
WiredTiger 存储引擎是 MongoDB 提供高并发、高性能数据存储的关键技术之一。通过 多版本并发控制(MVCC)、事务支持、写时复制(COW) 和 细粒度锁管理 等机制,WiredTiger 能够高效地处理大量并发的读写请求,保证数据的一致性和隔离性。
在使用MongoDB的过程中,可以结合WiredTiger 的读写模型做出更好的选择,优化数据库的读写性能,并充分利用存储引擎的优势。此外,结合事务管理、缓存管理和压缩策略,可以进一步提升 MongoDB 集群在高负载环境下的稳定性和性能。
通过合理调整 WiredTiger 的配置选项和事务管理,针对特定的应用场景进行优化,满足不同业务需求。





