Skip to content

Redis Cluster vs Codis vs Twemproxy vs 主从+哨兵对比

面试官:「你们项目用的是什么 Redis 集群方案?」

你:「用的主从 + Sentinel。」

面试官:「为什么不用 Cluster?」

你:「……」

今天来聊聊 Redis 分布式架构的各种方案,以及如何选择。

方案概览

方案数据分片高可用代理复杂度适用规模
主从 + Sentinel< 10 万 QPS
Codis< 100 万 QPS
Twemproxy< 50 万 QPS
Redis Cluster< 100 万 QPS
Redis 自建多实例手动自研自研按需

方案一:主从 + Sentinel

架构

┌─────────────────────────────────────────────────────────────────┐
│                      主从 + Sentinel 架构                         │
│                                                                 │
│              ┌───────────────┐                                  │
│              │   Sentinel    │                                  │
│              │   (哨兵集群)   │                                  │
│              └───────┬───────┘                                  │
│                      │                                           │
│              ┌───────▼───────┐                                  │
│              │    主节点       │                                  │
│              └───────┬───────┘                                  │
│                      │ 复制                                       │
│          ┌───────────┼───────────┐                              │
│          ▼           ▼           ▼                              │
│    ┌─────────┐ ┌─────────┐ ┌─────────┐                           │
│    │  从节点1  │ │  从节点2  │ │  从节点3  │                           │
│    └─────────┘ └─────────┘ └─────────┘                           │
│                                                                 │
│    客户端通过 Sentinel 获取主节点地址                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

特点

特性说明
优点架构简单、配置简单、故障自动切换
缺点无法水平扩展、主节点写入能力受限
适用场景小规模部署、读多写少、数据量有限

配置示例

bash
# 主节点配置
bind 0.0.0.0
port 6379
daemonize yes

# 从节点配置
replicaof 127.0.0.1 6379
replica-serve-stale-data yes

# Sentinel 配置
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000

适用规模

  • QPS:< 10 万(受主节点限制)
  • 数据量:< 100GB(受单机内存限制)
  • 节点数:通常 1 主 2 从

方案二:Codis

架构

┌─────────────────────────────────────────────────────────────────┐
│                         Codis 架构                               │
│                                                                 │
│   ┌──────────┐    ┌──────────┐    ┌──────────┐                  │
│   │  Codis   │    │  Codis   │    │  Codis   │                  │
│   │ Proxy 1  │    │ Proxy 2  │    │ Proxy 3  │                  │
│   └────┬─────┘    └────┬─────┘    └────┬─────┘                  │
│        │               │               │                         │
│        └───────────────┼───────────────┘                         │
│                        │                                         │
│              ┌─────────▼─────────┐                              │
│              │    Zookeeper      │                              │
│              │   (配置中心)       │                              │
│              └─────────┬─────────┘                              │
│                        │                                         │
│     ┌──────────────────┼──────────────────┐                     │
│     ▼                  ▼                  ▼                     │
│ ┌─────────┐        ┌─────────┐        ┌─────────┐                │
│ │  Redis  │        │  Redis  │        │  Redis  │                │
│ │ Master1 │        │ Master2 │        │ Master3 │                │
│ │(Slot 0-400)│      │(Slot 400-800)│   │(Slot 800-1024)│        │
│ └───┬─────┘        └───┬─────┘        └───┬─────┘                │
│     │                  │                  │                      │
│     ▼                  ▼                  ▼                      │
│ ┌─────────┐        ┌─────────┐        ┌─────────┐                │
│ │ Slave1   │        │ Slave2   │        │ Slave3   │                │
│ └─────────┘        └─────────┘        └─────────┘                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

特点

特性说明
优点支持数据分片、自动迁移、对客户端友好
缺点需要 ZooKeeper、代理有性能损耗、代码停更
适用场景中大规模、需要平滑扩容

Codis vs Redis Cluster

维度CodisRedis Cluster
分片方式Proxy 计算槽客户端/代理计算槽
配置中心ZooKeeper无(Gossip 协议)
槽迁移官方支持官方支持
代理Codis Proxy无(可有Twemproxy)
维护状态停更(2016)活跃维护
客户端兼容任意 Redis 客户端需支持 Cluster

Codis 配置

yaml
# codis.json
{
  "zk": "127.0.0.1:2181",
  "product": "codis-demo",
  "proxy_id": "proxy_1",
  "io_thread_num": 8,
  "worker_num": 8
}

方案三:Twemproxy

架构

┌─────────────────────────────────────────────────────────────────┐
│                      Twemproxy 架构                              │
│                                                                 │
│   ┌──────────┐    ┌──────────┐                                  │
│   │ Twemproxy│    │ Twemproxy│                                  │
│   │  Proxy1  │    │  Proxy2  │                                  │
│   └────┬─────┘    └────┬─────┘                                  │
│        │               │                                        │
│        └───────────────┼────────────────────────────────────── │
│                        │                                         │
│     ┌──────────────────┼──────────────────┐                     │
│     ▼                  ▼                  ▼                     │
│ ┌─────────┐        ┌─────────┐        ┌─────────┐                │
│ │  Redis  │        │  Redis  │        │  Redis  │                │
│ │ Server1 │        │ Server2 │        │ Server3 │                │
│ └─────────┘        └─────────┘        └─────────┘                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

特点

特性说明
优点轻量、配置简单、支持多种哈希算法
缺点不支持高可用(无故障转移)、不支持动态扩容
适用场景简单分片需求、作为过渡方案

Twemproxy 配置

yaml
# nutcracker.yml
redis1:
  listen: 127.0.0.1:6379
  hash: fnv1a_64
  distribution: ketama
  servers:
    - 127.0.0.1:6380:1
    - 127.0.0.1:6381:1
    - 127.0.0.1:6382:1

方案四:Redis Cluster

架构

┌─────────────────────────────────────────────────────────────────┐
│                      Redis Cluster 架构                         │
│                                                                 │
│         ┌─────────┐  ┌─────────┐  ┌─────────┐                  │
│         │ Master1 │  │ Master2 │  │ Master3 │                  │
│         │ (槽0-5460)│  │(槽5461-10922)│ (槽10923-16383)│       │
│         └────┬────┘  └────┬────┘  └────┬────┘                  │
│              │            │            │                        │
│              │            │            │                        │
│         ┌────▼────┐  ┌────▼────┐  ┌────▼────┐                  │
│         │ Slave1  │  │ Slave2  │  │ Slave3  │                  │
│         └─────────┘  └─────────┘  └─────────┘                  │
│                                                                 │
│   所有节点通过 Gossip 协议互联                                   │
│   客户端直连任意节点                                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

特点

特性说明
优点原生支持、去中心化、自动故障转移、在线扩容
缺点不支持跨槽操作、客户端需要支持 Cluster、复杂度高
适用场景大规模部署、需要平滑扩容

方案对比表

维度主从+SentinelCodisTwemproxyRedis Cluster
数据分片
高可用
自动故障转移
在线扩容
代理Codis ProxyTwemproxy
配置中心SentinelZooKeeper
运维复杂度
客户端兼容性一般
多 key 操作支持支持支持限制
社区活跃度

如何选择?

选择决策树

你的需求是什么?

        ├─ 小规模(&lt; 10 万 QPS,&lt; 100GB)?
        │       └─→ 主从 + Sentinel

        ├─ 需要水平扩展,但不想引入太多复杂度?
        │       └─→ Redis Cluster

        ├─ 使用 Java/Go 客户端,需要完整 Redis 命令支持?
        │       └─→ Codis(如果能接受停更)

        └─ 简单分片,不需要高可用?
                └─→ Twemproxy

场景分析

场景一:创业公司,小规模部署

推荐:主从 + Sentinel

理由

  • 架构简单,运维成本低
  • 初期数据量和 QPS 都不会太高
  • 故障自动切换,保证可用性

场景二:中型公司,需要平滑扩容

推荐:Redis Cluster

理由

  • 支持在线扩容,数据自动迁移
  • 原生支持,社区活跃
  • 不需要额外依赖(ZooKeeper)

场景三:需要完整 Redis 语义

推荐:Codis

理由

  • 代理计算槽,客户端无需适配
  • 支持所有 Redis 命令
  • 支持跨槽操作(通过 Proxy 处理)

场景四:简单缓存分片

推荐:Twemproxy

理由

  • 轻量级,配置简单
  • 满足基本分片需求
  • 不需要高可用时足够用

Java 客户端选择

客户端支持 Cluster支持 Sentinel特点
Jedis广泛使用
Lettuce响应式、支持连接池
Redisson丰富的分布式数据结构
java
// Jedis 连接 Sentinel
JedisSentinelPool pool = new JedisSentinelPool(
    "mymaster", sentinels, poolConfig
);

// Jedis 连接 Cluster
JedisCluster cluster = new JedisCluster(
    new HostAndPort("127.0.0.1", 7000),
    poolConfig
);

// Lettuce 连接 Cluster(Spring Boot 默认)
RedisClusterClient client = RedisClusterClient.create(
    RedisURI.create("redis://127.0.0.1:7000")
);
StatefulRedisClusterConnection conn = client.connect();

总结

方案适用场景不适用场景
主从+Sentinel小规模、高可用水平扩展
Redis Cluster中大规模、需扩容多 key 跨槽
Codis完整 Redis 语义不接受停更
Twemproxy简单缓存分片需要高可用

留给你的问题

假设你的业务使用 Redis Cluster 存储用户 Session。

问题:用户登录后,其 Session 数据(key = session:{userId})被路由到了 Node A。一段时间后,Node A 宕机,这个用户的 Session 数据会丢失吗?Cluster 是如何保证 Session 可用的?

基于 VitePress 构建