Redis入门指南:基础概念和注意事项总结 | 青训营

179 阅读5分钟

Redis

数据结构

  • key 都是字符串类型
  • value 有5种数据类型,分别是:String、Hash、List、Set、Zset

数据操作

  • 字符串类型(String):GET/SET/DEL/INCR/SETNX
  • 哈希类型(Hash):HSET/HGET/HINCRBY
  • 列表(List):LPUSH/RPOP/LRANGE
  • 有序集合类型(Zset):ZADD/ZRANGEBYSCORE/ZREVRANGE/ZINCRBY/ZSCORE

过期策略

过期即失效,但不等于删除,有三种过期策略,Redis只使用了定期过期和惰性过期两种

  • 定时删除:立即删除过期的key

    设置过期时间的同时,为该key创建一个定时器,key过期时立即进行删除

    内存释放最及时,但CPU占用最多,当key很多时,需要创建和维护大量定时器

  • 惰性删除:只有当访问key时才去检查key是否过期,过期了则删除

    CPU占用最少,但内存释放最不及时,当大量key过期却没有被访问时,会造成无效的内存占用

  • 定期删除:每隔一段时间对过期的key进行删除

    限制了删除时长和频率,CPU占用较少,内存释放较及时

内存淘汰策略

当内存不足以执行写入操作时,使用淘汰策略:

  • volatile-lru:在设置了过期时间的键空间中,使用LRU策略
  • allkeys-lru:在整个键空间中,使用LRU策略(最常用)
  • volatile-lfu:在设置了过期时间的键空间中,使用LFU策略
  • allkeys-lfu:在整个键空间中,使用LFU策略(最常用)

持久化机制

为了避免数据丢失了,Redis提供了RDBAOF两种持久化机制,把数据保存到磁盘。

RDB快照持久化

RDB 把内存数据以快照形式保存到磁盘上,每次将内存中的数据集快照写入磁盘中,在指定目录下生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据

  • 手动触发(一般不会用): save:同步,会阻塞当前redis服务进行持久化操作 bgsave :异步,Redis进程执行fork操作创建子进程进行持久化操作
  • 自动触发: save m n (m秒内数据集存在n次修改,自动触发bgsave)

RDB 适合大规模的数据恢复场景,如备份,全量复制等,异步可以可以最大化性能,速度比 AOF 的恢复速度快,但不能做到实时持久化

Redis默认开启

持久化时,过期的key不会被写入文件,恢复数据时,过期的key不会被导入内存

AOF追加文件持久化

AOF(Append Only File) 持久化,采用日志来记录每个写操作,追加到文件中,重启时再重新执行AOF文件中的命令来恢复数据,主要解决数据持久化的实时性问题,来保证数据的一致性和完整性,但当记录内容增多时,文件变大,数据恢复速度变慢。

默认不开启,可以通过配置项开启,且允许同时开启AOF和RDB

过期的key不会被持久化,过期的key被删除时,向AOF文件追加一条del命令

注意事项

  • 大Key: key 对应的value占用字节数特别多

    • 读取成本高
    • 容易导致慢查询(过期、删除)或请求超时
    • 主从复制异常,服务阻塞,无法正常响应请求

    解决办法

    • 将大key拆分为小key

    • 数据压缩,将value压缩后写入redis,读取时解压后再使用。压缩算法可以是gzip、snappy、lz4等, 如果存储的是JSON字符串,可以考虑使用MessagePack进行序列化。

      通常压缩率高,解压耗时就长

    • 区分冷热,热数据缓存在内存中,冷数据保存在db中

  • 热Key:Key的QPS特别高,容易导致Server实例出现CPU负载突增或者不均

    解决办法

    • 在业务服务侧设置Localcache,降低访问Redis的QPS,如Java的Guava、Golang的Bigcache

      Redis代理的热Key承载能力,本质上是结合了“热Key发现”、“LocalCache”两个功能

    • 分流。将key:value这一个热Key复制写入多份,例如key1:value,key2:value,访问的时候访问多个key,但value相同,以此将qps分散到不同实例上,降低负载。但代价是,更新时需要更新多个key,存在数据短暂不一致的风险

  • 批量操作可能导致慢查询

  • 缓存穿透:缓存未命中,查询绕过缓存,直接查询数据库

    在高并发场景下,热key如果过期,会有大量请求同时击穿至db,影响db性能和稳定

    如果有系统bug或人为攻击故意大量查询一定不存在的数据,也可能导致db响应慢甚至宕机

    解决办法:

    • 缓存空值。当查询到一个在缓存和数据库中都不存在的key时,则可以对该key缓存一个空value,下次再查时缓存直接返回空值
    • 布隆过滤器。布隆过滤器使用哈希技术能快速判断一个key在数据库中一定不存在或可能存在(存在假阳性),减少无效访问db
  • 缓存雪崩:大量缓存同时过期

    同一时间有大量key集中过期时,也会导致大量请求落到db上,导致查询变慢,甚至出现db无法响应新的查询

    解决办法

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