mongodb aggregate 性能优化_百万级高并发mongodb集群性能数十倍提升优化实践(上篇)...

1、背景

线上某集群峰值TPS超过100万/秒左右(主要为写流量,读流量很低),峰值tps几乎已经到达集群上限,同时平均时延也超过100ms,随着读写流量的进一步增加,时延抖动严重影响业务可用性。该集群采用mongodb天然的分片模式架构,数据均衡的分布于各个分片中,添加片键启用分片功能后实现完美的负载均衡。集群每个节点流量监控如下图所示:

be6d5d667ecf7d1959e46f5519c84840.png

5c04e3784bf2c6eddd51461519a64506.png

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

2.软件优化

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

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

2.1 业务层面优化

该集群总文档近百亿条,每条文档记录默认保存三天,业务随机散列数据到三天后任意时间点随机过期淘汰。由于文档数目很多,白天平峰监控可以发现从节点经常有大量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!"})

2.在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主节点触发,触发后主节点会直

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值