MongoDB各类场景的故障恢复概要(持续更新)

一、CPU/IOPS打满

结合mongostat和mongotop分析MongoDB各资源情况以及读写耗时。

#查看最近慢日志
db.system.profile.find().sort({$natrual: -1})
- 全表扫描
关注关键字“COLLSACN、docsExamined”,对全表扫描查询(或者更新/删除)建立合理索引进行优化。
- 不合理查询
关注关键字“IXSCAN、keysExamined”,对于复合索引,需要注意索引建立的前后顺序,以及对排序的优化。
- 大量数据排序
关注关键字“SORT、hasSortStage”,如果SQL需要对大量的数据进行排序,且排序无法通过索引来进行排序,MongoDB会把结果集放在内存进行排序,非常消耗CPU资源。可以考虑通过索引降低结果集大小或者利用索引进行排序来进行优化。
查看执行计划
db.t1.find({id:1}).explain()
#抓取正在执行的会话
db.currentOp()
//关注参数
client                         | 请求是由哪个客户端发起的
opid                           | 操作的opid,有需要的话,可以通过db.killOp(opid) 直接终止该操作
secs_running/microsecs_running | 这个值重点关注,代表请求运行的时间,如果这个值特别大,请看看请求是否合理
query/ns                       | 这个字段能看出是对哪个集合正在执行什么操作
lock*                          | 些跟锁相关的参数
//kill会话
db.killOp(opid)

三、活跃连接数打高

//抓取正在执行的会话
db.currentOp()
//关注参数
client                         | 请求是由哪个客户端发起的
opid                           | 操作的opid,有需要的话,可以通过db.killOp(opid) 直接终止该操作
secs_running/microsecs_running | 这个值重点关注,代表请求运行的时间,如果这个值特别大,请看看请求是否合理
query/ns                       | 这个字段能看出是对哪个集合正在执行什么操作
lock*                          | 些跟锁相关的参数
//kill会话
db.killOp(opid)

//同时针对可优化SQL进行优化
//查看最近慢日志
db.system.profile.find().sort({$natrual: -1})

四、磁盘打高/满

#获取mongoDB中数据库的大小命令
use databasename
db.stats()

#获取MongoDB中collection
db.collection.dataSize()
//collection中的数据大小
db.collection.storageSize()
//为collection分配的空间大小,包括未使用的空间
db.collection.totalIndexSize()
collection中索引数据大小
db.collection.totalSize()

//回收空间
 use somedb
 db.runCommnd({compact: "somecollection"})

 // compact oplog,在副本集primary上执行需要加 force 选项
 use local
 db.runCommnd({compact: "somecollection", force: true})

五、副本集故障

5.1 复制延迟

  • 网络延迟:减小副本集节点之间的网络延迟。
  • 磁盘吞吐量:保证磁盘吞吐。
  • 并发:并发大的情况下,primary节点上的一些耗时操作会阻塞secondary节点的复制操作,导致复制操作跟不上主节点的写入负荷。解决方法是通过设置操作的write concern。默认的副本集中写入操作只关心primary节点,但是可以指定写入操作同时传播到其他secondary节点,代价就是严重影响集群的并发性。
    • 注意:而且这里还存在一个问题如果,如果写入操作关心的某个节点宕机了,那么操作将会一直被阻塞直到节点恢复。
  • 适当的write concern:我们为了提高集群写操作的吞吐量经常会将writer concern设置为unacknowledged write concern,这导致primary节点的写操作很快而secondary节点复制操作跟不上。解决方法和第三点是类似的就是在性能和一致性之间做权衡。

5.2 复制中断

当secondary节点落后太多无法追赶上primary节点的时候,这时候可能需要考虑重新同步数据(Resync data)。

有两种方法一种是指定一个空的目录重新启动落后的节点,这很简单,但是数据量大的情况下回花费很长的时间。另一种方法是基于另一个节点的数据作为“种子”进行重新同步

六、分片故障

6.1 shard节点宕机

1、新建shard节点并启动

2、在mongos上删除原shard节点的配置信息

3、添加新shard节点的配置信息

七、数据丢失

1、通过备份使用mongorestore/mongoimport恢复数据

2、建立延迟从库

3、因为oplog具有幂等性,通过实时拷贝oplog做数据恢复

八、其它场景

8.1 内存打高

1、合理配置cacheSizeGB参数

1)如果服务器上只运行MongoDB服务,默认配置即可

2)如果服务器上还有别的服务运行,建议设置cacheSizeGB参数为可用内存的60%

2、控制并发连接数

1)MongoDB driver 在连接 mongod 时,会维护一个连接池(通常默认100),当有大量的客户端同时访问同一个mongod时,就需要考虑减小每个客户端连接池的大小

2)通过net.maxIncomingConnections限制MongoDB并发连接数,防止数据库过载

3、配置swap

1)如果配置了swap,可以有效的防止MongoDB服务出现OOM,但是当内存不足时,频繁的使用swap会严重影响数据库性能。

2)最优的场景是为MongoDB服务配置充足的内存,内存不足及时扩容

4、其他

1)尽量减少内存排序的场景,内存排序一般需要更多的临时内存

2)主备节点配置差距不要过大,备节点会维护一个buffer(默认最大256MB)用于存储拉取到oplog,后台从buffer里取oplog不断重放,当备同步慢的时候,这个buffer会持续使用最大内存。

3)控制集合及索引的数量,减少databse管理元数据的内存开销;集合、索引太多,元数据内存开销是一方面的影响,更多的会影响启动加载的效率、以及运行时的性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章