引言在高并发系统中缓存是提升性能的核心组件。Redis作为最流行的内存数据库不仅提供了丰富的数据结构还支持集群、哨兵、持久化等企业级特性。然而不合理的缓存设计会导致数据不一致、缓存穿透、热点Key等问题严重影响系统稳定性。本文将从Redis集群架构设计出发深入探讨缓存策略、高可用方案以及生产环境中的优化技巧。一、Redis集群架构选型1.1 部署模式对比| 模式 | 数据分片 | 高可用 | 适用场景 | 容量上限 | |------|----------|--------|----------|----------| | 单机 | 无 | 无 | 开发测试 | 内存上限 | | 主从复制 | 无 | 手动切换 | 读多写少 | 内存上限 | | Sentinel | 无 | 自动故障转移 | 中小规模 | 内存上限 | | Cluster | 有 | 自动 | 大规模生产 | 线性扩展 | | Codis | 有 | 依赖组件 | 已有集群平滑迁移 | 线性扩展 |1.2 Redis Cluster架构┌──────────────────────────────────────────┐ │ Redis Cluster (6 nodes) │ │ │ │ Master A (0-5460) Slave A1 │ │ ├ Key1, Key2... (replica) │ │ │ │ Master B (5461-10922) Slave B1 │ │ ├ Key3, Key4... (replica) │ │ │ │ Master C (10923-16383) Slave C1 │ │ ├ Key5, Key6... (replica) │ │ │ │ 每个Key通过CRC16(key) % 16383计算slot │ └──────────────────────────────────────────┘Cluster搭建# 创建6个节点3主3从 for port in 7000 7001 7002 7003 7004 7005; do mkdir -p redis-cluster/$port cat redis-cluster/$port/redis.conf EOF port $port cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes daemonize yes bind 0.0.0.0 protected-mode no maxmemory 2gb maxmemory-policy allkeys-lru EOF done # 启动所有节点 for port in 7000 7001 7002 7003 7004 7005; do redis-server redis-cluster/$port/redis.conf done # 创建集群 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二、缓存策略设计2.1 缓存更新策略| 策略 | 实现 | 优点 | 缺点 | |------|------|------|------| | Cache Aside | 应用控制读写 | 简单直观 | 并发更新可能不一致 | | Read Through | 缓存自身加载 | 对应用透明 | 首次加载延迟 | | Write Through | 同步写缓存DB | 一致性高 | 写入延迟增加 | | Write Behind | 异步批量写DB | 写入性能高 | 可能丢数据 |Cache Aside模式最常用import redis import json from functools import wraps class CacheManager: def __init__(self): self.redis_client redis.Redis( hostlocalhost, port7000, decode_responsesTrue, clusterTrue # 集群模式 ) self.db Database() # 实际数据库 def get(self, key, loaderNone, ttl3600): 读取缓存不存在则加载 value self.redis_client.get(key) if value is not None: return json.loads(value) # 缓存未命中 if loader: value loader() if value is not None: self.redis_client.setex(key, ttl, json.dumps(value)) return value return None def set(self, key, value, ttl3600):