Redis使用细节
分布式锁
因为Redis是单线程的,所以可以用setnx来模拟锁的获取释放从而实现分布式锁
在用setnx实现分布式锁时,会出现一些问题
- 业务超时解锁,导致并发问题。业务执行时间超过了锁超时的时间
- redis主从切换临界点问题,主从切换后,A持有的锁还没有同步到新的主节点,B在新的主节点获取到了锁
- redis集群脑裂,导致出现多个主节点
大key和热key
大key定义
-
String类型:value的字节数大于10KB即为大Key
-
Hash/Set等复杂结构类型:元素个数大于5000个或总value字节数大于10M即为大key
大key危害
- 读取成本高
- 容易导致慢查询
- 主从复制异常,服务阻塞,无法正常响应请求
消除大key的方法
1.拆分
将大key拆分为小key,例如一个String拆分成多个String
2.压缩
将value压缩后写入Redis,读取时解压后再用,注意选择一个合适的算法
3.集合类结构hash消除的方法
- 拆分,用hash取余,位掩码的方式决定放在哪个key中
- 区分冷热:比如榜单列表场景使用zset,只缓存前10页数据,后续的数据走db
热key定义
用户访问一个key的QPS特别高,导致server出现CPU负载突增或者不均的情况,热key没有明确的标准,一般QPS超过500就有可能被识别为热Key
解决热Key的方法
1.设置Localcache
在访问Redis前,在业务侧设置Localcache,降低访问Redis的QPS,如果Localcache过期或者未命中,则从Redis中将数据更新到LocalCache
2.拆分
将一个热key复制写入多份,访问的时候访问多个key,但是value是同一个,但是代价是更新时需要更新多个key
慢查询场景
容易导致慢查询的操作
-
批量操作一次性传入过多的key/value,如mset/hmset等操作,建议单批次不要超过100
-
zset大部分命令都是O(logn),当大小超过5k以上时,简单的zadd/zerm也可能导致慢查询
-
操作大key
缓存穿透和缓存雪崩
缓存穿透:热点数据查询绕过缓存,直接查询数据库
缓存雪崩:大量缓存同时过期
缓存穿透的危害:
- 查询一个一定不存在的数据,这样的所有请求都会打到db上
- 缓存过期时,一个热key过期,也会有大量的请求同时击穿至db
减少缓存穿透的方法
- 缓存空值,在查询到在缓存和数据库中都不存在,则可以缓存一个空值
- 布隆过滤器,使用一个算法来存储合法key
避免缓存雪崩的方法
- 将缓存失效的时间分散开,比如在原有的失效时间基础上增加一个随机值
- 使用缓存集群,避免单机宕机造成的缓存雪崩