03、docker安装Redis三主三从集群

100 阅读6分钟

docker安装Redis三主三从集群

Redis集群分区的方案

1、哈希取余分区

  • 介绍:假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

    3

  • 优点:操作简单,只需要根据公式判断落在哪台机器上

  • 缺点:扩缩容麻烦,redis节点数变化后,映射关系需要重新计算。

2.一致性哈希算法分区

  • 介绍:主要是解决由于Redis服务器个数变化导致的映射关系变化,尽量少的移动Redis节点上的数据。

    一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1(即哈希值是一个32位无符号整形),整个哈希环如下图:整个空间按顺时针方向组织,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、……直到2^32-1,也就是说0点左侧的第一个点代表2^32-1, 0和2^32-1在零点中方向重合,我们把这个由2^32个点组成的圆环称为Hash环。

3

  • 节点映射: 将集群中各个IP节点映射到环上的某一个位置。

    将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置。假如4个节点NodeA、B、C、D,经过IP地址的哈希函数计算(hash(ip)),使用IP地址哈希后在环空间的位置如下:

  • 落键规则: 首先计算key的hash值,hash(key),将这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上。

  • 优点:服务器个数发生变化时需要迁移的数据少,所以增删节点比较方便。

  • 缺点:一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题,

    例如系统中只有两台服务器:

3.哈希槽分区

  • 介绍: 一般采用这种方案

    • 哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot空间。

    • 解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

    • 一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot = CRC16(key) % 16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

三主三从集群安装

  • 新建6个Redis容器
# 节点1
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
# 节点2
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
# 节点3
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
# 节点4
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
# 节点5
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
# 节点6
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
  • 进入容器redis-node-1为6台机器构建集群关系
1、进入容器
docker exec -it redis-node-1 /bin/bash
2、进入docker容器后才能执行一下命令,且注意自己的真实IP地址
redis-cli --cluster create 192.168.111.147:6381 192.168.111.147:6382 192.168.111.147:6383 192.168.111.147:6384 192.168.111.147:6385 192.168.111.147:6386 --cluster-replicas 1
#--cluster-replicas 1 表示为每个master创建一个slave节点

  • 查看集群状态

    • 进入 6381查看集群状态
    1、进入容器
    docker exec -it redis-node-1 /bin/bash
    2、查看容器状态
    redis-cli -p 6381
    3、cluster info
    4、cluster node
    

主从容错案例

  • 先停止master 6381
docker stop redis-node-1

发现原来6381的从机6385变成了master了

主从扩容

  • 新建6387和6388两个节点
#节点7
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387

#节点8
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
  • 进入6387容器内部
docker exec -it redis-node-7 /bin/bash
  • 将新增的6387节点(空槽号)作为master节点加入原集群
redis-cli --cluster add-node IP:6387 IP:6381
  • 重新分配槽号
redis-cli --cluster reshard IP:6381

为什么63873个新的区间,以前的还是连续?
重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387
  • 为主节点6387分配从节点6388
命令:
redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
 
redis-cli --cluster add-node 192.168.111.147:6388 192.168.111.147:6387 --cluster-slave --cluster-master-id e4781f644d4a4e4d4b4d107157b9ba8144631451-------这个是6387的编号,按照自己实际情况

  • 检查集群信息
#需要进入容器内部
redis-cli --cluster check IP:6382

主从缩容

把刚才加入集群的6387和6388两台机器下线

  • 检查集群信息获取6388的ID号
#需要进入容器内部
redis-cli --cluster check IP:6382

  • 删除6388
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID

redis-cli --cluster del-node 192.168.111.147:6388 5d149074b7e57b802287d1797a874ed7a1a284a8

  • 把6387节点中的数据分配到其他节点上(本次全部放到6381中)
redis-cli --cluster reshard IP:6381

  • 把6387节点删除
命令:redis-cli --cluster del-node ip:端口 6387节点ID

redis-cli --cluster del-node 192.168.111.147:6387 e4781f644d4a4e4d4b4d107157b9ba8144631451

  • 检查集群的状态
redis-cli --cluster check IP:6381