优化Ubuntu环境下MongoDB存储空间的综合策略
定期执行数据清理是优化存储的基础。首先通过db.collection.stats()查看各集合的size(数据大小)、count(文档数量),识别占用空间大的集合;然后删除过期数据(如日志、临时记录)或不再需要的文档——删除单个文档用db.collection.deleteMany({条件}),删除整个集合用db.collection.drop()(会立即移除集合文件)。对于副本集,建议在secondary节点上执行清理,再同步到primary,避免影响主节点性能。
MongoDB支持文档压缩(WiredTiger引擎默认启用)和集合压缩。
/etc/mongod.conf中配置storage.wiredTiger.engineConfig.compressor,可选snappy(默认,压缩率适中、性能好)、zlib(高压缩率、影响性能)或lz4(平衡压缩率与性能),重启服务生效。compact命令回收集合的空闲空间(不会缩小数据文件,但会释放给操作系统),语法为db.runCommand({compact: '集合名'})。注意:4.4之前版本会阻塞所有操作,4.4及以后仅阻塞部分管理操作(如创建索引),建议在低峰期执行。索引能提升查询性能,但过多或不合理的索引会浪费存储。
db.collection.getIndexes()查看所有索引,删除未使用或重复的索引(如复合索引包含单字段索引),用db.collection.dropIndex('索引名')操作。nullable字段(如email可能为null),创建稀疏索引db.collection.createIndex({email: 1}, {sparse: true}),仅索引包含该字段的文档,减少索引大小。对于有明确过期时间的数据(如会话、日志),使用TTL(Time-To-Live)索引自动删除过期文档,无需手动干预。语法为db.collection.createIndex({expireAt: 1}, {expireAfterSeconds: 0})(expireAt字段需存储过期时间戳),MongoDB会每60秒检查并删除过期文档。例如,设置expireAt为当前时间加1天,文档会在1天后自动删除。
当单节点数据量过大(如TB级),分片是将数据分布到多个服务器的关键方案。通过sh.shardCollection()命令对集合进行分片(如按user_id哈希分片),将数据分散到多个分片节点,减少单个节点的存储压力。分片需配合分片键(如user_id)选择,确保数据均匀分布。
WiredTiger是MongoDB默认的高效存储引擎,优化其配置可提升存储利用率:
/etc/mongod.conf中设置storage.wiredTiger.engineConfig.cacheSizeGB为物理内存的50%-75%(如8GB内存设为4GB),避免缓存过大占用磁盘空间或过小导致频繁读取磁盘。storage.directoryPerDB: true(默认开启),每个数据库单独存储在/var/lib/mongodb/数据库名目录下,便于管理和清理单个数据库的文件。删除数据后,MongoDB不会立即释放磁盘空间,需通过压缩或修复数据库回收碎片:
use admin; db.runCommand({repairDatabase: 1})。建议每月或在大量删除数据后执行。通过内置命令或第三方工具监控存储状态,及时发现问题:
db.stats()查看数据库整体存储(dataSize:数据大小;indexSize:索引大小;storageSize:存储文件大小);db.collection.stats()查看集合级存储详情。mongostat(监控读写指标)、mongotop(监控集合级读写时间)或PMM(Percona Monitoring and Management,可视化监控)跟踪存储变化趋势,根据监控结果调整上述策略。通过以上策略的组合应用,可有效优化Ubuntu环境下MongoDB的存储空间利用率,兼顾性能与成本。操作前建议在测试环境验证效果,避免影响生产数据。