一、MongoDB数据持久化概述
1.1 什么是数据持久化
数据持久化是将数据存储到永久存储介质(磁盘)的过程,确保数据在系统重启后不会丢失。MongoDB通过WiredTiger存储引擎实现高效的数据持久化。
// 查看当前存储引擎
db.serverStatus().storageEngine
// 输出示例
{ "name" : "wiredTiger", "persistent" : true }
1.2 WiredTiger存储引擎
WiredTiger是MongoDB默认的存储引擎,提供以下特性:
| 特性 | 说明 |
|---|---|
| 文档级锁 | 支持并发读写 |
| 压缩 | 支持Snappy和Zstd压缩 |
| 检查点 | 自动数据一致性保证 |
| 日志 | Write-Ahead Logging恢复机制 |
| 缓存 | 可配置的内存缓存 |
1.3 数据持久化组件
数据持久化流程:
┌─────────────────────────────────────────────────────────┐
│ 写入操作 │
│ ↓ │
│ WiredTiger缓存 (内存) │
│ ↓ │
│ Journal日志 (预写日志) │
│ ↓ │
│ 数据文件 (磁盘持久化) │
└─────────────────────────────────────────────────────────┘
二、配置数据目录
2.1 默认数据目录
# 查看默认数据目录
mongod --dbpath /var/lib/mongodb
# 或在配置文件中
cat /etc/mongod.conf
# storage:
# dbPath: /var/lib/mongodb
2.2 自定义数据目录
# 1. 创建数据目录
sudo mkdir -p /data/mongodb
sudo chown -R mongod:mongod /data/mongodb
sudo chmod 755 /data/mongodb
# 2. 修改配置文件
sudo nano /etc/mongod.conf
# 修改:
storage:
dbPath: /data/mongodb
journal:
enabled: true
# 3. 重启MongoDB
sudo systemctl restart mongod
# 4. 验证数据目录
ls -la /data/mongodb
2.3 目录权限配置
# 1. 设置正确的权限
sudo chown -R mongod:mongod /data/mongodb
sudo chmod 700 /data/mongodb
# 2. 查看目录内容
ls -la /data/mongodb/
# 输出示例:
# drwxr-xr-x 1 mongod mongod 4096 May 12 03:00 collection-0-1234567890.wt
# drwxr-xr-x 1 mongod mongod 4096 May 12 03:00 collection-2-1234567890.wt
# -rw-r--r-- 1 mongod mongod 49152 May 12 03:00 _mdb_catalog.wt
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 diagnostic.data
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 index-1-1234567890.wt
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 journal
# -rw-r--r-- 1 mongod mongod 65536 May 12 03:00 mongod.lock
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 sizeStorer.wt
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 storage.bson
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 WiredTiger
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 WiredTiger.lock
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 WiredTiger.turtle
# -rw-r--r-- 1 mongod mongod 4096 May 12 03:00 WiredTiger.wt
三、Journal日志配置
3.1 Journal原理
Journal是Write-Ahead Logging (WAL)机制,确保数据在系统崩溃后能够恢复。
# 1. 查看Journal目录
ls -la /data/mongodb/journal/
# 输出示例:
# drwxr-xr-x 1 mongod mongod 4096 May 12 03:00 WiredTigerLog.0
# drwxr-xr-x 1 mongod mongod 4096 May 12 03:00 WiredTigerPreplog.0
# drwxr-xr-x 1 mongod mongod 4096 May 12 03:00 WiredTigerPreplog.marker
3.2 启用Journal
# 编辑配置文件
sudo nano /etc/mongod.conf
# 确保Journal启用:
storage:
dbPath: /data/mongodb
journal:
enabled: true
directoryPerDB: true
# 重启服务
sudo systemctl restart mongod
# 验证Journal状态
db.adminCommand({getLog: "startupWarnings"})
3.3 Journal配置参数
# 高级Journal配置
storage:
journal:
enabled: true
commitIntervalMs: 100 # 提交间隔(毫秒)
# WiredTiger引擎配置
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 2 # 缓存大小
journalCompressor: snappy # 日志压缩算法
collectionConfig:
blockCompressor: snappy # 集合压缩算法
indexConfig:
prefixCompression: true # 索引前缀压缩
四、检查点(Checkpoint)配置
4.1 检查点机制
检查点是WiredTiger将内存数据刷新到磁盘的机制,确保数据一致性。
// 查看检查点信息
db.serverStatus().wiredTiger.checkpoint
// 输出示例:
{
"log records applied" : 0,
"scanned" : 1000,
"maximum log record size" : 134,
"minimum rec id for checkpoint" : 3,
"seconds since last checkpoint" : 60,
"checkpointed on close" : true,
"time of last checkpoint" : "Wed, 12 May 2026 03:00:00 GMT",
"transactions checkpointed" : 50
}
4.2 配置检查点频率
# 在mongod.conf中配置
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 2
collectionConfig:
blockCompressor: snappy
# 检查点配置
checkpoint:
wait: 60 # 检查点间隔(秒)
floor: 100 # 最小数据量(MB)
# 命令行方式
mongod --wiredTigerCheckpointDelaySecs=60
4.3 检查点监控
// 监控检查点状态
db.adminCommand({serverStatus: 1}).wiredTiger.checkpoint
// 定期检查
while (true) {
var status = db.adminCommand({serverStatus: 1}).wiredTiger.checkpoint;
print("Seconds since last checkpoint: " + status["seconds since last checkpoint"]);
print("Time of last checkpoint: " + status["time of last checkpoint"]);
sleep(60000); // 每分钟检查
}
五、WiredTiger缓存配置
5.1 缓存工作原理
WiredTiger使用内存缓存来加速读写操作。
// 查看缓存统计
db.serverStatus().wiredTiger.cache
// 输出示例:
{
"application threads page read from disk to cache count" : 1000,
"application threads page write from cache to disk count" : 500,
"bytes currently in the cache" : 2147483648,
"maximum bytes configured" : 2147483648,
"percentage of cache in use" : 50.0,
"tracked dirty bytes in the cache" : 1073741824,
"bytes read into cache" : 10737418240,
"bytes written from cache" : 5368709120
}
5.2 配置缓存大小
# 在mongod.conf中配置
storage:
wiredTiger:
engineConfig:
# 缓存大小设置为系统内存的50-60%
cacheSizeGB: 4 # 4GB缓存
# 命令行方式
mongod --wiredTigerEngineConfigString "cache_size=4G"
5.3 缓存调优建议
| 场景 | 缓存配置 | 说明 |
|---|---|---|
| 单机 | 50-60% RAM | 平衡读写性能 |
| 副本集 | 40-50% RAM | 保留内存给连接 |
| 分片集群 | 30-40% RAM | 需要更多内存给路由 |
# 生产环境推荐配置
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 8
journalCompressor: snappy
collectionConfig:
blockCompressor: zstd
indexConfig:
prefixCompression: true
六、数据压缩配置
6.1 支持的压缩算法
| 算法 | 压缩比 | CPU消耗 | 适用场景 |
|---|---|---|---|
| Snappy | 中 | 低 | 默认选择 |
| Zstd | 高 | 中 | 高压缩比场景 |
| Zlib | 最高 | 高 | 归档场景 |
| 无压缩 | 1 | 无 | 高性能场景 |
6.2 配置集合压缩
// 创建压缩集合
db.createCollection("logs", {
storageEngine: {
wiredTiger: {
configString: "block_compressor=zstd"
}
}
})
// 修改集合压缩
db.runCommand({
collMod: "logs",
storageEngine: {
wiredTiger: {
configString: "block_compressor=zstd"
}
}
})
6.3 配置索引压缩
// 创建压缩索引
db.products.createIndex(
{ "category": 1, "name": 1 },
{
storageEngine: {
wiredTiger: {
configString: "prefix_compression=true"
}
}
}
)
// 查看索引压缩状态
db.products.getIndexes()
七、数据加密
7.1 静态数据加密
# 1. 生成加密密钥(256位)
openssl rand -base64 32 > /data/mongodb/mongodb-keyfile
chmod 600 /data/mongodb/mongodb-keyfile
chown mongod:mongod /data/mongodb/mongodb-keyfile
# 2. 配置加密
sudo nano /etc/mongod.conf
storage:
dbPath: /data/mongodb
journal:
enabled: true
encryption:
mode: AES256 # 企业版功能
keyFile: /data/mongodb/mongodb-keyfile
# 3. 重启MongoDB
sudo systemctl restart mongod
7.2 客户端字段级加密
// MongoDB 4.2+ 支持客户端加密
// 创建加密客户端
const client = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: {
local: {
key: Buffer.from(base64Key, 'base64')
}
}
}
});
// 插入加密字段
await client.db('medical').collection('patients').insertOne({
name: "John Doe",
ssn: "123-45-6789", // 将自动加密
diagnosis: "Hypertension"
});
7.3 TLS/SSL传输加密
# 1. 生成证书
# 使用Let's Encrypt或自签名证书
# 2. 配置TLS
sudo nano /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
allowConnectionsWithoutCertificates: false
# 3. 重启MongoDB
sudo systemctl restart mongod
# 4. 验证TLS连接
mongod --ssl --sslMode requireSSL --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem
八、备份与恢复
8.1 文件系统快照
# 1. 使用LVM快照(推荐)
# 创建快照
sudo lvcreate -L 10G -s -n mongodb-snap /dev/vg00/lv_mongodb
# 挂载快照
sudo mkdir -p /mnt/mongodb-snap
sudo mount -o ro /dev/vg00/mongodb-snap /mnt/mongodb-snap
# 复制数据
sudo rsync -av /mnt/mongodb-snap/ /backup/mongodb/
# 卸载并删除快照
sudo umount /mnt/mongodb-snap
sudo lvremove /dev/vg00/mongodb-snap
8.2 mongodump/mongorestore
# 备份单个数据库
mongodump --db=myapp --out=/backup/mongodb/$(date +%Y%m%d)
# 备份所有数据库
mongodump --out=/backup/mongodb/$(date +%Y%m%d)
# 备份特定集合
mongodump --db=myapp --collection=users --out=/backup/
# 恢复数据库
mongorestore --db=myapp /backup/mongodb/20260512/myapp/
# 恢复并覆盖
mongorestore --db=myapp --drop /backup/mongodb/20260512/myapp/
8.3 增量备份
# 1. 启用oplog
# 在副本集成员上
cfg = rs.conf()
cfg.members[0].priority = 1
rs.reconfig(cfg)
# 2. 创建增量备份脚本
#!/bin/bash
# incremental_backup.sh
OPLOG_START=$(date +%Y-%m-%d)
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# 导出oplog
mongodump --db=local --collection=oplog.rs \
--query="{ts: {\$gt: Timestamp($(date +%s), 0)}}" \
--out=/backup/oplog/$TIMESTAMP
# 压缩备份
tar -czf /backup/oplog/$TIMESTAMP.tar.gz /backup/oplog/$TIMESTAMP
# 保留最近7天的增量备份
find /backup/oplog -mtime +7 -delete
九、性能优化
9.1 预分配数据文件
// 查看预分配状态
db.serverStatus().wiredTiger["data-handle"]["max file size"].write
// 手动预分配(可选)
// WiredTiger默认自动预分配
9.2 批量写入优化
// 使用Bulk操作
const bulk = db.collection.initializeUnorderedBulkOp();
// 批量插入
for (let i = 0; i < 10000; i++) {
bulk.insert({ _id: i, data: "value" });
}
bulk.execute();
// 批量更新
const bulk = db.users.initializeUnorderedBulkOp();
bulk.find({ status: "active" }).update({ $set: { status: "updated" }});
bulk.execute();
9.3 写入确认配置
// 确认写入到journal
db.collection.insertOne(
{ item: "example" },
{ writeConcern: { j: true, w: "majority", wtimeout: 5000 } }
)
// 写入关注级别
// w: "majority" - 确认写入到大多数副本集成员
// j: true - 确认写入到journal
// wtimeout: 5000 - 超时时间(毫秒)
十、监控与故障恢复
10.1 监控数据持久化
// 监控写入延迟
db.adminCommand({serverStatus: 1}).opcounters
// 监控journal使用
db.adminCommand({serverStatus: 1}).wiredTiger.log
// 监控缓存命中率
var cache = db.serverStatus().wiredTiger.cache;
var hitRatio = 1 - (cache["pages read from cache"] / cache["pages read into cache"]);
print("Cache hit ratio: " + hitRatio);
10.2 故障恢复流程
# 1. 检查数据目录
ls -la /data/mongodb/
# 2. 检查journal目录
ls -la /data/mongodb/journal/
# 3. 修复崩溃的数据
# 如果MongoDB无法启动
mongod --repair --dbpath /data/mongodb
# 4. 指定journal目录修复
mongod --repair --dbpath /data/mongodb --journalPath /data/mongodb/journal
10.3 数据恢复案例
# 场景:系统崩溃后数据丢失
# 1. 停止MongoDB
sudo systemctl stop mongod
# 2. 备份损坏的数据
cp -r /data/mongodb /data/mongodb.bak
# 3. 运行修复
sudo -u mongod mongod --dbpath /data/mongodb --repair --journalPath /data/mongodb/journal
# 4. 检查修复结果
ls -la /data/mongodb/
# 5. 启动MongoDB
sudo systemctl start mongod
# 6. 验证数据
mongosh --eval "db.adminCommand({serverStatus: 1}).ok"
十一、总结
MongoDB数据持久化配置是确保数据安全的关键,包括:
- 数据目录配置:选择高性能磁盘,合理设置权限
- Journal日志:启用并优化提交间隔
- 检查点机制:平衡性能与数据安全
- WiredTiger缓存:根据系统内存合理配置
- 数据压缩:选择合适的压缩算法
- 数据加密:保护敏感数据安全
- 备份恢复:建立完善的备份机制
核心要点:
– 将数据目录放在SSD上以提升IO性能
– Journal是数据恢复的关键,务必启用
– 缓存大小设置为系统内存的50-60%
– 定期监控缓存命中率和写入延迟
– 建立自动化备份机制
– 配置TLS/SSL加密传输
通过本文的指南,你可以在CentOS上构建高可用的MongoDB数据持久化环境。
注:本文基于CentOS 7/8和MongoDB 7.0编写,具体配置可能因版本差异而略有不同。