连环触发!MongoDB核心集群雪崩故障背后竟是……( 四 )
- 客户端发起与mongos的链接;
- mongos服务端accept接收链接后 , 链接建立成功;
- 客户端发送db.isMaster命令给服务端;
- 服务端应答isMaster给客户端;
- 客户端发起与mongos代理的sasl认证(多次和mongos交互);
- 客户端发起正常的find流程 。
此外 , 通过提前部署的脚本,该脚本在系统负载高的时候自动抓包 , 从抓包分析结果如下图所示:
文章插图
上图时序分析如下:
- 11:21:59.506174 链接建立成功
- 11:21:59.506254 客户端发送db.IsMaster到服务端
- 11:21:59.656479 客户端发送FIN断链请求
- 11:21:59.674717 服务端发送db.IsMaster应答给客户端
- 11:21:59.675480 客户端直接RST
总结:通过抓包和mongos日志分析 , 可以确定链接建立后快速断开的原因是:客户端访问代理的第一个请求db.isMaster超时了 , 因此引起客户端重连 。 重连后又开始获取db.isMaster请求 , 由于负载CPU 100%, 很高 , 每次重连后的请求都会超时 。 其中配置超时时间为500ms的客户端 , 由于db.isMaster不会超时 , 因此后续会走sasl认证流程 。
因此可以看出 , 系统负载高和反复的建链断链有关 , 某一时刻客户端大量建立链接(2.2W)引起负载高 , 又因为客户端超时时间配置不一 , 超时时间配置得比较大得客户端最终会进入sasl流程 , 从内核态获取随机数 , 引起sy%负载高 , sy%负载高又引起客户端超时 , 这样整个访问过程就成为一个“死循环” , 最终引起mongos代理雪崩 。
3、线下模拟故障
到这里 , 我们已经大概确定了问题原因 , 但是为什么故障突发时间点那一瞬间2万个请求就会引起sy%负载100%呢 , 理论上一秒钟几万个链接不会引起如此严重的问题 , 毕竟我们机器有40个CPU 。 因此 , 分析反复建链断链为何引起系统sy%负载100%就成为了本故障的关键点 。
1)模拟故障过程
模拟频繁建链断链故障步骤如下:
- 修改mongos内核代码 , 所有请求全部延时600ms
- 同一台机器起两个同样的mongos , 通过端口区分
- 客户端启用6000个并发链接 , 超时时间500ms
2) 故障模拟测试结果
为了保证和故障的mongos代理硬件环境一致 , 因此选择故障同样类型的服务器 , 并且操作系统版本一样(2.6.32-642.el6.x86_64) , 程序都跑起来后 , 问题立马浮现:
文章插图
由于出故障的服务器操作系统版本linux-2.6过低 , 因此怀疑可能和操作系统版本有问题 , 因此升级同一类型的一台物理机到linux-3.10版本 , 测试结果如下:
推荐阅读
- centos7 安装 MongoDB (复制粘贴系列)
- 谷歌证实有线耳机亦可触发Google Assistant通知朗读功能
- 十分钟了解Mongodb数据库
- 阿里后端面试官的连环炮,看看你能撑到哪一步?
- docker 安装 MongoDB 就是这么简单?