likes
comments
collection
share

数据库QPS调优,好像也没那么难

作者站长头像
站长
· 阅读数 47

背景 

DBA提示近期凌晨mongo数据库集群QPS指标告警(具体指标为从每天凌晨1点到6点的QPS维持在1.4w-1.5w)急需要排查解决,否则很有因QPS持续过高造成集群产生死锁和脑裂进而导致集群宕机风险。

分析

从DBA给过来的具体的各项指标来看,造成数据库QPS居高不下的原因主要是在凌晨1点有两个大表在同时写入。经排查,是大数据组每天凌晨会触发定时任务,通过kafka做全量数据投递,单独的kafka消费项目通过消费kafka里的全量数据,入库,做save操作,实现大数据量的T+1 日更新。其中两个大表的的数据量平均一天7000w和4000w。

解决

从数据源头层面

增加业务类型过滤,代码逻辑里面只消费指定业务类型的数据。

错峰投递数据,大数据组凌晨1点开始一个定时投递任务,凌晨3点开始另外一个定时投递任务。

从数据消费层面

修改kafka的max.poll.records属性值,从原来的100降到20,面对同一批待消费的数据,通过减小单次批量获取的数量,来提升批量获取的次数,进而增加数据传输的网络消耗,延长整体消费时间,降低数据库平均QPS。

从数据限流层面

借助hutool的ThreadUtil在各个需要消费的Topic里面增加一个限流工具,比如可以指定在持续消费某Topic的数量达到某一阈值时,手动让线程sleep多少秒。注意不能超过kafka的max.poll.interval.ms设置的时间(当时设置的是600s),不然会造成kafka的rebalance,代码如下:

/**
 * 限流
 *
 * @param atomicLong
 * @param sleepMills
 * @param limitSize
 * @param addSize
 */
public static void currentLimit(AtomicLong atomicLong, long sleepMills, int limitSize, int addSize) {
	if (atomicLong.get() >= limitSize) {
		ThreadUtil.safeSleep(sleepMills);
		atomicLong.set(0);
	}
	atomicLong.addAndGet(addSize);
}

优化后效果

数据在凌晨1点开始错峰投递,凌晨5点前可以消费完。

QPS 下降至1k-2k,是优化前QPS的10%,优化效果明显。

思考

在弄清楚数据流向的来龙去脉之后,其实这类问题运用一些简单的理性思维很好解决。

就像初中时的一道物理题一样

问:减少噪音的三种方法是什么?

答:在声源处控制,在噪声传播途中控制,在人耳处减弱噪声。

转载自:https://juejin.cn/post/7241101553712218171
评论
请登录