线程模型
Redis 是单线程还是多线程?
| 版本 | 命令执行 | 其他操作 |
|---|---|---|
| 6.0 前 | 单线程 | 持久化、删除等使用子进程 |
| 6.0+ | 单线程 | 网络 IO 可以多线程 |
为什么单线程还这么快?
| 原因 | 说明 |
|---|---|
| 纯内存操作 | 微秒级响应 |
| IO 多路复用 | 单线程处理多连接 |
| 高效数据结构 | 专门优化的数据结构 |
| 单线程无锁 | 避免上下文切换和锁竞争 |
Redis 6.0 多线程
网络模型
IO 多路复用
Redis 使用 IO 多路复用处理多个客户端连接。事件类型
| 事件 | 说明 |
|---|---|
| 文件事件 | 客户端连接、读写 |
| 时间事件 | 定时任务(serverCron) |
事件处理流程
数据结构
底层数据结构
| 结构 | 说明 | 用途 |
|---|---|---|
| SDS | 简单动态字符串 | String |
| IntSet | 整数集合 | 小 Set |
| Dict | 哈希表 | Hash、Set、ZSet |
| ZipList | 压缩列表 | 小 List、Hash、ZSet |
| QuickList | 快速列表 | List |
| SkipList | 跳表 | ZSet |
| Listpack | 紧凑列表(Redis 7.0+) | 替代 ZipList |
SDS(简单动态字符串)
| 特性 | C 字符串 | SDS |
|---|---|---|
| 获取长度 | O(n) | O(1) |
| 缓冲区溢出 | 可能 | 不会 |
| 修改字符串 | 每次都分配 | 预分配 + 惰性释放 |
| 二进制安全 | ❌ | ✅ |
Dict(哈希表)
ZipList(压缩列表)
SkipList(跳表)
- 平均查找复杂度 O(log n)
- 每个节点有多层指针
- 适合范围查询
数据类型与底层结构
| 类型 | 编码 |
|---|---|
| String | int、embstr、raw |
| List | quicklist(ziplist + 链表) |
| Hash | listpack(小)、hashtable(大) |
| Set | intset(整数)、hashtable |
| ZSet | listpack(小)、skiplist + hashtable(大) |
编码转换条件
过期策略
删除策略
| 策略 | 说明 | 优缺点 |
|---|---|---|
| 惰性删除 | 访问时检查是否过期 | 内存不及时释放 |
| 定期删除 | 定时随机检查并删除 | CPU 消耗 |