CentOS环境下MongoDB性能瓶颈破解方法
/etc/sysctl.conf添加vm.nr_hugepages=0,并执行sudo sysctl -p生效;同时修改/etc/rc.local确保开机自动禁用。vm.swappiness设置为0(默认60),减少系统使用swap分区的概率,避免内存不足时频繁换页导致的性能下降。noop或deadline调度算法(编辑/etc/default/grub,修改GRUB_CMDLINE_LINUX参数,如GRUB_CMDLINE_LINUX="quiet elevator=noop",然后更新grub并重启)。WiredTiger是MongoDB的默认存储引擎(MongoDB 3.2+),其缓存大小直接影响性能。编辑/etc/mongod.conf,设置storage.wiredTiger.engineConfig.cacheSizeGB为物理内存的50%-80%(如16GB内存可设置为8GB),避免缓存过大占用过多内存导致系统或其他应用内存不足。
storage.journal.commitIntervalMs(默认100ms)控制journal日志的刷新频率,降低该值可提高数据持久性但增加I/O负载;提高该值则相反,需根据数据安全性需求权衡(如测试环境可设置为500ms,生产环境建议保持默认)。/etc/mongod.conf,设置systemLog.logRotate: rename,并配合logrotate工具定期切割日志,避免日志文件过大占用磁盘空间。find、sort、update的字段创建索引(如db.collection.createIndex({username: 1}))。db.collection.createIndex({status: 1, createTime: -1}),适用于status=1且按createTime降序查询的场景)。db.collection.createIndex({name: 1, age: 1}),查询{name: "张三", age: {$gt: 18}}时可使用覆盖索引)。db.collection.getIndexes()查看现有索引,删除不再使用的索引(如db.collection.dropIndex({old_field: 1})),减少索引维护开销。db.collection.reIndex()重建索引(注意:重建期间会锁表,建议在低峰期操作)。db.collection.aggregate([{ $indexStats: {} }])查看索引使用频率,删除长期未使用的索引(如usageCount为0的索引)。db.collection.find({username: "张三"}, {name: 1, age: 1, _id: 0}))。explain("executionStats")查看执行计划,确认winningPlan中使用了索引)。$or:$or查询可能导致索引失效,尽量改用$in(如db.collection.find({$or: [{status: 1}, {status: 2}]})可改为db.collection.find({status: {$in: [1, 2]}}))。skip()+limit()的大偏移量分页(如skip(10000).limit(10))会导致性能下降,建议使用“游标分页”(记录上一页的最后一条记录的_id,下次查询find({_id: {$gt: last_id}}, {limit: 10}))。通过副本集实现读写分离,在连接字符串中设置readPreference="secondaryPreferred",将读请求分发到从节点,减轻主节点的压力(注意:从节点数据可能有延迟,不适合实时性要求高的场景)。
对于海量数据(如TB级),使用分片将数据分散到多个服务器。选择合适的分片键(如user_id、order_id等高基数字段),避免数据倾斜(如避免使用status等低基数字段作为分片键),提高查询和写入的横向扩展能力。
mongostat(查看每秒操作数、延迟等)、mongotop(查看集合级别的读写时间)定期监控数据库性能。operationProfiling.slowOpThresholdMs设置为100ms),定期分析慢查询日志,针对性优化查询语句或索引。