redis集群分片
cluster
- 自带sentinel故障转移机制,内置高可用支持
- 客户端连接一个可用节点
- solt 分配到对应节点
solt (16384)
最大节点为16384 建议不要超过1000
latex
2^{14}=16384
CRC16算法
槽位缩容和扩容 比如集群添加主节点 或者 主节点下线
槽位映射
哈希取余分区
宕机会发生数据混乱
一致性哈希算法
解决分布式缓存数据变动的问题 构建一致性哈希环 ip节点映射 落到服务器上 容错性 扩展性
哈希槽分区
解决均匀分配问题 为什么是2^{14} 而不是2^{16} 心跳包
2^{16} 的心跳包是8k 2^{16}/8=8k
集群节点不要超过1000 槽位越小 节点越少
集群不保证强一致性
搭建
三主三从 启动六台redis实例
配置x6
text
daemonize yes
bind 0.0.0.0
protected-mode no
port 6379
dir ./
pidfile "./redis.pid"
logfile "./redis.log"
dbfilename dump.rdb
appendonly yes
appendfilename appendonly.aof
requirepass 123456
masterauth 123456
cluster-enabled yes
cluster-config-file cluster.conf
cluster-node-timeout 5000
构建主从关系
bash
redis-cli -a 123456 --cluster create --cluster-replicas 1 \
ip:port [ip:port...]
yes
构建集群
链接客户端操作
链接客户端操作
bash
redis-cli -a 123456 -c
异常
主节点宕机 从节点上位成为主节点 节点恢复成为从节点入队
节点从属调整
主从切换
bash
CLUSTER FAILOVER
主从扩容关系
添加2个节点
node1 node2
通过现有节点加入集群
bash
redis-cli -a 123456 --cluster add-node \
<new-node-ip:port> <existing-node-ip:port>
检查状态
bash
redis-cli -a 123456 --cluster check <existing-node-ip:port>
重新hash
bash
redis-cli --cluster reshard <existing-node-ip:port>
重新分配槽点slot
给新添加的节点添加从节点
bash
redis-cli -a 111111 --cluster add-node <new-slave-ip:port> <master-ip:port> \
--cluster-slave --cluster-master-id <id>
集群缩容
注意仅能删除从节点或者没有槽位的master节点 先将槽位分给别人
bash
redis-cli --cluster del-node <existing-node-ip:port> id
注意 不在一个槽位下无法直接使用mset mget
使用统配
bash
meget k1{z} v1 k2{z} v2
docker启动redis集群3主三从
配置文件
docker-compose.yml
yaml
name: "redis-cluster"
services:
redis1:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
ports:
- "6381:6381"
- "16381:16381"
env_file:
- .env
command:
- redis-server
- --port 6381
- --cluster-announce-port 6381
- --cluster-announce-bus-port 16381
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
redis2:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
env_file:
- .env
command:
- redis-server
- --port 6382
- --cluster-announce-port 6382
- --cluster-announce-bus-port 16382
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
ports:
- "6382:6382"
- "16382:16382"
redis3:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
env_file:
- .env
command:
- redis-server
- --port 6383
- --cluster-announce-port 6383
- --cluster-announce-bus-port 16383
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
ports:
- "6383:6383"
- "16383:16383"
redis4:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
env_file:
- .env
command:
- redis-server
- --port 6384
- --cluster-announce-port 6384
- --cluster-announce-bus-port 16384
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
ports:
- "6384:6384"
- "16384:16384"
redis5:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
env_file:
- .env
command:
- redis-server
- --port 6385
- --cluster-announce-port 6385
- --cluster-announce-bus-port 16385
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
ports:
- "6385:6385"
- "16385:16385"
redis6:
image: registry.cn-beijing.aliyuncs.com/zbzly/redis
env_file:
- .env
command:
- redis-server
- --port 6386
- --cluster-announce-port 6386
- --cluster-announce-bus-port 16386
- --bind ${bind}
- --protected-mode ${protectedMode}
- --dir ${dir}
- --pidfile ${pidfile}
- --logfile ${logfile}
- --dbfilename ${dbfilename}
- --appendonly ${appendonly}
- --appendfilename ${appendfilename}
- --requirepass ${password}
- --masterauth ${password}
- --cluster-enabled ${clusterEnabled}
- --cluster-config-file ${clusterConfigFile}
- --cluster-node-timeout ${clusterNodeTimeout}
- --cluster-announce-ip ${serverIp}
ports:
- "6386:6386"
- "16386:16386"
.env
properties
#服务器ip
serverIp=192.168.152.200
#集群密码
password=123456
#开放连接
bind=0.0.0.0
#关闭保护模式
protectedMode=no
#文件存储目录
dir=/data
#pid文件
pidfile=/data/redis.pid
#日志文件
logfile=/data/redis.log
#dump文件
dbfilename=dump.rdb
#开启aof
appendonly=yes
#aof文件
appendfilename=appendonly.aof
#开启集群
clusterEnabled=yes
#集群配置文件
clusterConfigFile=cluster.conf
#集群超时时间
clusterNodeTimeout=5000
初始化集群
bash
redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.152.200:6381 192.168.152.200:6382 \
192.168.152.200:6383 192.168.152.200:6384 192.168.152.200:6385 192.168.152.200:6386
集群要求最少三个节点 指定从节点为1则至少需要6个(3+3*1)节点
若初始化未成功返回信息可能是节点无法通信