面试题答案
一键面试故障检测
- 监控工具:利用MongoDB自带的监控命令(如
db.serverStatus()
),以及第三方监控工具(如Prometheus + Grafana),实时监测集群状态。例如,通过监控节点的心跳信息、响应时间、磁盘I/O等指标,当Config Server或Primary节点的心跳中断、响应时间过长或者磁盘空间使用率过高时,及时发出警报。 - 日志分析:定期查看MongoDB的日志文件(
mongod.log
),从中查找关键错误信息,如节点失联、选举失败等日志记录,来判断故障节点。
故障恢复流程
Config Server故障恢复
- 确定故障:通过上述检测手段确定Config Server故障后,检查是否有备用的Config Server节点。如果有,检查备用节点是否正常工作。若备用节点正常,手动将其提升为活跃的Config Server节点。
- 数据同步:如果备用节点数据落后于故障的Config Server节点,从其他健康的Config Server节点同步数据。使用
rs.syncFrom("<healthy - config - server - address>")
命令来同步数据。 - 重启服务:确保数据同步完成且配置正确后,重启备用Config Server节点的服务,使其正常提供服务。
- 集群重新配置:检查整个集群的配置,确保所有节点都能正确连接到新的Config Server。使用
rs.conf()
命令查看配置,如有必要,使用rs.reconfig()
命令进行重新配置。
Primary节点故障恢复
- 选举新Primary:MongoDB副本集具备自动选举机制。当Primary节点故障后,副本集中的Secondary节点会发起选举。在选举过程中,节点会根据优先级、日志的完整性等因素竞争成为新的Primary。
- 数据修复(如有需要):如果在故障期间数据出现不一致情况,新的Primary节点会尝试从其他Secondary节点同步数据以修复不一致。可以使用
db.adminCommand({replSetSyncFrom: "<secondary - address>"})
命令手动触发同步。 - 应用调整:应用程序可能需要重新连接到新的Primary节点。确保应用程序的连接字符串配置正确,能够及时发现并连接到新的Primary。
恢复后性能优化
索引优化
- 分析查询:使用
explain()
方法分析应用程序中的查询语句,确定哪些查询需要索引优化。例如,在一个电商订单查询场景中,经常按照订单创建时间和用户ID查询订单,db.orders.find({createdAt: {$gte: ISODate("2023 - 01 - 01")}, userId: "123456"}).explain()
,如果查询执行计划显示全表扫描,就需要创建复合索引db.orders.createIndex({createdAt: 1, userId: 1})
。 - 删除无用索引:定期清理不再使用的索引,避免过多索引占用磁盘空间和影响写性能。可以通过
db.collection.getIndexes()
查看所有索引,结合业务查询分析哪些索引不再使用,然后使用db.collection.dropIndex({"index - name": 1})
删除。
查询优化
- 投影优化:只返回必要的字段,减少数据传输量。例如在用户信息查询中,只需要用户名和邮箱,
db.users.find({age: {$gt: 18}}, {name: 1, email: 1, _id: 0})
,这样可以减少网络传输和处理的数据量。 - 批量操作:将多个写操作合并为一个批量操作,减少客户端与服务器之间的交互次数。例如在插入多条订单数据时,使用
db.orders.insertMany([{orderNo: "001", amount: 100}, {orderNo: "002", amount: 200}])
。
存储优化
- 数据分片:根据业务需求对数据进行合理分片,如按照地区、时间等维度。例如在一个全球电商平台中,按照地区对订单数据进行分片,将不同地区的订单数据存储在不同的分片上,提高查询性能和集群的扩展性。
- 存储引擎优化:根据数据读写特点选择合适的存储引擎,如WiredTiger适用于大多数场景,具备较好的压缩和并发性能。可以在启动MongoDB时通过
--storageEngine
参数指定存储引擎。 - 磁盘优化:使用高速磁盘(如SSD),提高数据读写速度。并且合理配置磁盘I/O参数,如
wiredTiger.engineConfig.cacheSizeGB
设置WiredTiger存储引擎的缓存大小,以提高性能。