参考文章
引言
之前在项目中用到redis时,复习了一遍redis的一些知识;最近感觉要把使用redis时遇到的问题总结一下了
缓存一致性问题
假设场景:
a. 用户登录时将 权限缓存在redis中
b. 管理员将用户其中一个权限 删掉了
c. 更新sql 数据库 删除缓存
==更新策略==:先更新数据库 再删除缓存
这种更新套路
老外提出了一个缓存更新套路,名为《Cache-Aside pattern》。其中就指出
知名社交网站facebook也在论文
中提出,他们用的也是先更新数据库,再删缓存的策略。
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效
如果sql 数据库 更新成功 但是删除缓存有问题怎么办
1.重试机制,如果代码写的没有问题 可能是网络问题等 ;重试几次 如果还是删除失败 说明服务器所处的环境也是有问题的
2.读取数据库的变更日志(binlog日志)
缓存穿透
例如:黑客故意请求缓存中不存在的数据,导致所有请求直接到达了数据库
1.提供一个迅速判断请求是否有效的拦截机制,比如布隆过滤器,维护一系列合法有效的key,迅速判断请求是否有效
参考文章中还有其他的方法,但是都感觉不好
2.互斥锁,缓存无效的时候,先获取锁,才能去请求数据库;获取不到锁则休眠一段时间再试,明显会降低吞吐量
3.异步更新策略,无论key是否能拿到值,都直接返回。如果缓存无效了,异步起线程读数据库,更新缓存(其实还是到达了数据库)。 对于有效key做预热处理
缓存雪崩
例如:即缓存有大面积失效,同时来了一大波请求直接到达数据库,导致数据库连接异常
1.互斥锁
2.双缓存。缓存A设置过期时间, 缓存B不设置。需要做缓存预热
A缓存大面积失效,同时大量请求达到
从A中拿数据,有直接返回
A中没有,从B中拿(肯定能拿到),异步起线程更新A/B中数据
更新缓存时同时更新A/B
并发竞争key问题
当有多个系统同时set一个key 的情形 (暂时自己还没有遇到这种问题)
2.如果对key操作,不要求顺序
比如 按先后顺序 a设置为 a1 b设置为 b1 c设置为c1
网友评论