云数据库DDS实例shard连接数异常激增影响业务的事件,问题分析如下
保障现象:
在当天22日 21:50-22:21时间段内,连接数异常激增,同时伴随有大量慢日志,实例整体响应速度下降。
3 月 23 日 19:35 贵司报障该实例再次出现shard 连接数激增的现象。
排查处理:
- 经过排查发现 3月22日 21:50 - 22:51 分时间段内 WiredTiger cache usage 处于高水位 95%,同时 available read tickets 和 available write tickets 为0。
结论:
- 发生在3月22日21:50-22:20分的shard2连接数上涨是什么原因导致的?
主要是WiredTiger cache usage 太高达到了 95%,此时用户线程参与淘汰clean page,导致部分读写业务处于等待状态,后续进来的业务 因为拿不到 ticket 也处于等待状态,此时客户端因为业务接受超时断开连接,又有新的连接进来。Mongodb对连接处理的特点是客户端主动断开连接,数据库服务端还会继续执行之前的操作,直到该操作被执行完成,该连接才会断开。如此反复老连接数据库服务端还在持有新连接已经进来,反应在监控上的表现就是连接数短时间内激增。 - 为何从监控上看 系统内存使用率并不高,在70%左右,而cache usage满了?
mongodb内存占用分为 存储引擎(DDS 4.0 为 Wiredtiger)cache占用和server层占用,其中cache内部实现为LRUcache,一般配置为max_cache_size=OS Memory * 0.4 - OS Memory *0.6,当内存增长到配置值时,则这部分占用不再上涨,通过淘汰使用率低的内存来进行内存管理。存储引擎稳态运行时,内部内存占用分为 cache_used 和 cache_free两部分,加起来占用为max_cache_size。当cache_used占用超过max_cache_size 95%时,用户线程会陷入暂停,参与到LRUCache的内存管理。
server层占用,分为数据库上层的内部通信线程,后台线程等固定开销和用户侧下发的请求所占用的内存等。 - 业务并没有明显变化,WiredTiger cache usage 从来没有满过,为何突然在 3月22日 21:50分开始满了?
(1) 通过shard2 硬盘读写情况,我们发现业务在缓慢增长,3月22日晚9点以后增长更明显。
(2) 通过观察前一天WiredTiger cache usage的监控,不难发现在21:00-22:00,也有冲高,只是持续时间比较短,业务上应该感知并不明显。
- 单个shard上业务请求并发量在10000左右,并不算非常高,为何WiredTiger cache usage 会达到95%,导致业务阻塞?
这和业务的数据存储结构有关系,mongodb的数据存储结构简单来说,数据的存储由索引和数据段组成,对于WiredTiger,一个索引一个btree,一个数据段也是一个btree。
WiredTiger cache 主要存放内存中btree page为单位的页。cache的读入和淘汰都是以page为单位。
通过沟通发现业务查询用到的_id是hash索引,并且业务随机分散程度非常高,这种情况下极其容易出现每次查询一条文档就需要新加载一整个page到wiredTiger cache中,page的利用率太低了。导致业务量一上涨 cache容易满。 - WiredTiger cache 调高之后为何还会还会卡顿?
Cache size 调高之后 瓶颈又转移到了 IO,业务是随机点查,缓存中的命中率太低了,就需要不断地读 磁盘上的page 到 cache中。
复现场景数据库方面排查结论:
-
客户当前业务瓶颈为内存,mongodb内存占用分为 存储引擎cache占用和server层占用,其中存储引擎的max_cache_size,固定占用节点内存的50%,因此server层最大可用内存亦为50%,server层内存由tcmalloc管理,cache层内存由LRUcache进行管理。当server层内存出现瓶颈时,体现为内存占用接近100%,甚至发生out of memory。而当LRUcache出现瓶颈时,则会导致业务受损等现象。客户当前瓶颈即为存储引擎cache部分的内存出现瓶颈。
-
当wt_cache_usage到达95%后,业务会受损,具体表现为需要客户线程去逐出使用率低的内存,整体业务执行变慢。
-
当前存储引擎cache逐出速率上限受到业务影响,具体体现为,迁移load数据时,cache逐出速率峰值可达到近400M/s,接近IO吞吐上限,故障场景时,逐出速率约固定在100M每秒,通过阅读wiredTIger源码,可知wiredTiger逐出内存page受到了业务访问频率的影响(例如被标记淘汰的页,正在被其他线程使用时,则淘汰终止),合理推测此时由于业务模型访问数据较为离散,LRU逐出cache的速率变低。
-
客户当前部分业务模型,会占用较多cache,这部分业务可在短期内将cache_usage打满,使存储引擎cache出现瓶颈。
复现场景业务方面排查结论:
1.业务模型过于离散,导致cache淘汰速率高,受硬盘吞吐率限制,淘汰速度达不到使用速率
改进措施:
1、 短期方案增加shard分摊单个shard上的 cache 和 IO 压力。
2、 业务侧要灵活控制读写分离,尽可能做到细粒度控制。
If condition:
set readPreference=secondaryPreferred
return ReadSecondaryClient
else:
set readPreference= primaryPreferred
return ReadPrimaryClient
3. 业务需要阶段性压测,一般情况下推荐使用日常业务量最高峰的2-3倍来进行压测
4. 规格升配,扩大内存,调高max_cache_size参数