vault backup: 2026-08-09 19:06:40
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
---
|
||||
tags: [test/review, redis, rdb-aof, persistence, fork, snapshot]
|
||||
create time: 2026-08-09 12:00
|
||||
---
|
||||
|
||||
# RDB与AOF持久化_测试题
|
||||
|
||||
## 概述
|
||||
本测试覆盖 Redis 的 RDB 快照、AOF 追加日志以及混合持久化三种方案。共 10 道题:6 道选择题、3 道填空题、1 道简答题,考察对 fork 机制、COW 开销、重写原理及选型策略的理解。
|
||||
|
||||
---
|
||||
|
||||
## 一、选择题(6道,由浅入深)
|
||||
|
||||
> **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
|
||||
|
||||
### Q1(基础)— 考察定义层面
|
||||
|
||||
Redis 的 `BGSAVE` 命令触发 RDB 持久化的核心步骤中,哪一步是造成内存峰值的关键因素?
|
||||
|
||||
A. 子进程遍历内存数据结构写入临时文件
|
||||
B. fork 子进程时操作系统复制被修改的内存页(Copy-On-Write)
|
||||
C. 将临时文件 mv 替换为 dump.rdb
|
||||
D. 主进程继续处理客户端写请求
|
||||
|
||||
### Q2(基础)— 考察行为判断
|
||||
|
||||
在 AOF 的三种 `appendfsync` 策略中,哪一种会在每次写命令执行后都调用一次操作系统 fsync 系统调用?
|
||||
|
||||
A. always
|
||||
B. everysec
|
||||
C. no
|
||||
D. 自动触发模式
|
||||
|
||||
### Q3(进阶)— 考察核心原理
|
||||
|
||||
RDB 文件采用压缩二进制格式存储。关于其特性,以下说法正确的是:
|
||||
|
||||
A. RDB 文件是纯文本格式,可以直接用 text editor 查看和编辑
|
||||
B. RDB 文件在不同 Redis 版本之间完全兼容,可以跨版本还原
|
||||
C. RDB 是无损压缩的二进制格式,但不同版本间不兼容
|
||||
D. RDB 只保存过期 key 的数据,跳过已失效的数据
|
||||
|
||||
### Q4(进阶)— 考察对比辨析
|
||||
|
||||
AOF 重写(Rewrite)过程中,子进程序列化数据的方式是:
|
||||
|
||||
A. 读取旧的 AOF 文件,去除重复命令后写入新文件
|
||||
B. 遍历当前内存数据,将每个 key 用 SET 命令逐条序列化
|
||||
C. 读取 RDB 快照文件并转换为 AOF 格式
|
||||
D. 直接从数据库查询最新数据然后序列化
|
||||
|
||||
### Q5(深入)— 考察场景推理
|
||||
|
||||
某 Redis 实例内存使用量约为 12GB,每次 BGSAVE 时 COW 导致额外占用约 500MB,持续数秒。运维同学希望在不停机的情况下降低 BGSAVE 期间的内存峰值。以下哪种方案最有效?
|
||||
|
||||
A. 增大 save 时间窗口减少触发频率
|
||||
B. 改用 `appendfsync no` 策略关闭持久化
|
||||
C. 开启混合持久化并将业务拆分到多个实例
|
||||
D. 增加 maxmemory 配置以提供更大的内存池
|
||||
|
||||
### Q6(深入)— 考察源码级别细节
|
||||
|
||||
混合持久化(Hybrid Persistence)的文件结构是怎样的?
|
||||
|
||||
A. 前半部分是 AOF 文本指令,后半部分是 RDB 二进制快照
|
||||
B. 前半部分是 RDB 全量快照,后半部分是 fork 时刻之后的增量 AOF 命令
|
||||
C. RDB 和 AOF 完全独立,分别存储在两个文件中
|
||||
D. 随机分布,RDB 部分和 AOF 部分交错排列
|
||||
|
||||
---
|
||||
|
||||
## 二、填空题(3道)
|
||||
|
||||
### F1 — 填空
|
||||
|
||||
`save 900 1` 的含义是:在 900 秒内有至少 ______ 个 key 被修改,则自动触发 BGSAVE 快照。
|
||||
|
||||
> **提示**: 语法为 save <seconds> <changes>。
|
||||
|
||||
### F2 — 填空
|
||||
|
||||
AOF 重写期间,父进程同时将新的写命令写入一个叫 ______ 的缓冲区,确保重写完成后的数据不会丢失。
|
||||
|
||||
> **提示**: 这个缓冲区的名字与其用途直接相关。
|
||||
|
||||
### F3 — 填空
|
||||
|
||||
当 Redis 内存超过 ______ GB 时,fork 导致的 COW 成本会显著剧增,需要特别注意性能影响。
|
||||
|
||||
> **提示**: 这是一个经验阈值。
|
||||
|
||||
---
|
||||
|
||||
## 三、简答题(1道)
|
||||
|
||||
### S1
|
||||
|
||||
一个电商系统的购物车数据存储在 Redis 中,数据特点如下:
|
||||
- 数据量中等(内存约 3GB),读多写少
|
||||
- 对数据安全性要求较高,最多允许丢失 1 分钟数据
|
||||
- 每晚凌晨需要对数据进行冷备份到对象存储
|
||||
|
||||
请为该系统设计一套持久化方案,说明具体配置选择及其理由,并解释每层设计如何满足不同需求。
|
||||
|
||||
> **答题框架提示**:
|
||||
> 1. 日常运行的持久化策略选择(AOF vs RDB vs 混合)
|
||||
> 2. appendfsync 的参数选择依据
|
||||
> 3. 冷备份的操作方式及注意事项
|
||||
> 4. 各方案的取舍权衡
|
||||
|
||||
---
|
||||
|
||||
## 参考答案与解析
|
||||
|
||||
### 选择题答案
|
||||
|
||||
| 题号 | 正确答案 | 解析 |
|
||||
|------|---------|------|
|
||||
| Q1 | B | fork 瞬间父子进程共享内存页,当父进程修改某页时操作系统会复制该页给子进程使用(Copy-On-Write)。这意味着 RDB 过程中的内存峰值 = 当前内存 + fork 瞬间的增量变化量。其他选项虽然是流程的一部分但不是造成峰值的原因。 |
|
||||
| Q2 | A | always 策略每条命令执行完就 fsync,等同于 MySQL innodb_flush_log_at_trx_commit=1,最安全但性能最差。everysec 每秒一次,no 由 OS 决定刷新时机。 |
|
||||
| Q3 | C | RDB 是无损压缩的二进制格式,空间效率高,但不同 Redis 版本间的 RDB 文件不兼容,不能跨版本还原。 |
|
||||
| Q4 | B | AOF 重写不是简单地删旧写新,而是 fork 子进程后直接遍历当前内存数据,将每个 key 用 SET 命令序列化。这比读取旧 AOF 更高效,因为去除了已过期 key 的记录。 |
|
||||
| Q5 | C | 12GB 已经超过了 10GB 的经验阈值,fork 的 COW 成本会非常可观。混合持久化可以加快启动恢复速度,拆分实例可以避免单次 fork 过大的开销。A 只能减少触发频率但不能降低单次成本;B 会牺牲数据安全;D 治标不治本。 |
|
||||
| Q6 | B | 混合持久化 = RDB 全量快照(前半部分)+ 增量 AOF 命令(后半部分)。RDB 部分保证从 fork 时刻的完整状态,AOF 部分保证增量不丢,兼顾了启动速度和数据安全性。 |
|
||||
|
||||
### 填空题答案
|
||||
|
||||
| 题号 | 答案 | 解析 |
|
||||
|------|------|------|
|
||||
| F1 | 1 | save 900 1 表示 900 秒内至少有 1 个 key 变更就触发快照。这是 Redis 默认的自动触发规则之一(通常搭配 save 300 10 和 save 60 10000 形成三级触发体系)。 |
|
||||
| F2 | aof_rewrite_buffer | AOF 重写期间旧 AOF 保持不变,子进程生成新文件的同时父进程把新写命令累积到 aof_rewrite_buffer 中,合并后原子替换原 AOF 文件,确保零丢失。 |
|
||||
| F3 | 10 | 当内存超过 10GB 时,fork 导致 COW 成本剧增。此时应考虑增大 AOF 重写阈值或将业务拆分到多实例,避免单次 fork 过大的内存开销。 |
|
||||
|
||||
### 简答题参考答案
|
||||
|
||||
S1:**参考答案要点**:
|
||||
1. 日常运行推荐开启混合持久化(aof-use-rdb-preamble yes),兼顾数据安全性和启动恢复速度。大多数互联网公司的标准配置。
|
||||
2. appendfsync 设置为 everysec(默认值),在性能和安全性之间取得平衡——最多丢 1 秒数据,系统调用开销仅约 1ms。
|
||||
3. 冷备策略:每天凌晨通过 BGSAVE 生成 dump.rdb 后上传到 OSS/S3。注意 SAVE 是阻塞命令,不要在高峰期执行,应使用 BGSAVE 后台执行后再复制文件。
|
||||
4. 对于 3GB 数据量,fork COW 成本可控,无需拆分实例。但可以监控 last_bgsave_status 确认健康度。
|
||||
|
||||
**评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点及各方案的取舍分析。
|
||||
|
||||
## 关联笔记
|
||||
- [[03.Redis/core/Redis 五大核心数据结构]]
|
||||
- [[03.Redis/core/集群与哨兵机制]]
|
||||
- [[03.Redis/strategies/多级缓存架构设计]]
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
tags: [test/review, redis, data-structures, sds, quicklist, skiplist]
|
||||
create time: 2026-08-09 12:00
|
||||
---
|
||||
|
||||
# Redis 五大核心数据结构_测试题
|
||||
|
||||
## 概述
|
||||
本测试覆盖 Redis 五种核心数据结构的底层实现原理,包括 SDS、quicklist、hash编码切换、intset/hashtable 切换以及 skiplist + hashtable 的 ZSet 结构。共 10 道题:6 道选择题、3 道填空题、1 道简答题。
|
||||
|
||||
---
|
||||
|
||||
## 一、选择题(6道,由浅入深)
|
||||
|
||||
> **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
|
||||
|
||||
### Q1(基础)— 考察定义层面
|
||||
|
||||
Redis String 类型底层使用 SDS(Simple Dynamic String)而非 C 字符串。以下哪一项**不是** SDS 相比 C 字符串的核心优势?
|
||||
|
||||
A. O(1) 获取字符串长度
|
||||
B. 二进制安全,不会因为 \0 截断
|
||||
C. 支持自动缩容以释放多余内存
|
||||
D. 修改字符串时通过 free 字段实现惰性空间释放
|
||||
|
||||
### Q2(基础)— 考察行为判断
|
||||
|
||||
对于一个 Hash 类型的键,在 Redis 4.0+ 中,当满足什么条件时会从 ziplist 切换到 hashtable 编码?
|
||||
|
||||
A. 元素数量超过 512 或者任意 value 长度超过 64 字节
|
||||
B. 元素数量超过 1000
|
||||
C. 任意 key 长度超过 64 字节
|
||||
D. Hash 中包含浮点数类型的 value
|
||||
|
||||
### Q3(进阶)— 考察核心原理
|
||||
|
||||
Redis List 从 3.2 版本起统一使用 quicklist 实现。关于 quicklist 的结构特点,以下说法正确的是:
|
||||
|
||||
A. quicklist 是一个双向链表,每个节点本身是一个独立的 linkedlist
|
||||
B. quicklist 的每个节点是 ziplist(或 listpack),通过 list-max-ziplist-size 控制节点大小
|
||||
C. quicklist 只能单向遍历,无法支持 LPUSH 和 RPUSH 的组合操作
|
||||
D. quicklist 的节点大小固定为 4KB,不支持动态调整
|
||||
|
||||
### Q4(进阶)— 考察对比辨析
|
||||
|
||||
关于 Set 类型的 intset 和 hashtable 两种编码,以下哪项描述是正确的?
|
||||
|
||||
A. intset 可以存储字符串,但 hashtable 只能存储整数
|
||||
B. intset 升级到达到的最大整数格式为 int64_t,且不可降级
|
||||
C. 当 Set 中包含混合类型(整数 + 字符串)时,Redis 会同时使用 intset 和 hashtable
|
||||
D. intset 查找时间复杂度为 O(N),hashtable 平均为 O(1)
|
||||
|
||||
### Q5(深入)— 考察场景推理
|
||||
|
||||
某电商系统使用 ZSet 实现商品销量排行榜,zadd score member 其中 score 为销量数值。随着商品数量从几十增长到数百万,ZSet 内部编码发生了什么变化?这种变化的根本原因是什么?
|
||||
|
||||
A. 从 hashtable 切换到 skiplist,因为 hashtable 不够灵活
|
||||
B. 从 quicklist 切换到 ziplist,因为数据量增大后 ziplist 更高效
|
||||
C. 从 quicklist 切换到 skiplist + hashtable,因为 skiplist 提供 O(log N) 的有序访问而 hashtable 提供 O(1) 的成员查找
|
||||
D. 编码保持不变,始终使用 skiplist + hashtable,因为 Redis 会自动优化
|
||||
|
||||
### Q6(深入)— 考察源码级别细节
|
||||
|
||||
Redis 7.0 引入了一项针对小字符串的内存优化:SDS_TYPE_5 直接存储在 dictEntry 的键槽中。这项优化的主要目的是什么?
|
||||
|
||||
A. 减少字符串比较的时间复杂度
|
||||
B. 完全避免额外堆分配,降低内存碎片和 malloc 开销
|
||||
C. 使短字符串可以使用更大的 maxlevel=64 来提升跳表性能
|
||||
D. 让 SDS 兼容 C 字符串协议以便与旧版客户端通信
|
||||
|
||||
---
|
||||
|
||||
## 二、填空题(3道)
|
||||
|
||||
### F1 — 填空
|
||||
|
||||
Redis ZSet 的内部实现组合了两种数据结构:跳表用于按 score 排序,______ 用于按 member 做 O(1) 查找。
|
||||
|
||||
> **提示**: 思考 ZSet 需要同时支持"按分数范围查询"和"精确成员查询"两个维度。
|
||||
|
||||
### F2 — 填空
|
||||
|
||||
对于 quicklist,如果将 `list-max-ziplist-size` 设置为 **-2**,则表示每节点最大不超过 ______ KB。
|
||||
|
||||
> **提示**: 回顾表格中负数取值的含义。
|
||||
|
||||
### F3 — 填空
|
||||
|
||||
Hash 类型在 Redis 4.0 之前使用 zipmap,4.0~5.x 使用 ziplist。默认切换到 hashtable 的条件是:元素数量大于 512 或任意 value 长度超过 ______ 字节。
|
||||
|
||||
> **提示**: 这是 Redis 对压缩列表上限的一个关键阈值。
|
||||
|
||||
---
|
||||
|
||||
## 三、简答题(1道)
|
||||
|
||||
### S1
|
||||
|
||||
一个社交应用的点赞功能需要同时满足以下需求:
|
||||
1. 统计每个用户的点赞总数(类似 `user_id:like_count`)
|
||||
2. 维护一个用户点赞过的所有帖子 ID 列表(类似 `user:1:liked_posts`)
|
||||
3. 对帖子维护一个被点赞用户列表,并按点赞时间排序
|
||||
|
||||
请结合 Redis 五大核心数据结构的特点,说明你会如何选择数据结构来存储以上信息?为什么不用其他替代方案?
|
||||
|
||||
> **答题框架提示**:
|
||||
> 1. 逐一对应三个业务需求选择最合适的结构
|
||||
> 2. 考虑每种结构的编码切换策略
|
||||
> 3. 分析替代方案的缺陷(如用 List 维护排序的代价)
|
||||
|
||||
---
|
||||
|
||||
## 参考答案与解析
|
||||
|
||||
### 选择题答案
|
||||
|
||||
| 题号 | 正确答案 | 解析 |
|
||||
|------|---------|------|
|
||||
| Q1 | C | SDS 不支持自动缩容,只通过 free 字段保留空闲空间供下次复用。这是设计取舍——频繁缩容反而浪费 CPU。其他选项均为 SDS 核心优势:len 字段 O(1) 获得长度、记录 len 而非依赖 \0 实现二进制安全、free 实现惰性空间释放。 |
|
||||
| Q2 | A | Redis 4.0+ 的 Hash 哈希表切换条件是:有一个 value > 64 字节或元素数 > 512。注意 Redis 4.0 已将 ziplist 作为 Hash 编码废弃,默认用 hashtable。 |
|
||||
| Q3 | B | quicklist 是双向链表,每节点为 ziplist(Redis 7.0+ 为 listpack)。通过 list-max-ziplist-size 控制每节点规模。A 错在节点是 ziplist 而非 linkedlist;C 错在支持两端操作;D 错在可配置。 |
|
||||
| Q4 | B | intset 升级路径是 int16_t → int32_t → int64_t,一旦扩容 realloc 整个结构且不可降级。A 反了;C 不存在混存机制,非整数出现就全部转为 hashtable;D 反了,intset 二分查找 O(log N),hashtable 平均 O(1)。 |
|
||||
| Q5 | C | 数据量大后 ZSet 从 ziplist/quicklist 切换到 skiplist + hashtable 双结构。skiplist 保证有序性(O(log N) 查找),hashtable 保证 O(1) 的 member 查找。D 不对,小数据量时用 quicklist/ziplist 省内存。 |
|
||||
| Q6 | B | Redis 7.0 的 native 优化中,小字符串用 SDS_TYPE_5 直接内嵌在 dictEntry 中,无需额外 malloc 分配独立对象。这减少了内存碎片并降低了 malloc 系统调用次数。 |
|
||||
|
||||
### 填空题答案
|
||||
|
||||
| 题号 | 答案 | 解析 |
|
||||
|------|------|------|
|
||||
| F1 | hashtable | ZSet 同时维护了一个 skiplist(按 score 升序排列)和一个 hashtable(按 member 做 O(1) 查找),两者同步更新,兼顾有序性和快速定位。 |
|
||||
| F2 | 8 | list-max-ziplist-size = -1 表示不限制(仅受 memory 约束),-2 <= 8KB,-3 <= 4KB,-4 <= 2KB,-5 <= 1KB(默认)。负数表示以 KB 为单位的大小上限。 |
|
||||
| F3 | 64 | 这是 Hash 编码切换的关键阈值之一:value 长度 > 64 字节 或元素数 > 512,都会促使 Redis 从 ziplist/zipmap 切换到 hashtable。 |
|
||||
|
||||
### 简答题参考答案
|
||||
|
||||
S1:**参考答案要点**:
|
||||
1. 点赞总数使用 String 类型,通过 INCR 命令原子递增,简单高效;也可嵌套在 Hash 中用 field 存储多种计数。
|
||||
2. 点赞帖子列表可用 ZSet,score 存点赞时间戳,member 存 post_id,天然有序且支持范围查询(ZREVRANGEBYSCORE)。
|
||||
3. 帖子的点赞用户列表同样用 ZSet,score 为点赞时间,member 为用户 ID,配合 ZRANGE 取 Top-N。
|
||||
4. 替代分析:List 虽然能存列表,但不支持按时间排序的高效插入;Hash 适合字段-值映射但不适合有序列表场景。
|
||||
|
||||
**评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点,并给出合理的替代方案分析。
|
||||
|
||||
## 关联笔记
|
||||
- [[03.Redis/core/RDB 与 AOF 持久化]]
|
||||
- [[03.Redis/core/集群与哨兵机制]]
|
||||
- [[03.Redis/strategies/多级缓存架构设计]]
|
||||
- [[03.Redis/strategies/缓存穿透击穿雪崩解决方案]]
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
tags: [test/review, redis, cluster-sentinel, sharding, gossip, failover]
|
||||
create time: 2026-08-09 12:00
|
||||
---
|
||||
|
||||
# 集群与哨兵机制_测试题
|
||||
|
||||
## 概述
|
||||
本测试覆盖 Redis Sentinel 的高可用故障转移机制和 Redis Cluster 的槽位分片架构。共 10 道题:6 道选择题、3 道填空题、1 道简答题,考察对 CAP 权衡、Gossip 协议、选举流程和槽位迁移的理解。
|
||||
|
||||
---
|
||||
|
||||
## 一、选择题(6道,由浅入深)
|
||||
|
||||
> **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
|
||||
|
||||
### Q1(基础)— 考察定义层面
|
||||
|
||||
Redis Sentinel 判定 master 节点进入"客观下线"(ODOWN)状态的最低条件是:
|
||||
|
||||
A. 单个 Sentinel 节点 PING 超时
|
||||
B. quorum(n/2+1)个 Sentinel 认为 master SDOWN
|
||||
C. 所有 Sentinel 节点一致同意
|
||||
D. master 连续 5 次 PING 无响应
|
||||
|
||||
### Q2(基础)— 考察行为判断
|
||||
|
||||
关于 Redis Cluster 的哈希槽分配,以下哪项计算方式是正确的?
|
||||
|
||||
A. MD5(key) % 16384
|
||||
B. CRC16(key) % 16384
|
||||
C. SHA1(key) % 16384
|
||||
D. Hash(key) % 1024
|
||||
|
||||
### Q3(进阶)— 考察核心原理
|
||||
|
||||
Sentinel 进行故障转移时,选择 slave 升为主节点的优先依据是:
|
||||
|
||||
A. priority 参数最低的那个 slave
|
||||
B. replication offset 最大的那个 slave
|
||||
C. 运行时间最长的 slave
|
||||
D. 最近收到 PING 回复最快的 slave
|
||||
|
||||
### Q4(进阶)— 考察对比辨析
|
||||
|
||||
Redis Sentinel 和 Redis Cluster 在设计上做出了不同的取舍,以下对比错误的是:
|
||||
|
||||
A. Sentinel 支持 DB0~DB15 多库,Cluster 仅支持 DB0
|
||||
B. Sentinel 不支持水平分片,Cluster 通过 16384 槽位分片实现扩展
|
||||
C. Sentinel 倾向 AP 可用性优先,Cluster 倾向 CP 一致性优先
|
||||
D. Sentinel 扩容需要手动迁移或重新搭建,Cluster 可在线增量迁移
|
||||
|
||||
### Q5(深入)— 考察场景推理
|
||||
|
||||
某服务部署了 3 个 Sentinel 节点来保护一个 Master-Slave 集群。如果其中 1 个 Sentinel 因网络隔离不可达,会发生什么?
|
||||
|
||||
A. 剩余的 2 个 Sentinel 仍然能够达成 quorum(n/2+1=2),继续执行故障检测和转移
|
||||
B. 由于无法达到 quorum,故障检测完全停止
|
||||
C. 剩余的 Sentinel 会自动新增第 4 个 Sentinel 来补足票数
|
||||
D. Master 进入只读模式等待失联的 Sentinel 恢复
|
||||
|
||||
### Q6(深入)— 考察源码级别细节
|
||||
|
||||
Redis Cluster 在执行在线槽位迁移时,源节点和目标节点通过什么标志位协作完成过渡?
|
||||
|
||||
A. MIGRATING 和 IMPORTING
|
||||
B. TRANSFER 和 RECEIVE
|
||||
C. SOURCE 和 TARGET
|
||||
D. PREPARING 和 COMMITTING
|
||||
|
||||
---
|
||||
|
||||
## 二、填空题(3道)
|
||||
|
||||
### F1 — 填空
|
||||
|
||||
Sentinel 故障转移的第一步是将 master 标记为 SDOWN(主观下线),需要至少 ______ 个 Sentinel 确认才会升级为 ODOWN(客观下线)。
|
||||
|
||||
> **提示**: 如果有 3 个 Sentinel,quorum = n/2 + 1 = 3/2 + 1 = ?
|
||||
|
||||
### F2 — 填空
|
||||
|
||||
Redis Cluster 将数据划分为 ______ 个 hash slot,Key 的定位通过 CRC16(key) % 16384 计算得到对应的槽位。
|
||||
|
||||
> **提示**: 这个数字是一个质数附近的数值。
|
||||
|
||||
### F3 — 填空
|
||||
|
||||
当客户端向错误的 Cluster 节点发送请求时,RabbitMQ(应为 Redis Cluster)会返回 ______ 重定向消息,告知客户端前往正确的节点查找。
|
||||
|
||||
> **提示**: 有两种重定向类型,ASK 用于迁移中的过渡期。
|
||||
|
||||
---
|
||||
|
||||
## 三、简答题(1道)
|
||||
|
||||
### S1
|
||||
|
||||
你正在为一个需要高可用的金融交易系统设计 Redis 基础设施。该系统的读写比例约为 3:7,对数据一致性要求极高但不支持多 DB(即只用 DB0)。已知有以下约束条件:
|
||||
- 不能容忍脑裂现象导致的双主问题
|
||||
- 需要在故障发生时自动完成故障转移
|
||||
- 客户端连接地址需要保持相对稳定
|
||||
|
||||
请选择合适的架构方案(Sentinel 或 Cluster),列出你的配置建议,并说明如何将脑裂风险降到最低。
|
||||
|
||||
> **答题框架提示**:
|
||||
> 1. 架构方案的选择理由(CP vs AP 权衡)
|
||||
> 2. Sentinel 的部署数量和位置
|
||||
> 3. 关键的参数配置
|
||||
> 4. 脑裂防护机制(min-replicas-to-write 等)
|
||||
|
||||
---
|
||||
|
||||
## 参考答案与解析
|
||||
|
||||
### 选择题答案
|
||||
|
||||
| 题号 | 正确答案 | 解析 |
|
||||
|------|---------|------|
|
||||
| Q1 | B | quorum = n/2 + 1,其中 n 是配置的 Sentinel 总数。3 个 Sentinel 时需要 2 个认为 master SDOWN 才会触发 ODOWN。A 只是单个节点的 SDOWN(主观下线)。C 过于严格不利于故障快速发现。D 不是判定标准。 |
|
||||
| Q2 | B | Redis Cluster 使用 CRC16(key) % 16384 计算 Key 所属的槽位。MD5/SHA1 不是 Cluster 使用的算法。 |
|
||||
| Q3 | B | Sentinel 选择 replication offset 最大的 slave 升级为主,因为这代表它与 master 同步的最新、最完整的数据。priority 可作为辅助排序条件。 |
|
||||
| Q4 | C | 反了!Sentinel 倾向 CP(主从切换期间短暂不可用但保证一致),Cluster 倾向 AP(分片后允许不同分区有不同视角)。A、B、D 均为正确描述。 |
|
||||
| Q5 | A | 3 个 Sentinel 的 quorum = 3/2 + 1 = 2。剩余 2 个可达的 Sentinel 刚好达到 quorum,可以继续执行故障检测。少数派宕机不影响多数派的正常工作。 |
|
||||
| Q6 | A | 迁移时源节点 setslot MIGRATING <slot> <target-id>,目标节点 setslot IMPORTING <slot> <source-id>。迁移完成后双方取消标志位设为 NODE。 |
|
||||
|
||||
### 填空题答案
|
||||
|
||||
| 题号 | 答案 | 解析 |
|
||||
|------|------|------|
|
||||
| F1 | 2 | 3 个 Sentinel 的 quorum = 3/2 + 1 = 2。只要 2 个及以上 Sentinel 认为 master SDOWN,就会将其标记为 ODOWN 并触发后续故障转移流程。 |
|
||||
| F2 | 16384 | Redis Cluster 固定使用 16384 个槽位(0-16383),Key 通过 CRC16(key) % 16384 分配到对应槽位所在的节点。 |
|
||||
| F3 | MOVED / ASK | 向错误节点发请求时,若 slot 已迁移到目标节点,目标节点返回 MOVED(迁移完成)或 ASK(迁移中过渡)重定向,让客户端重试正确节点。 |
|
||||
|
||||
### 简答题参考答案
|
||||
|
||||
S1:**参考答案要点**:
|
||||
1. 选择 Redis Sentinel 而非 Cluster。原因:数据一致性要求高(CP 倾向)、读写比 3:7 且不需要水平扩展、只用单 DB(Cluster 仅支持 DB0 但这里正好满足)。
|
||||
2. Sentinel 部署至少 3 个奇数节点,跨机房/机架部署避免单点故障。quorum 设为 n/2 + 1。
|
||||
3. 关键参数:down-after-milliseconds 合理设置(如 30000ms)、failover-timeout 控制超时、parallel-syncs 控制同步并发数。
|
||||
4. 脑裂防护:设置 min-replicas-to-write(如 ≥1)和 min-replicas-max-lag(如 10s)。当 master 连接的合法从节点数低于阈值或延迟超过限制时,master 拒绝写操作,防止脑裂时双主写入。
|
||||
|
||||
**评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖架构选择理由、部署方案、关键参数和脑裂防护四个维度。
|
||||
|
||||
## 关联笔记
|
||||
- [[03.Redis/core/Redis 五大核心数据结构]]
|
||||
- [[03.Redis/core/RDB 与 AOF 持久化]]
|
||||
- [[03.Redis/strategies/多级缓存架构设计]]
|
||||
Reference in New Issue
Block a user