Redis Cluster作为Redis官方推出的分布式解决方案,其核心优势围绕高可用性、横向扩展性、高性能三大维度展开,同时兼顾易用性数据分布效率,完美解决了单机Redis在内存、并发、单点故障等方面的瓶颈。以下是其优势的详细阐述:

一、高可用性:自动故障转移,保障服务连续性

Redis Cluster通过主从复制(Master-Replica)自动故障转移(Auto-Failover)机制,彻底解决了单点故障问题。每个主节点可配置多个从节点,主节点负责处理读写请求,从节点实时复制主节点数据以提供冗余。当主节点发生故障时,集群会通过多数派协议(超过半数主节点确认故障)自动选举从节点提升为新主节点,整个过程无需人工干预,确保服务不中断。

例如,在电商大促场景中,即使某台主节点因硬件故障宕机,从节点也能在短时间内接管业务,避免用户购物车、订单等数据无法访问的情况发生。这种机制使得Redis Cluster的可用性远高于单机Redis,满足企业级应用对高可靠的严格要求。

二、横向扩展性:线性扩容,突破单机瓶颈

Redis Cluster采用哈希槽(Hash Slot)机制实现数据的分布式存储,整个集群预分配16384个哈希槽(0-16383),每个主节点负责一部分槽位。当需要扩展集群容量或提升性能时,只需在线添加新节点,集群会自动将现有节点的部分哈希槽迁移至新节点,无需停机。

这种横向扩展方式使得Redis Cluster的性能与容量可随节点数量线性增长,彻底突破了单机Redis的内存限制(如单机最多支持几十GB内存)和并发瓶颈(如单机最多处理10万+ QPS)。例如,某大数据缓存应用可通过添加节点,将数据量从单机的50GB扩展至1TB以上,同时将QPS从10万提升至100万以上。

三、高性能:分布式存储,并发处理能力提升

Redis Cluster的高性能源于数据分布客户端直连机制:

  1. 数据分布:数据被分散存储在多个节点上,每个节点仅处理部分请求,降低了单个节点的负载压力。例如,10个节点的集群可将并发请求分散至10个节点,理论上吞吐量是单机的10倍。

  2. 客户端直连:客户端无需经过代理层(如Twemproxy、Codis),可直接连接任意集群节点。节点会根据请求的键计算所属哈希槽,若槽不属于当前节点,会返回MOVEDASK错误引导客户端重定向至正确节点。这种机制减少了网络跳转,提升了请求处理效率。

四、易用性:原生支持,部署维护简便

Redis Cluster是Redis官方提供的解决方案,原生支持集群功能,无需额外安装代理组件(如Codis的Proxy层)。部署时,只需通过redis-cli --cluster create命令即可快速创建集群,支持自动分配哈希槽与主从关系。

此外,集群中的每个节点都保存了其他节点的状态信息(如主从关系、槽归属),通过Gossip协议定期交换信息,自动保持配置一致性。这种去中心化架构使得集群的维护成本远低于传统代理模式的分布式方案。

五、数据分布效率:哈希槽机制,均匀性与灵活性兼顾

Redis Cluster采用16384个哈希槽的固定分配方式,确保数据在节点间的均匀分布。每个键通过CRC16(key) % 16384计算所属槽位,避免了数据倾斜问题(如某些节点存储大量数据,而其他节点空闲)。

同时,哈希槽机制支持灵活的扩缩容:当添加新节点时,只需将现有节点的部分槽位迁移至新节点;当删除节点时,其负责的槽位会自动分配给其他节点。这种机制使得数据分布始终保持在均衡状态,提升了集群的整体性能。

六、搭建教程

准备redis配置文件

# redis.comf
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
bind 0.0.0.0
cluster-announce-ip <本地IP>
cluster-announce-port 6379
cluster-announce-bus-port 16379
# 设置密码
requirepass <密码>
# 连接设置
maxclients 100000
tcp-backlog 511
timeout 0
tcp-keepalive 60

准备docker compose 文件

version: '3'
services:
  redis-6379:
    image: redis:7
    container_name: redis-6379
    restart: always
    network_mode: host       # 使用宿主机网络模式
    volumes:
      - /root/redis/redis.conf:/usr/local/etc/redis/redis.conf
      - /root/redis/data:/data
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]

启动 redis

# 启动
docker compose up -d
# 删除数据重启
docker compose down && rm -r data && docker compose up -d

创建集群,在任意服务器上执行

docker exec -it redis-6379 redis-cli --cluster create \
  <节点1IP>:6379 \
  <节点2IP>:6379 \
  <节点3IP>:6379 \
  --cluster-replicas 0 -a <密码>
  
 # 查看集群状态
docker exec -it redis-6379 redis-cli -a Ux#Redis@Passwd -c cluster nodes
docker exec -it redis-6379 redis-cli -a Ux#Redis@Passwd -c cluster info
# 进入redis-cli
docker run -it --rm redis:latest \
  redis-cli -c -h 10.0.12.16 -p 6379 -a <密码>

七、迁移旧数据

使用 redis-shake

配置文件 redis-shake.toml

[sync_reader]
cluster = false
address = "<单机IP>:16379"
password = "123456"
tls = false
sync_rdb = true
sync_aof = true

[redis_writer]
cluster = true
address = "<集群任意IP>:6379"  # 只写一个节点
password = "<密码>"
tls = false
off_reply = false

[filter]
allow_keys = []
allow_key_prefix = []
allow_key_suffix = []
allow_key_regex = []
block_keys = []
block_key_prefix = []
block_key_suffix = []
block_key_regex = []
allow_db = []
block_db = []
allow_command = []
block_command = []
allow_command_group = []
block_command_group = []
function = ""

[advanced]
dir = "data"
ncpu = 0
pprof_port = 0
status_port = 0
log_file = "shake.log"
log_level = "info"
log_interval = 5
log_rotation = true
log_max_size = 512
log_max_age = 7
log_max_backups = 3
log_compress = true

rdb_restore_command_behavior = "panic"
pipeline_count_limit = 1024
target_redis_client_max_querybuf_len = 1073741824
target_redis_proto_max_bulk_len = 512000000
empty_db_before_sync = false

执行迁移

./redis-shake redis-shake.toml