Redis 使用及注意事项 | 青训营

55 阅读4分钟

Redis是一种开源的高性能键值存储系统,它将数据存储在内存中以实现快速响应。Redis最常用的场景是将热数据存储在内存中,以提高读写操作的效率。

为什么需要Redis呢?主要有以下几个原因:

  1. 数据从单表演进到分库分表,数据量增长,读写压力不断增加,需要一个高效的数据存储系统来满足需求。
  2. MySQL等关系型数据库从单机演进到集群,但在某些场景下,关系型数据库的读写性能无法满足要求,因此需要引入Redis作为缓存层进行读写加速。
  3. Redis具有出色的性能,可以支持高并发的读写请求。

Redis的基本工作原理如下:

  1. 数据存储在内存中,通过内存的高速读写来实现快速响应。
  2. 为了防止重启导致数据丢失,Redis会将数据保存到硬盘上。增量数据会保存到AOF(Append Only File)文件中,而全量数据则保存在RDB文件中。
  3. Redis是单线程的,即所有操作命令都由同一个线程处理。这样能够确保操作的原子性,并避免多线程带来的竞争和安全性问题。

在使用Redis时,需要注意以下几点:

一、大Key和热Key

  1. 大Key是指在Redis中存储的数据量较大的Key。对于不同的数据类型,大Key的定义有所不同,例如对于String类型,如果其value的字节数大于10KB,则被认为是大Key;对于复杂数据结构类型(Hash/Set/Zset/List等),如果元素个数大于5000个或总value字节数大于10MB,则被认为是大Key。
  2. 大Key会导致读取成本高,并且容易导致慢查询、主从复制异常等问题,甚至会导致服务阻塞无法正常响应请求。
  3. 消除大Key的方法包括拆分和压缩。可以将大Key拆分为小Key进行存储,或者对value进行压缩后再写入Redis。

热Key是指在Redis中访问频率特别高的Key。热Key没有明确的标准,一般来说,如果一个Key的QPS超过500,则有可能被识别为热Key。

解决热Key的方法包括设置Localcache、拆分和使用Redis代理的热Key承载能力。可以在访问Redis之前,在业务服务侧设置Localcache来降低访问Redis的QPS;将热Key复制写入多份,进行拆分,将访问请求分散到不同的实例上,降低负载;使用具备热Key承载能力的Redis访问代理来处理热Key的访问请求。

二、慢查询场景 容易导致Redis慢查询的操作包括:

  1. 批量操作一次性传入过多的key/value,如mset/hmset/sadd/zadd等操作。建议单批次的操作不要超过100,否则性能会明显下降。
  2. 对Zset类型的操作,当Zset的大小超过5k时,简单的zadd/zrem操作也可能导致慢查询。
  3. 操作的单个value过大,超过10KB。因此应避免使用大Key。
  4. 对大Key的delete/expire操作也可能导致慢查询,特别是在Redis 4.0之前,不支持异步删除unlink,导致大Key删除时会阻塞Redis。

三、缓存穿透和缓存雪崩 缓存穿透指的是热点数据直接绕过缓存直接查询数据库的情况,而缓存雪崩是指大量缓存同时过期导致大量请求落到数据库上。

缓存穿透的危害主要体现在查询一个一定不存在的数据或缓存过期时,会有大量请求直接打到数据库上,影响数据库性能和稳定性。

为了减少缓存穿透,可以缓存空值或使用布隆过滤器来存储合法的Key。

为了避免缓存雪崩,可以将缓存失效时间分散开,例如在原有的失效时间基础上增加一个随机值,以此来分散过期时间;另外,使用缓存集群也可以避免单机宕机造成的缓存雪崩问题。

总结起来,使用Redis需要注意大Key和热Key的问题,避免产生慢查询操作,并且要防止缓存穿透和缓存雪崩的发生。