前言
前段时间,有位小伙伴去小米面试,被问到一个经典问题:“Redis 为什么能支撑 10 万+ QPS?”
他回答“因为它是内存数据库”,面试官追问:“Memcached 也是内存数据库,为什么 Redis 能处理更复杂的数据结构还更快?”他一时语塞,直接挂了。
今天这篇文章专门跟大家一起聊聊这个话题,希望对你会有所帮助。
一、开篇:10 万+ QPS 是什么概念?
先看一组官方基准测试数据(普通笔记本环境下):
- GET 请求:约 103,504 QPS
- SET 请求:约 100,894 QPS
- INCR 请求:约 99,662 QPS
开启 Pipeline 后,INCR 请求的 QPS 可飙升至 1,061,301,突破百万。
面试官想听的,绝不是“内存快”三个字。
下面我们用一张总览图揭示 Redis 高性能的四大支柱:

下面我们逐一深入剖析。
二、支柱一:内存为王
Redis 所有数据都存储在内存中。
一次内存访问约 0.1 微秒,而磁盘随机 IO 需要 10 毫秒。
内存比磁盘快 10 万倍。
示例对比:从 1000 万用户中查询某个 ID 的信息。
MySQL 即使有索引,至少需要 2~3 次磁盘 IO(20~30ms);
Redis 直接在内存中哈希查找,耗时约 0.1ms。
这就是量级的差距。

三、支柱二:极致的数据结构
Redis 提供了五种核心数据结构:字符串、哈希、列表、集合、有序集合。
每种结构都不是简单的封装,而是针对场景做了深度定制。
3.1 简单动态字符串(SDS)
C 语言原生字符串获取长度需要遍历 (O(N)),且修改时容易造成缓冲区溢出。Redis 设计了 SDS 结构:
struct sdshdr {
int len; // 已使用长度
int free; // 未使用长度
char buf[]; // 字节数组
};
graph LR
subgraph SDS结构
A[len=5] --> B[free=2]
B --> C[buf='H''e''l''l''o''\0'...]
end
- 获取长度 O(1):直接读
len 字段。
- 杜绝缓冲区溢出:修改前检查剩余空间,不足则自动扩容。
- 空间预分配:扩展时多分配一些空闲空间,减少内存重分配次数。
3.2 压缩列表(ziplist)
当哈希表或列表的元素较少、值较小时,Redis 会用 连续内存块 存储,称为 ziplist。
它避免了指针开销,且能充分利用 CPU 缓存。

- 优点:内存紧凑,访问快。
- 条件:元素个数 < 512 且值长度 < 64 字节时自动启用。
3.3 跳表(Skip List)
有序集合(ZSET)的底层实现之一。
跳表是多级索引链表,查找时间复杂度 O(logN),实现比平衡树简单。
跳表结构示意:

查找时从最高层开始,跳跃前进,效率极高。
3.4 渐进式 rehash
Redis 的哈希表扩容时,不会一次性将所有键值对迁移,而是 分多次、渐进地搬迁。这是 Redis 内部精妙的设计之一。

这样将搬家开销平摊到后续操作中,避免了服务卡顿。
四、支柱三:单线程 + IO 多路复用
Redis 处理网络请求的核心线程只有一个。
为什么单线程还能那么快?
- CPU 不是瓶颈:内存操作极快,CPU 等待时间很少。
- 无锁竞争:没有多线程同步开销。
- IO 多路复用:一个线程通过
epoll 监控成千上万个连接,有事件才处理。

这就是 Redis 能支撑 高并发 的核心——单线程处理逻辑,多线程处理网络 IO。
五、支柱四:从单线程到多核利用
Redis 6.0 之前,网络读写也是单线程,在高流量时可能成为瓶颈。
6.0 后引入了 IO 多线程,但 命令执行仍然是单线程。

- IO 读:多线程并行读取客户端请求并解析协议。
- 命令执行:主线程按顺序执行命令,保证原子性。
- IO 写:多线程并行将结果写回客户端。
这样充分利用了多核 CPU 的网络处理能力,而核心逻辑依然简单可靠。
六、其他性能助推器
Pipeline 批量操作:一次性发送多条命令,减少网络往返。
Jedis jedis = new Jedis("localhost");
Pipeline p = jedis.pipelined();
for (int i = 0; i < 1000; i++) {
p.incr("counter");
}
p.sync();
避免大 Key:单个 Key 超过 10KB 可能阻塞服务。使用 redis-cli --bigkeys 检查。
合理持久化:压测时可关闭持久化,避免 RDB/AOF 干扰。
七、优缺点与适用场景
| 优点 |
缺点 |
适用场景 |
| 性能极高(10 万+ QPS) |
存储成本高(内存贵) |
缓存加速 |
| 数据结构丰富 |
单线程命令易阻塞 |
实时计数器 |
| 持久化保障 |
单节点容量有限 |
分布式锁 |
| 高可用集群 |
大 Key 风险 |
排行榜/社交 Feed |
总结
Redis 的 10 万+ QPS,是四大支柱的合力结果:
- 内存存储:绕过磁盘 IO。
- 极致数据结构:SDS、ziplist、跳表、渐进式 rehash 等深度优化。
- 单线程 + IO 多路复用:避免锁竞争,高效处理并发。
- 多线程 IO:提升网络吞吐,保持核心简单。
知其然,更要知其所以然。
希望这篇图文并茂的深度解析,能帮你彻底理解 Redis 高性能的底层逻辑。你在面试中还遇到过哪些 Redis 刁钻问题?欢迎评论区交流~