Redis篇9——Redis深度剖析:

在上一篇文章中,我们聊了 Redis 高性能的基石------I/O 多路复用。我们把它比作**"海底捞的沙发等位模式"**:通过一个大屏幕(Epoll)让唯一的服务员(主线程)能监控无数个在沙发上等待的客人,从而避免了"死排队"。

但是,随着互联网的发展,只有"大屏幕叫号"还不够了。于是 Redis 6.0 引入了多线程。

很多人听到"多线程"三个字就开始慌:Redis 变复杂了吗?需要加锁了吗? 别急,今天我们继续用餐厅的逻辑,把这三个核心问题一次性讲清楚。


一、 Redis 6.0 为什么要引入多线程?

首先要澄清一个概念:Redis 6.0 引入多线程,并不是说它变成了一个多线程数据库。 它操作内存数据的核心逻辑(也就是"Get/Set"这种内存操作),依然是单线程的。

那多线程用在哪儿了?为什么要用?

1. 之前的瓶颈:大厨太累了

我们回到海底捞的场景。 在 Redis 6.0 之前,虽然有"大屏幕"负责叫号,客人不需要傻站着排队,但是当号叫到了之后,流程是这样的:

  • 场景(单线程模式)

    1. 大屏幕叫号:5 号桌客人入座。

    2. 点单(IO Read - 慢)大厨(主线程) 必须亲自跑到 5 号桌,拿着小本本听客人报菜名。客人说话慢,大厨就得在那儿等着记录。

    3. 做菜(Execute - 快):大厨拿到单子,跑回后厨,瞬间炒好。

    4. 上菜(IO Write - 慢):大厨又得亲自端着菜跑回 5 号桌。

发现问题了吗? 现在的 CPU(大厨的厨艺)太快了,纳秒级的。真正拖后腿的是**"跑到桌边听客人说话""端菜过去"**这两个环节(即网络 I/O 读写)。 大厨的时间全浪费在跑堂上了,灶台经常是空的。

2. Redis 6.0 的变革:雇佣"传菜员"

简单来说:前面通过IO多路复用去避免BIO阻塞的思路还是不变的,只不过针对传递数据的过程,多引入了几个线程来操作,降低了主线程的压力。

为了解放大厨,Redis 6.0 引入了多线程 I/O。 这里的多线程,相当于给大厨配了几个**"传菜员"**。

  • 场景(6.0 多线程模式)

    1. 大屏幕叫号:5、6、7 号桌客人同时入座。(这一步没变,依然是主线程负责监控)。

    2. 点单(多线程并发 - 变了!): 大厨大手一挥:"传菜员 A、B、C,你们分别去听 5、6、7 号桌的点单,把单子记下来给我!"

      • 效果 :原来大厨要跑 3 趟,现在 3 个传菜员同时跑。大厨站在灶台边,一步都没动。
    3. 做菜(单线程执行 - 没变!) : 传菜员把 3 张单子交给大厨。 注意:大厨依然是一个人、挨个儿炒这 3 份菜。 因为不需要别人插手核心的炒菜环节,所以不需要复杂的锁,依然极速且安全。

    4. 上菜(多线程并发 - 变了!): 菜炒好了,大厨让传菜员 A、B、C 分别端走。

3. 结论

Redis 6.0 引入多线程,是为了解决网络 I/O 的读写瓶颈。 它把"听"和"说"这两个费嘴皮子的事儿外包给了子线程,让主线程更专注于"动脑子"(操作内存)。


二、 架构取舍:Redis 是 AP 还是 CP?

聊完了微观的线程,我们看看宏观的架构。 在分布式系统的 CAP 定理中,Redis 是坚定的 AP 派(允许容错)

  • C (Consistency 一致性):所有节点在同一时间的数据完全一致。

  • A (Availability 可用性):服务一直可用,哪怕读到的数据是旧的。

  • P (Partition Tolerance 分区容错性):网线断了系统也能工作。

1. 为什么是 AP?

想象一下,Redis 的主节点在北京,从节点在上海。突然由于施工,中间的光缆断了(分区 P 发生)。 此时,有一个用户向北京节点写入数据。

  • 如果是 CP(如 Zookeeper、银行系统) : 北京节点会说:"我不确定上海那边能不能收到,为了防止数据不一致,我拒绝写入,暂停服务 。" ------ 保了数据,丢了服务。

  • 如果是 AP(Redis) : 北京节点会说:"管他呢,能不能连上上海以后再说。我先收下你的数据,保证你现在能用 。" ------ 保了服务,丢了一致性。

2. 代价:异步复制的数据丢失

因为 Redis 选择了"快"和"可用",它默认采用了异步复制

  1. 主节点写入成功。

  2. 主节点立刻返回 OK 给客户端。

  3. 主节点在后台通过异步线程,慢慢把数据同步给从节点。

风险 :如果在第 2 步和第 3 步之间,主节点突然断电,而数据还没来得及发给从节点。那么当从节点变成新的主节点时,这条数据就永远丢失了

这就是 Redis 的性格:活着比完美更重要。


三、 事务哲学:Redis 支持事务回滚吗?

很多用惯了 MySQL 的同学,在用 Redis 事务时会觉得它是个"渣男"。

1. Redis 的事务是什么?

Redis 的事务(MULTI / EXEC)本质上是一个**"不插队的批处理队列"**。

  • 你输入 MULTI,Redis 就给你发一个空篮子(队列)。

  • 你往里放命令,Redis 不执行,只告诉你 QUEUED(入队成功)。

  • 你喊 EXEC,Redis 就锁住大厨,一口气把篮子里的命令全做完,中间不允许任何人插队。

2. 为什么不支持回滚?

在 MySQL 中,如果事务执行一半报错了,数据库会像暖男一样,通过 Undo Log 帮你回滚,仿佛一切都没发生过。 但在 Redis 里,如果中间有一条命令报错(比如对 String 类型求 List 长度):

  • 报错的那条命令失败。

  • 其他的命令依然照常执行!

  • Redis 拒不认错,拒不回滚

3. Redis 为什么要这么做?

这体现了 Redis 极简主义的设计哲学:

  1. 性能至上 :支持回滚需要记录复杂的日志(Undo Log),还要管理版本控制,这太慢了。Redis 是跑在内存里的超跑,不能背这么重的包袱。

  2. 都是你的错 :Redis 官方认为,事务失败通常是因为语法错误类型错误 (比如把字符串当数组用)。这是程序员在写代码时逻辑不严谨造成的 Bug,应该在开发阶段修好,而不是让数据库在生产环境牺牲性能来给你兜底。

所以,Redis 的态度是:"我很快,但我很冷酷。你自己写代码小心点。"


四、 总结

这篇博客我们站在上一篇 IO 模型的基础上,进一步拆解了 Redis 的三个核心特性:

  1. 线程模型 :从"大厨跑堂"进化为"大厨+传菜员",Redis 6.0 的多线程只用来处理网络读写,核心计算依然是单线程。

  2. 架构模式 :Redis 是 AP 系统。为了高可用和低延迟,它接受短暂的数据不一致,甚至接受极端情况下的数据丢失。

  3. 事务特性 :Redis 支持批量执行的原子性,但不支持回滚。它要求开发者对自己写的代码负责,以换取极致的性能。

到此为止,Redis篇完结。

相关推荐
今晚务必早点睡2 小时前
Redis——快速入门第五课:Redis 常见坑 & 面试高频问题
数据库·redis·面试
理人综艺好会2 小时前
Redis学习之单线程
redis·websocket·学习
盒马coding2 小时前
Patroni + HAProxy + Keepalived + watchdog + ETCD 各组件原理
数据库·etcd
TG:@yunlaoda360 云老大2 小时前
如何通过华为云国际站代理商CSBS进行跨Region备份与容灾?
大数据·数据库·华为云
bing.shao2 小时前
FerretDB 完美对接 MongoDB
数据库·mongodb
大学生资源网2 小时前
基于springboot的农村综合风貌展示平台设计与实现(源码+文档)
java·数据库·spring boot·后端·毕业设计·源码·springboot
严文文-Chris2 小时前
向量数据库选型完全指南
数据库
未来之窗软件服务2 小时前
自建开发工具IDE(七)数据库集群智能升级东方仙盟数据库同化,五行八卦排序+游戏修仙,精准补齐差异还能圆武侠梦—东方仙盟筑基期
数据库·游戏·oracle·仙盟创梦ide·东方仙盟·东方仙盟架构·东方仙盟商业开发
奔跑吧邓邓子2 小时前
Neo4j图数据库实战:解锁关系数据的无限潜力
数据库·实战·neo4j