5548 字
28 分钟
MySQL与Redis核心知识点

MySQL与Redis核心知识点#

一、MySQL日志系统#

1.1 MySQL日志分类#

1.1.1 Server层日志#

  • Error Log(错误日志)

    • 记录MySQL服务器启动、运行和关闭过程中遇到的问题
    • 包括启动参数、服务器异常、崩溃恢复、表损坏等
    • 用于诊断MySQL服务器的问题
  • Slow Query Log(慢查询日志)

    • 记录执行时间超过指定阈值的SQL查询
    • 用于分析慢查询,使用mysqldumpslow工具分析
  • General Query Log(通用查询日志)

    • 记录连接ID、IP地址、用户名、执行的SQL语句等
    • 用于诊断问题、审计和性能分析
  • Binary Log(二进制日志)

    • Server层生成的二进制日志
    • 记录对MySQL数据库进行更改的所有操作
    • 用于数据备份、数据恢复以及主从集群数据同步

1.1.2 InnoDB引擎层日志#

  • Redo Log(重做日志)

    • 物理日志,记录在某个数据页上做了什么修改
    • 用于数据崩溃恢复,保证事务持久性
    • 大小固定,循环写入
  • Undo Log(回滚日志)

    • 逻辑日志,记录数据在被事务修改之前的旧值
    • 实现事务原子性,主要用于事务回滚和MVCC

1.1.3 复制相关日志#

  • Relay Log(中继日志)

    • MySQL从库从主库同步的binlog日志
    • 实现MySQL的主从异步复制
  • 审计日志

    • 记录数据库操作活动的日志
    • 用于审计、安全和合规检查

1.2 Redo Log vs Binary Log#

特性Redo LogBinary Log
层次InnoDB引擎层Server层
用途崩溃恢复,保证事务ACID数据备份、恢复、主从同步
记录内容物理日志,记录数据页修改逻辑日志,记录SQL语句或行变更
写入时机事务执行过程中事务提交时
写入方式循环写入(空间固定)追加写入
持久化WAL机制,先写日志再写数据事务提交时写入

1.3 Undo Log工作机制#

1.3.1 事务回滚实现#

  • 事务之间通过链表结构记录:A → B → C
  • 回滚时根据链表查找前一个状态
  • 回滚后,清除或标记已回滚的undo log记录

1.3.2 Undo Log清理时机#

  • 当某个版本不会被任何现有和未来的事务看到时
  • 读事务在ReadView中记录自己开始时看到的最大事务编号
  • 如果一个事务编号小于所有当前活跃的读事务,就可以被清理

二、MySQL架构#

2.1 MySQL Server架构分层#

┌─────────────────────────────────┐
│ 客户端连接层 │
├─────────────────────────────────┤
│ 服务层 │
│ ┌────────────────────────┐ │
│ │ NoSQL接口 │ SQL接口 │ │
│ ├────────────────────────┤ │
│ │ 解析器 │ 查询优化器 │ 缓存 │ │
│ └────────────────────────┘ │
├─────────────────────────────────┤
│ 存储引擎层 │
│ InnoDB │ MyISAM │ Memory │
├─────────────────────────────────┤
│ 系统文件层 │
│ 数据文件 │ 日志文件 │ 配置文件 │
└─────────────────────────────────┘

2.1.1 网络连接层#

  • 客户端连接器
  • MySQL 8.0默认最大连接数:151
  • 长连接问题
    • 临时使用的内存资源在断开时才会释放
    • 长期积累可能导致内存占用过大
    • 解决方案
      1. 定期断开长连接
      2. MySQL 5.7+:执行mysql_reset_connection重置连接资源

2.1.2 服务层#

  • NoSQL接口:负责JSON字段的增删改查
  • SQL接口:接收客户端SQL命令,响应查询结果
  • 解析器:将SQL解析成解析树,检查语法和语义
  • 查询优化器
    • 将解析树转换成执行计划
    • 评估优化性能,选择合适索引,确定连接顺序
    • 优化器局限性
      • 统计信息不准确
      • 最小执行成本≠最快速度
      • IO估算未考虑缓存
      • 某些操作无法准确估算

2.1.3 存储引擎层#

  • 本质上是表处理器
  • 管理表创建、数据检索、索引创建
  • 支持自定义存储引擎开发

2.2 SQL语句执行过程#

客户端发送SQL
连接器验证身份和权限
[MySQL 8.0前] 查询缓存?
解析器:语法分析 + 语义分析
优化器:生成执行计划
执行器:调用存储引擎接口
存储引擎:数据读写
返回结果给客户端

三、MySQL索引#

3.1 索引分类#

3.1.1 按数据结构分#

  • B+ Tree索引(InnoDB默认)
  • Hash索引
  • Full-text全文索引

3.1.2 按物理存储分#

  • 聚簇索引(主键索引)
  • 二级索引(辅助索引)

3.1.3 按字段特性分#

  • 主键索引(PRIMARY KEY)
  • 唯一索引(UNIQUE)
  • 普通索引(INDEX)
  • 前缀索引

3.1.4 按字段个数分#

  • 单列索引
  • 联合索引(复合索引)

3.2 B树 vs B+树#

特性B树B+树
数据存储所有节点都存储数据只有叶子节点存储数据
叶子连接叶子节点间无连接叶子节点双向链表连接
查询效率不稳定(1~h次)稳定(始终h次)
范围查询需要中序遍历直接遍历叶子链表
空间利用较低较高(非叶子节点只存索引)
树高度相对较高相对较矮

3.2.1 为什么MySQL选择B+树#

B+树结构示例:
[10|20] <- 只存索引
/ | \
[5|10] [15|20] [25|30] <- 只存索引
↓ ↓ ↓
[5]←→[10]←→[15]←→[20]←→[25]←→[30] <- 数据+双向链表

优势

  1. 磁盘I/O友好:非叶子节点不存数据,单节点可存更多索引
  2. 范围查询高效:通过叶子节点链表顺序访问
  3. 查询性能稳定:所有查询路径长度相同
  4. 更高的扇出:树更矮,减少I/O次数

3.3 InnoDB三大特性#

  1. 自适应Hash索引:自动为热点数据建立Hash索引
  2. Buffer Pool:缓冲池,减少磁盘I/O
  3. 双写缓冲区:保证数据页的可靠性

3.4 索引失效场景#

3.4.1 索引生效条件#

  • 全值匹配(=、<、>、IN等)
  • 最左前缀原则
  • 范围查询
  • ORDER BY排序
  • GROUP BY分组

3.4.2 索引失效场景#

  1. 违反最左前缀原则:联合索引未从第一个字段开始
  2. 使用函数或运算WHERE DATE(create_time) = '2024-01-01'
  3. 隐式类型转换:字符串字段与数字比较
  4. 索引选择性差:如性别字段
  5. OR条件:存在非索引字段
  6. 索引碎片过多:需要重建索引
  7. 数据量太小:优化器选择全表扫描
  8. 优化器估算错误:统计信息不准确

3.5 索引优化口诀#

  • 全值匹配我最爱,最左前缀要遵守
  • 带头大哥不能死,中间兄弟不能断
  • 索引列上少计算,范围之后全失效
  • LIKE百分写最右,覆盖索引不要星
  • 不等空值还有OR,索引影响要注意
  • 字符引号不能丢,SQL优化有诀窍

四、MySQL事务#

4.1 事务隔离级别#

4.1.1 并发问题#

  • 脏读:读到其他事务未提交的数据
  • 不可重复读:同一事务内两次读取同一行数据结果不同
  • 幻读:同一事务内两次查询结果集行数不同

4.1.2 隔离级别与解决方案#

隔离级别脏读不可重复读幻读实现机制
读未提交无隔离
读已提交MVCC(每次SELECT生成ReadView)
可重复读✓*MVCC(首次SELECT生成ReadView)+ Next-Key Lock
串行化所有SELECT自动加共享锁

*注:MySQL InnoDB的可重复读通过Next-Key Lock解决了幻读问题

MySQL默认隔离级别:可重复读(REPEATABLE READ)

4.2 MVCC机制#

4.2.1 版本链#

每行数据在InnoDB中有隐藏列:

  • DB_TRX_ID:最后修改的事务ID
  • DB_ROLL_PTR:回滚指针,指向undo log
  • DB_ROW_ID:隐藏主键(无主键时使用)

4.2.2 ReadView#

ReadView包含:

  • m_ids:活跃事务ID列表
  • min_trx_id:最小活跃事务ID
  • max_trx_id:下一个要分配的事务ID
  • creator_trx_id:创建该ReadView的事务ID

4.2.3 可见性判断#

if (DB_TRX_ID < min_trx_id)
return 可见; // 事务已提交
else if (DB_TRX_ID >= max_trx_id)
return 不可见; // 事务在ReadView后开始
else if (DB_TRX_ID in m_ids)
return 不可见; // 事务未提交
else
return 可见; // 事务已提交

4.3 当前读 vs 快照读#

4.3.1 快照读(Snapshot Read)#

  • 普通SELECT(不加锁)
  • 基于MVCC读取快照版本
  • 不加任何锁
SELECT * FROM table WHERE id = 1;

4.3.2 当前读(Current Read)#

  • 读取最新版本并加锁
  • 触发场景:
-- SELECT加锁
SELECT ... FOR UPDATE; -- 加X锁
SELECT ... FOR SHARE; -- 加S锁
-- DML操作(都是当前读)
UPDATE table SET ...; -- 加X锁
DELETE FROM table WHERE ...; -- 加X锁
INSERT INTO table VALUES ...; -- 加插入意向锁

4.3.3 UPDATE的特殊性#

-- 事务A
START TRANSACTION;
SELECT * FROM user WHERE id = 1; -- 快照读,age = 20
-- 事务B
UPDATE user SET age = 21 WHERE id = 1;
COMMIT;
-- 事务A继续
SELECT * FROM user WHERE id = 1; -- 快照读,仍是age = 20
UPDATE user SET name = 'Tom' WHERE id = 1; -- 当前读,读到age = 21

UPDATE必须是当前读的原因

  1. 保证数据一致性
  2. 避免丢失更新
  3. 通过锁机制防止并发问题

4.4 InnoDB串行化实现#

InnoDB的串行化不是物理串行执行,而是通过锁机制实现:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- 所有SELECT自动转换为
SELECT ... FOR SHARE; -- 自动加S锁 + Next-Key Lock
-- DML操作
UPDATE/DELETE/INSERT; -- 加X锁 + Next-Key Lock

锁策略

  • SELECT:自动加共享锁 + Next-Key Lock(行锁+间隙锁)
  • DML:加排他锁 + Next-Key Lock
  • 范围查询:锁定整个范围,完全防止幻读

五、MySQL锁机制#

5.1 锁分类#

5.1.1 按操作类型#

  • 共享锁(S锁):读锁,不阻塞读,阻塞写
  • 排他锁(X锁):写锁,阻塞其他读写

5.1.2 按粒度分类#

表级锁

  • 表锁:锁整张表,粒度大,并发低
  • 元数据锁(MDL):Server层表锁,DDL时阻塞DML
  • 自增锁(AUTO-INC):保证自增值并发安全
  • 意向锁
    • 意向共享锁(IS):事务想获取S锁
    • 意向排他锁(IX):事务想获取X锁
    • 作用:快速判断表中是否有行锁

行级锁

  • 记录锁(Record Lock):锁定单行记录
  • 间隙锁(Gap Lock):锁定范围,防止插入
  • 临键锁(Next-Key Lock):记录锁+间隙锁
  • 插入意向锁:INSERT专用,间隙锁的特殊类型

5.1.3 按态度分类#

  • 乐观锁:提交时检测冲突(版本号/CAS)
  • 悲观锁:操作前加锁(InnoDB各种锁)

5.2 加锁规则#

  • DELETE:当前读,加X锁
  • INSERT:加插入意向锁
  • UPDATE:当前读,加X锁

六、MySQL优化#

6.1 深度分页优化#

问题:LIMIT 1000000, 10需要扫描100万条数据

优化方案

-- 1. 使用子查询(延迟关联)
SELECT * FROM table t1
JOIN (SELECT id FROM table LIMIT 1000000, 10) t2
ON t1.id = t2.id;
-- 2. 记录上次位置
SELECT * FROM table WHERE id > last_id LIMIT 10;
-- 3. 使用覆盖索引
SELECT id, name FROM table LIMIT 1000000, 10; -- (id,name)建立联合索引

6.2 表设计优化#

  • 选择合适的数据类型(定长用CHAR)
  • 字段设置NOT NULL + 默认值
  • 只创建必要的索引
  • 日期比较存储为UNSIGNED INT

6.3 SQL优化建议#

  • 小表驱动大表
  • 避免SELECT *
  • 使用TRUNCATE代替DELETE FROM
  • 合理使用索引覆盖
  • 避免在索引列上计算

6.4 常用SQL技巧#

-- 自定义排序
SELECT * FROM t1 WHERE id IN (7,3,1,4,5,8,10)
ORDER BY FIELD(id, 7,3,1,4,5,8,10);
-- NULL值排最后
SELECT * FROM t1
ORDER BY IF(ISNULL(k3), 1, 0), k1, k2 LIMIT 10;
-- 统计分析
SELECT
COUNT(DISTINCT user_id) as total_users,
SUM(quantity * price) as total_sales,
SUM(quantity * price) / COUNT(DISTINCT user_id) as avg_price
FROM orders;
-- 分组汇总
SELECT product_id,
SUM(quantity * price) as sales,
CASE
WHEN SUM(quantity * price) < 100 THEN '低'
WHEN SUM(quantity * price) < 200 THEN '中'
ELSE '高'
END as level
FROM orders
GROUP BY product_id WITH ROLLUP;
-- 多条件筛选示例
SELECT DISTINCT user_id
FROM orders
WHERE user_id IN (
SELECT user_id FROM orders WHERE product_id = 101
)
AND user_id IN (
SELECT user_id FROM orders WHERE product_id = 102
)
AND user_id NOT IN (
SELECT user_id FROM orders WHERE product_id = 103
);

七、Redis数据类型#

7.1 五大基础数据类型#

7.1.1 String(字符串)#

  • 底层实现:SDS(Simple Dynamic String)
  • 应用场景
    • 缓存对象(JSON序列化)
    • 计数器(INCR/DECR)
    • 分布式锁(SET NX EX)
    • Session共享

7.1.2 List(列表)#

  • 底层实现:quicklist(双向链表+压缩列表)
  • 应用场景
    • 消息队列(LPUSH/BRPOP)
    • 文章列表、Timeline
  • 关键命令:LPUSH/RPUSH、LPOP/RPOP、LRANGE、BRPOP(阻塞)

7.1.3 Hash(哈希)#

  • 底层实现:ziplist → hashtable(元素增多时转换)
  • 应用场景
    • 对象存储(用户信息、商品信息)
    • 购物车(用户ID为key,商品ID为field)
  • 优势:可以只修改对象的某个字段

7.1.4 Set(集合)#

  • 底层实现:intset → hashtable
  • 应用场景
    • 共同好友(SINTER交集)
    • 点赞用户(去重)
    • 抽奖系统(SRANDMEMBER)
  • 集合操作:交集(SINTER)、并集(SUNION)、差集(SDIFF)

7.1.5 ZSet(有序集合/Sorted Set)#

  • 底层实现
    • ziplist(元素少时)
    • skiplist(跳表)+ hashtable(元素多时)
  • 特点:每个成员关联一个score分数,按分数排序
  • 核心应用场景
    • 排行榜系统:游戏排行、热搜榜单
    • 延迟队列:score存储执行时间戳
    • 滑动窗口限流:score存储时间戳,统计时间窗口内请求数
    • 优先级队列:score表示优先级

面试重点:ZSet为什么用跳表而不用红黑树?

  1. 范围查询效率高:跳表遍历更简单,红黑树需要中序遍历
  2. 实现简单:跳表比红黑树的实现和调试更简单
  3. 内存占用灵活:可以通过调整索引构建概率来平衡内存和性能
  4. 并发友好:跳表更容易实现无锁操作

7.2 三大特殊数据类型(面试常考)#

7.2.1 Bitmap(位图)#

  • 本质:String的位操作
  • 典型应用
    • 用户签到(一年365天仅需46字节)
    • 在线状态统计
    • 布隆过滤器基础
  • 优势:极度节省内存

7.2.2 HyperLogLog#

  • 用途:基数统计(去重计数)
  • 特点:固定12KB内存,误差率0.81%
  • 应用:UV统计(独立访客数)

7.2.3 GEO(地理位置)#

  • 底层:基于ZSet实现(GeoHash编码作为score)
  • 应用:附近的人、距离计算

7.3 数据类型选择(面试必备)#

场景数据类型选择理由
缓存用户信息String/HashString简单;Hash可部分更新
排行榜ZSet自动排序,支持范围查询
消息队列List/StreamList简单;Stream功能完整
共同好友Set交集运算
用户签到Bitmap节省内存
UV统计HyperLogLog固定内存消耗
附近的人GEO原生地理位置支持
分布式锁StringSET NX EX原子操作

八、Redis持久化#

8.1 RDB(快照)#

8.1.1 触发条件#

默认配置:

  • 900秒内有1次修改
  • 300秒内有10次修改
  • 60秒内有10000次修改

8.1.2 特点#

  • 优点
    • 压缩的二进制文件,体积小
    • 恢复速度快
    • 适合备份和灾难恢复
  • 缺点
    • 可能丢失最后一次快照后的数据
    • fork子进程时可能阻塞

8.2 AOF(追加日志)#

8.2.1 写入流程#

命令执行 → AOF缓冲区 → 系统调用write → 内核缓冲区 → fsync → 磁盘

8.2.2 同步策略#

  • always:每个命令都同步,最安全但性能最差
  • everysec:每秒同步一次(默认)
  • no:由操作系统决定

8.2.3 AOF重写#

  • 目的:解决AOF文件过大问题
  • 机制:创建新AOF文件,合并命令,只保留最终状态

8.3 混合持久化(4.0+)#

  • RDB快照 + AOF增量日志写入同一文件
  • 结合两者优势:快速恢复 + 低数据丢失风险

九、Redis缓存问题#

9.1 缓存穿透#

问题:大量请求不存在的数据,直接打到数据库

解决方案

  1. 参数校验:拦截非法请求
  2. 缓存空值:将NULL结果缓存短时间
  3. 布隆过滤器:快速判断数据是否存在
    • 注意:标准布隆过滤器不支持删除
    • 可用Counting Bloom Filter支持删除

9.2 缓存击穿#

问题:热点数据过期,大量请求打到数据库

解决方案

  1. 热点数据永不过期
  2. 分布式锁:只允许一个请求查询数据库
  3. 双Key策略:主Key过期时间短,备Key过期时间长
  4. 缓存预热:定时更新热点数据

9.3 缓存雪崩#

问题:大量缓存同时过期或Redis宕机

解决方案

避免同时过期

  1. 随机过期时间:基础时间 + 随机值
  2. 互斥锁:使用singleflight等工具
  3. 二级缓存:本地缓存 + Redis
  4. 缓存预热:提前加载热点数据

避免Redis宕机影响

  1. 高可用集群:主从、哨兵、Cluster
  2. 限流降级:保护数据库
  3. 熔断机制:快速失败

十、缓存与数据库一致性#

10.1 一致性问题的本质#

缓存一致性问题通常发生在”缓存数据存在业务更新”的场景,核心问题是:缓存删除前旧数据被查询到,并在删除后旧数据执行了覆盖

10.2 更新策略对比#

10.2.1 Cache Aside Pattern(旁路缓存)#

主流方案,分为读写两个流程:

写操作

1. 更新数据库
2. 删除缓存

读操作

1. 读缓存,命中返回
2. 未命中,读数据库
3. 写入缓存

10.2.2 各种更新策略的问题#

策略操作顺序主要问题发生条件
先删缓存,后更新DBredis.delete() → db.update()旧数据回填并发读在删除后、更新前查询DB
先更新DB,后删缓存db.update() → redis.delete()短暂不一致删除失败或延迟
先更新缓存,后更新DBredis.set() → db.update()DB更新失败导致不一致缓存有新值,DB是旧值

10.3 延迟双删策略#

10.3.1 核心思想#

删除缓存 → 更新数据库 → 延迟N秒 → 再次删除缓存

延迟时间计算公式

延迟时间 = 1.5 * TP99(
数据主从同步时间 +
数据库查询时间 +
写入缓存时间
)

10.3.2 实现方式演进#

1. 同步延迟双删

// 问题:阻塞业务线程,增加接口RT
redis.delete(key);
db.update();
Thread.sleep(100); // 阻塞当前线程
redis.delete(key);

2. 异步延迟双删

// 优点:不阻塞主线程
// 问题:重启时丢失延迟任务
redis.delete(key);
db.update();
executorService.schedule(() -> {
redis.delete(key);
}, 100, TimeUnit.MILLISECONDS);

3. MQ延迟双删

// 优点:持久化,重启不丢失
// 问题:增加系统复杂度
redis.delete(key);
db.update();
mq.sendDelay("DELETE_CACHE_TOPIC", key, 100);

4. 监听Binlog异步删除

// 优点:无代码侵入,解耦业务
// 实现:Canal监听MySQL binlog
业务代码:
db.update(); // 仅更新数据库
Canal系统:
监听binlog → 删除缓存 → 延迟删除

10.4 最佳实践建议#

10.4.1 方案选择#

  • 简单系统:使用”先更新DB,后删缓存”
  • 中等复杂度:使用MQ异步延迟双删
  • 复杂系统:使用Binlog + Canal方案

10.4.2 注意事项#

  1. 延迟双删不是万能的:只能大概率解决问题
  2. 读写分离场景:必须考虑主从延迟
  3. 不要过度设计:根据业务容忍度选择方案
  4. 分布式锁谨慎使用
    • 串行化会严重影响性能
    • 增加Redis强依赖
    • 可能导致雪崩效应

10.4.3 核心原则#

  • 最终一致性:接受短暂不一致,保证最终一致
  • 业务优先:根据业务对一致性的要求选择方案
  • 避免强一致:如果要求强一致,不应使用缓存
  • 监控告警:建立完善的监控体系

10.5 一致性问题总结#

问题根源

  • 缓存和数据库是两个独立系统
  • 无法保证原子性操作
  • 网络延迟和故障

解决思路

  1. 尽量避免不一致(合理的更新策略)
  2. 降低不一致影响(缩短时间窗口)
  3. 接受最终一致性(合理的业务预期)

十一、Redis内存管理#

11.1 过期删除策略#

Redis采用惰性删除 + 定期删除组合策略:

  1. 惰性删除:访问时检查是否过期
  2. 定期删除:定时任务随机抽样删除
  3. 过期字典:Hash表存储key和过期时间

11.2 内存淘汰策略#

当内存不足时(maxmemory限制):

策略说明
noeviction不淘汰,拒绝写入(默认)
allkeys-lru所有key中淘汰最近最少使用
allkeys-lfu所有key中淘汰最不频繁使用
allkeys-random所有key中随机淘汰
volatile-lru过期key中淘汰最近最少使用
volatile-lfu过期key中淘汰最不频繁使用
volatile-random过期key中随机淘汰
volatile-ttl淘汰TTL最短的key

11.3 LRU vs LFU#

11.3.1 LRU(Least Recently Used)#

传统LRU

  • 双向链表实现
  • 访问移到头部
  • 淘汰尾部

Redis近似LRU

  • 随机采样(默认5个)
  • 记录最后访问时间戳
  • 淘汰最久未访问的
  • 问题:缓存污染(大量数据一次性读取)

11.3.2 LFU(Least Frequently Used)#

Redis LFU实现

  • 24位字段:16位时间戳 + 8位访问频率
  • 访问频率采用对数增长
  • 解决了LRU的缓存污染问题

11.4 大Key问题#

11.4.1 判断标准#

  • String类型:value > 1MB
  • 集合类型:元素数 > 10000

11.4.2 影响#

  • 内存占用过多
  • 网络传输阻塞
  • 主从同步延迟
  • 集群数据倾斜
  • 影响持久化性能

11.4.3 解决方案#

  1. 拆分:大Key拆分为多个小Key
  2. 异步删除:使用UNLINK代替DEL
  3. 过期时间:设置更短的TTL
  4. 定期扫描:及时发现并处理

十二、Redis高可用#

12.1 主从复制#

12.1.1 同步方式#

  • 全量同步

    • 主节点生成RDB快照
    • 发送RDB文件给从节点
    • 发送缓冲区命令
  • 增量同步

    • 基于复制缓冲区(repl_backlog_buffer)
    • 使用PSYNC命令实现部分重同步
    • 通过offset判断同步位置

12.1.2 一致性判断#

通过复制偏移量(replication offset)判断主从是否一致

12.2 哨兵模式#

12.2.1 故障检测#

  1. 组建哨兵集群:通过发布/订阅机制来监控主从节点
  2. 监控节点
    • 定期发送PING命令
    • 通过INFO命令获取从节点信息
  3. 故障判定
    • 主观下线:单个哨兵判定
    • 客观下线:达到quorum数量哨兵同意

12.2.2 故障转移#

  1. 选举Leader哨兵
    • 需要majority(超过半数)票数
    • 注意:quorum和majority是不同的值
  2. 选择新主节点
    • 优先级(replica-priority)
    • 复制偏移量(数据最新)
    • Run ID(最小者胜出)
  3. 执行切换
    • 被选出的从节点执行SLAVEOF NO ONE
    • 其他从节点指向新主
    • 通知客户端新主节点信息

12.3 Redis Cluster#

  • 16384个槽位(slots)
  • 数据分片存储
  • 去中心化架构
  • 自动故障转移
MySQL与Redis核心知识点
https://fuwari.vercel.app/posts/database_and_redis/
作者
Jarrett
发布于
2025-08-24
许可协议
CC BY-NC-SA 4.0