redis缓存失效时,众所周知,如果不做保护自己放任请求去并发重新加载缓存,会导致大量请求直接打到数据库上,即出现缓存击穿问题。
项目组为了解决这个问题,使用了竞争获取锁刷新缓存的方式,应对缓存失效。
比如A B两个请求到达,在redis进行锁竞争,获取锁的线程开始查表刷缓存。获取不到锁的线程则开始通过循环sleep的方式,查询缓存是否刷新完毕,如果循环等待时间超过一定1秒,就放弃。
这样看起来很完美,实际上引起了Redis的性能问题
生产环境中,发现redis 的请求延迟和请求量均在2小时左右周期性出现波峰。
生产环境的服务器数量大概在两百台左右,对单key对象的接口请求qps大概峰值在1万,重新加载缓存需要的实际并不短,假如超过了1秒,理论上会带来10000*20的redis单key qps,已经超过了redis的单节点性能上线。
这个问题的启发:不要在请求中去把请求量放大。