1. 启用WiredTiger存储引擎及压缩功能
WiredTiger是MongoDB的默认存储引擎(MongoDB 3.2+版本起),相比旧版MMAPv1,它原生支持文档级压缩,能显著减少存储空间占用。可通过配置文件(/etc/mongod.conf)或启动参数开启:
storage.engine下指定wiredTiger,并通过collectionConfig.blockCompressor选择压缩算法(支持snappy、zstd,其中zstd压缩比更高但CPU消耗略大,snappy更平衡)。示例如下:storage:
engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 4 # 根据服务器内存调整(建议为物理内存的50%-75%)
collectionConfig:
blockCompressor: zstd # 或snappy
mongod --dbpath /var/lib/mongodb --wiredTigerCollectionBlockCompressor zstd
compact命令重新压缩(需停机或进入维护模式):use admin;
db.runCommand({compact: "yourCollectionName", compression: "zstd"});
注意:compact命令仅整理碎片并应用压缩,不会缩小数据文件大小(需配合repairDatabase或compactServer释放空间)。2. 使用compact命令整理碎片与压缩
compact命令是MongoDB提供的原地压缩工具,可重新组织集合数据文件、删除未使用的空间(如删除文档后的碎片),并应用当前配置的压缩算法。
mongo --eval 'db.getSiblingDB("yourDB").runCommand({compact: "yourCollectionName"})';
mongo --eval 'db.adminCommand({compact: 1})';
compactServer命令(MongoDB 4.4+支持),它会启动后台进程逐步压缩所有数据库:mongo --eval 'db.adminCommand({compactServer: true, compression: "zstd"})';
注意:压缩操作会消耗大量CPU和I/O资源,建议在低峰时段执行;执行前务必备份重要数据。3. 清理无用数据与日志
use yourDB;
db.logs.remove({timestamp: {$lt: ISODate("2025-01-01")}}); // 删除2025年前的日志
dropDatabase命令彻底删除:use unusedDB;
db.dropDatabase(); // 删除整个数据库
mongod.log)会持续增长,可通过修改配置文件限制日志大小或开启滚动:systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
logRotate: reopen # 日志滚动策略(需配合logrotate工具使用)
或使用logrotate工具自动切割日志(需在/etc/logrotate.d/mongodb中配置)。4. 优化数据模型设计
不合理的数据模型是导致存储空间浪费的主要原因之一,需遵循以下原则:
db.collection.stats().indexSizes查看索引占用空间)。db.logs.createIndex({expireAt: 1}, {expireAfterSeconds: 0}); // 30天后自动删除
示例中,expireAt字段需存储过期时间戳(如new Date(Date.now() + 30*24*60*60*1000))。5. 使用数据分片水平扩展
当单台服务器的磁盘空间不足以容纳数据时,可通过**分片(Sharding)**将数据分布到多个服务器上。分片需先配置shard key(如_id、user_id),然后将集合设置为分片集合:
// 开启分片功能
sh.enableSharding("yourDB");
// 对集合进行分片(以user_id为分片键)
sh.shardCollection("yourDB.yourCollection", {user_id: 1});
分片后,数据会按shard key分散到多个分片服务器,有效缓解单台服务器的磁盘压力。
6. 定期监控与维护
df -h查看磁盘整体使用情况,通过db.stats()(查看数据库存储信息)、db.collection.stats()(查看集合存储信息)监控MongoDB的存储占用:mongo --eval 'printjson(db.stats())';
mongo --eval 'printjson(db.yourCollection.stats())';
use yourDB;
db.yourCollection.reIndex(); // 重建指定集合的索引
或重建所有索引(需停机):mongod --dbpath /var/lib/mongodb --repair;
注意:重建索引会消耗大量时间和资源,建议在维护窗口执行。