问题
这个一个耗时2天半的新布署环境线上问题定位。在查到问题后,发现似乎很简单,但为什么定位了2天半呢?原因是:“不知道自己不知道”。这篇blog对排查过程做一个记录。
定位过程
- 下游业务反馈,系统告警,发现mongodb有较高的 p99 rtt。
- 数据库没有慢查询,确认慢查询已开启。
- 怀疑底层网络,阿里云反馈ecs之间的网络链路有秒级抖动,有一个时间点可以匹配上。
- 观察发现A组件对数据库的慢查询仅出现在ecs秒级抖动的一个小时,但B组件对数据库的慢查询在全天不规律出现,怀疑是两个不同的问题。
- 对比 A1/B1/C1环境,发现仅C1 有偶发的P99等于1S尖刺,确认存在问题。
- 看代码确认监控指标含义,注意到mongo_ts的bucket是比较稀疏的,说明监控上的1S,真实含义是500MS+:[100, 500, 1_000, 5_000, 10_000, 50_000, 100_000, 500_000, 1000_000],结合其它更精确的打点能确认,大部分的P99请求是落在低于1S的,而ECS秒级抖动的时候,是大于1S的。
- 了解链路,发现C1环境的数据库和应用在不同可用区,B1环境也同样布署,但没有问题。
- 对比其它差异,了解到C1的linux内核和B1不一样。
- 观察业务量的变化,发现业务量多的时候更容易有高RTT,可能是概率性的。
- 观察业务的分布,发现主要集中在a1表,b1表,这些表相对之下有较大的业务量级。
- 分析高RTT节点规律,发现较为随机,几乎所有节点都会出现。
- 观察数据库机器负载,仅连接数上升,确实开启了慢查询,也确实没有慢查询,无大于100MS的请求,CPU,内存,IO显然没达到瓶颈,链接数也在安全范畴,重传(检查错误)很少。
- 观察宿主机负载,CPU,内存,IO显然没达到瓶颈,连接在宿主机不可见。
- 在宿主机开启脚本,监测网络抖动情况,一个晚上后最大的RTT为8MS。
- 了解链路,mongodb的机器上,可见的连接是 k8s pod 的 IP,故和数据库的链路等同服务之间的链路,对k8s某些资源瓶颈的怀疑减少了。
- 针对熟悉的业务排查,对比 a1 表数据的方差,a1 表大小很固定,排除大docnment。
- 用 netstat -s 观察 mongo, 问题 pod 的 tcp error,c1环境对比b1环境未发现异常。
- 用更高频的 mtr/ping 在容器内检测网络质量,在出现问题时网络质量还行,基本没有大于5MS的,怀疑icmp无法检测出问题,但通过tcp检测会刷太多的mongodb连接日志。
- 根据业务分析,某个容器在8-9点的抖动概率很高,在容器内抓包,抓到了某个节点在9点的波动,通过监控,容器内的链接数上升确认抓到了抖动时流量。
- 用wireshark分析tcp包的rtt,都在50MS以内。
- 用 tcp.flags.syn==1 定位到秒级的抖动时间点(大量连接创建),人肉一个个包解析。发现现存连接未发生抖动。
- 继续人肉分析包,发现新建连接后,需要5次RTT往返(1次TCP握手,1次is_master,3次sasl握手),耗时近20MS,才会开始业务请求。结合创建连接在 mongo_pool 为单点,在一瞬间有10个连接创建时,最后一个请求将等待200MS. 21:00:53 秒有 53条连接新建,是可能产生较大抖动的。
- 搜索sasl含义,发现可能和密码认证相关,发现a1/b1未开启密码,c1环境开启了密码。问题定位成功。
总结
该问题类似https://segmentfault.com/a/11...。
都是某个单点存在预期外的消耗,抖动时(请求不是平均分布的,1000QPS可能是前100MS就有500QPS),单点可能产生堆积,乃至有高RTT。
定位的思路是按USE(utilization、saturation、erros)方法来做的。耗时长的主要原因是,“不知道不知道”,即,不知道mongo 认证的消耗。方法论大家都懂,定位性能,BUG的难点往往在于,对系统,链路的理解不够充分。还好在不同的层面上有足够多的观测工具,比如tcpdump抓包几乎可以定位所有的网络问题。
后继处理
为什么mongo auth 需要三次rtt:
https://www.mongodb.com/docs/...
最后,我优化了mongo的监控打点,区分了
- 使用者等待整个mongo操作时间,包含可能的连接分配、认证。
- 命令执行时间,仅仅是网络收发的等待。
另外参考了mongo的官方driver,将认证过程从连接新建时挪到了使用前,这样,将认证消耗从连接池进程,挪到了使用进程,经过压测证实性能问题修复。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。