Redis 集群部署
# Redis 集群部署
三台机器、每台两个实例、--cluster-replicas 1 —— 这是最小的可用生产形态。本文按「为什么这么摆 → 怎么装 → 怎么确认 → 有哪些坑」的顺序走。
版本说明
本文写于 2022-03,2026-08 重写。
命令与参数按 Redis 6.x/7.x 核对:--cluster 系列子命令自 5.0 起取代了旧的 redis-trib.rb,本文全程使用前者。7.0 起新增的 sharded pub/sub、FUNCTION 等特性本文未涉及。
# 一、为什么是 3 主 3 从,为什么交叉摆放
为什么至少 3 个主节点:Redis Cluster 的故障判定是主节点投票制,需要超过半数的主节点认为某个节点失联才会触发故障转移。2 个主节点凑不出多数,任何一个挂掉集群都无法自愈。
为什么主从要跨机器:一台机器上的主和它自己的从同时消失,那部分槽位就没人接管,集群直接不可用。所以下面创建集群时给的节点顺序是有讲究的——先列出三台机器的 7001(成为主),再列三台的 7002(成为从),--cluster-replicas 1 会把从分配到与其主不同的机器上。
192.0.2.11 7001(主) 7002(从)
192.0.2.12 7001(主) 7002(从)
192.0.2.13 7001(主) 7002(从)
2
3
16384 个槽位怎么分:CLUSTER 按 CRC16(key) % 16384 决定 key 归属,3 个主节点大致各持有 5461 个槽。槽位是分配单位,扩缩容就是搬槽位。
# 二、安装
yum install python-pip -y
pip install --upgrade pip
pip install tqdm
wget http://download.redis.io/releases/redis-6.2.14.tar.gz -P /opt
openssl rand -base64 20 # 随机生成密码,别用弱口令
# 每台机器上各起两个实例
python rediscluster_install.py -a <PASSWORD> -p 7001,7002 -h 192.0.2.11
systemctl status redis7001.service
systemctl status redis7002.service
2
3
4
5
6
7
8
9
10
11
12
# 三、配置文件里几个值得解释的参数
egrep -v "^$|^#" redis7001.conf
port 7001
bind 192.0.2.11
cluster-enabled yes
cluster-config-file /data/redis7001/redis_nodes.conf
cluster-node-timeout 15000
appendonly yes
maxclients 100000
maxmemory 0
dir /data/redis7001
repl-backlog-size 200m
tcp-backlog 1024
logfile /data/redis7001/redis_server_7001.log
pidfile /data/redis7001/redis_7001.pid
daemonize yes
rename-command CONFIG "ADMIN_CONFIG"
rename-command SHUTDOWN "ADMIN_SHUTDOWN"
rename-command FLUSHALL "ADMIN_FLUSHALL"
rename-command FLUSHDB "ADMIN_FLUSHDB"
rename-command KEYS ""
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 0 0 0
client-output-buffer-limit pubsub 32mb 8mb 60
masterauth <PASSWORD>
requirepass <PASSWORD>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
几个不能照抄的地方:
cluster-config-file是 Redis 自己维护的,不要手改。它记录了节点 ID 与槽位归属;实例重启后靠它认回自己在集群里的身份。手工编辑或误删会让节点以新身份加入,造成槽位混乱。cluster-node-timeout 15000:判定节点失联的门槛,同时也是故障转移的最短耗时量级。调小转移更快但更容易被网络抖动误判,调大则故障期间不可用时间变长。15s 是偏保守的取值。maxmemory 0表示不限制——集群模式下这很危险:内存吃满后 OOM Killer 杀掉的是整个实例,比触发淘汰策略糟糕得多。生产上应设为物理内存的 60%–70% 并配合maxmemory-policy。masterauth必须与requirepass一致,否则主从复制在需要认证时会失败——这是集群起来了但数据不同步的高频原因。rename-command KEYS ""是禁用而非改名。KEYS在大库上是 O(N) 阻塞操作,禁掉它比依赖开发自觉更可靠,替代品是SCAN。
# 四、创建集群
redis-cli -a <PASSWORD> --cluster create \
192.0.2.11:7001 192.0.2.12:7001 192.0.2.13:7001 \
192.0.2.11:7002 192.0.2.12:7002 192.0.2.13:7002 \
--cluster-replicas 1
2
3
4
# 五、怎么确认集群真的可用
装完不等于可用。四条命令逐项确认:
# 1. 槽位是否全覆盖、有无 fail 节点
redis-cli -a <PASSWORD> -h 192.0.2.11 -p 7001 cluster info
# 期望:cluster_state:ok / cluster_slots_assigned:16384 / cluster_known_nodes:6
# 2. 主从关系是否跨机器
redis-cli -a <PASSWORD> -h 192.0.2.11 -p 7001 cluster nodes
# 期望:每个 slave 行末尾指向的 master ID,不在同一台机器上
# 3. 一致性检查
redis-cli -a <PASSWORD> --cluster check 192.0.2.11:7001
# 4. 重命名后的命令是否生效
redis-cli -c -a <PASSWORD> -h 192.0.2.11 -p 7001 admin_config get maxclients
2
3
4
5
6
7
8
9
10
11
12
13
故障转移也要验一次,否则等真出事才发现从节点接不上:手动 ADMIN_SHUTDOWN 一个主节点,观察 cluster nodes 中对应的从节点是否在 cluster-node-timeout 后升为 master、cluster_state 是否回到 ok。验完把节点拉起来,它会作为从节点重新加入。
# 六、日常运维命令
集群登录(-c 表示跟随 MOVED 重定向,不加的话跨槽位访问会直接报错):
redis-cli -c -a <PASSWORD> -h 192.0.2.11 -p 7001
新增节点(前一个地址是新节点,后一个是集群中任意已有节点):
redis-cli -a <PASSWORD> --cluster add-node 192.0.2.14:7002 192.0.2.11:7001 --cluster-slave
新增主节点后槽位不会自动搬过去,需要显式重分配:
redis-cli -a <PASSWORD> --cluster reshard 192.0.2.11:7001
剔除节点(第二个参数是节点 ID,不是地址;主节点必须先把槽位搬空才能删):
redis-cli -a <PASSWORD> --cluster del-node 192.0.2.11:7001 f24b935a50a788692479c6beaf7c556f6d082253
布隆过滤器模块:
yum install git
cd /data
git clone https://github.com/RedisBloom/RedisBloom.git
cd RedisBloom && make
echo "loadmodule /data/RedisBloom/redisbloom.so" >> /data/redis7001/redis7001.conf
2
3
4
5
模块要在每个节点上都装且版本一致,只装一台会导致带 BF 命令的请求在部分节点上报未知命令。
# 七、坑与边界
- 命令行
-a传密码会进 shell history 和ps输出。演示这么写,生产上应改用REDISCLI_AUTH环境变量或交互式输入。本文里的<PASSWORD>就是这个原因。 - 集群模式下跨槽位的多 key 操作会被拒绝(
MSET、SUNION等),除非用{}hash tag 把相关 key 钉到同一个槽。这是从单机迁到集群时最常见的应用改造点。 --cluster-replicas 1只保证副本数,不保证机架/可用区分布。跨机房部署时它给出的拓扑不一定符合预期,创建完必须用第五节第 2 条核对。- 本文是自建部署的口径。 云托管的 Redis 集群(如 ElastiCache)通常屏蔽了
CLUSTER类命令与配置文件,上面的运维手段大部分用不上。 appendonly yes下的重写策略没在本文覆盖:AOF 文件增长与auto-aof-rewrite-percentage相关,磁盘紧张时需要单独评估。