by shihang.mai
1. redis缓存雪崩
大量的key同一时间消失,导致关于这些key的请求全部到库
1.1 项目
我们会将设备的数据晚上0点执行定时任务刷新到redis,并设置key的失效时间=30小时,不知道什么原因,当时只更新了一部分数据,直接导致30h时导致大量的key失效,所有获取设备信息的请求打到库上。导致其他业务好慢
1.2 解决方法
- 将失效时间随机
- 在redis-server log显示
redis cannot allocate memory
后面查到了原因,是redis持续插入大量数据时,一直向liunx拿内存,到超过一定值时,就分配内存失败,导致只更新了一部分。设置linux系统参数vm.overlimt_menoy = 1就解决了。
- vm.overlimt_menoy = 1:直接分配内存
- vm.overlimt_menoy = 0或者=2,超过一定值就分配失败。当然值是根据不同的公式来的,具体忘记了
为什么没触发默认的回收策略?
猜的:首先,我们没限制redis的内存。没设置,并不会触发淘汰策略。
2. redis缓存击穿
某一个key失效,导致关于这个key的请求全部到库
2.1 项目
某一个设备当天特别多告警,云公司大量运维人员同一时间请求这个key,导致全部请求打到库中,导致其他业务好慢.虽然我们并发量不大,但是查询出来的信息,需要关联多个表。
2.2 解决方法
- 当发现这个key失效时,其中一个线程setnx设置key并设置过期时间(分布式锁),去库中获取数据,并写到redis。
- 其他线程等待,等锁释放后,直接取缓存中的数据
当然redis作分布式锁有很多问题:
- 无法精确估计TTL时间
- 单点redis的话还有设置时redis挂的问题
- 就算是哨兵,当我setnx key的时候,还没同步给salve,master已经down掉,主从切换,又会导致key并没存在在redis中
- 用红锁,java STW时,又会导致锁失效
- 我还是建议分布式锁用zk,zk临时节点就是一个session并有也支持序列节点,又有watch机制、zab协议快速恢复集群状态。用它不香吗
3. redis缓存穿透
查找一个不存在的key,直接将这个请求到数据库
3.1. 项目
当时阿里投诉给云公司,承载它们虚拟机的主机down了,怎么没人立刻维修,因为这个投诉算是云公司的重大投诉,大量的运维人员都去查这个设备,然后其他运维人员发现系统好慢。后面查找原因,发现这个设备根本没在系统纳管,redis缓存中和库根本没,而这个设备信息需要关联大量表。
3.2 解决
即使数据库查询到的数据为null时候也写缓存。但是把缓存的过期时间设置短一点,比如1分钟,过期了再走一遍数据库查询数据是否存在
网友评论