这是我参与「第五届青训营 」伴学笔记创作活动的第15天。
2.5 限流
要求1秒内放行的请求为N,超过N则禁止访问
- Key:xxxxxx
- 对这个Key调用incr,超过限制N则禁止访问
- 1671356046是当前时间戳
2.6 分布式锁
并发场景,要求一次只能有一个协程执行。执行完成后,其他等待中的协程才能执行。
可以使用redis的setnx实现,利用了两个特性
- Redis是单线程执行命令
- setnx只有未设置过才能执行成功
3 Redis使用注意事项
3.1 大Key、热Key
| 数据类型 | 大Key标准 |
|---|---|
| String | value的字节数大于10KB |
| Hash/Set/Zset/list等复杂数据结构类型 | 元素个数大于5000个或总value字节数大于10MB |
大Key的危害
- 读取成本高
- 容易导致查询慢
- 主从复制异常、服务阻塞、无法正常响应请求
消除大Key的方法
- 拆分:将大Key拆分成小key。例如一个String拆分成多个String
- 压缩:将value压缩后写入redis,读取时解压后再使用。压缩算法可以是gzip, snappy, lz4等。如果存储的是JSON字符串,可以考虑使用MessagePack进行序列化。
- 集合类结构hash, list, set
- 拆分:可以用hash取余、位掩码的方法决定放在哪个Key中
- 区分冷热:如榜单列表场景用zset,只缓存前10页数据,后续数据走db
热Key:用户访问一个Key的QPS特别高,导致Server实例出现CPU负载突增或者不均的情况。
解决热Key的方法
- 设置Localcache
- 拆分:将key: value这一热Key复制多份写入,访问时访问多个Key,将qps分散到不同实例上。代价是,更新时需更新多个Key,存在数据短暂不一致的风险
- 使用Redis代理的热Key承载能力
3.2 慢查询场景
- 批量操作一次性传入过多key/value
- zset大小超过5k
- 操作的单个value过大
- 对大key的delete/expire
3.3 缓存穿透、缓存雪崩
缓存穿透:热点数据查询绕过缓存,直接查询数据库
缓存雪崩:大量缓存同时过期
缓存穿透的危害:
- 查询一个一定不存在的数据:因不会缓存不存在的数据,这类请求直接打到db,若有系统bug或人为攻击,容易导致db响应慢甚至宕机
- 缓存过期:热Key过期
减少缓存穿透:
- 缓存空值
- 布隆过滤器
减少缓存雪崩:
- 缓存空值
- 使用缓存集群,避免单机宕机造成的缓存雪崩