深入理解 Redis | 青训营笔记

36 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第13天

Redis,作为以性能著称的KV数据库,在实际业务中使用已经非常广泛。如果没有Redis做缓存,Mysql很难能够承载那么大的请求量。

为什么需要Redis

数据分冷热,将热数据放在内存当中。

Redis基本工作原理

  • 数据从内存中读写
  • 数据保存到硬盘上防止重启数据丢失
    • 增量数据保存到AOF文件
    • 全量数据RDB文件
  • 单线程处理所有操作命令

Redis那么快,除了单线程、基于内存等,还有它特殊的数据结构。

Redis应用实例

连续签到

  • 在Redis中设置一个值,后天的0点过期
  • String数据结构,sds,使用在存储计数、Session

消息通知

用list作为消息队列

  • 使用场景:消息通知
  • List数据结构:Quicklist
    • 由一个双向链表和listpack实现

计数

一个用户有多项计数需求,可通过hash结构存储

  • Hash数据结构dict
  • rehash:迁移某一个哈希节点下的值到另一个节点,数据量大时会阻塞用户请求
  • 渐进式rehash:每次用户访问都迁移少量数据,平摊所有的迁移开销

排行榜

积分变化时,排名要实时变更

  • zset数据结构,zskiplist跳表
  • 结合dict后,可实现通过key操作跳表

限流

要求1秒内放行的请求为N,超过N禁止访问

利用当前时间戳构造一个key,对这个key调用incr,实现访问计数。

分布式锁

并发场景,要求一次只能有一个协程执行。执行完成后,其它等待中的协程才能执行。

可以使用redis的setnx实现,利用了两个特性

  • Redis单线程执行命令
  • setnx只有未设置过才能执行成功

但这并不是高可用的实现,因为可能会被超时的任务阻塞。

Redis使用注意事项

大Key,热Key

数据类型大key标准
String类型value的字节数大于10KB
Hash/Set/Zset/list等复杂数据结构类型元素个数大于5000个或总value字节数大于10MB
  • 读取成本高
  • 容易导致慢查询
  • 主从复制异常,服务阻塞无法正常响应请求

消除大Key的方法

  1. 拆分
  2. 压缩
  3. 集合类结构
    1. 拆分
    2. 区分冷热

热Key解决方法:

  1. 设置Localcache
  2. 拆分
  3. 使用Redis代理的热Key承载能力,实际上是结合了:
    1. 热Key发现
    2. LocalCache

慢查询场景

  1. 批量操作一次性传入过多key/value
  2. 大key

缓存穿透、缓存雪崩

缓存穿透:热点数据查询绕过缓存,直接查询数据库

  1. 查询一个一定不存在的数据
  2. 缓存过期时

减少方法:

  1. 缓存空值
  2. 布隆过滤器

缓存雪崩:大量缓存同时过期

  1. 分散缓存失效时间
  2. 使用缓存集群,避免单机宕机导致缓存雪崩