连环触发!MongoDB核心集群雪崩故障背后竟是……( 四 )
2) 故障模拟测试结果
为了保证和故障的mongos代理硬件环境一致 , 因此选择故障同样类型的服务器 , 并且操作系统版本一样(2.6.32-642.el6.x86_64) , 程序都跑起来后 , 问题立马浮现:
文章插图
由于出故障的服务器操作系统版本linux-2.6过低 , 因此怀疑可能和操作系统版本有问题 , 因此升级同一类型的一台物理机到linux-3.10版本 , 测试结果如下:
文章插图
从上图可以看出 , 客户端6000并发反复重连 , 服务端压力正常 , 所有CPU消耗在us% , sy%消耗很低 。 用户态CPU消耗3个CPU , 内核态CPU消耗几乎为0 , 这是我们期待的正常结果 , 因此觉得该问题可能和操作系统版本有问题 。
为了验证更高并反复建链断链在Linux-3.10内核版本是否有2.6版本同样的sy%内核态CPU消耗高的问题 , 因此把并发从6000提升到30000 , 验证结果如下:
测试结果:通过修改MongoDB内核版本故意让客户端超时反复建链断链 , 在linux-2.6版本中 , 1500以上的并发反复建链断链系统CPU sy% 100%的问题即可浮现 。 但是 , 在Linux-3.10版本中 , 并发到10000后 , sy%负载逐步增加 , 并发越高sy%负载越高 。
总结:linux-2.6系统中 , MongoDB只要每秒有几千的反复建链断链 , 系统sy%负载就会接近100% 。 Linux-3.10 , 并发20000反复建链断链的时候 , sy%负载可以达到30% , 随着客户端并发增加 , sy%负载也相应的增加 。 Linux-3.10版本相比2.6版本针对反复建链断链的场景有很大的性能改善 , 但是不能解决根本问题 。
4、客户端反复建链断链引起sy% 100%根因
为了分析%sy系统负载高的原因 , 安装perf获取系统top信息 , 发现所有CPU消耗在如下接口:
文章插图
从perf分析可以看出 , cpu 消耗在_spin_lock_irqsave函数 , 继续分析内核态调用栈 , 得到如下堆栈信息:
- 89.81% 89.81% [kernel] [k] _spin_lock_irqsave - _spin_lock_irqsave
- mix_pool_bytes_extract
- extract_buf
extract_entropy_user
urandom_read
vfs_read
sys_read
system_call_fastpath
0xe82d
上面的堆栈信息说明 , MongoDB在读取 /dev/urandom, 并且由于多个线程同时读取该文件 , 导致消耗在一把spinlock上 。
到这里问题进一步明朗了 , 故障root case 不是每秒几万的连接数导致sys 过高引起 。 根本原因是每个mongo客户端的新链接会导致MongoDB后端新建一个线程 , 该线程在某种情况下会调用urandom_read 去读取随机数/dev/urandom, 并且由于多个线程同时读取 , 导致内核态消耗在一把spinlock锁上 , 出现cpu 高的现象 。
5、MongoDB内核随机数优化
1) MongoDB内核源码定位分析
上面的分析已经确定 , 问题根源是MongoDB内核多个线程读取/dev/urandom随机数引起 , 走读MongoDB内核代码 , 发现读取该文件的地方如下:
文章插图
上面是生成随机数的核心代码 , 每次获取随机数都会读取”/dev/urandom”系统文件 , 所以只要找到使用该接口的地方即可即可分析出问题 。
继续走读代码 , 发现主要在如下地方:
//服务端收到客户端sasl认证的第一个报文后的处理 , 这里会生成随机数
//如果是mongos , 这里就是接收客户端sasl认证的第一个报文的处理流程
Sasl_scramsha1_server_conversation::_firstStep(...) {... ...
unique_ptr sr(SecureRandom::create);binaryNonce[0] = sr->nextInt64;
binaryNonce[1] = sr->nextInt64;
binaryNonce[2] = sr->nextInt64;
... ...
}
//mongos相比mongod存储节点就是客户端 , mongos作为客户端也需要生成随机数
SaslSCRAMSHA1ClientConversation::_firstStep(...) {... ...
unique_ptr sr(SecureRandom::create);binaryNonce[0] = sr->nextInt64;
binaryNonce[1] = sr->nextInt64;
binaryNonce[2] = sr->nextInt64;
... ...
}
2) MongoDB内核源码随机数优化
从前面的分析可以看出 , mongos处理客户端新连接sasl认证过程都会通过"/dev/urandom"生成随机数 , 从而引起系统sy% CPU过高 , 我们如何优化随机数算法就是解决本问题的关键 。
- 京东双11提前?连环折扣“王炸”开场,10.21爆品来了
- MongoDB提供多云集群,AWS、微软和谷歌都在列
- 由热靴移至机侧 尼康发布全新闪灯触发器
- 标签|iOS 14在Safari中长按不同按钮会触发的各种功能
- HBase Compaction作用和触发条件
- 没人说|iPhone12遭遇连环差评,华为也曾“绿屏”,但基本没人说
- Python操作三大数据库 - MongoDB
- 要来|【国元资讯早班车】惊魂!千亿国企债券违约连环爆!5G杀手级应用要来了!
- 不用读的说明书,为何每个产品中都有它的身影,连环保的苹果也不例外
- 连环套|「网络安全」刷单要看“进度条”那是骗子“连环套”!