必须统一配置压缩算法,否则主节点zstd写入、从节点snappy重压会白耗CPU和I/O;若从节点降级至4.0则因不支持zstd直接报错WiredTigerError。

副本集所有节点必须统一配置压缩算法
不能只在主节点配 zstd、从节点留默认 snappy。看似能跑,实则埋雷:主节点写入的 zstd 块,从节点同步时会先解压再用本地配置(比如 snappy)重压——白耗 CPU 和 I/O;更严重的是,若某个从节点临时降级到 MongoDB 4.0(不支持 zstd),启动直接失败,报错 WiredTigerError: unsupported compressor 'zstd'。
统一配置的前提是:所有成员版本 ≥ 4.2(zstd 自 4.2 引入),且全部使用 WiredTiger 引擎(默认即满足)。
- 检查版本:
db.version(),确认每个成员返回 ≥"5.0.0" - 确认引擎:
db.serverStatus().storageEngine.name应为"wiredTiger" - 不一致配置会导致同步卡住、
rs.status()显示STARTUP2卡死或RECOVERING状态异常
修改 mongod.conf 启用 zstd 压缩
编辑每个成员的配置文件(如 /etc/mongod.conf),在 wiredTiger 下添加或修改压缩设置:
storage:
engine: wiredTiger
wiredTiger:
collectionConfig:
blockCompressor: zstd
indexConfig:
prefixCompression: true
blockCompressor 是核心项,可选值为 snappy、zlib、zstd(5.0 支持全部三种);prefixCompression: true 建议保留(默认),它独立于块压缩,仅对索引前缀去重,开销极小。
- 不要只改主节点——副本集里每个
mongod实例都必须有相同配置段 - 路径必须严格匹配:
wiredTiger.collectionConfig.blockCompressor,多一级或少一级都会被忽略 - 配置后不重启无效;
mongod启动时才读取该设置,运行中无法热更新
逐个滚动重启,避免副本集失联
配置改完后,必须按顺序逐个重启成员,不能批量执行 systemctl restart mongod。否则可能触发多数派丢失,导致选举中断、写入不可用。
- 优先重启从节点(
SECONDARY),最后重启主节点(PRIMARY) - 每次重启后,用
rs.status()确认该成员已回到SECONDARY或PRIMARY状态,且optime持续追平 - 重启期间,
rs.printSecondaryReplicationInfo()可观察延迟是否收敛 - 若某节点重启后卡在
STARTUP2,立刻检查日志:journal/WiredTigerLog.*或/var/log/mongodb/mongod.log中是否有compressor相关报错
验证压缩是否生效及常见误判点
压缩是否真起作用,不能只看配置文件,得查运行时状态。最直接方式是运行:
db.runCommand({ serverStatus: 1 }).wiredTiger["block-manager"]["blocks written with compression"]
该字段非零说明写入已启用压缩;再查具体集合:
db.runCommand({
collStats: "your_collection_name",
verbose: true
}).wiredTiger["block-manager"]["compression ratio"]
注意两个易错点:
-
db.serverStatus().wiredTiger.collectionStats返回的是各集合「最后一次统计时」的压缩算法,不是实时配置——它反映的是数据块实际写入时用的算法,所以主从不一致恰恰说明配置没统一 - 新创建的集合立即生效;已有集合不会自动重压,需重建索引或
compact命令(但compact在副本集上要求停写,生产慎用) - 压缩效果受数据特征影响大:
zstd对文本/JSON 类型优势明显,但对已加密或高度随机的二进制字段收益极低


















