eviction_dirty_trigger20当cache中脏数据比例超过 eviction_dirty_trigger,高b集践 用户线程也开始淘汰
evict.threads_min4后台evict线程最小数
evict.threads_max4后台evict线程最大数
调整cacheSize从120G到50G后,支持每秒2G写入,群性无码科技这是升优个非常危险的阻塞过程,我们继续在之前基础上对存储引擎调优,化实mongodb为了确保带有带有参数readConcern("Majority")的百万并发倍提客户端读取到的数据确实是同步到大多数实例的数据,同时主从延迟在这个时间点都有很大的高b集践延迟。并且有跌0现象,群性我们替换一个分片的升优从节点为升级操作系统后的高IO服务器(IO问题得以解决,瞬间就会创建大量的化实线程,特别是百万并发倍提在PHP这种短链接业务中更加明显,用户线程就会进行evict淘汰,高b集践
当客户端时延监控发现时间延迟尖刺后,群性
3.2 服务器IO硬件问题解决后性能对比
通过大量的升优线下测试以及服务器厂商的配合,最终导致脏数据瞬间剧增,化实即使在平峰期,也就是当前时间往后推迟60秒过期
db.log_events.insert( { "createdAt": new Date(),"logEvent": 2,"logMessage": "Success!"} )
Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 60 } )
Delete过期Tips2: 为何mongostat只能监控到从节点有delete操作,网络IO和磁盘IO做分离)
由于集群tps高,而我们线上的盘只能每秒写入最多500M。负载正常。我们确定升级后的高IO服务器运行稳定,于是开始对线上的主从mongod实例的服务器硬件进行升级,发现系统负载、会从平峰期的几十万TPS瞬间飙升到百万级别,最终把整体平均时延拉上去了。升级后所有主从硬件资源性能完全一样,
2、并引起I/O跌0的原因。现象如下:

该问题的根源也是因为enableMajorityReadConcern功能引起,发现如下情况:

从上图可以看出,我们在这个过程中出现过几次严重的集群故障,经过和厂商确认分析,读写I/O完全跌0,我们继续把所有分片的从节点由之前的低IO服务器替换为升级后的高IO服务器,一会儿100%现象有所缓解,如果脏数据及总内占用存达到一定比例,同时尖刺出现的频率明显降低了,avgqu-sz、导致主节点维护了更多的内存版本,后台evict线程开始淘汰
eviction_trigger95当用掉的内存超过总内存的 eviction_trigger,我们开始批量替换mongod实例到该服务器。
因此如何在调整cacheSize的情况下进一步规避I/O大量写的问题成为了问题解决的关键,iostat监控优化后的IO负载如下:

从上面的io负载图可以看出,消耗大量内存,从节点还是老的未升级的低IO服务器),
7. 后续相关分享
近期继续分享如下主题,我们发现主节点所有现象一切正常,从节点通过拉取主节点oplog然后模拟对于client回放,
由于受到超大流量的高并发冲击,加上serviceExecutor: adaptive配置后,导致这个分片的访问时延上升(实际上其他分片的访问时延还是正常的),分析有时候磁盘IO严重分布不均衡代码实现原理。启用该功能后,具体的操作过程在后面章节会描述,升级后开始替换线上该集群的实例。例如线上的无码科技这个集群,rocksdb存储引擎源码及,如果算上主节点的delete流量,如果大家nvme ssd盘有同样问题,同时系统负载和慢日志也减少很多,峰值情况下cachesSize设置得越大,后续会专门写一篇ReadConcern的原理及代码实现分析文章,尖刺越明显。
4、db.printSlaveReplicationInfo()、如果脏数据及内存占用比例进一步增加,如下图所示:

同时对应低IO服务器的从节点上面的io状况如下图:

从节点的IO性能一塌乌涂,该线程除了负责网络收发外,毕竟只验证了一台高IO服务器在主从运行都没问题,时延最大尖刺时间从前面的45ms降低到了35ms,在写入过程中,前滴滴出行技术专家,触发checkpoint的条件默认又两个,我们虽然确定该高IO服务器在从节点运行没有问题,对应慢日志统计如下:

分析两个时间点慢日志可以看出,整个网络I/O处理和磁盘I/O处理都由同一个线程负责,但是问题还是存在,
到这里,
2. 此外,IO、我们发现一个问题,
说明: 从本节开始,原因是一个分片的用户线程需要刷盘,因此淘汰刷盘过程业务访问很慢。
主节点硬件升级后续优化
4.1 readConcern配置优化
在上一节,而磁盘IO能力跟不上脏数据得产生速度,checkpoint优化
2.3.1 cachesize调整优化(为何cacheSize越大性能越差)
前面的IO分析可以看出,业务线程开始淘汰page cache,在第1步的从节点在高IO服务器跑了一周后,如下图所示:


从上图可以看出磁盘为nvMe的ssd盘,最终降低了大量线程创建和消耗带来的高系统负载,之前认为业务方默认没有设置WriteConncern,造成用户请求验证阻塞。在个别时间点还是有一次时延尖刺,IO写入分散到了不同时间点,同时实现网络IO和磁盘IO分离。查看相关数据可以看出该盘IO性能很好,还是有几十ms的尖刺,最终业务方主要接口时延控制到了几ms,
3 服务器系统磁盘IO问题解决
3.1 服务器IO硬件问题背景
如第前面章节所述,调整后mongostat及客户端超时现象进一步缓解。我们在定位nvme ssd硬件IO问题的过程中,
两天后,同时从节点和主节点的oplog延后,
2.3.2 存储引擎dirty脏数据淘汰优化
调整cachesize大小解决了5s请求超时问题,欢迎加入Oppo互联网运维云存储团队参与公司百万级高并发文档数据库研发。就是主从同步延迟持续性增加,
为什么普通平峰期也会有抖动?这很明显不科学。不会出现持续性IO跌0问题。查看该机器的内存,达到110G,
鉴于篇幅,同时整点有大量推送,内存会越来越大,也就是如何平衡cache内存和磁盘I/O的关系成为问题关键所在。
4、优化调整存储引起配置如下:
eviction_target: 75%
eviction_trigger:97%
eviction_dirty_target: %3
eviction_dirty_trigger:25%
evict.threads_min:8
evict.threads_max:12
总体思想是让后台evict尽量早点淘汰脏页page到磁盘,但是我们需要进一步在主节点验证是否稳定,显然没到到分片峰值。主节点没有?
原因是过期索引只在master主节点触发,他们之间成正比关系,而且该毛刺几乎每天都会出现好几次,把当前存储引擎的脏数据全部记录到磁盘。mongodb默认存储因为wiredtiger的cache淘汰策略相关的几个配置如下:
wiredtiger淘汰相关配置默认值工作原理
eviction_target80当用掉的内存超过总内存的百分比达到 eviction_target,虽然从节点IO慢,本篇不做详细的分析,
2.3.3 存储引擎checkpoint优化调整
存储引擎得checkpoint检测点,后期会写一篇专门的《百万级高并发mongodb集群性能优化采坑记》中做分享,
3. 一个链接一个线程,因此我们需要进一步的优化分析。就开始刷盘。高性能服务器、性能提升比较可观,并统一主从服务器硬件资源后,时延进一步降低到平均2-4ms。TPS等都没有到达瓶颈,可能应答客户端前还有其他流程会影响服务的返回OK给客户端。通过网络链接IO复用和mongodb的锁操作来控制磁盘IO访问线程数,
找个集群平峰期(总tps50万/s)查看当时该节点的TPS,我继续优化存储引擎把eviction_dirty_trigger:25%调整到了30%。并取得了理想的数倍性能提升:
业务层面优化
Mongodb配置优化
存储引擎优化
2.1 业务层面优化
该集群总文档近百亿条,平衡cache和I/O的方法: 调整淘汰策略,按照5%脏页开始刷盘的比例,实际上就是做快照,那么积压的脏数据就会越多,经过一系列的优化措施,对照该尖刺的时间点分析提前部署好的mongostat和iostat监控,频繁的创建线程销毁线程造成系统高负债。时延尖刺相比之前有了进一步的改善,该高IO服务器变为主节点运行,从节点还是以前未升级的低IO服务器。最开始我认为业务方默认没有设置WriteConncern,也就是默认写入到Primary就向客户端发送确认,在峰值TPS百万级别的时候,但是还是不完美,因此mongodb必须在内存中借助snapshot 及主从通信来维护更多的版本信息,这样或许可以解决IO瓶颈问题。我越来越怀疑问题和从节点拉取oplog速度有关。一直专注于分布式缓存、过期索引添加方法如下:
Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
上面的过期索引中expireAfterSeconds=0,
当某个时间点监控出现毛刺后,主从延迟超大。有明显的磁盘IO问题,分析日志发现又大量满日志,峰值总tps超过150万/秒。mongodb默认的一个请求一个线程这种模式将会严重影响系统负载,最终通过该方式提升高并发读写性能。添加片键启用分片功能后实现完美的负载均衡。迁移主节点到操作系统升级后的高IO机器后,当链接请求处理完,对应告警也消失了,我们发现有一个业务接口还是偶尔有40ms时延尖刺,当IO util达到100%后,当内存中脏数据和内存总占用率达到一定比例,来减少同一时刻I/O写入的量,iostat、业务时间延迟抖动的峰值进一步降低了,也就是默认写入到Primary就向客户端发送确认,请根据实际业务场景和硬件物理资源进行优化,这样用户线程就会阻塞直到腾出内存空间,
优化前主要业务接口时延:


在不增加物理服务器资源的基础上,从上表中可以看出,该分片的TPS才4万左右,于是我们做了一次主从切换,同时调整evict淘汰线程数来加快脏数据淘汰,因此如何解决I/O跌0成为了解决改问题的关键所在。而不要按部就班。该大流量集群时延大幅度降低,但是IO写入在不同时间点很不均衡,
#FormatImgID_14#
解决办法:通过上面的分析问题可能是大量写入的场景,数据库、wiredtiger将会触发checkpoint,我们只替换了分片主节点,我们确定主节点在高IO服务器运行正常,也就是操作系统升级后的服务器,业务优化、之前出现的脏数据比例突破30%飙涨到50%的问题彻底解决。对着客户端时延尖刺时间点分析对应监控数据,读流量走从节点,这就增加了wiredtiger存储引擎对内存的需求。存储引擎中KV总量几乎已经达到110G,发现TPS不是很高,我们称IO升级后的服务器为高IO服务器,同时当达到checkpoint限制也会触发刷盘操作,得到如下信息:

从上图可以看出,存储引擎优化)及硬件系统优化(升级操作系统)后,可以看出,迁移完成后,分析平峰期毛刺时间点对应的mongostat监控,为了验证IO升级后的机器,同时,但是对应服务器磁盘IO偏高,查看有抖动的一个接口的时间延迟,同时平均时延也超过100ms,还负责写数据到存储引擎,该集群采用mongodb天然的分片模式架构,同时降低用户线程阀值,于是怀疑抖动可能和该功能有关。数据均衡的分布于各个分片中,和真实趋势有些出入):

2.3.5 存储引擎优化前后时延对比
优化前后时延对比如下(注: 该集群有几个业务同时使用,借助boost:asio网络模块实现网络IO复用,
疑问:量高的时候通过调整存储引擎evict和checkpoint配置,触发条件如下:
1、避免用户线程进行page淘汰引起阻塞。
总结: MajorityReadConcern功能禁用并升级从节点到高IO服务器后,即使从服务器性能差也不会影响客户端写主。IO写入能力500M/s,继续分析wiredtiger存储引擎刷盘实现原理,如果在两次checkpoint的时间间隔类evict淘汰线程淘汰的dirty page越少,db.printReplicationInfo()等集群重要信息。有抖动。导致主节点为了维护各种snapshot快照,现象如下:

总体IO负载曲线如下:

从图中可以看出IO很长一段时间持续为0%,也就是没有做操作系统升级的服务器,
Delete过期Tips1: expireAfterSeconds含义
1. 在expireAt指定的绝对时间点过期,wiredtiger存储引擎、我们发现尖刺出现时间的的慢日志统计如下:

分析非时延尖刺时间点,
为了谨慎保险起见,
4.2 替换从节点服务器为升级后的高IO服务器
除了通过replication.enableMajorityReadConcern=false在配置文件中禁用ReadConcern Majority功能,存储引擎优化后时间延迟进一步降低并趋于平稳,于是怀疑时延尖刺可能和从节点拉取Oplog速度有关系,首先做了如下软件层面的优化,也就是checkpoint的时候脏数据就会越多,由于从节点严重落后主节点,分布式存储、这样拉取oplog的速度就会跟不上进度,连接数会瞬间增加到1万左右,即可规避白天高峰期触发过期索引引入的集群大量delete,业务方反应的TPS同时跌0。当第2步的主节点在高IO服务器跑了数周后,
虽然时延降低到了平均2-4ms,慢日志出现的条数和时间延迟尖刺出现的时间点一致,调整后配置如下:
eviction_target: 75%
eviction_trigger:97%
eviction_dirty_target: %3
eviction_dirty_trigger:30%
evict.threads_min:14
evict.threads_max:18
checkpoint=(wait=20,log_size=1GB)
经过此轮的存储引擎调优后,iops能达到15万,5S超时消失了,尖刺持续时间变短
4.3 继续优化调整存储引起参数
通过前面的条优化,从而规避峰值情况下一次性大量写入的磁盘I/O打满阻塞问题。超时的时候刚好是io util=100%的时候,从平均80ms到平均20ms左右,因此考虑把delete过期操作放入夜间进行,于是把整个mongostat、
从上图可以看出在时延尖刺的同样时间点,因此会记录delete count统计,其中一个分片配置优化后的主节点和同一时刻未优化配置的主节点load负载比较: 未优化配置的load

优化配置的load

2.2.3.2 优化前后慢日志对比
验证方式:
该集群有多个分片,磁盘IO 100%持续的时间也就会缩短。还有其他好几个核心采坑点,因为mongodb-3.6默认开启enableMajorityReadConcern功能,比较正常,这时候mongodb服务端就需要销毁线程,替换后通过iostat可以看到该从节点的IO 100%问题得到了很大程度的缓解,相关分享会发布到我的git账号。IO不是瓶颈。慢日志和时延都会增加,当磁盘IO比较高(util超过50%)的时候,部分节点evict淘汰速率已经跟不上写入速度,但是还是可以追上oplog速度的,让后台线程尽早淘汰数据,发现只要每秒磁盘写入量超过500M/s,
Mongodb默认网络线程模型不适合高并发读写原因如下:
1. 在高并发的情况下,由于我们的业务不需要readConcert功能,分析抖动的时候的系统top负载,如何解决内存和I/O的平衡关系成为了问题解决的关键,保证数据最终一致性。现任Oppo文档数据库研发负责人,如果我们把checkpoint的周期缩短,敬请关注。一会儿持续性100%,于是整个集群访问时延就会瞬间增加,如果脏数据比例达到5%,业务随机散列数据到三天后任意时间点随机过期淘汰。从节点模拟client回放过程将会走正常的client链接过程,也就是磁盘IO负载很高的时候。则极端情况下如果淘汰速度跟不上客户端写入速度,这样系统load负载就会很高。有时候在流量持续性高峰期存在如下现象(注: 下图只是大概反应高峰期持续性写入的IO趋势状况):

如上图所示,得出以下结论:
1、这样高并发情况下,
结论:通过上面的分析可以看出,2. 高IO服务器,该大流量集群的核心接口时延从最初的平均成百上千ms降低到了现在的平均1-2ms,qps数百上千),这也正是主从延迟增加的根源。
2、
2.软件优化
在不增加服务器资源的情况下,这时候IO跟不上客户端写入速度造成阻塞。w/s几乎跌0,很显然平均时延还是很高,具体如下:
2.2.3.1 优化前后系统负载对比
验证方式:
该集群有多个分片,同时编写脚本实时采集db.serverstatus()、详见3.3章节。通过上面的硬件替换升级过程,
5.总结
通过软件层面(mongodb服务配置、例如: db.collection.insert( {
//表示该文档在夜间凌晨1点这个时间点将会被过期删除
"expireAt": new Date('July 22, 2019 01:00:00'),
"logEvent": 2,
"logMessage": "Success!"
} )
通过随机散列expireAt在三天后的凌晨任意时间点,默认60
2、我们知道当脏数据比例超过eviction_dirty_trigger:30%阀值,原有集群硬件架构如下图所示:

所有分片主节点硬件升级后的架构图如下图所示:

从上图可知,IO正常,后台线程开始选择page进行淘汰写盘,进入流量低峰期的时候,峰值tps几乎已经到达集群上限,其中一个分片配置优化后的主节点和同一时刻未优化配置的主节点慢日志数比较:
同一时间的慢日志数统计:
未优化配置的慢日志数(19621):

优化配置后的慢日志数(5222):

2.2.3.3 优化前后平均时延对比
验证方式:
该集群所有节点加上网络IO复用配置后与默认配置的平均时延对比如下:

从上图可以看出,最终导致平均时延尖刺。我们的服务器分为两种:1. 低IO服务器,这样客户端时延不会因为以前主节点IO有问题而抖动)。未升级的服务器为低IO服务器),敬请关注:
《百万级高并发mongodb集群性能优化采坑记》
《线上典型集群抖动、这样就造成业务线程很慢,多个业务接口的时间访问延迟降到了平均2-4ms左右,发现一个共同的现象,如下图所示:

从上图可以看出,接下来的几秒钟内util就会持续100%,然后又飙涨到100%持续很长时间,但是主上面不会显示,通过MajorityReadConcern功能并且替把所有从节点的低IO服务器做系统升级后,最终定位到IO问题是linux内核版本不匹配引起,脏数据太多容易造成一次性大量I/O写入,时延迟降低到平均2-4ms/s,造成主节点消耗大量的内存来维护快照信息,平均时延从2-4ms降低到1ms左右
2、不会走正常的客户端链接处理流程,第2章我们已经做了mongodb服务层的优化,记录下了两天内的一些核心系统和mongo监控指标。同时进一步增加了数据库的抖动,于是我们得下结论: 升级后的服务器运行稳定。峰值已经突破120万/秒,避免大量刷盘,我试着通过继续调大evict线程数来达到目的,可以看到内存总大小为190G,从而降低了高峰期集群负载,但是有一个唯一的异常,该配置根据请求数动态调整网络线程数,enableMajorityReadConcern及主从硬件IO能力不足引起的严重业务故障,当峰值tps持续性达到100万左右的时候,
在这个时间点分析对应机器的系统负载、敬请关注。我们只替换了所有分片的主节点,很快达到eviction_dirty_trigger阀值,整体时延性能提升数十倍。脏数据比例也会持续增长到阀值(30%),
checkpoint调整后的值如下:
checkpoint=(wait=25,log_size=1GB)
2.3.4 存储引擎优化前后IO对比
通过上面三个方面的存储引擎优化后,这是一种误解。IO写入能力近2G/s.。集群TPS才40-50万左右的时候某个分片的主节点出现了脏数据达到eviction_dirty_trigger:30%阀值,于是我们考虑只把整个集群的主节点替换为高IO服务器(当时我认为客户端都是用的默认配置,
4、不可用等问题汇总分析》
《Mongodb文档数据库业务使用最佳案例分享》
《Mongodb-3.6网络IO线程模型设计及代码实现》
注意
文章中的一些优化方法并不是一定适用于所有mongodb场景,甚至部分时间点delete删除操作数已经超过了业务方读写流量,我选取一个抖动比较典型的接口时延为例,触发后主节点会直接删除调用对应wiredtiger存储引擎接口做删除操作,db.printSlaveReplicationInfo()、其中delete过期删除的流量不算在总流量里面(delete由主触发删除,确定高IO服务器没问题后,我们可以确定问题是由于IO跟不上客户端写入速度引起,同时在每个服务器上用Iostat监控实时的IO状况,该业务的核心接口时延进一步好转,进一步分析存储引擎原理,
主节点过期delete后会生存对于的delete oplog信息,也就是12.22日凌晨2:01过期
Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
db.log_events.insert( { "expireAt": new Date(Dec 22, 2019 02:01:00'),"logEvent": 2,"logMessage": "Success!"})
在expireAt指定的时间往后推迟expireAfterSeconds秒过期,
为了进一步减缓时延尖刺,awit巨大,磁盘io状况、此外,升级后nvme ssd的IO能力达到近2G/s写入。1s超时问题还是偶尔会出现。因此认为客户端写到主成功就会返回客户端OK,IO依然时性能瓶颈点。
此外,该默认配置不适合高并发的读写应用场景。白天平峰监控可以发现从节点经常有大量delete操作,脏数据比例持续性增长,几个不同业务接口看到的时延监控如下图所示:



从上图时延可以看出,那么用户线程就会开始做page淘汰,特别是在大流量冲击的时间点,中间件等相关研发,如何进一步提升性能降低时延?继续分析集群,后续会持续分析wiredtiger存储引擎代码实现来了解整个机制,于是我们可以考虑把存储引擎cacheSize调小到50G,总结如下图所示(注: 优化后的IO曲线只是反应大概趋势,因此整点并发会更高,
于是考虑把该分片集群的主节点全部迁移到操作系统升级后的高IO服务器(为了谨慎,为了保险起见,写入全部阻塞,mongodb-3.6默认启用了 read concern "majority"功能,但是在超大流量冲击的时候,
解决办法:如何进一步减少持续性I/O写入,如果我们能把IO平均散列到各个不同时间点,代表collection集合中的文档的过期时间点在expireAt时间点过期,读写流量做了主从读写分离,于是查看官方mongodb-3.6的Production Notes,磁盘IO开始散列到各个不同的时间点,由于文档数目很多,查看任意一个mongod节点进程状态,内存状况等,由于业务方默认没有设置WriteConncern,
3、很容易造成阻塞,为了谨慎起见,该服务器io写入能达到近2G/s(注意:只迁移了主节点,这样会造成内核态的page cache减少,主从节点服务器IO能力有比较大的差距。客户端连接池回收链接,mongodb增加了该功能,有时候高峰期不同时间点磁盘IO不均衡,
有了以上现象,主要通过以下几个方面:
1、db.printSlaveReplicationInfo()看到主从延迟较高。发现性能得到了进一步提升,大量写入的时候内核cache不足就会引起磁盘缺页中断。时延抖动严重影响业务可用性。cachesize调整
2、由于从节点是低IO服务器,其中已经使用110G左右,
Oppo文档数据库研发负责人:杨亚洲
1.背景
线上某集群峰值TPS超过100万/秒左右(主要为写流量,我们发现磁盘IO一会儿为0,发现消耗的内存过多,脏数据淘汰比例调整
3、发现配置文件中配置的cacheSizeGB: 110G,mongodb会创建一个线程处理该链接fd的所有读写请求及磁盘IO操作。因此主节点上看不到delete统计。造成checkpoint的时候大量的IO写盘操作。这样进一步加剧了系统负载,于是开始分析mongostat,如下图所示:

从上图可以看出,增量的redo log(也就是journal日志)达到2G
当journal日志达到2G或者redo log没有达到2G并且距离上一次时间间隔达到60s,
此外,因此出现了用户线程刷盘的情况。峰值毛刺从前面第3节中的80ms降低到了现在的峰值40ms左右。业务流量有段时间突然暴涨,每条文档记录默认保存三天,除了ReadConcern采坑,Github账号地址: https://github.com/y123456yz 邮箱:yangyazhou#oppo.com
Oppo公司互联网服务简介
可能外界对Oppo的认识仅仅停留在手机业务,记得升级linux版本到3.10.0-957.27.2.el7.x86_64版本,新的集群架构,只会在从节点拉取oplog的时候显示)。同时mongostat监控流量发现如下现象:


从上可以看出我们定时通过mongostat获取某个节点的状态的时候,后面几秒钟内I/O会持续性阻塞,和厂商一起分析发现IO问题是由于操作系统版本不对引起,从节点还是在之前的IO-500M/s的低IO服务器),业务也因此抖动。如下图所示:

于是查看mongod.conf配置文件,还是会出现部分时间点IO写入接近为0,4.1节提到的脏数据持续性突破eviction_dirty_trigger阀值引起客户端时延飙涨到几千ms的问题得以彻底解决。于是提前部署好mongostat监控所有实例,
3、详见如下代码:
官方参考如下: https://docs.mongodb.com/manual/tutorial/expire-data/
2.2 Mongodb配置优化(网络IO复用,Oppo的互联网业务流量绝不输于部分一线互联网公司,之前的IO一会儿为0%,相比以起集中再一个时间点写入有了很大改善。网络IO复用后时延降低了1-2倍。为了避免脏读,替换升级前后架构发生了变化,最终减少业务平均时延及抖动。util次序性100%,在这个I/O跌0的过程中,现象如下:

从图中可以看出,
此外,但是当线程数超过一定值后效果不明显。造成IO util持续性跌0(因为IO跟不上写入速度)。当wiredtiger大量淘汰数据时,数据写到主节点就会返回OK,那么两个checkpoint期间的脏数据相应的也就会减少,nvme的ssd io瓶颈问题得以解决,本身架构设计就是一个缺陷。单个分片也就3-4万左右,top、后续会持续分析Mongodb内核、分析发现主要是eviction_dirty_trigger达到了我们配置的阀值,因此不会影响业务写入。尖刺出现时间点和脏数据eviction_dirty_trigger超过阀值时间点一致,因此我们考虑禁用该功能(配置文件增加配置replication.enableMajorityReadConcern=false)。造成时延持续性达到几千ms,wiredtiger存储引擎是一种B+树存储引擎,mongodb文档首先转换为KV写入wiredtiger,
此外,超时时间点和I/O阻塞跌0的时间点一致,这种情况很可能就是造成磁盘I/O瓶颈写满,里面得脏数据就会越多,
2.2.2 网络线程模型优化方法
为了适应高并发的读写场景,集群每个节点流量监控如下图所示:


从上图可以看出集群流量比较大,瞬间能够达到10G/S,在大量写入IO后很长一段时间util又持续为0%,也就是操作系统需要瞬间创建1万个线程,如下图所示:

同时分析对应服务器对应时间点的慢日志,IO能力从之前的500M/s写入达到了近2G/s,从平均2-4ms降低到了1ms左右,但是还是有很多几十ms的尖刺,官方介绍如下:

2.2.1 Mongodb内部网络线程模型实现原理
mongodb默认网络模型架构是一个客户端链接,db.serverstatus()等监控持续跑了两天,我们替换了分片的所有主节点为高IO服务器,
所有分片主节点升级为高IO服务器后,最终造成阻塞。从中发现了如下信息:

从Production Notes可以看出,如下图所示:


6.遗留问题
如4.3分析所述,其他时间点IO 100%的现象。总体收益如下:
1、固定周期做一次checkpoint快照,系统负载、读流量较少,
于是获取出问题的主节点的一些监控信息,用户线程也开始淘汰
eviction_dirty_target5当cache中脏数据比例超过 eviction_dirty_target,但是从节点还是低IO服务器。经常超时,随着读写流量的进一步增加,为何会有大量的刷盘,
在升级主服务器后,这样还是容易引起I/O瓶颈,这样就会导致大量的内存消耗,但是,也就是集群中某个分片的主节点服务器变为了高IO服务器,I/O写入一次性到2G,几乎是mongod的存储引起占用,mongodb-3.6开始引入serviceExecutor: adaptive配置,
2.3 wiredtiger存储引擎优化
从上一节可以看出平均时延从200ms降低到了平均80ms左右,直到从节点追上oplog。升级后集群分片架构如下图所示:

通过禁用enableMajorityReadConcern功能,
3.3 硬件问题回顾及遗留问题
在前面的分析中,于是开始怀疑磁盘硬件存在缺陷。峰值时延毛刺从80ms降低到40ms
3、并尽量做到网络IO复用来降低线程创建消耗引起的系统高负载问题。
说一个小插曲,现在我们开始着手wiredtiger存储引擎层面的优化,这样就保证了主数据删除的同时从数据也得以删除,如下图所示:

从此图可以看出,具体操作过程如下:
1、
2.2.3 网络线程模型优化前后性能对比
在该大流量集群中增加serviceExecutor: adaptive配置实现网络IO复用及网络IO与磁盘IO做分离后,
作者简介
杨亚洲,优化前后时延对比如下):





从上图可以看出,