千亿级高并发MongoDB集群在某头部金融机构中的应用及性能优化实践(上)

2022-07-12 06:56:28

  某头部金融机构采用MongoDB存储首要的金融数据,数据量较大,数据界限约2000亿操纵,读写流量较高,峰值打破百万级/每秒。本文分享该千亿级高并发MongoDB集群的踩坑阅历及职能优化推行,通过本文可能领会如下音信:

  该MongoDB集群 采用众分片架构计划,交易不按期长工夫高并发读写,该集群交易靠山总结如下:

  跟着工夫推移,集群数据界限超越千亿,集群碰到了少少疑义题目,如主从切换、节点卓殊挂掉、节点数秒卡顿、切主后新主数极端钟不成用等题目,下面章节将逐渐分享这些题目,并给出对应的优化举措。

  鉴于篇幅,本文无法分享完该案例碰到的全数题目及其优化举措,因而《千亿级高并发MongoDB集群正在某头部金融机构中的运用及职能优化推行(下)》中将延续分享本案例遗留的职能优化举措,同时分享散布式数据库主旨道由模块道理,并给出腾讯云数据库正在最新MongoDB版本中对道由改善模块所做的优化。

  从上面可能看出,diagnose.data是为了官方工程师了解各样题目引入的成效。FTDC数据文献是bson+压缩+私有条约,不是直观可读的,接受了MongoDB数据文献雷同的文献拜访权限,默认环境下全数mongo节点开启ftdc成效。

  diagnostic.data目次中根据工夫记载各样区别诊断音信到metrics文献,除了erim文献,其他文献内容大约10M操纵。

  官方jira体系申明该bug依然正在3.6版本中修复,可是又有新用户正在讲述正在3.6版本中碰到了同样的题目,而且根据官方提议做了memlock unlimited设备。

  走读 对应版本MongoDB内核代码,可能看出内核认证流程和修账号流程会行使SecureAllocator内存分派器举行内存分派,默认环境通过mmap+mlock格式举行memlock分派,可是这里内核源码实质上加了一个开合,用户可能本身裁夺是否行使memlock。主旨代码如下:

  从 上面的内核主旨代码可能看出,认证流程、账号创修流程的security内存分派有两种格式,如下:

  di sabledSecureAllocatorDomains正在官方文档没用申明,源委实质测试验证,禁用memlock对链接认证影响不大,同时由于用户是长连结乞求,因而影响根本上疏忽。

  主从 切换经过中,因为读写流量都走主节点,因而切换经过会有大方报错,搜罗对应日记,主旨日记如下:

  从 上面的主旨日记可能看出,该工夫点从节点和主节点的保活超时了,该从节点从新提议了一次推举,推举大抵1秒钟操纵杀青,该从节点被提拔为新的主节点。

  上面日记了解开端占定主从切换由保活超时惹起,题目根因定位就须要了解出惹起保活超时的理由。因为该云下集群监控音信缺失,因而搜罗用户diagnose.data诊断数据举行了解,最终通过了解诊断数据确认根因。

  了解该集群众个节点日记,只要该从节点产生了保活超时地步,其他分片节点不存正在该题目,而且该从节点一秒钟内火速被选为新的主节点,因而可能消释汇集颤动题目。

  对当令间点主节点有大方慢查,通过慢查可能看出该工夫段慢查问工夫正在几十毫秒到数秒、数十秒摇动,因而节点不是统统hang死的,可能消释节点长工夫hang死的环境。

  借使主压力过大,主节点的全数乞求存正在列队地步,这时刻就可以惹起保活超时。同时,团结后面的诊断数据了解,最终确认该题目由主压力过大惹起。

  该集群只要mongostat监控音信,无其他监控数据,切换前一段工夫该主节点对应mongostat监控音信如下:

  从上面的 打印结果可能看出,正在切换前一段工夫的流量较高,该分片主节点读写流量超越15W/s,used内存慢慢靠近95%。可是很可惜,靠近切换前一分钟内的mongostat监控没有获取到,对应报错音信如下:

  从上面的mongostat监控看出,跟着userd行使越来越高,用户线程入手窒碍并举行脏数据舍弃,读写职能也有所低落,qrw、arw活泼部队和等候部队也越来越高。通过这些地步可能根本确认乞求列队越来越首要,因为邻近主从切换工夫点邻近的mongostat数据没有获取到,因而解析diagnose.data诊断数据确定根因。

  主节点降级为从节点前30秒和后15秒的读写活泼部队诊断数据如下(左图为读活泼部队数,右图为写活泼部队数):

  上图为读写活泼乞求数,也即是mongostat监控中的arw。同时了解diagnose.data中的读写等候部队,其结果如下(左图为读等候部队,右图为写等候部队):

  上图 读写乞求部队数,也即是mongostat中的qrw,分外代外部队中列队的读乞求数和写乞求数,切换前30秒操纵读写部队中列队的乞求数都很高,靠近1000,列队地步首要。

  因为从节点按期会和主节点举行保活探测,借使主节点10秒钟没应答,则从节点会主动提议推举。从上面的了解可能确定根因,主压力过大,列队地步首要,因而最终酿成从节点保活超时。

  申明:上面4个诊断图中的value值为该工夫点的诊断项取值,后面的inc-dec中的数据为每隔一秒钟的增量数据,是比拟上一秒的蜕变。

  团结交易行使环境领会到该集群由众个交易拜访,此中对集群影响较大的厉重是某个交易不按期长工夫跑批措置职业举行大方数据读写。为了避免批量职业经过中对其他交易的影响,交易测举行如下改制:

  其它,正在交易举行交易改制时代,为了避免主从切换后酿成的集群不成用题目,MongoDB内核也做了适应优化,厉重通过适应调解主从保活超往往间来规避缓解题目:

  正在 集群运转经过中,还产生少少对照稀罕的题目,集群有时刻低峰期的时刻产生hang住地步,这时代数秒乃至数十秒内全数乞求超时,主旨日记如下:

  从上面 日记可能看出,ftdc诊断模块已提示时延破费厉重聚集正在tcmalloc模块,也即是tcmalloc模块hang住惹起了通盘实例乞求等候。于是解析对当令间点diagnose.data诊断数据,hang住卓殊工夫点前后的tcmalloc诊断数据如下:

  如 上图所示,卓殊工夫点tcmalloc模块缓存的内存十秒钟内刹时一次性开释了靠近40G内存,因而酿成了通盘节点hang住。

  优化 举措:及时pageHeap开释,避免一次性大方cache聚集式开释惹起节点hang住,MongoDB及时加快开释对应内存敕令如下,可通过tcmallocReleaseRate节制开释速率:

  该 敕令可能加疾开释速率,片面MongoDB内核版本不维持,借使不维持也可能通过下面的敕令来举行激进的内存开释:

  该集群除了碰到前面的几个题目外,还碰到了一个更首要的题目,主从切换后数极端钟不成用题目。下面咱们入手团结日记和诊断数据了解新主数极端钟不成用题目根因:

  从上面的日记可能,从节点发觉主节点保活超时,大约15秒钟内火速被提拔为新的主节点,通盘经过全部寻常。

  集群因为流量过大,已提前闭塞balance成效。可是,从节点切主后,交易拜访十足hang住,试着kill乞求、手动HA、节点重启等都无法管理题目。下面是一次完全主从切换后集群不成用的日记记载及其了解经过,囊括道由改善经过、拜访hang住记载等。

  MongoDB内核道由模块笼盖分片集群散布式成效的全数流程,成效极其繁复。鉴于篇幅,下面只了解此中主旨流程。

  通过上面 的日记了解,根本上可能确认题目是因为主从切换后道由改善惹起,可是通盘经过陆续30分钟操纵,交易30分钟操纵不成用,这确实不成采纳。

  M ongoDB内核道由改善流程对照繁复,这里只了解3.6.3版本切主后的道由改善厉重流程:

  新主收到mongos转发的乞求后,从当地内存中获取该外版本音信,然后和mongos率领shardVersion版本号做对照,借使mongos转发的主版本号比当地内存中的高,则申明本节点道由音信不是最新的,因而就须要从config server获取最新的道由版本音信。

  第一个乞求到来后,举行道由版本检测,发觉当地版本低于采纳到的版本,则进入改善道由流程。进入该流程前加锁,后续道由改善交由ConfigServerCatalogCacheLoader线程池措置,第一个乞求线程和后面的全数乞求线程等候线程池异步获取道由音信。

  构制500万chunk,然后模仿集群主从切换刷道由流程,通过验证可能复现上一节刷道由的第二阶段20秒和第三阶段15秒时延破费,可是第一阶段的32分钟时延破费永远无法复现。

  从上面代码可能看出,正在把获取到的增量道由音信悠久化到当地config.cache.chunks外的时刻会写入一个noop空操作到local.oplog.rs外,当noop空操作同步到大片面从节点后,该函数返回,不然从来窒碍等候。

  上面 代码走读狐疑从config server获取增量道由音信因为主从延迟酿成通盘流程窒碍,因为该集群没有主从延迟联系监控,而且卓殊工夫点mongostat音信缺失,为了确认集群卓殊工夫点是否真的有主从延迟存正在,因而只可借助diagnose.data诊断数据来了解。

  因为主节点依然hang住,不会有读写流量,借使主节点流量为0,而且从节点有大方的回放ert统计,则申明确实有主从延迟。刷道由hang住还原工夫点前35秒操纵的opcountersRepl.insert增量诊断数据如下:

  从节点回放杀青工夫点,和刷道由hang住还原工夫点一概,从诊断数据可能确认题目由主从延迟惹起。

  为了进一步验证确认主从延迟对刷道由的影响,搭修分片集群,向该集群写入百万chunks,然后举行如下操作,手动触发主节点举行道由改善:

  通过mongos拜访该chunk数据,mongos会率领最新的shardVersion发送给主节点,这时刻主节点发觉本田主版本号比mongos率领的乞求版本号低,就会进入从config server获取最新道由音信的流程,最终走到waitForLinearizableReadConcern等候一个noop操作同步到无数节点的逻辑,因为这时刻两个从节点都是延迟节点,因而会从来窒碍

  通过验证,当撤废从节点的延迟属性,mongos拜访数据顿时返回了。从这个验证逻辑可能看出,主从延迟会影响刷道由逻辑,最终酿成乞求窒碍。

  申明:3.6.8版本入手去掉了刷道由须要等候无数派写告成的逻辑,不会再有由于主从延迟惹起的刷道由窒碍题目。

  前面提到该集群只会正在主从切换的时刻触发道由改善,因为该集群各个分片balance对照平衡,因而闭塞了balance,如此就不会举行moveChunk操作,外对应的shardVserion主版本号不会蜕变。

  可是,因为该交易对一概性条件较高,因而只会读写主节点。道由元数据默认悠久化正在lectionxx外中,内存中记载道由音信是一种“惰性”加载经过,因为从节点没有读流量拜访该外,因而内存中的该外的元数据版本音信从来为0,也即是日记中的”GTE cache version ”,切主后内存元数据版本同样为0。当用户通过mongos拜访新主的时刻版本号笃信小于mongos转发率领的版本号,进而会进入道由改善流程。

  Chunk道由音信存储正在cache.chunks.dbxx.collectionxx外中,从节点及时同步主节点该外的数据,可是该数据没有加载到从内存元数据中。借使咱们正在切主之条件前把cache.chunks外中悠久化的道由数据加载到内存中,如此切主后就可能确保和集群该外的最新版本音信一概,同时通过mongos拜访该主节点的时刻由于版本音信一概,就不会进入道由改善流程,从而优化规避切主举行道由改善的流程。

  团结3.6.3版本MongoDB内核代码,内核只要正在用户乞求同时带有以下参数的环境下才会从对应从节点举行道由版本检讨并加载cache.chunks外中悠久化的最新版本音信到内存元数据中:

  从上面的了解可能看出,只要对指定外做读写分袂设备拜访,而且带上联系readConcern设备,才会举行道由版本检讨,并会获取最新道由数据同时加载到内存中。因而,借使正在切主之条件前把最新的道由数据加载到内存,则mongos转发乞求到新主后就不会进入道由改善流程。

  从节点提前及时加载最新道由数据到cache中,可能通过按期运转如下剧本来告竣,通过mongos按期拜访全数分片从节点,剧本主旨代码如下:

  通过上面的按期探测剧本,从节点及时加载最新道由到内存中可能规避极大片面环境下切主进入道由改善的流程。可是因为只可按时探测运转剧本,因而借使正在两次探测时代集群道由版本发作了蜕变,而且蜕变的道由还没有加载到内存中,这时刻仍是有可以存正在道由版本音信纷歧概的环境,仍是会进入道由改善流程。借使这时刻主从有延迟,仍是会触发刷道由卡顿较长工夫题目。

  为领会决这种尽头环境主从延迟惹起的道由改善长工夫hang住题目,可能正在切主后举行主从延迟检讨,借使存正在无数从节点有延迟的环境,可能通过以下举措优化管理:

  上面了解可能看出,《题目地步》章节提到道由改善经过三个阶段耗时划分为:32分钟、20秒、15秒。此中,第一阶段已了解杀青,第二阶段的20秒和第三阶段的15秒工夫破费如故待管理。

  正在4.x版本及最新的5.0版本,全量道由改善和增量道由改善经过总体做了少少优化,可是当chunks数抵达百万级别时,道由改善经过仍是有秒级颤动。

  本文只了解了道由改善的厉重流程,鉴于篇幅,后续会正在特意的《千亿级高并发MongoDB集群正在某头部金融机构中的运用及职能优化推行(下)》和《MongoDB分片集群主旨道由道理及其告竣细节》中举行更具体的了解,并给出腾讯云MongoDB团队正在道由改善流程中的内核优化举措。

  如前文所述,本文中片面定位次序依赖FTDC是由于体系监控和运维器材的缺失导致只可从基层器材入手定位和了解题目,借使有一个好的运维监控体系,本文里的许众题目将能更轻松地管理。