赞
踩
目录
2、创建一个redis配置模板文件【redis-conf.tmpl】
Redis集群是一个提供在多个Redis节点之间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上。
如上图 ,3 个 Redis 作为一个集群,一共有3个master节点,每个master节点会分得一部分的哈希槽 , 但是,当某一个 Redis 服务节点突然间出现故障了么办呢?为了使得整个集群变得高可用,我们给每个 master 节点下面至少增加一个slave 节点,当某个master 节点故障,则会自动使用slave 升级为master节点。那么集群如何知道某个节点故障了呢?这里就要说到他直接的通讯方式【每个节点都使用tcp协议相互通讯交流,当有某个master 出现故障是,所有节点都会知道这个出现故障的master ,这是 集群会自动把故障下面的slave升级为master节点】,当在每个master 节点下增加 slave 节点,这样,整个集群就会有 6个节点。其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
如上图,增加了主从的 slave 节点,整个集群就变成了 6个节点。这6个节点是如何通讯,并且是如何存储数据的呢?
Redis集群中引入了哈希槽的概念,Redis集群有一共有16384个哈希槽【0,1,2,……,16382,16383】,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽,搭建Redis集群时会先给集群中每个master节点分配一部分哈希槽。比如当前集群有3个master节点,master1节点包含0~5500号哈希槽,master2节点包含5501~11000号哈希槽,master3节点包含11001~16383号哈希槽,当我们执行“set key value”时,假如 CRC16(key) % 16384 = 777,那么这个key就会被分配到master6381节点上,如下图
使用哈希槽的方式,一共16384个槽位,当需要增加一个新的master节点时,只需要把对应槽位的数据移动到对应的槽位上即可。
Redis集群中,节点之间通过建立TCP连接,使用gossip协议来传播集群的信息。什么是gossip协议呢?通俗一点的就是一群大妈,大家围起来在树头下聊天,把自己的八卦说给其他大妈听。在集群上,master1 分别使用 tcp 连接把自身的情况告诉 master2、master3 、slave1 、slave2、slave3 这5个节点;相对的 这5个节点也对应建立 tcp 链接,把自身的情况告知其他的节点。
Redis 集群最少需要 3个 master节点,为了高可用 给每个master 节点下面配置一个或多个 slave 节点,在这里,我们使用 3个 master + 3个 slave 来部署集群。
环境搭建:Centos 7 + docker
# ip addr
结果输出:
ens33: 里面的 inet 为我们服务器的 IP 地址
docker0:里面的inet 为我们的docker IP 地址
服务器IP: 192.168.23.131
docker 的IP : 172.17.0.1
请基础上面两个IP
---------------------------------------------------
不会用docker 的请自行研究
- // 安装最新的 redis 镜像
- docker pull redis:latest
使用 docker images [iamge_name] 命令可以查看到redis 的镜像
由于我这个是在同一个服务器下进行操作,因此预设下面6个端口,在创建 docker 的 redis 容器时,把容器中的 6379 端口分别映射到主机的6个端口上。
现在安装 6 个redis 容器,6个容器分别对应 主机的端口:
6381 | 6382 | 6383 | 6384 | 6385 | 6386 |
由于这里是docker 在同一个服务器下,因此需要在主机服务器先创建好配置文件,然后在创建redis 容器时,对配置文件进行挂载。
mkdir redis-cluster
输出
下面为部分配置,详细的配置请看
- port ${PORT}
- masterauth 123456
- requirepass 123456
- cluster-enabled yes
- cluster-config-file nodes.conf
- cluster-node-timeout 5000
- cluster-announce-ip 172.17.0.1
- cluster-announce-port ${PORT}
- cluster-announce-bus-port 1${PORT}
- appendonly yes
配置描述说明
port | redis 端口号 |
masterauth | 对于主从结构的redis集群,当主redis设置了连接密码时,需要在从redis上设置此密码。 |
requirepass | redis实例自身的连接密码,当客户端请求连接当前Redis服务器时,需要使用的密码 |
cluster-enabled | 启动集群模式 |
cluster-config-file nodes.conf | 集群节点信息文件 |
cluster-node-timeout 5000 | redis节点宕机被发现的时间 |
cluster-announce-ip | (集群节点的汇报ip,防止nat,预先填写为网关ip后续需要手动修改配置文件) ,单机直接使用 ifconfig 如下, 直接使用docker 的ip 172.17.0.1 |
cluster-announce-port | 集群节点的汇报port,防止nat |
cluster-announce-bus-port | 集群节点的汇报bus-port,防止nat |
appendonly yes | 开启aof |
创建模板后
创建一下文件,并且根据上诉模板 替换对应的${POST} 端口号
请看 每个端口号文件夹对应的redis.conf ,下面是我的端口6381 下面的 redis.conf 文件的内容,跟模板一致,只是端口号替换成了对应的数字:
快速创建文件的命令
- # 直接运行
- for port in `seq 6381 6386`; do
- mkdir -p ${port}/conf &&
- mkdir -p ${port}/data &&
- PORT=${port} envsubst < ./redis-conf.tmpl > ./${port}/conf/redis.conf
- done
根据上面的端口号和对应的文件配置,创建对应的容器
- for port in `seq 6381 6386`; do
- docker run -d --net=host -v /home/yel/redis-cluster/${port}/conf/redis.conf:/etc/redis/redis.conf -v /home/yel/redis-cluster/${port}/data:/data --restart always --name=redis-${port} redis redis-server /etc/redis/redis.conf;
- done
运行结果:
可以看到上图,6个容器均创建成功,并且已经全部正在运行中;如果某个容器出现问题或者状态不对,请使用docker logs 容器ID 进行查看对应容器的日志。
docker logs 使用说明_Yel_Liang的博客-CSDN博客docker logs 使用说明https://blog.csdn.net/Yel_Liang/article/details/132087291
运行成功后,我们可以尝试一下链接上面的redis
这台是我本机的redis 管理工具,下面链接一下,看看是否链接成功
从上图可见,本地是可以访问虚拟机上面docker 容器的 6381 端口 下的redis 的,如果您不能访问,则需要开放防火墙端口,我这里提前关闭了防火墙。
当我们在工具上添加数据时,发现无法数据
报错 CLUSTERDOWN Hash slot not served
在上面的操作中,我们可以看到,我们只是把容器给创建并且启动起来了,而且对应的redis 配置时已经开启了集群模式 【cluster-enabled yes】,虽然把redis 启动起来了,但是还没有把 这 6个 redis 服务进行一个链接
随便进入一个redis 容器内部
docker exec -it redis-6381 /bin/bash
执行 创建集群 命令
- // 创建集群
- redis-cli -a 123456 --cluster create 172.17.0.1:6381 172.17.0.1:6382 172.17.0.1:6383 172.17.0.1:6384 172.17.0.1:6385 172.17.0.1:6386 --cluster-replicas 1
能看到上图输出,即创建集群成功,现在我们查看一下这6个redis 服务在整个集群中担任什么角色。
进入容器
- // 随便进入一个容器内部
- docker exec -it redis-6381 /bin/bash
查看集群主从详情
- // 查看集群主从详情
- redis-cli -a 123456 -c -p 6381 cluster nodes
在上面可以看到哪个服务器是主节点,哪个是从节点,并且能看到主节点分配的哈希槽的范围是多少,详细看下图:
通过上图,可以看出集群内的节点情况。
进入容器内
- // 随便进入一个容器内部
- docker exec -it redis-6381 /bin/bash
进入redis 内部
redis-cli -a 123456 -c -h 192.168.23.131 -p 6381
参数此说明:
操作结果:
从上图可以看出,我们已经能进入redis 里面了,下面尝试写入
当我们输入 【set yel 感谢看到这里 】 后,提示
Redirected to slot [8044] located at 172.17.0.1:6382
因为 在输入的时候 CRC16(yel) % 16384 = 8044 ,哈希槽为 8044 ,在上面第5点【5、查看集群状态】时,可以看到 8044 哈希槽值 在 6382 这个master节点上,因此redis 告诉我们,8044 这个哈希槽在 6382 ,我帮你定向到 这个 6382 这个master节点,然后进行写入。
在主机上链接一下 6382 这个redis 节点,查看里面的数据
从上图可以看到,刚开始写入的 【set yel 感谢看到这里 】 已经被写进入了,现在我们尝试在 redis 管理器进行写入,看又是什么效果。
从上图,他告诉我们[set 2323 2323 ] 这个 哈希槽在 14515 ,应该移动到 6383 的 master 节点(node)上写入,因此在本地使用redis 管理工具链接时非集群的方式,因此抛出。
MOVED 14515 172.17.0.1:6383
在【6、在redis容器内进行操作】 ,我们在 6382 master节点上写入了一个 键值 为 yel 的值 ,这时 当 6382 master节点突然间故障掉,后面redis 容器会变为什么状态呢?
a、在docker 里面,停掉 6382 这个容器。
b、查看redis 集群的主从信息
根据上面的信息,得出下面的图。
我们可以看到,当redis 集群的某个主节点(master)出现故障后,主节点(master)下面的从节点(slave)被集群提升为了 主节点 ,现在我们进入 6384 节点,看一下节点 6384 里面的是否有 键值 yel
在上图我们看到, 原本 键值 yel 是在 6382 主节点上,但是 6382节点故障后,6384节点竟然也存在 键值 yel 。由于 6382 与 6384 是主从结构,在 6382 中写入的数据,会同步到 6384 里面,因此在6382 节点故障,并不会影响到 redis 整个集群的工作。但是现在我们如果把 6382 给重新修复开启起来,会有怎样的效果呢?
上图,先通过 docker start redis-6382 启动了 redis-6382 容器,
通过docker ps -a 查看容器状态 , 使用 docker exec 进入 容器内部,查看一下 键值 yel 在不在,根据上图,可以看到,这个 yel键值 还在 6384 中,查看容器的状态,看到 6382 变成了 6384 的 从节点,当把 6384 故障掉后,如下如
从上图可以看到 , 节点6384 故障掉之后,从节点 6382 代替了 6384 变成了主节点,然后进去查看 键值 yel , 发现 yel 键值 在 6382 节点中 。
从上图,看到 6382 和 6384 两个节点故障了,只剩下2个主节点和2个从节点,看哈希槽值的分配,可以看到 5461~10922 这部分的槽值故障掉了 , 现在查看集群中 键值 yel 还在不在集群中。
从上图可以发现,整个集群宕机了,这时,整个集群变为不可用的状态。想要整个集群启用,重新开启 容器 6382 或 6384 即可。开启之后,查看 键值 yel 还在不在集群中。
在 6382 中还是存在键值 yel, 这是为什么呢?因为在我们配置集群的时候,配置参数 为 aof 持久化机制 [appendonly yes] 。
新增主节点端口 6391
- mkdir -p 6391/conf &&
- mkdir -p 6391/data &&
- PORT=6391 envsubst < ./redis-conf.tmpl > ./6391/conf/redis.conf
运行结果:
docker run -d --net=host -v /home/yel/redis-cluster/6391/conf/redis.conf:/etc/redis/redis.conf -v /home/yel/redis-cluster/6391/data:/data --restart always --name=redis-6391 redis redis-server /etc/redis/redis.conf;
运行结果
从上图可以知道。新创建了一个容器 redis-6391,运行成功。
a、进入redis 内部
docker exec -it redis-6391 /bin/bash
b、给集群增加master节点
redis-cli -a 123456 --cluster add-node 192.168.23.131:6391 192.168.23.131:6381
第一个IP 为新增的 redis 服务地址 , 第二个为集群内 的某个redis 集群地址。运行后的结果如下。
上图的输出后,我们查看一下集群内的信息
redis-cli -c -a 123456 -h 172.17.0.1 -p 6381 cluster nodes
命令输出:
从上图可以知道,6391 已经成为集群的一个master节点了,但是,redis 集群的存储时根据 哈希槽来分配存储位置的,上图很明显可以看出 6391 根本就没有分配到哈希槽,所以,在这个阶段上,6391 并不能在集群中起到任何作用,因此我们需要重新分配一下哈希槽。
- // 方法一
- redis-cli -a 123456 --cluster reshard 192.168.23.131:6391 --cluster-from 40d78aee9209f228365e441a6bc62ea0b7601f76,142bd0adf0a36a77a398eb22d848e241949683ca
-
- // 方法二
- redis-cli -a 123456 --cluster reshard 172.17.0.1:6391 --cluster-from 142bd0adf0a36a77a398eb22d848e241949683ca --cluster-to 286ed4ce493e832a078d6862444b605f472294ae --cluster-slots 2000
-
第一个为 新创建的master节点 --cluster-from 后面跟的是 原来集群中 master 节点的 id 值(多个用,隔开)。这个id 值可以通过 cluster nodes 查看到。
--cluster-from : 跟来源的master节点ID值
--cluster-to : 目标节点ID值
--cluster-slots : 分配多少哈希槽
// 你想移动多少个插槽(从1到16384)?
How many slots do you want to move (from 1 to 16384)?
这里可以输入 2000
// 接收节点ID是什么?
What is the receiving node ID?
请提前基础这个新创建的节点id
新增从节点端口 6392
这个里跟创建主节点一样,就不一一填写了,最后得到的容器如下
创建 slave 节点一直不成功,每次创建的都是 master节点,有大神知道的求评论
进入集群内,并查看当前情况,如下:
现在要给 端口为 6391 的主节点增加一个从节点
redis-cli -a 123456 --cluster reshard 172.17.0.1:6391
reshard 后面跟集群的里面任意的ip与端口;运行如下:
有上图可以看到 ID = 299dba3d634dc818fc092c2c909f6099b639d4d3 一共有 51 个槽位,下面输入需要给这个ID 增加 2000 槽位。
输入一:How many slots do you want to move (from 1 to 16384)?
需要移动多少个槽位?
输入二:What is the receiving node ID?
请问需要移动到哪一个槽位,输入ID? 最后这个ID 会加上对应的槽位
输入三:Source node #1:
输入 all , 在其主节点中获取对应数量的槽位分配到输入二的节点ID
运行完成,查看分配的槽位数,最总ID = 299dba3d634dc818fc092c2c909f6099b639d4d3 的槽位数变成了 2051 个,如下图:
redis-cli -a 123456 --cluster reshard 172.17.0.1:6391 --cluster-from 299dba3d634dc818fc092c2c909f6099b639d4d3 --cluster-to 914b1f35236e72b041f13d800458ccfd6f771571 --cluster-slots 2000
reshard 后面跟 集群任意一个redis 服务器及端口
--cluster-from 减少槽位的主节点ID
--cluster-to 增加槽位的主节点ID
--cluster-slots 变动的数量
执行 命令之前:
master节点 ID = 299dba3d634dc818fc092c2c909f6099b639d4d3 中一共存在 51 个槽位;
master节点 ID = 914b1f35236e72b041f13d800458ccfd6f771571 中一个存在 4040 个槽位
执行命令
redis-cli -a 123456 --cluster reshard 172.17.0.1:6391 --cluster-from 299dba3d634dc818fc092c2c909f6099b639d4d3 --cluster-to 914b1f35236e72b041f13d800458ccfd6f771571 --cluster-slots 51
输出结果:
主节点 ID = 299dba3d634dc818fc092c2c909f6099b639d4d3 槽位变为了 0 ,并且变成了 端口 172.17.0.1:6392 的从节点。
删除节点,比较简单,命令如下:
redis-cli -a 123456 --cluster del-node 172.17.0.1:6384 1183fa907276729afc3587ed8c318b05f895193e
del-node 后面跟需要删除的节点 服务地址与端口 并且加上 对应的id
上图是删除从节点的操作流程记录。如果需要删除主节点,需要先把主节点上面的哈希槽位移动到其他的 master节点【第七大点地2小点:指定某个节点移动槽位】,再进行删除。
redis-cli -a 123456 --cluster info 172.17.0.1:6381
ip 与端口为集群上的任意一个redis 服务地址
结果如下:
redis-cli -a 123456 --cluster check 172.17.0.1:6381
ip 与端口为集群上的任意一个redis 服务地址
结果如下:
Redis高可用架构—Redis集群(Redis Cluster)详细介绍https://baijiahao.baidu.com/s?id=1730440988136689035&wfr=spider&for=pc
集群搭建(Redis)(超详细)_redis集群搭建_一起去飞~的博客-CSDN博客(超详细)集群搭建(Redis)_redis集群搭建https://blog.csdn.net/CharmingC1/article/details/126806364
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。