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)核心结构哈希表dictB 树查找复杂度O(1)O(logN)数据组织Key-Value 直接定位多层树节点逐层遍历Redis 的哈希表通过计算 key 的哈希值直接定位到桶bucket一步到位。MySQL 的 B 树哪怕只有百万行数据也要从根节点一路走到叶子节点层层比较。更关键的是Redis 的底层其实有6 种数据结构在支撑底层结构对应的数据类型特点简单动态字符串SDSString二进制安全O(1) 取长度哈希表dictHashO(1) 查找链地址法解决冲突压缩列表ziplist→ listpackHash/List/ZSet小数据量时内存紧凑连续存储双向链表List顺序读写 O(N)跳表skiplistSorted 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 多路复用底层调用epollLinux、kqueueBSD、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 模型为什么不用 epollMySQL 在网络层用的是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)线程模型单线程命令执行 多线程 IO6.0多线程 连接池IO 模型epoll 多路复用事件驱动BIO poll/select典型延迟微秒级毫秒级事务支持无仅简单事务ACID 完整支持适用场景缓存、计数、排行榜、分布式锁复杂查询、事务、持久化写在最后Redis 快不是因为某一个点而是内存 哈希表 单线程无锁 epoll 多路复用这四张牌同时打出的结果。每一张单拿出来都是优势合在一起就是碾压。但快不等于全能。Redis 不支持复杂查询、没有事务保障、数据依赖内存容量。MySQL 慢是因为它要保数据安全、保事务一致、保查询灵活——这些都是有代价的。选型的本质不是谁更快而是谁更适合。需要极致速度且数据模型简单Redis 当仁不让。需要复杂关系和事务保障MySQL 无可替代。