Redis有三种删除策略:
1.定时删除:
创建一个定时器,当key设置有过期时间,且过期时间到达时,立即执行key的删除操作
- 优点:节约内存,到时就删除,立即释放不必要的内存占用
- 缺点:CPU压力较大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
- 总结:用处理器性能换取存储空间(时间换空间),适用于小内存,强CPU场景
2.惰性删除:
数据到达过期时间,不做处理。等下次访问该数据时,如果未过期,返回数据。如果已过期,删除,返回不存在。
- 优点:节约CPU性能,发现不得不删除的时候才删除
- 缺点:内存空间压力很大,出现长期占用内存的数据
- 总结:用存储空间换取处理器性能 (空间换时间),适用于大内存,弱CPU场景
3.定期删除:
每个库都有独自维护的过期库expires
定期删除的优点在于CPU性能占用设置有峰值,检测频度可自定义,内存压力和CPU压力都不大。但是仅仅是通过给key设置时长还是有问题的,因为还是有很多过期key堆积在内存中,容易引起内存不足。那么如何解决这方面的问题呢?就是Redis的内存淘汰机制(逐出算法)。
Redis使用内存存储数据,在执行每一个命令前,会调用FreeMemoryIFNeeded()检查内存是否充足,如果内存不满足新加入数据的最低存储要求,redis要删除一些数据为清理空间。清理的策略被称为逐出算法:
Redis目前有8种逐出策略:
1.volatile-lru:从已设置过期时间的数据中,挑选最近最少使用的数据淘汰。(针对时间)
2.volatile-lfu:从已设置过期时间的数据中,挑选最近使用次数最少的数据淘汰。(针对访问频率)
3.volatile-ttl:从已设置过期时间的数据中,挑选快要过期的数据。
4.volatile-random:从已设置过期时间的数据中,任意选择数据淘汰。
5.allkeys-lru:在所有的key中,移除最近最少使用的key。
6.allkeys-lfu:在所有的key中,移除最近使用次数最少的key。
7.allkeys-random:任意挑选数据淘汰。
8.no-eviction:禁止驱逐数据(Redis4.0默认策略)。
需要注意的时,逐出过程并不是100%的能够清理出足够的空间,如果不成功反复执行,在所有数据都尝试完毕后,如果还是不能满足内存清理的要求,将会出现错误信息。
(error) OOM command not allowed when used memory >'maxmemory'
处理数据删除,需要注意的还有缓存的一些问题。
分别有
缓存预热:在系统启动前,提交将相关的缓存数据直接加载到缓存系统,避免在用户请求的时候,先查数据库,然后再缓存数据的问题,
缓存雪崩:大面积key同一时间失效,所有请求直接落在数据库上,造成数据库压力过大,可能导致服务器宕机。
解决方案:1.更多的页面静态化处理;
2.构造多级缓存
3.灾难预警机制
4.限流,降级(短时间牺牲客户体验,限制一部分请求,降低服务器压力,待业务低速运转后,再逐步放开)
5.删除策略进行切换(lru->lfu)
6.数据分类,有效期策略调整(稀释集中到期的key的数量)
7.超热数据 永久key
缓存击穿:某个热点key过期,大量请求落在服务器。
解决方案:1.二级缓存
2.设置永久key
3.延长过期时间,待访问量降低后移除
缓存穿透:redis出现大面积未命中(请求的key不在redis中,直接落在服务器)
解决方案:1.布隆过滤器
2.缓存null
3.做好参数校验
4.实时监控(redis的命中率)
5.key加密(不满足直接驳回)