为什么使用redis
改善性能。当大SQL执行耗时久,且结果不频繁变动,就特别适合将运行结果放入缓存,后面的请求从缓存中读取,使得请求能够迅速响应
缓解并发压力。大并发下,所有请求都是直接访问数据库的,会出现连接异常。redis做一个缓冲,让请求先访问redis,而不是数据库。redis缺点
1、缓存与数据库双写一致性问题
2、缓存雪崩问题(缓存同一时间大面积失效,这时又来了一波请求,结果请求都怼到数据库上,从而连接异常)
3、缓存击穿问题(黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而连接异常)
4、缓存的并发竞争问题redis的过期策略与内存淘汰机制
思考:为什么redis只能存5G,而你写了10G,redis怎么删除的。为什么设置过期时间,时间到了,内存占用率还是那么高
redis采用的是定期删除+惰性删除策略
定期删除不等于定时删除,定期删除是指redis默认100ms检查是否有过期的key,有则删除。但redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查,因此,只采用定期删除策略,会导致很多key到时间没有删除。惰性删除会在你获取key时,redis检查是否过期,如果过期,此时就会删除。
但是如果一直没有被删除(定期删除没有删,也没有被访问),则redis内存会越来越高,应该采用内存淘汰机制:在redis.conf中有一行配置:# maxmemory-policy volatile-lru
该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己)
1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。
2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。
3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。
4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐
解决缓存击穿问题
1、利用互斥锁,缓存失效的时候,先获得锁,得到锁了再请求数据库,没得到锁,则休眠一段时间重试
2、采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存过期,则异步起一个线程去读数据库,更新缓存,需要做缓存预热操作。
3、提供一个迅速判断请求是否有效的拦截机制解决雪崩问题
1、给换成的失效时间加上随机值,避免集体失效
2、使用互斥锁,但是该方案吞吐量明显下降了
3、双缓存
Redis学习笔记(五) 总结
点赞
收藏