最近跟着阳哥学了docker相关的知识后,搭建redis集群这里做一个小总结,也希望这篇文章能帮助到有需要的人
Redis 集群(cluster)并没有选用上面一致性哈希,而是采用了哈希槽(slot)的这种概念。主要的原因就是上面所说的,一致性哈希算法对于数据分布、节点位置的控制并不是很友好。
redis cluster 包含了16384个哈希槽,每个 key 通过计算后都会落在具体一个槽位上,而这个槽位是属于哪个存储节点的,则由用户自己定义分配。例如机器硬盘小的,可以分配少一点槽位,硬盘大的可以分配多一点。如果节点硬盘都差不多则可以平均分配,所以哈希槽这种概念很好地解决了一致性哈希的弊端。
另外在容错性和扩展性上,表象与一致性哈希一样,都是对受影响的数据进行转移。而哈希槽本质上是对槽位的转移,把故障节点负责的槽位转移到其他正常的节点上。扩展节点也是一样,把其他节点上的槽位转移到新的节点上,但一定要注意的是,对于槽位的转移和分派,redis 集群是不会自动进行的,而是需要人工配置的。所以 redis 集群的高可用是依赖于节点的主从复制与主从间的自动故障转移。
1、安装并启动redis容器
//拉取镜像
docker pull redis
/**
* 先启动(三主三从)的实例
* 参数说明
* -d 守护进程
* -p 端口映射 -p 宿主机端口:容器端口
* --name 容器名称
* --privileged=true 获得宿主机root权限
* -v 绑定共享映射目录 -v 宿主机目录:容器目录
* --cluster-enabled yes 开启集群
* --appendonly yes 开启AOF持久化
* --port 绑定端口
* 注:每个Redis群集节点都需要打开两个TCP连接,用于为客户端提供服务的普通Redis TCP端口,
* 例如6379,加上通过向数据端口添加10000获得的端口,所以这里6379 跟16379端口都要绑定上。
* 这个地方如果没有两个端口都绑定的话可能会导致redis开启集群失败Waiting for the cluster to join…
*/
docker run -d -p 6381:6381 -p:16381:16381 --name redis-node-1 --privileged=true -v ~/docker_data/redis-node-1:/data redis --cluster-enabled yes --appendonly yes --port 6381
docker run -d -p 6382:6382 -p:16382:16382 --name redis-node-2 --privileged=true -v ~/docker_data/redis-node-2:/data redis --cluster-enabled yes --appendonly yes --port 6382
docker run -d -p 6383:6383 -p:16383:16383 --name redis-node-3 --privileged=true -v ~/docker_data/redis-node-3:/data redis --cluster-enabled yes --appendonly yes --port 6383
docker run -d -p 6384:6384 -p:16384:16384 --name redis-node-4 --privileged=true -v ~/docker_data/redis-node-4:/data redis --cluster-enabled yes --appendonly yes --port 6384
docker run -d -p 6385:6385 -p:16385:16385 --name redis-node-5 --privileged=true -v ~/docker_data/redis-node-5:/data redis --cluster-enabled yes --appendonly yes --port 6385
docker run -d -p 6386:6386 -p:16386:16386 --name redis-node-6 --privileged=true -v ~/docker_data/redis-node-6:/data redis --cluster-enabled yes --appendonly yes --port 6386
2、创建开启redis集群并测试
//查看宿主机内网ip 这里演示的内网ip是192.168.1.10 自行替换
ifconfig
//进入到一个redis容器中
docker exec -it redis-node-1 /bin/bash
//开启集群 如图2.1
redis-cli --cluster create 192.168.1.10:6381 192.168.1.10:6382 192.168.1.10:6383 192.168.1.10:6384 192.168.1.10:6385 192.168.1.10:6386 --cluster-replicas 1
//进入redis-cli
redis-cli -p 6381 -c //-c 连接集群
//查看集群信息 如图2.2
cluster info
//查看集群节点 如图2.3
cluster nodes
//根据规律找出对应的主从节点,这里的是以我的为准,具体每个人的可能不一样,以自己查出来的为准
master slave
1 5
2 6
3 4
//可以看到数据 会随机写入到不同的集群机器中,会分配到不同的哈希槽中
当主节点挂了的时候,从节点会自动变成主节点
//我们先停止1号机,看看5号从机会不会自动接管主节点
docker stop redis-node-1
//进入容器
docker exec -it redis-node-2 /bin/bash
//进入集群
redis-cli -p 6382 -c
//查看集群信息 可以看到1号机变成了fail 5号机从库变成了主库
cluster nodes
主节点恢复后,从节点还是主节点,原来的主节点变成了从节点
//重新启动1号机
docker start redis-node-1
//进入到容器中
docker exec -it redis-node-2 /bin/bash
//进入集群
redis-cli -p 6382 -c
//查看集群信息 可以看到1号机变成了从库 5号机还是主库
cluster nodes
3、集群扩容
//以一号机为例查看集群哈希槽分配信息 如图3.1
redis-cli --cluster check 192.168.1.10:6381
//退出到宿主机终端,重新启动两个redis容器 端口号6387 6388
docker run -d -p 6387:6387 -p:16387:16387 --name redis-node-7 --privileged=true -v ~/docker_data/redis-node-7:/data redis --cluster-enabled yes --appendonly yes --port 6387
docker run -d -p 6388:6388 -p:16388:16388 --name redis-node-8 --privileged=true -v ~/docker_data/redis-node-8:/data redis --cluster-enabled yes --appendonly yes --port 6388
//进入到redis容器中
docker exec -it redis-node-1 /bin/bash
//扩容主节点
redis-cli --cluster add-node 192.168.1.10:6387 192.168.1.10:6381 如图3.2
//查看节点信息 可以看到新增加的主节点是没有分配槽号的 所以我们要给它分配槽号 如图3.3
redis-cli --cluster check 192.168.1.10:6381
/**
* 重新分配槽号
* 这里我们还是想均分槽号,所以:总槽号 / 主节点机器数量 = 每个主节点的槽号 16384 / 4 = 4096 如图3.4
*/
redis-cli --cluster reshard 192.168.1.10:6381
//给主机器分配从节点 如图3.5
redis-cli --cluster add-node 192.168.1.10:6388 192.168.1.10:6387 --cluster-slave --cluster-master-id dee2839e876e2b1896176587efb80c0db8566836
//再次查看 可以看到 从原来的三主三从,变成了四主四从了 如图3.6
redis-cli --cluster check 192.168.1.10:6381
4、集群缩容
//先删除从节点 如图4.1
redis-cli --cluster del-node 192.168.1.10:6388 ed1b59b9515588390fb39c46da4116c92581c233
/**
* 重新分配槽号 如图4.2
* 这里的意思将 7号机的4096槽号分配回1号机中
*/
redis-cli --cluster reshard 192.168.1.10:6381
//再次查看节点信息 可以看到 7号机的槽号变成了0,1号机的槽号变成了8192 如图4.3
redis-cli --cluster check 192.168.1.10:6381
//删除主节点
redis-cli --cluster del-node 192.168.1.10:6387 dee2839e876e2b1896176587efb80c0db8566836
//再次查看节点信息 可以看到我们刚刚扩容的机器已经被删除了 如图4.4
redis-cli --cluster check 192.168.1.10:6381