☰
Redis入门|五种数据结构、使用场景、持久化RDBAOF
2026/10/31 10:56:35 网站建设 项目流程

前言

Redis(Remote Dictionary Server),基于 C 语言开发的内存键值数据库。数据主要放在内存,所以读写性能极高,单机 QPS 可达十万级别。 很多人以为 Redis 只能做缓存,其实它能力很强:分布式锁、计数器、限流、消息队列、排行榜都可以实现。

核心特点:

  1. 内存存储,高性能;
  2. 单线程模型(Redis6.0 之后多线程处理 IO,命令执行依旧单线程串行);
  3. 丰富的数据结构;
  4. 支持持久化,可以把内存数据落盘;
  5. 支持主从复制、哨兵、集群,实现高可用。

注意:Redis 的单线程指命令执行模块单线程,网络 IO、持久化、删除大 key 等操作是多线程。

一、五种常用数据结构 + 业务场景

1. String 字符串(最基础)

底层:简单动态字符串 SDS 命令示例:

set name "zhangsan" get name incr count # 原子自增

适用场景

  1. 普通缓存:用户信息、商品基础信息;
  2. 计数器:文章阅读量、点赞数,incr原子操作;
  3. 分布式 Session 共享;
  4. 简单限流:记录用户访问次数。

坑:value 不宜过大,建议控制 10KB 以内,大 key 会影响性能。

2. List 列表

底层:双向链表(quicklist),有序,允许重复元素,可以头插、尾插。 命令:

lpush list1 a b rpop list1 lrange list1 0 -1

适用场景

  1. 简单消息队列(lpush + rpop);
  2. 最新消息列表:首页最新动态;
  3. 时间轴,朋友圈消息。

缺点:消息丢失、重复消费问题,生产业务消息队列优先 MQ,List 只适合简单临时场景。

3. Hash 哈希

key 对应一个 map 结构,存储多个 field-value。类似 Java 里 HashMap。

hset user:1001 name lisi age 20 hget user:1001 name hgetall user:1001

适用场景

  1. 对象存储:用户信息、商品信息,只需要修改某个字段,不用整体更新;
  2. 购物车:用户 id 作为 key,商品 id 为 field,数量为 value。

对比 String:如果用 String 存对象,修改单个字段需要序列化 / 反序列化整个对象;Hash 可以单独更新 field。

4. Set 集合

无序,元素不允许重复。支持交集、并集、差集。

sadd set1 a b c smembers set1 sinter set1 set2 # 交集

适用场景

  1. 去重:点赞用户,保证一人只能点赞一次;
  2. 共同好友(交集);
  3. 抽奖活动,随机抽取元素。

5. Sorted Set(ZSet 有序集合)

元素不可重复;每个元素带一个 score 分数,根据 score 自动排序。

zadd rank 90 tom 80 jack zrange rank 0 -1 withscores zrevrange rank 0 -1 withscores # 倒序

适用场景

  1. 排行榜:直播间热度、商品销量、积分排行榜;
  2. 延时任务(score 存时间戳);
  3. 带权重的队列。

二、Redis 持久化:RDB & AOF

Redis 是内存数据库,重启后内存数据丢失。持久化就是把内存数据保存到磁盘,重启恢复数据。两种方案:RDB、AOF,可以单独开启,也可以同时开启。

2.1 RDB(Redis DataBase)

RDB 是快照持久化:在某个时间点,把内存中全部数据生成一份二进制.rdb文件保存到磁盘。

触发方式
  1. 手动触发:save(主线程阻塞)、bgsave(fork 子进程,后台执行,推荐)
  2. 自动触发:配置文件save 900 1,900 秒至少 1 个 key 改动,则执行 bgsave。

bgsave 原理:调用 fork 创建子进程,子进程拷贝父进程内存页(写时复制 COW),子进程把数据写入 rdb 文件,主线程继续处理请求。

RDB 优点

  1. 文件体积小,二进制压缩,适合做备份;
  2. 恢复速度快,故障重启加载 rdb 很快;
  3. fork 子进程,主线程不阻塞(bgsave)。

RDB 缺点

  1. 丢失最后一次快照之后的数据:两次快照之间宕机,这段时间数据丢失;
  2. fork 子进程,当数据量巨大时,fork 会短暂阻塞主线程;
  3. 无法做到实时持久化。

2.2 AOF(Append Only File)

AOF:日志追加持久化。记录每一条写命令,以文本形式追加到 aof 日志文件。Redis 重启时,重新执行 AOF 里所有命令,恢复数据。

AOF 默认关闭,需要手动开启appendonly yes

AOF 刷盘策略(appendfsync)

  1. always:每一条写命令都刷盘。安全性最高,几乎不丢数据;性能最差。
  2. everysec(默认):每秒刷一次磁盘。最多丢失 1 秒数据,推荐配置,平衡性能和安全。
  3. no:交给操作系统自行刷盘,性能最好,丢失数据最多。

AOF 重写机制:AOF 文件持续追加,文件越来越大。Redis 自动触发 AOF Rewrite,把多条命令合并成一条,压缩 AOF 文件,不会丢失数据。重写也是 fork 子进程完成。

AOF 优点

  1. 数据安全性更高,everysec 最多丢 1 秒数据;
  2. 日志文本格式,可读性强。

AOF 缺点

  1. 文件体积比 RDB 大很多;
  2. 数据恢复速度比 RDB 慢;
  3. AOF 重写也会 fork 子进程,大数据量有阻塞风险。

2.3 RDB + AOF 同时开启(生产推荐)

  • Redis 重启优先加载 AOF 文件(AOF 数据更完整);
  • RDB 做冷备份,AOF 保障实时数据;

组合方案兼顾备份能力与数据安全。

三、三大缓存经典问题

3.1 缓存穿透

请求查询不存在的数据,缓存没有命中,请求全部打到数据库。大量请求压垮 DB。

解决方案:

  1. 缓存空值;
  2. 布隆过滤器,拦截不存在 key。

3.2 缓存击穿

热点 key 过期,大量并发请求瞬间打到数据库。

解决方案:

  1. 互斥锁;
  2. 热点 key 永不过期。

3.3 缓存雪崩

大量 key 在同一时间集体过期,或者 Redis 宕机;大量请求全部访问数据库,数据库压力瞬间崩溃。

解决方案:

  1. 过期时间增加随机值,打散过期时间;
  2. Redis 高可用(主从 + 哨兵 / 集群);
  3. 限流熔断;
  4. 多级缓存。

四、生产环境最佳实践

  1. 合理设计 key,规范命名,不要过长;
  2. 规避大 key,大 key 读写阻塞 Redis;
  3. 持久化:线上一般开启 AOF everysec + RDB 定时备份;
  4. 禁止使用 keys 命令,大数据量下阻塞主线程;用 scan 代替;
  5. 设置内存淘汰策略maxmemory-policy;
  6. 主从、哨兵、集群保证高可用;
  7. 缓存数据设置过期时间,不要无限存放。

五、面试高频问答

Q1:Redis 单线程模型怎么理解?

A:Redis 命令执行是单线程串行执行;IO、持久化等操作多线程。单线程避免锁竞争,配合内存操作,性能很高。

Q2:RDB 和 AOF 区别?

A:RDB 是时间点快照,文件小,恢复快,会丢失快照间隔数据;AOF 记录写命令日志,安全性更高,文件大,恢复慢。线上推荐两者同时开启。

Q3:五种数据结构分别适用场景?

A:String 做计数器、基础缓存;List 简单消息队列;Hash 存储对象;Set 去重、交集;ZSet 排行榜。

Q4:AOF 重写是什么?为什么需要?

A:AOF 持续追加,文件越来越大;AOF 重写合并命令,压缩日志体积,不影响原有 AOF 日志。

Q5:缓存雪崩、击穿、穿透三者区别?

A:穿透:查不存在数据;击穿:单个热点 key 过期;雪崩:大量 key 同时过期。

结语

Redis 不只是简单缓存组件,丰富的数据结构让它可以实现很多业务能力。持久化 RDB 与 AOF 是核心考点,要理解两者的取舍:RDB 适合备份,AOF 保障数据安全。同时一定要掌握缓存三大问题,这是 Redis 高频提问。

使用 Redis 最重要的是:内存数据库,做好持久化、内存控制、规避大 key。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询