记一次redis带宽问题

问题

在压测一个查询接口时,此接口在查询mysql前会查询一次redis,tps始终不理想,通过扩展实例个数也不能解决问题,遂

问题排查

查看代码实现逻辑,发现在查询redis时为防止缓存击穿,所以加了一个10ms的锁,因为压测使用的参数只有一个,所以怀疑是因为大量查询同一个key由于锁的原因造成性能下降,为了验证这个问题把参数改为动态读取csv,csv中存储大量参数保证密集的请求中无重复参数,最终发现tps并没有什么变化。

排除了之前的参数因数,然后在压测过程中观察实例的cpu内存是否存在异常,但也没有发现异常。然后通过arms查看代码执行过程中是否存在问题,发现在连接redis的时间非常长,初步认为是因为redis内存过低的原因,但是加大redis内存并没有带来tps的提升

最终问题定位

最终发现压测过程中redis的带宽被打满了,然后取出接口每次请求redis获取的结果发现结果的大小达到了191kb,在高并发请求下每次接口被调用时都会先从redis获取数据而从redis获取的结果有非常大导致redis带宽被打满所以成为了性能的瓶颈。

问题解决

定位问题后也解决之前的一个困惑点,因为从前一年的接口压测数据显示,此接口tps非常高,一年间代码并没有任何改动但是接口的tps却下降的非常厉害,原因就是前一年的压测数据是此接口刚刚上线,接口的实现逻辑是当后台有新数据创建便会将新数据塞进一个json保存到redis,一年间创建了很多数据,但是大量数据都存储到一个json中,便导致了上述的问题,最终通过改变在redis中保存的数据结构由json改为map解决问题。

补充

在初期的问题定位中,一开始请求的参数在数据库中是不存在的,所以认为瓶颈在mysql,但是通过对mysql 的监控发现mysql的压力远没有达到官方64000qps的极限,所以增大mysql的连接池,但是性能反而下降了。由上述问题定位的原因不难发现,其实问题就在于查询mysql前会查一次redis,而redis的带宽就是此接口的瓶颈。

おすすめ

転載: juejin.im/post/7075562601018556453