# Redis 分片集群

主从和哨兵可以解决高可用,高并发读的问题。但是依然有两个问题没有解决 :

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征 :

  • 集群中又多个 master, 每个 master 保存不同的数据
  • 每个 master 都可以由多个 slave 节点
  • master 之间通过 ping 监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

# 搭建分片集群

分片集群的搭建相对简单很多,只需开启 cluster 模式即可 (其他设置不是必须)

1
2
3
4
5
6
docker run -it -p 6379:6379 --name redis_1 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_1/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes
docker run -it -p 6380:6379 --name redis_2 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_2/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes
docker run -it -p 6381:6379 --name redis_3 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_3/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes
docker run -it -p 6382:6379 --name redis_4 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_4/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes
docker run -it -p 6383:6379 --name redis_5 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_5/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes
docker run -it -p 6384:6379 --name redis_6 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_6/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes

之后在一个节点中创建集群即可

1
redis-cli --cluster create --cluster-replicas 1 172.17.0.2:6379 172.17.0.3:6379 172.17.0.6:6379 172.17.0.7:6379 172.17.0.8:6379 172.17.0.9:6379

Redis 如何判断某个 key 应该在哪个实例?

  • 将 16384 个插槽分配到不同的实例
  • 根据 key 的有效部分计算哈希值
  • 余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个 Redis 实例?

  • 这一类数据使用相同的有效部分,例如 key 都以 {typeId} 为前缀

# 集群伸缩

首先新建一个 redis 服务

1
docker run -it -p 6385:6379 --name redis_7 --privileged=true --restart=always -v /home/wong/data/redis/redis.conf:/etc/redis/redis.conf -v /home/wong/data/redis/redis_7/data:/data -d redis:latest redis-server /etc/redis/redis.conf --cluster-enabled yes

然后进入一个 redis 实例将新实例加入集群

1
redis-cli --cluster add-node 172.17.0.10:6379 172.17.0.2:6379

此时只是新节点只是加入了集群,并没有重新分配插槽,所以我们还需要重新分配插槽

1
redis-cli --cluster reshard <被划分的节点IP:Port>

# 数据迁移

利用 cluster failover 命令可以让集群中的某个 master 宕机,切换到执行 cluster failover 命令的这个 slave 节点,实现无感知的数据迁移。流程如下 :

手动的 Failover 支持三种不同模式 :

  • 缺省:默认的流程,如图 1~6 步
  • force : 省略了对 offset 的一致性检验
  • takeover : 直接执行第 5 步,忽略数据一致性,忽略 master 状态和其他 master 的意见

image-20230209153825317