搞会这个索引添加法,十亿级时延敏感集群想抖动都难
作者介绍
杨亚洲,前滴滴出行专家工程师,现任OPPO文档数据库mongodb负责人,负责数万亿级数据量文档数据库mongodb内核研发、性能优化及运维工作,一直专注于分布式缓存、高性能服务端、数据库、中间件等相关研发。
线上某mongodb集群存储影响公司收入流水的核心数据,本文分享该集群为何多个索引串行后台会引起集群抖动,并且部分节点出现了连接数耗光等问题。同时通过本案例,给出时延敏感业务该最优方式添加索引,做到对业务最小化影响或者无影响。
索引对业务查询性能提升起着至关重要的作用,但是绝大部分mongodb程序员和DBA对时延敏感业务的索引添加方法是错误的。
本文主要完成一下几个目的:
为何background后台加索引会引起时延敏感集群抖动?
为何前面两个索引添加过程没触发告警,第三个索引添加完成后才触发告警?
为何只有从节点抖动,主节点时延一切正常?
为何连接数暴涨?
连接数耗光,mongoshell无法登陆查看节点内部状态信息,如何破局?
时延敏感型业务如何做到业务无感知索引添加?
一、业务背景
某业务存储公司核心数据,集群异常会影响公司流水收入,该业务对时延非常敏感,稍有抖动就容易引起客户端超时异常,该业务场景如下:
数据量很小,10亿级
核心业务
时延敏感
分片模式,单个分片
读写分离
读多写少
峰值流量810Ws
该集群对应mongodb内核版本:3。6。13,某天业务自己通过mongodb管控平台串行方式添加几个索引(background后台添加),一个索引添加执行完成返回后,业务开始下一个索引的添加。
添加第一个索引和第二个索引完成后,业务没告警,但是当业务添加完第三个索引后,开始收到部分查询时延超过阀值告警。
二、集群架构
2。1集群部署架构
该集群部署架构如下:
该业务集群对应流量监控曲线如下:
如上图所示,该业务部署只有一个分片,该分片为一主四从结构5节点。分片1采用5节点的原因如下:
核心业务,5副本方式部署,可以容忍两个节点估值
时延敏感,由于业务优先读从节点,因此可以通过增加分片从节点的方式提升业务的QPS。
2。2一个分片为何要选择分片模式?复制集不是可以满足要求吗?
从上面的结构图可以看出,该集群只有一个分片,采用了分片模式架构,为何不选择复制集架构,这样还可以省掉mongos代理和configserver的成本开销。采用分片模式主要基于如下因素考虑:
该业务当前数据比较小,10亿级别,但是随着时间增长后续可能会增加到百亿级别,考虑到以后可能存在分片扩容的需求,因此采用了分片模式。
该集群当前写入更新比较少,后续可能存在大量写入更新的场景,大量写入更新需要多分片来支撑。
我司在mongos代理增加了很多功能,例如限流、流量控制、权限细化控制、监控信息完善等功能,因此默认采用分片模式。
三、问题快速发现及解决
3。1问题发现
某天,突然告警中心打来电话,突然收到如下告警信息:
几乎四个从节点先后收到同样的告警,节点时延部分请求超过20ms,由于该业务是非常核心的影响业务营收的核心集群,非常紧张。但是,有一个很奇怪的现象,主节点访问时延正常,只有从节点时延抖动。
此外,还不停收到实例不可用异常告警,对应监控曲线如下:
说明:上图曲线一根代表客户端当前已用连接数,一根曲线代表剩余可用连接数。
3。2问题排查过程
收到告警后,发现业务有很多慢日志(时延敏感业务,慢日志打印阀值为20ms),同时慢日志都走了最优索引。
通过mongoshell登陆对应节点后台
于是通过mongoshell登陆节点后台,但是登陆不上,出现如下打印:
1。MongoDBshellversionv3。6。13
2。connectingto:mongodb:x。x。x。x:20001test?gssapiServiceNamemongodb
3。20210429T11:09:15。0490800EQUERY〔thread1〕Error:networkerrorwhileattemptingtoruncommandisMasteronhostx。x。x。x:20001:
4。connectsrcmongoshellmongo。js:263:13
5。(connect):1:6
6。exception:connectfailed
由于节点登陆不上,因此登陆到存储节点查看后台日志,日志中有大量的打印提示连接数耗光了,如下图:
节点系统监控统计分析
从上面的现象可以看出链接耗光了,于是分析节点所在服务器系统监控,发现一个问题,磁盘IO非常高,如下:
分析mongod实例日志
由于从节点登陆不上,系统磁盘IO很高,因此怀疑有慢操作在运行,于是分析实例日志,发现如下现象:
问题确认
通过前面的分析可以得出问题根因在于加索引引起从节点磁盘IO过高,最终引起业务查询时延上升抖动。
通过和业务沟通,业务这段时间确实通过我们的管控平台串行方式加了几个索引,磁盘IO过高由业务加索引引起,同时从节点同一时刻有多个索引添加。加索引过程首先需要读取表数据,然后通过数据构建索引,这个过程都会有多次IO操作。磁盘IO是公用的,服务器IO高会引起该服务器上所有的IO操作变慢,因此最终引起从节点读服务抖动。
问题解决过程
到这里,我们已经确定问题是由于加索引引起,只有把索引干掉磁盘IO才会恢复正常,因此我们需要尽快干掉索引。然而,由于连接数已经耗光,无法链接从节点,所以我们不能做killop操作。
由于无法登陆后台做killop操作,于是直接kill进程,kill进程后启动,发现mongod还是在构建索引,如下:
重启后,还是需要构建索引,因为之前索引没有执行完成mongod进程就挂了,因此需要重建索引来保持与主节点状态一直。
不过,mongod为了解决类似问题,提供了一个noIndexBuildRetry参数来跳过实例加索引中途异常重启后重构索引的流程,该参数功能如下说明:
dontretryanyindexbuildsthatwereinterruptedbyshutdown
noIndexBuildRetry放弃启动从节点mongod实例,业务很快恢复:
mongodfhomeservicemongodbconfmongod20001。confnoIndexBuildRetry
四、createIndex构建索引核心流程及问题暴露过程
4。1createIndex构建索引核心流程
业务链接代理通过createIndex命令添加background后台索引,其运行流程如下图所示:
主节点接受到createIndex命令后的执行主要流程如下:
主节点查询对应表数据,然后build构建索引。
索引数据构建执行完成后,返回客户端OK。(注意:主构建完成后就通知OK给客户端,实际上这时候从节点还没有开始构建索引)
生成createIndex对应oplog数据到oplog表
从节点获取到createIndex对应oplog操作,然后重放createIndex构建索引。
4。2问题暴露流程
通过分析日志时间点和告警时间点,和业务确认,发现当业务第三个索引添加完成后(实际上只是主节点构建索引完成),开始触发时延告警阀值。总接时间序列如下:
T1时刻第一个索引主节点构建完成,然后同步到两个从节点构建索引,也就是T1时刻两个从节点只有一个索引index1在运行。
T2时刻第二个索引主节点构建完成,然后从节点获取到这个索引执行,这时候由于从节点读流量大,因此构建索引比主节点慢,最终index1和index2都在两个从节点运行。此时,访问时延还没有触发时延告警阀值。
以此类推,T3时刻第三个索引添加完成,从节点通过oplog获取到第三个索引运行,由于此时index1、index2都还没有运行完成,因此两个从节点同时构建index1、index2和index3索引。三个索引的同时运行,进一步加重了磁盘IO负载和系统开销,业务访问时延进一步上升,最终造成部分查询时延超过20ms。
总结如下图所示:
五、疑问解答
为何background后台加索引会引起时延敏感集群抖动?
如上面分析,虽然业务是串行的方式一个索引添加成功后再添加下一个background后台索引,由于主从索引构建执行时间的长短不同,从节点通过拉取对应oplog重放,最终引起某一时刻开始三个索引在所有从节点同时运行,引起IO负载很高,最终触发业务访问时延告警。
为何前面两个索引添加过程没触发告警,第三个索引添加完成后才触发告警?
如上,从节点拉取Oplog获取到第三个索引执行的时候IO负载进一步增加,最终触发了20ms访问时延阀值。
为何只有从节点抖动,主节点时延一切正常?
主节点由于业务添加是一个索引后台添加完成后,才添加第二个索引。也就是主节点同一时刻只会有一个索引在执行,IO负载低,此外由于主节点写流量本身不高,读流量几乎都在从节点,索引加索引执行很快,并且几乎不会影响写流量时延。
为何连接数暴涨?
连接数暴涨实际上是加索引引起业务访问慢的结果,由于三个索引同时在从节点构建索引运行,造成从节点IO负载很高,最终造成业务访问变慢。
访问变慢后,会引起客户端链接池中的链接不够用,于是客户端会动态的增加链接池中的连接数来进行后端DB访问,最终造成了mongod服务端连接数到达配置上线出现无法链接的问题。
连接数耗光,mongoshell无法登陆查看节点内部状态信息,如何破局?
连接数耗光,mongoshell将无法连接节点,无法获取节点内部状态。可以对该功能做优化,对指定的客户端(默认127。0。0。1)设置白名单,取消maxconnections限制,这样我们即可通过节点本机登陆mongod后台获取内部状态信息。
例如增加了链接限制白名单后,就可以通过127。0。0。1登陆到节点内部,然后通过killOp操作把从节点正在构建索引的操作干掉。
六、时延敏感型业务如何做到业务无感知索引添加?
方法一:所有主从确保索引执行完成后添加下一个索引(影响相对较小)
后台background加索引,确保所有主从索引构建完成后,才开始下一个索引的创建,避免出现本文所说的多个索引同时在从节点执行引起业务抖动。
说明:mongodb高版本中对后台添加索引做了优化,从节点拉取建索引对应oplog重放的时候,只有第一个索引执行完成,才会执行第二个索引,从而避免了同时多个索引同时执行引起的抖动。
方法二:单机启动,然后加索引,加完索引后再加入到副本集(业务无任何感知)
无感知添加索引步骤如下:
从复制集中移除某个从节点
单机方式启动该节点
阻塞方式(不带background)加索引,这样索引构建速度更快
索引添加完成后,副本集方式启动该节点
把该节点加入复制集
通过以上步骤,即可无感知方式完成一个从节点的索引添加,其他节点添加过程重复该操作过程即可。
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editordbaplus。cn
哪个牌子的奶粉好?什么牌奶粉好呢?这可能是很多家长困扰的问题,我给你的答案是适合孩子的就是最好的,现在到处充斥着婴儿奶粉的广告,一个比一个说的好听,一个比一个请的明星腕大,然并卵,别人用着好的,……
空巢老人与养儿防老引发的思考中国正迈入老龄化社会,生育率低、人口结构老化、社保制度滞后已成未来发展的重大隐患。谁来养活中国?有数据显示,2000至2010年十年间,中国城镇空巢老人比例由42上升到54,农……
在自由自在的想象世界里遨游,是一个人童年里最大的幸福很多时候我们都需要等待,等红灯,等地铁,等公交,等火车,等登机,有时很短,三五分钟就结束了,有时很长,几个小时甚至十几个小时,更长的等待也经常遇到。面对长时间的等待,无所……
地摊经济,人间烟火气地摊经济,人间烟火气最近地摊经济刷屏了,朋友圈,微信群峰平台都是谈论地摊经济。大家都在摩拳擦掌,准备跃跃试试,各种段子横空出世。律师上街头摆摊挂咨询的图片,有人街头摆摊专……
宝宝马上就要上幼儿园,这些入园准备你做好了吗幼儿从家到幼儿园是人生第一个重大转折。有些家长会很紧张,但是宝宝进入幼儿园要做的准备实在太多,不知道该做什么才好?也有些家长一点也不在意,什么准备也不做,宝宝进入幼儿园之后,真……
21月龄宝宝发育对照标准(036逐月分解系列)您的孩子已经21个月大了!当你开始看到孩子在玩具和游戏的选择上表现出兴趣的时候,游戏就变得更加有趣了。小紫萱可能喜欢撞玩具车,而小子轩可能会喜欢你的闪亮粉红色高跟鞋。这个……
江苏这4所二本院校太热门,第4所985的高分学霸都抢着报考江苏的高等教育资源是非常丰富的,不仅有南京大学、东南大学、南京航空航天大学等非常知名的双一流定向,也有不少知名度相对较低却很有实力的二本院校。今天就给大家推荐其中比较有代表性的……
接单记录生活接单晚上,高官致电,称上司需要装修房子,荐我赴约。我犹豫又犹豫,对于接单已经淡忘了许久,似乎不愿再接单,虽然含有金钱的诱惑,钱多多益善,且时常缺钱,但能维持生活。感……
三个方法改善写作业拖拉没有时间观念的孩子很多家长都非常希望利用假期给孩子培养良好的时间观念,但却不知如何下手,阳光一路就带大家一起探讨关于幼儿时间观念培养的问题。虽然时间是非常抽象的事物,但其实孩子们在很小的时……
女性的这些行为,就是在给子宫制造垃圾,6成以上的女性都有子宫是女性生殖系统的重要组成部分,生命的孕育便是从子宫开始的,但是不得不说时下很多年轻女性对于子宫的保养并不十分重视,而且在日常生活中还存在着一些伤害子宫的行为习惯。比如说宫内……
华氏宝贝宝宝不爱喝水怎么办?宝妈必备,五个小妙招轻松get宝宝不爱喝水是很多宝妈的心头大患该如何养成良好的饮水习惯呢?Get这些小妙招妈妈再也不担心宝宝不爱喝水啦!给水增加一些味道可以在水里加入药食……
放假通知幼儿园2021年中秋节放假通知及假期注意事项暑气褪去,秋意渐浓!一年一度中秋佳节即将来临!月圆人圆,中秋是团圆的时刻和家人一起吃着月饼赏着月幸福莫过于此!2021年幼儿园假期安排也正式……