这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
今日学习 Redis
常见的使用目的是缓存 MySQL 中的数据,将从磁盘获取数据变成从内存获取数据。
- 读场景:先尝试去 Redis 读,如果没有再从 SQL 查询,并且同步 Redis
- 写场景:修改 SQL,之后监听 binlog 修改对应的 Redis 缓存
可以使用 RDB + AOF 进行数据持久化,但是只能是一种保险手段
dict 的 Rehash 和 渐进式 Rehash 必考
使用场景:
- 连续签到:必须每天十二点前签到,断签会归零连续签到次数,可以使用 Redis 的过期功能和计数 incr 功能
- 消息队列:使用 Redis 的 List 作为消息队列,List底层的 QuickList 一般面试必考,由一个双向链表和listpack组成
- 对象类型可以用 hash 存储,此时可以使用 Redis 的 Pipeline 减少网络传输,提高多条指令的执行效率
- 排行榜:对大量数据进行排序的操作,使用 ZSet 会比 SQL 快很多
- 限流:对一个请求对应的 key 调用 incr,如果在时间戳范围内超过规定次数则则禁止访问
- 分布式锁:使用 setnx 指令表示抢锁过程,但是要由业务自己释放锁,存在问题:业务超时解锁,执行时间超过锁超时时间;主备切换的问题;Redis 集群脑裂导致多个主节点的问题
使用的注意事项:
- 避免出现“大Key”,如果避免不了要进行拆分和压缩
- 对于“热key”可以设置 Localcache 减小对 Redis服务的请求压力;也可以写入多个 Key(加入随机后缀) 打入不同集群,但是会存在短暂不一致的问题;对 Redis 服务器加一个代理,相当于实现了 Localcache和“热key发现”两个功能
缓存穿透和缓存雪崩:
- 缓存穿透:热点数据查询绕过缓存,直接查询数据库
- 缓存雪崩:大量缓存同时过期
缓存穿透的场景一个是请求者故意请求一定不存在于 Redis 的key,或者同时间大量缓存失效让请求直接打到 DB;对于第一种可以设一个空值进行缓存,下层再查询直接返回空的结果,也可以使用 bloom 过滤器存储合法key
避免缓存雪崩可以采取在原本过期时间上加一个随机值,避免同时失效;也可以将热门数据设置很长的过期时间;还可以使用缓存集群,避免单机故障导致的缓存雪崩。