80 lines
1.9 KiB
Markdown
80 lines
1.9 KiB
Markdown
---
|
||
title: "Redis 进阶:数据结构底层实现与集群方案"
|
||
date: "2026-05-20"
|
||
category: "数据库"
|
||
tags: ["Redis", "缓存", "数据结构"]
|
||
excerpt: "从 SDS、ziplist、skiplist 等底层数据结构讲起,到 RDB/AOF 持久化、哨兵模式、Cluster 集群。"
|
||
---
|
||
|
||
## 一、底层数据结构
|
||
|
||
### 1.1 简单动态字符串(SDS)
|
||
|
||
Redis 没有使用 C 语言的字符串,而是自己实现了 SDS:
|
||
|
||
- 二进制安全
|
||
- 杜绝缓冲区溢出
|
||
- 获取字符串长度 O(1)
|
||
- 空间预分配和惰性释放
|
||
|
||
### 1.2 压缩列表(ziplist)
|
||
|
||
连续内存块组成的顺序存储结构,节约内存:
|
||
|
||
```
|
||
[zlbytes][zltail][zllen][entry...][zlend]
|
||
```
|
||
|
||
当列表元素较少或元素较小时使用。Redis 7.0 后被 listpack 替代。
|
||
|
||
### 1.3 跳跃表(skiplist)
|
||
|
||
有序集合的底层实现之一,平均 O(log n) 的查找效率:
|
||
|
||
```c
|
||
typedef struct zskiplistNode {
|
||
sds ele; // 成员对象
|
||
double score; // 分值
|
||
zskiplistNode *backward; // 后退指针
|
||
zskiplistLevel {
|
||
zskiplistNode *forward;
|
||
unsigned long span;
|
||
} level[];
|
||
} zskiplistNode;
|
||
```
|
||
|
||
## 二、持久化机制
|
||
|
||
### 2.1 RDB
|
||
|
||
快照方式,将某一时刻的内存数据写入磁盘:
|
||
|
||
```
|
||
save 900 1 # 900秒内至少1个key变化
|
||
save 300 10 # 300秒内至少10个key变化
|
||
```
|
||
|
||
### 2.2 AOF
|
||
|
||
记录每次写操作命令,重启时重放:
|
||
|
||
- `appendfsync always` — 每条命令都同步
|
||
- `appendfsync everysec` — 每秒同步(推荐)
|
||
- `appendfsync no` — 由操作系统决定
|
||
|
||
> 生产环境建议 RDB + AOF 同时开启,取长补短。
|
||
|
||
## 三、集群方案
|
||
|
||
### 3.1 哨兵模式
|
||
|
||
监控主节点,自动故障转移。最少需要 3 个哨兵节点。
|
||
|
||
### 3.2 Cluster 集群
|
||
|
||
数据分片,16384 个哈希槽分布在多个节点。支持水平扩展。
|
||
|
||
## 四、总结
|
||
|
||
理解底层数据结构有助于合理选择数据类型和预估内存占用。生产环境要做好持久化和高可用方案。
|