Redis使用细节(持续更新中)

ANewPro / 2023-08-25 / 原文

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

避免缓存雪崩的方法

  • 将缓存失效的时间分散开,比如在原有的失效时间基础上增加一个随机值
  • 使用缓存集群,避免单机宕机造成的缓存雪崩