首页 » 网站建设 » php110g技巧_百万级高并发mongodb集群机能数十倍提升优化实践

php110g技巧_百万级高并发mongodb集群机能数十倍提升优化实践

访客 2024-12-08 0

扫一扫用手机浏览

文章目录 [+]

从上图可以看出集群流量比较大,峰值已经打破120万/秒,个中delete过期删除的流量不算在总流量里面(delete由主触发删除,但是主上面不会显示,只会在从节点拉取oplog的时候显示)。
如果算上主节点的delete流量,总tps超过150万/秒。

软件优化

在不增加做事器资源的情形下,首先做了如下软件层面的优化,并取得了空想的数倍性能提升:

php110g技巧_百万级高并发mongodb集群机能数十倍提升优化实践

业务层面优化Mongodb配置优化存储引擎优化

2.1 业务层面优化

php110g技巧_百万级高并发mongodb集群机能数十倍提升优化实践
(图片来自网络侵删)

该集群总文档近百亿条,每条文档记录默认保存三天,业务随机散列数据到三天后任意韶光点随机过期淘汰。
由于文档数目很多,白天平峰监控可以创造从节点常常有大量delete操作,乃至部分韶光点delete删除操作数已经超过了业务方读写流量,因此考虑把delete过期操作放入夜间进行,过期索引添加方法如下:

Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

上面的过期索引中expireAfterSeconds=0,代表collection凑集中的文档的过期韶光点在expireAt韶光点过期,例如:

db.collection.insert( {

//表示该文档在夜间凌晨1点这个韶光点将会被过期删除

"expireAt": new Date('July 22, 2019 01:00:00'),

"logEvent": 2,

"logMessage": "Success!"

} )

通过随机散列expireAt在三天后的凌晨任意韶光点,即可规避白天高峰期触发过期索引引入的集群大量delete,从而降落了高峰期集群负载,终极减少业务均匀时延及抖动。

Delete过期Tips1: expireAfterSeconds含义

1. 在expireAt指定的绝对韶光点过期,也便是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秒过期,也便是当前韶光今后推迟60秒过期

db.log_events.insert( {"createdAt": new Date(),"logEvent": 2,"logMessage": "Success!"} )

Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 60 } )

Delete过期Tips2: 为何mongostat只能监控到从节点有delete操作,主节点没有?

缘故原由是过期索引只在master主节点触发,触发后主节点会直接删除调用对应wiredtiger存储引擎接口做删除操作,不会走正常的客户端链接处理流程,因此主节点上看不到delete统计。

主节点过期delete后会生存对付的delete oplog信息,从节点通过拉取主节点oplog然后仿照对付client回放,这样就担保了主数据删除的同时从数据也得以删除,担保数据终极同等性。
从节点仿照client回放过程将会走正常的client链接过程,因此会记录delete count统计,详见如下代码:

官方参考如下: https://docs.mongodb.com/manual/tutorial/expire-data/

2.2 Mongodb配置优化(网络IO复用,网络IO和磁盘IO做分离)

由于集群tps高,同时整点有大量推送,因此整点并发会更高,mongodb默认的一个要求一个线程这种模式将会严重影响系统负载,该默认配置不适宜高并发的读写运用处景。
官方先容如下:

2.2.1 Mongodb内部网络线程模型实现事理

mongodb默认网络模型架构是一个客户端链接,mongodb会创建一个线程处理该链接fd的所有读写要求及磁盘IO操作。

Mongodb默认网络线程模型不适宜高并发读写缘故原由如下:

1. 在高并发的情形下,瞬间就会创建大量的线程,例如线上的这个集群,连接数会瞬间增加到1万旁边,也便是操作系统须要瞬间创建1万个线程,这样系统load负载就会很高。

2. 此外,当链接要求处理完,进入流量低峰期的时候,客户端连接池回收链接,这时候mongodb做事端就须要销毁线程,这样进一步加剧了系统负载,同时进一步增加了数据库的抖动,特殊是在PHP这种短链接业务中更加明显,频繁的创建线程销毁线程造成系统高负债。

3. 一个链接一个线程,该线程除了卖力网络收发外,还卖力写数据到存储引擎,全体网络I/O处理和磁盘I/O处理都由同一个线程卖力,本身架构设计便是一个毛病。

2.2.2 网络线程模型优化方法

为了适应高并发的读写场景,mongodb-3.6开始引入serviceExecutor: adaptive配置,该配置根据要求数动态调度网络线程数,并只管即便做到网络IO复用来降落线程创建花费引起的系统高负载问题。
此外,加上serviceExecutor: adaptive配置后,借助boost:asio网络模块实现网络IO复用,同时实现网络IO和磁盘IO分离。
这样高并发情形下,通过网络链接IO复用和mongodb的锁操作来掌握磁盘IO访问线程数,终极降落了大量线程创建和花费带来的高系统负载,终极通过该办法提升高并发读写性能。

2.2.3 网络线程模型优化前后性能比拟

在该大流量集群中增加serviceExecutor: adaptive配置实现网络IO复用及网络IO与磁盘IO做分离后,该大流量集群时延大幅度降落,同时系统负载和慢日志也减少很多,详细如下:

2.2.3.1 优化前后系统负载比拟

验证办法:

该集群有多个分片,个中一个分片配置优化后的主节点和同一时候未优化配置的主节点load负载比较: 未优化配置的load

优化配置的load

2.2.3.2 优化前后慢日志比拟

验证办法:

该集群有多个分片,个中一个分片配置优化后的主节点和同一时候未优化配置的主节点慢日志数比较:

同一韶光的慢日志数统计:

未优化配置的慢日志数(19621):

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

2.2.3.3 优化前后均匀时延比拟

验证办法:

该集群所有节点加上网络IO复用配置后与默认配置的均匀时延比拟如下:

从上图可以看出,网络IO复用后时延降落了1-2倍。

2.3 wiredtiger存储引擎优化

从上一节可以看出均匀时延从200ms降落到了均匀80ms旁边,很显然均匀时延还是很高,如何进一步提升性能降落时延?连续剖析集群,我们创造磁盘IO一下子为0,一下子持续性100%,并且有跌0征象,征象如下:

从图中可以看出,I/O写入一次性到2G,后面几秒钟内I/O会持续性壅塞,读写I/O完备跌0,avgqu-sz、awit巨大,util次序性100%,在这个I/O跌0的过程中,业务方反应的TPS同时跌0。

此外,在大量写入IO后很长一段韶光util又持续为0%,征象如下:

总体IO负载曲线如下:

从图中可以看出IO很长一段韶光持续为0%,然后又飙涨到100%持续很永劫光,当IO util达到100%后,剖析日志创造又大量满日志,同时mongostat监控流量创造如下征象:

从上可以看出我们定时通过mongostat获取某个节点的状态的时候,常常超时,超时的时候刚好是io util=100%的时候,这时候IO跟不上客户端写入速率造成壅塞。

有了以上征象,我们可以确定问题是由于IO跟不上客户端写入速率引起,第2章我们已经做了mongodb做事层的优化,现在我们开始动手wiredtiger存储引擎层面的优化,紧张通过以下几个方面:

cachesize调度脏数据淘汰比例调度checkpoint优化

2.3.1 cachesize调度优化(为何cacheSize越大性能越差)

前面的IO剖析可以看出,超时时间点和I/O壅塞跌0的韶光点同等,因此如何办理I/O跌0成为理解决改问题的关键所在。

找个集群平峰期(总tps50万/s)查看当时该节点的TPS,创造TPS不是很高,单个分片也就3-4万旁边,为何会有大量的刷盘,瞬间能够达到10G/S,造成IO util持续性跌0(由于IO跟不上写入速率)。
连续剖析wiredtiger存储引擎刷盘实现事理,wiredtiger存储引擎是一种B+树存储引擎,mongodb文档首先转换为KV写入wiredtiger,在写入过程中,内存会越来越大,当内存中脏数据和内存总占用率达到一定比例,就开始刷盘。
同时当达到checkpoint限定也会触发刷盘操作,查看任意一个mongod节点进程状态,创造花费的内存过多,达到110G,如下图所示:

于是查看mongod.conf配置文件,创造配置文件中配置的cacheSizeGB: 110G,可以看出,存储引擎中KV总量险些已经达到110G,按照5%脏页开始刷盘的比例,峰值情形下cachesSize设置得越大,里面得脏数据就会越多,而磁盘IO能力跟不上脏数据得产生速率,这种情形很可能便是造成磁盘I/O瓶颈写满,并引起I/O跌0的缘故原由。

此外,查看该机器的内存,可以看到内存总大小为190G,个中已经利用110G旁边,险些是mongod的存储引起占用,这样会造成内核态的page cache减少,大量写入的时候内核cache不敷就会引起磁盘缺页中断,引起大量的写盘。

办理办法:通过上面的剖析问题可能是大量写入的场景,脏数据太多随意马虎造成一次性大量I/O写入,于是我们可以考虑把存储引起cacheSize调小到50G,来减少同一时候I/O写入的量,从而规避峰值情形下一次性大量写入的磁盘I/O打满壅塞问题。

2.3.2 存储引擎dirty脏数据淘汰优化

调度cachesize大小办理了5s要求超时问题,对应告警也消逝了,但是问题还是存在,5S超时消逝了,1s超时问题还是偶尔会涌现。

因此如何在调度cacheSize的情形下进一步规避I/O大量写的问题成为了问题办理的关键,进一步剖析存储引擎事理,如何办理内存和I/O的平衡关系成为了问题办理的关键,mongodb默认存储由于wiredtiger的cache淘汰策略干系的几个配置如下:

调度cacheSize从120G到50G后,如果脏数据比例达到5%,则极度情形下如果淘汰速率跟不上客户端写入速率,这样还是随意马虎引起I/O瓶颈,终极造成壅塞。

办理办法: 如何进一步减少持续性I/O写入,也便是如何平衡cache内存和磁盘I/O的关系成为问题关键所在。
从上表中可以看出,如果脏数据及总内占用存达到一定比例,后台线程开始选择page进行淘汰写盘,如果脏数据及内存占用比例进一步增加,那么用户线程就会开始做page淘汰,这是个非常危险的壅塞过程,造成用户要求验证壅塞。
平衡cache和I/O的方法: 调度淘汰策略,让后台线程尽早淘汰数据,避免大量刷盘,同时降落用户线程阀值,避免用户线程进行page淘汰引起壅塞。
优化调度存储引起配置如下:

eviction_target: 75%

eviction_trigger:97%

eviction_dirty_target: %3

eviction_dirty_trigger:25%

evict.threads_min:8

evict.threads_min:12

总体思想是让后台evict只管即便早点淘汰脏页page到磁盘,同时调度evict淘汰线程数来加快脏数据淘汰,调度后mongostat及客户端超时征象进一步缓解。

2.3.3 存储引擎checkpoint优化调度

存储引擎得checkpoint检测点,实际上便是做快照,把当前存储引擎的脏数据全部记录到磁盘。
触发checkpoint的条件默认又两个,触发条件如下:

固定周期做一次checkpoint快照,默认60s增量的redo log(也便是journal日志)达到2G

当journal日志达到2G或者redo log没有达到2G并且间隔上一次韶光间隔达到60s,wiredtiger将会触发checkpoint,如果在两次checkpoint的韶光间隔类evict淘汰线程淘汰的dirty page越少,那么积压的脏数据就会越多,也便是checkpoint的时候脏数据就会越多,造成checkpoint的时候大量的IO写盘操作。
如果我们把checkpoint的周期缩短,那么两个checkpoint期间的脏数据相应的也就会减少,磁盘IO 100%持续的韶光也就会缩短。

checkpoint调度后的值如下:

checkpoint=(wait=25,log_size=1GB)

2.3.4 存储引擎优化前后IO比拟

通过上面三个方面的存储引擎优化后,磁盘IO开始均匀到各个不同的韶光点,iostat监控优化后的IO负载如下:

从上面的io负载图可以看出,之前的IO一下子为0%,一下子100%征象有所缓解,总结如下图所示:

2.3.5 存储引擎优化前后时延比拟

优化前后时延比拟如下(注: 该集群有几个业务同时利用,优化前后时延比拟如下):

从上图可以看出,存储引擎优化后韶光延迟进一步降落并趋于平稳,从均匀80ms到均匀20ms旁边,但是还是不完美,有抖动。

3 做事器系统磁盘IO问题办理

3.1 做事器IO硬件问题背景

如第3节所述,当wiredtiger大量淘汰数据后,创造只要每秒磁盘写入量超过500M/s,接下来的几秒钟内util就会持续100%,w/s险些跌0,于是开始疑惑磁盘硬件存在毛病。

从上图可以看出磁盘为nvMe的ssd盘,查看干系数据可以看出该盘IO性能很好,支持每秒2G写入,iops能达到2.5W/S,而我们线上的盘只能每秒写入最多500M。

3.2 做事器IO硬件问题办理后性能比拟

于是考虑把该分片集群的主节点全部迁移到另一款做事器,该做事器也是ssd盘,io性能达到2G/s写入(把稳:只迁移了主节点,从节点还是在之前的IO-500M/s的做事器)。
迁移完成后,创造性能得到了进一步提升,时延迟降落到2-4ms/s,三个不同业务层面看到的时延监控如下图所示:

从上图时延可以看出,迁移主节点到IO能力更好的机器后,时延进一步降落到均匀2-4ms。

虽然时延降落到了均匀2-4ms,但是还是有很多几十ms的尖刺,鉴于篇幅将不才一期分享大家缘故原由,终极保存所有时延掌握在5ms以内,并肃清几十ms的尖刺。

此外,nvme的ssd io瓶颈问题缘故原由,经由和厂商确认剖析,终极定位到是linux内核版本不匹配引起,如果大家nvme ssd盘有同样问题,记得升级linux版本到3.10.0-957.27.2.el7.x86_64版本,升级后nvme ssd的IO能力达到2G/s以上写入。

4 总结及遗留问题

通过mongodb做事层配置优化、存储引擎优化、硬件IO提升三方面的优化后,该大流量写入集群的均匀时延从之前的均匀数百ms降落到了均匀2-4ms,整体性能提升数十倍,效果明显。

但是,从4.2章节优化后的时延可以看出,集群偶尔还是会有抖动,鉴于篇幅,下期会分享如果肃清4.2章节中的时延抖动,终极保持韶光完备延迟掌握在2-4ms,并且无任何超过10ms的抖动,敬请期待,下篇会更加精彩。

此外,在集群优化过程中采了一些坑,下期会连续剖析大流量集群采坑记。

标签:

相关文章

php为无色透明技巧_水货钻石其实也还行

从各种钻石中,可以看到大大小小的“包裹体” 图片来源:参考文献包裹体的种类多样。比钻石形成更早的包裹体,叫“原生包裹体”;与钻石同...

网站建设 2024-12-19 阅读0 评论0

phpstudy发送gbk技巧_php的文件上传

这里首先声明一下这一章的内容比较多,比较难,你要抱着和自己去世磕的态度。细微之处不放过,多敲多练是王道。 学习就像爬山,得一步一步...

网站建设 2024-12-19 阅读0 评论0