作者:Grey
原文地址: Redis学习笔记五:缓存常见问题
击穿
key的过期造成高并发访问数据库。
解决方案
使用Redis setnxt方法,加一把锁,只有这个人可以访问数据库,并把数据存入缓存,其他的流量就可以从缓存读取数据了。
- get key
- setnx
3-1 ok -> DB拿数据
3-2 false sleep -> 1
会导致的问题是:死锁
比如去DB拿数据的那个请求挂了,会导致死锁。
解决办法:设置锁的过期时间
但是如果没挂,但是锁到期了,但是超时了。
可以通过多线程来解决,一个线程取DB,另外一个线程监控是否取回来,更新锁时间。
以上问题会导致客户端的复杂度增加。引入zk。
穿透
查询一个根本不存在的key
解决方案
使用布隆过滤器,有两种实现方案:
- 客户端包含布隆过滤器
- 客户端只实现算法
- Redis集成布隆过滤器
布隆过滤器有缺点,只能增加,不能删除
可以改成布谷鸟过滤器
雪崩
设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案
如果对于过期时间要求不高,可以把原有的失效时间基础上增加一个随机值,比如1-5分钟随机。
如果对过期时间要求非常高,必须在某个时间过期,这个时候就必须要强依赖击穿方案,或者在业务层做一些延迟处理。
更多的说明见:
主从DB与cache一致性
Redis如何淘汰过期的keys
Redis keys过期有两种方式:被动和主动方式。
当一些客户端尝试访问它时,key会被发现并主动的过期。
当然,这样是不够的,因为有些过期的keys,永远不会访问他们。 无论如何,这些keys应该过期,所以定时随机测试设置keys的过期时间。所有这些过期的keys将会从密钥空间删除。
具体就是Redis每秒10次做的事情:
测试随机的20个keys进行相关过期检测。
删除所有已经过期的keys。
如果有多于25%的keys过期,重复步奏1.
这是一个平凡的概率算法,基本上的假设是,我们的样本是这个密钥控件,并且我们不断重复过期检测,直到过期的keys的百分百低于25%,这意味着,在任何给定的时刻,最多会清除1/4的过期keys。
Redis中布隆过滤器插件的安装和简明使用
- 访问RedisBloom的github并下载最新的Release Zip包:https://github.com/RedisBloom/RedisBloom/releases
- yum install unzip -y
- 通过unzip命令解压下载的插件包
unzip v2.2.4.zip
cd RedisBloom-2.2.4/
- 执行make
- 将make生成的so文件拷贝到redis的安装目录下:
cp redisbloom.so /opt/grey/redis6/
- 停止Redis,并执行
redis-server --loadmodule /opt/grey/redis6/redisbloom.so
即可加载布隆过滤器插件,加载后,通过redis-cli连接进来的客户端,可以通过bf开头的命令使用布隆过滤器。
[root@node1 RedisBloom-2.2.4]# redis-cli
127.0.0.1:6379> BF.ADD a b
(integer) 1
127.0.0.1:6379> BF.EXISTS a b
(integer) 1
127.0.0.1:6379> BF.EXISTS a x
(integer) 0