当前位置: 首页 > news >正文

Redis 为什么速度远超MySQL?

Redis 为什么速度远超 MySQL?一文讲透 IO 模型与底层数据结构

当 Redis 的响应以微秒计,而 MySQL 还在磁盘上"翻箱倒柜"时,这个性能差距到底从何而来?

答案藏在两个维度里:数据怎么存的,以及请求怎么处理的


一、存储介质:内存 vs 磁盘,这是降维打击

Redis 把所有数据塞进内存,MySQL 的数据躺在磁盘上。

这不是"快一点"的区别,而是量级的区别。内存访问速度是纳秒级,磁盘 I/O 是毫秒级——差了将近100 万倍

MySQL 即便有 InnoDB Buffer Pool 缓存热点数据,一旦缓存未命中,就必须回磁盘。而 Redis 从第一次访问开始,就是内存直读,根本不存在"缓存未命中"这个概念。

Redis 的瓶颈从来不是 CPU,而是内存大小和网络带宽。


二、底层数据结构:O(1) vs O(logN),算法层面的碾压

特性RedisMySQL (InnoDB)
核心结构哈希表(dict)B+ 树
查找复杂度O(1)O(logN)
数据组织Key-Value 直接定位多层树节点逐层遍历

Redis 的哈希表通过计算 key 的哈希值,直接定位到桶(bucket),一步到位。MySQL 的 B+ 树哪怕只有百万行数据,也要从根节点一路走到叶子节点,层层比较。

更关键的是,Redis 的底层其实有6 种数据结构在支撑:

底层结构对应的数据类型特点
简单动态字符串(SDS)String二进制安全,O(1) 取长度
哈希表(dict)HashO(1) 查找,链地址法解决冲突
压缩列表(ziplist)→ listpackHash/List/ZSet(小数据量时)内存紧凑,连续存储
双向链表List顺序读写 O(N)
跳表(skiplist)Sorted Set多级索引,查找 O(logN)
整数数组List/ZSet(小整数时)顺序存储,节省空间

其中跳表是个精妙设计:在链表基础上增加多级索引,从底层往上"跳",把 O(N) 的遍历压到 O(logN)。这也是 Sorted Set 能高效实现排行榜的核心原因。

而 MySQL 的 B+ 树虽然支持范围查询,但每次查询都要经历多次磁盘寻址,代价不菲。


三、IO 模型:这才是 Redis 真正的杀手锏

如果说内存存储是"先天优势",那IO 多路复用就是 Redis 的"后天绝学"。

先看五种 IO 模型的本质区别

模型特点适用场景
阻塞 IO线程傻等,直到数据就绪连接少、简单场景
非阻塞 IO线程轮询,CPU 空转不推荐,浪费资源
IO 多路复用一个线程管多个连接,事件驱动高并发、连接数多 ✅
信号驱动 IO内核发信号通知,TCP 不实用UDP 为主
异步 IO全程不阻塞,理想模型依赖 OS 支持,Java 7+ 才有

Redis 用的是IO 多路复用,底层调用epoll(Linux)、kqueue(BSD)、select(兜底),默认epoll

epoll 的核心优势

  • 没有连接数限制(select 有 1024 的硬伤)
  • 内存共享机制,不需要像 select 那样每次把 fd 集合从用户态拷贝到内核态
  • 内核直接维护事件就绪列表,效率远高于用户态轮询

Redis 6.0 之前:纯粹的单线程 + 多路复用

一个线程搞定一切:接收请求 → 执行命令 → 返回响应。

客户端连接 → epoll 监听 → 事件就绪 → 单线程处理 → 响应

优势极其明显:无锁、无上下文切换、无竞态条件。命令执行是内存操作,微秒级完成,单线程完全够用,QPS 轻松破万。

但瓶颈也很清晰:当网络 IO 本身成为负担(大包读写、高延迟网络),主线程会卡在 IO 上,后面的命令全部排队。

Redis 6.0 之后:多线程 IO 登场

Redis 6.0 引入了多线程,但注意——核心命令执行依然是单线程

新架构是这样的:

阶段负责线程说明
接收连接、读请求IO 线程(默认 4 个)多线程并行处理网络 IO
执行命令(读写数据)主线程(单线程)无锁执行,保证原子性
写响应IO 线程多线程并行写入

这是一个精妙的折中:把最耗时间的 IO 从主线程剥离,把最需要安全的命令执行留给单线程。既解决了 IO 瓶颈,又没丢掉无锁的简洁。


四、MySQL 的 IO 模型:为什么不用 epoll?

MySQL 在网络层用的是BIO(阻塞 IO)+ 连接池,配合poll/select做多路复用。

为什么不上 epoll?三个字:JDBC 不支持

JDBC 诞生于 20 年前,那时只有 BIO。MySQL 的 Java 驱动(Connector/J)遵循 JDBC 标准,天然就是阻塞模式。每来一个连接,MySQL 就开一个线程(受max_connections限制)。

这和 Web Server 的场景完全不同:

  • Web Server:请求无状态、短促,NIO + 多路复用是最优解
  • MySQL:一个 session 里 SQL 必须串行执行(事务隔离、锁机制),连接本身就是"重资源"

所以 MySQL 的架构选择是合理的:BIO + 线程池 + 连接池,在 JDBC 生态下已经是最优实践。随便加大连接数,反而会因为上下文切换和锁竞争拖垮性能。


五、一张表总结核心差距

维度RedisMySQL
存储介质内存磁盘(+ Buffer Pool 缓存)
数据结构哈希表/跳表等,O(1)B+ 树,O(logN)
线程模型单线程命令执行 + 多线程 IO(6.0+)多线程 + 连接池
IO 模型epoll 多路复用(事件驱动)BIO + poll/select
典型延迟微秒级毫秒级
事务支持无(仅简单事务)ACID 完整支持
适用场景缓存、计数、排行榜、分布式锁复杂查询、事务、持久化

写在最后

Redis 快,不是因为某一个点,而是内存 + 哈希表 + 单线程无锁 + epoll 多路复用这四张牌同时打出的结果。每一张单拿出来都是优势,合在一起就是碾压。

但快不等于全能。Redis 不支持复杂查询、没有事务保障、数据依赖内存容量。MySQL 慢,是因为它要保数据安全、保事务一致、保查询灵活——这些都是有代价的。

选型的本质不是"谁更快",而是"谁更适合"。需要极致速度且数据模型简单,Redis 当仁不让。需要复杂关系和事务保障,MySQL 无可替代。

http://www.jsqmd.com/news/1067659/

相关文章:

  • 微信单向好友检测神器:5分钟找出谁删除了你,让社交关系更透明
  • Visual Paradigm、Umbrello:UML建模工具2026年4月到6月更新(共11款)
  • Rust的#[repr(packed)]优化
  • mba论文国内外研究现状怎么查
  • Vision-R1_ Incentivizing Reasoning Capability in Multimodal Large Language Models
  • 性价比之巅:芯片/IC烧录座源头厂家技术揭秘
  • JavaScript的Array.fromAsync:从异步可迭代对象创建数组
  • EPE珍珠棉内衬是如何定制出来的?从产品测量到批量生产的完整流程
  • Python 协程任务错误处理机制
  • SPT-AKI存档编辑器:塔科夫离线版玩家的终极管理工具
  • AI技术重塑就业生态:AI岗位量爆涨8.7倍,顶尖人才年薪300万!
  • 当面试官让我手写一个Promise时,他在考察什么?
  • 解锁paperxie新玩法|毕业论文智能写作,轻松搞定毕业核心难题
  • 概率论基础概念 + MATLAB 可视化
  • K老答——从心所欲皆源本
  • 附近的机电维修在哪个地方
  • AI搜索引擎内容采集机制与GEO优化策略研究
  • 炉石传说自动化脚本终极指南:5分钟上手解放双手
  • 游戏图形特效粒子系统与后期处理
  • DM数据库SQL优化初探
  • 【共创季稿事节】重生AI推理大师:鸿蒙 NEXT 原生 AI 游戏应用开发实战
  • Go周刊2026W25 | Go 1.27 RC1 发布、goroutine 泄漏分析、gopls MCP 服务器、Go Micro v6、goja JS 引擎
  • Translumo:当屏幕上的文字不再是障碍,而是桥梁
  • Rust的async函数中的局部变量捕获策略与闭包在状态机生成中的内存分配
  • OpenCore Configurator:黑苹果图形化配置工具的终极指南
  • AI搜索占位总没效果?读懂收录逻辑才能破局
  • 职场宝妈的轻滋养,简简单单喝滴鸡精
  • 500kw柴油发电机组选型适配要点 山东大型厂区备用供电方案
  • 植物大战僵尸终极修改器:PvZ Toolkit完整技术解析与使用指南
  • 可靠性技术软件容错设计与故障恢复的自动化机制