Redis 进阶与持久化实战教程

Redis 进阶与持久化机制

1.1 持久化机制

Redis 提供三种持久化机制:

✅ 1. RDB(快照)持久化

RDB 将 Redis 在某个时间点的数据保存成二进制文件 dump.rdb

🧩 特点:

  • 启动恢复速度快
  • 性能好,适合冷备份
  • 但断电会丢失最后一次快照之后的数据

💡 配置(redis.conf):

1
2
3
save 900 1     # 900秒内至少1个key变化,触发快照
save 300 10 # 5分钟内至少10个key变化
save 60 10000 # 60秒内超过10000个key变化

📌 Python 示例(模拟写数据 + 强制触发 RDB):

1
2
3
4
5
6
7
8
9
10
import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# 写入大量数据
for i in range(1000):
r.set(f"user:{i}", f"value-{i}")

# 手动触发RDB保存(需开启redis-cli)
# 命令行输入 SAVE

✅ 2. AOF(Append Only File)持久化

记录每一个写命令,并在重启时重新执行。

🧩 特点:

  • 数据更不易丢失
  • 文件体积大
  • 恢复速度慢于 RDB

💡 配置(redis.conf):

1
2
3
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec # 推荐:每秒同步

📌 Python 示例:

1
2
3
4
5
import redis

r = redis.Redis()
r.set("product:1001", "iPhone15")
r.set("stock:1001", 50)

这些命令都会追加到 AOF 文件中。


✅ 3. 混合持久化(RDB + AOF)

Redis 4.0 起支持混合方式,在 AOF 文件中先写入 RDB 再写命令。

📌 开启方式:

1
aof-use-rdb-preamble yes

🎯 实战建议:

企业中可选 混合持久化,在容灾与性能间做平衡。


1.2 主从复制(Replication)

Redis 支持一主多从结构,从节点实时同步主节点数据。


🧩 优势:

  • 读写分离,减轻主节点压力
  • 灾备冗余,容灾恢复快

💡 主从配置:

主节点无需配置,子节点配置如下:

1
replicaof 127.0.0.1 6379   # 指定主节点IP和端口

📌 Python 示例:

1
2
3
4
5
6
7
8
9
import redis

# 写数据到主节点
master = redis.Redis(host='localhost', port=6379)
master.set("user:1", "Alice")

# 读数据从从节点(主从同步完成后)
slave = redis.Redis(host='localhost', port=6380)
print(slave.get("user:1"))

1.3 Redis 哨兵模式(Sentinel)

Redis Sentinel 用于监控主从结构自动主从切换


🧩 工作机制:

  • 节点故障时自动切换主节点
  • 通知客户端新的主节点地址

💡 sentinel.conf 示例:

1
2
3
4
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

📌 启动哨兵:

1
redis-sentinel sentinel.conf

📌 Python 示例(感知主节点):

建议使用 redis.sentinel.Sentinel 模块:

1
2
3
4
5
6
7
from redis.sentinel import Sentinel

sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
master = sentinel.master_for('mymaster', socket_timeout=0.1)

master.set("key", "value")
print(master.get("key"))

1.4 Redis 集群模式(Cluster)

Redis Cluster 是官方提供的分布式方案


🧩 特点:

  • 分片存储数据(哈希槽 slot)
  • 自带容错、主从、复制机制
  • 最少需要 6 个节点(3 主 3 从)

💡 搭建 Redis Cluster:

  • 每个节点配置:
1
2
3
4
5
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
  • 创建集群命令:
1
2
3
4
redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

📌 Python 使用 redis-py-cluster

1
pip install redis-py-cluster
1
2
3
4
5
6
7
from rediscluster import RedisCluster

startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)

rc.set("user:200", "Tom")
print(rc.get("user:200"))

📌 Redis 哈希槽(Hash Slot)详解

📌 什么是哈希槽?

在 Redis 的 集群模式(Cluster) 中,为了实现数据的分布式存储,引入了一个核心概念 —— 哈希槽(Hash Slot)

  • Redis 集群总共有 16384 个哈希槽(编号范围 0~16383)
  • 所有的 key 通过哈希算法映射到这 16384 个槽位中
  • 每个节点负责一定数量的哈希槽(例如:3 个节点,每个大约 5461 个槽)

⚠️ 注意:哈希槽不是键,而是键分布到节点的桥梁。


🧮 哈希槽是如何计算的?

Redis 使用 CRC16 算法计算 key 的哈希值,并对 16384 取模:

1
hash_slot = CRC16(key) % 16384

🔎 示例(使用 redis-cli):

1
2
127.0.0.1:7000> CLUSTER KEYSLOT mykey
15495

表示:mykey 被映射到 哈希槽 15495


🎯 为什么引入哈希槽?

传统的 Redis 无法分布式部署,单点数据量大容易瓶颈。

哈希槽的引入可以解决:

  1. 均匀分布:数据根据哈希槽均匀地分布到不同节点
  2. 水平扩容:可以动态迁移槽位实现节点扩展
  3. 故障转移:某个节点宕机,槽位迁移至其他节点

🏗️ 集群架构中的哈希槽分配

一个标准 Redis 集群:

1
2
3
Node A: 0 - 5460
Node B: 5461 - 10922
Node C: 10923 - 16383

当插入一个 key 时:

  • Redis 通过 CRC16 计算 key 映射的 slot
  • 将该键值对存入负责该槽的节点

🔁 集群重分片(重新分配槽)

当新增节点 D,Redis 支持将部分槽从 A/B/C 迁移至 D:

1
redis-cli --cluster reshard 127.0.0.1:7000

系统会提示你:

  • 迁移多少个槽(如 2000)
  • 源节点
  • 目标节点

迁移完成后,新节点开始接收请求。


🧠 哈希标签(Hash Tags)

为了确保多个 key 在同一个槽中(保证原子性操作),Redis 提供了 Hash Tag

1
2
{user1000}.name
{user1000}.email

以上两个 key 的槽是一样的,因为 Redis 只对 花括号中的内容进行 CRC16 计算。

📌 常用于:

  • Lua 脚本操作多个 key
  • pipeline 或事务中 key 保证在一个节点上

🛠️ Python 示例

我们使用 crcmod 模拟 Redis 的 CRC16 算法计算哈希槽。

✅ 安装依赖
1
pip install crcmod
✅ Python 示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
import crcmod

def get_redis_slot(key: str) -> int:
# 获取 {} 中内容作为计算字段
if "{" in key and "}" in key:
key = key[key.find("{") + 1:key.find("}")]
crc16 = crcmod.predefined.mkPredefinedCrcFun("crc-16")
return crc16(key.encode()) % 16384

# 示例
keys = ["user:1001", "{user1001}.name", "{user1001}.email"]
for k in keys:
print(f"Key: {k}, Slot: {get_redis_slot(k)}")
✅ 输出结果示例
1
2
3
Key: user:1001, Slot: 5796
Key: {user1001}.name, Slot: 5796
Key: {user1001}.email, Slot: 5796

📌 你可以看到,{user1001}.xxx 的槽值相同,便于放在一个节点上。


❗ 注意事项

场景 说明
事务(MULTI/EXEC) 所有 key 必须在一个槽内,否则执行失败
Lua 脚本 同样受限于槽
pipeline 批量操作 建议使用哈希标签确保 key 落入同一个槽
拓展节点 使用 redis-cli --cluster reshard 操作槽

✅ 使用建议

  • 在设计 key 时,合理使用哈希标签 {}
  • 避免在一个操作中跨槽访问多个 key
  • 定期监控哈希槽的分布情况(可使用 RedisInsight 等工具)
  • 做好数据迁移/节点扩容前的预案(备份、验证)

📦 企业实战建议:

场景 推荐模式
高性能缓存 RDB + AOF 混合持久化
弹性读写分离 主从复制
高可用部署 Sentinel 哨兵模式
海量分布式存储 Cluster 集群模式

🧠 总结

Redis 的进阶使用与企业级部署策略,包括:

  • RDB、AOF 与混合持久化的取舍与配置
  • 主从架构实现读写分离
  • 哨兵模式保证高可用
  • 集群模式解决海量数据水平扩展

✅ 建议配合 Prometheus + Grafana 进行监控部署
✅ 持久化策略可根据业务数据安全级别动态调整


Redis 进阶与持久化实战教程
https://dreamshao.github.io/2025/07/15/redis持久化/
作者
Yun Shao
发布于
2025年7月15日
许可协议