Docker安装Redis集群失败经历汇总

news/2024/5/11 10:21:41/文章来源:https://blog.csdn.net/qq_42971035/article/details/128088862

在程序员的开发过程中,Redis可以说基本上是必不可少的缓存中间件。不管是二进制包还是docker安装Redis的文章在网上都是数不胜数。我之前自己玩Redis的时候基本不是二进制包安装就是docker安装,也没有尝试过集群方式。每次需要的时候,网上百度一篇文章,安装一个单机版的,有的时候行,有的文章不行。

也正是因为这个原因,本篇文章就想着自己创建Redis,通过docker方式进行部署。算是记录一下,方便以后使用。最后,然后我们再安装一下Redis集群模式。结果没想到,刚开始成功了,但是没有做记录,后来搞的时候竟然搞成了这个鬼样子。最后各种解决问题,还是没有解决。

既然是容器,那么删除很方便,我们之后把这个集群删除,重新部署,等到部署成功后会把文章链接贴到本篇文章中。集群的部署一定要贴合实际,不搞demo那种玩法,搞就搞生产上的部署方案与可行性。

一、单机版

# 1.查询所有镜像
docker search redis# 2.拉取redis镜像
docker pull redis# 3.查看所有镜像
docker images# 4.宿主机创建需要挂载的目录和文件
mkdir -p /usr/local/redis/{data,conf}
touch /usr/local/redis/conf/redis.conf# 5.创建redis容器并进行端口映射、容器命名和目录文件挂载
docker run -p 6379:6379 --name redis \
-v /usr/local/redis/data:/data \
-v /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf# 6.查看正在运行的容器
docker ps# 或者所有容器
docker ps -a# 7.进入容器,此处的redis指的是容器名或容器id
docker exec -it redis bash# 进入redis命令行界面
redis-cli# 8.测试# 测试方法一
set key1 v1# 命令行返回:OK
set key1# 命令行返回:“v1”# 测试方法二
ping# 客户端返回:PONG# 此时代表一台redis安装成功# 9.退出redis命令行
Ctrl + c# 10.退出redis容器
Ctrl + pq# 或者直接启动容器并进入
docker exec -it redis redis-cli# 退出容器
Ctrl + pq
# 或者
exit

 

二、Redis集群部署

集群节点情况:

节点

Ip

端口

主从

Node01

192.168.222.100

6380

Master

6381

Slave

Node02

192.168.222.103

6380

Master

6381

Slave

Node03

192.168.222.104

6380

Master

6381

Slave

2.1 方案一

# 1.创建目录
mkdir -p /usr/local/redis-cluster/{master-6380,slave-6381,slave-6382}# 2.拉取镜像
docker pull redis# 3..创建master节点的redis容器
docker run -d --name redis-master-6380 --net host --privileged=true \
-v /usr/local/redis-cluster/master-6380/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/master-6380/data:/data \
redis redis-server /etc/redis/redis.conf# 4..创建slave-6381的redis容器
docker run -d --name redis-slave-6381 -p 6381:6379 --privileged=true \
-v /usr/local/redis-cluster/slave-6381/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/slave-6381/data:/data \
redis redis-server /etc/redis/redis.conf# 5.创建slave-6382的redis容器
docker run -d --name redis-slave-6382 -p 6382:6379 --privileged=true \
-v /usr/local/redis-cluster/slave-6382/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/slave-6382/data:/data \
redis redis-server /etc/redis/redis.conf# 6.分别在三台机器上创建三台redis# 7.进入随便一台redis容器(这里以第一台服务器的master节点为例)docker exec -it redis-master-6380 bash# 通过端口映射的方式安装的redis集群有一定的问题,就是使用redis的服务必须和redis在一台机器上,
# 不然无法访问。

2.2 方案二

# 1.创建三台redis,通过 --net 指定网络类型 host模式,这种情况不需要端口映射。# 创建的容器是没有自己独立的网络命名空间的,是跟物理机共享一个网络空间,进而可以# 共享物理机的所# 有端口与IP,这样就可以让公共网络直接访问容器# 此时需要对外共享容器端口服务,只需要指定对外暴露的端口即可,-p 6379/-p 6380等。# 下文中使用的是 --port 6380docker create --name redis-master-6380 --net host \
-v /usr/local/redis-cluster/master-6380/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/master-6380/data:/data \
redis:latest --cluster-enabled yes --cluster-config-file redis-master-6380.conf --port 6380docker create --name redis-slave-6381 --net host \
-v /usr/local/redis-cluster/slave-6381/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/slave-6381/data:/data \
redis:latest --cluster-enabled yes --cluster-config-file redis-slave-6381.conf --port 6381docker create --name redis-slave-6382 --net host \
-v /usr/local/redis-cluster/slave-6382/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis-cluster/slave-6382/data:/data \
redis:latest --cluster-enabled yes --cluster-config-file redis-slave-6382.conf --port 6382# 参数解释--cluster-enabled:是否启动集群,选值:yes 、no--cluster-config-file 配置文件.conf :指定节点信息,自动生成--cluster-node-timeout 毫秒值: 配置节点连接超时时间--appendonly:是否开启持久化,选值:yes、no# 主节点最少3个,3个才能保证集群的健壮性。# 2.启动三台redisdocker start redis-master-6380 redis-slave-6381 redis-slave-6382# 或者,如果只有这三个容器的话docker start $(docker ps -aq)# 3.查看日志docker logs redis-master-6380

 主要是这句话:

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /et

c/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

翻译过来就是:

警告过度提交内存设置为0!在内存不足的情况下,后台保存可能会失败。要解决此问题,请添加“vm”。过量提交内存=1'到/etc/sysctl.conf,然后重新启动或运行命令'sysctl-vm。overcommit_memory=1'以使其生效。

解决方案在警告中已经给出:修改 /etc/sysctl.conf 配置文件,增加 vm.overcommit_memory = 1 

关于 /etc/sysctl.conf 配置

/etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。

/proc/sys目录下存放着大多数内核参数,并且可以在系统运行时进行更改,不过重新启动机器就会失效。

即,/proc/sys下内核文件与配置文件 sysctl.conf 中变量存在着对应关系。

Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做 Overcommit(过量使用)。

当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。

内核参数 overcommit_memory

它是 内存分配策略。可选值:0、1、2。

0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2, 表示内核允许分配超过所有物理内存和交换空间总和的内存

修改内核参数,要有root权限:

方法 1:编辑 /etc/sysctl.conf ,新增一行vm.overcommit_memory=1,然后sysctl -p使配置文件生效。

方法 2:临时设置:sysctl vm.overcommit_memory=1

不修改也不要紧。

# 4.进入其中一个容器docker exec -it redis-master-6380 /bin/bash# 5.创建集群redis-cli --cluster create 192.168.222.100:6380  192.168.222.100:6381 192.168.222.100:6382 --cluster-replicas 0# 这里是采用 redis-cli 命令方式创建集群,一共有三台机器。
# --cluster-replicas 0 指定集群副本数为0,也就是说上面三台全部是主节点,没有从节点。

 

 

# 如果报错:

[ERR] Node 192.168.222.100:6380 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 

删除所有redis容器和对应的映射文件,重新生成容器并创建即可。

# 5.进入其中一台redis节点redis-cli# 或者redis-cli -c# 很可能报错:Could not connect to Redis at 127.0.0.1:6379: Connection refused# 原因是:# redis.conf 配置文件不存在,或者未绑定127.0.0.1。# 解决方案:# 找到 bind开头的配置行
# 表示redis服务程序会监听这台电脑上的本地环回地址
# 如果配置文件中,只bind了这一个ip,那么就不能远程
# 访问这台服务器上的redis服务了。
# bind 127.0.0.1 ::1    # 表示redis服务程序会监听我们指定的ip地址,当然这个ip地址必须
# 是这台电脑的一个合法ip地址才行。
# bind x.x.x.x ::1       #表示redis服务程序会监听任意一个合法的ip
# bind 0.0.0.0 ::1      # 假如在配置文件中 的内容是:bind x.x.x.x ::1# 那么在使用redis-cli连接redis-server时,应该使用 :或者 redis-cli -h x.x.x.x -p port(配置文件中指定的端口号)
# redis-cli -h x.x.x.x -p 6379   # 所以此时,我们的命令应该是:redis-cli -h 192.168.222.100 -p 6380# 或者,-c是以集群模式启动
# 如果是集群而不加该参数,会导致set值的时候报错redis-cli -c -h 192.168.222.100 -p 6380# 6.查看集群信息cluster nodes# 或者查看集群状态cluster info# 集群帮助命令cluster help# 7.集群赋值与获取值# 在一个节点赋值,可能会存放到其他节点上,然后可以到其他节点上获取该key的值# 8.退出redis命令行Ctrl + c# 9.退出redis容器Ctrl + pq


因为我们创建的时候设置的redis数量比较少,而且指定的--cluster-replicas 0,导致最终我们的集群全部是主节点的。至此,我们的三主的redis集群搭建成功。

下面的方案我们创建一个三主三从的redis集群。

2.3 方案三

# 1.分别在三台机器上创建三个redis容器

# 这里没有映射redis.conf文件夹

# --cluster-config-file redis.conf 指定redis的配置文件,每个节点的data目录下生成一个该文# 件,这里我们统一使用redis.conf来命名,然后还会生成一个dump.RDB持久化快照文件。

# docker创建的redis默认持久化策略是RDB,如果我们想修改持久化策略,可以使用如下命令:

docker run -d --name redis-master-6380 --net host --privileged=true \

-v /usr/local/redis-cluster/master-6380/data:/data \

redis:latest --cluster-enabled yes --appendonly yes --cluster-config-file redis.conf --port 6380

# 我们在这里不使用AOF持久化,不添加--appendonly yes参数

# 我们直接一次性copy下面方框中的三条命令,直接执行即可创建并运行三个redis容器

docker run -d --name redis-master-6380 --net host --privileged=true \

-v /usr/local/redis-cluster/master-6380/data:/data \

redis:latest --cluster-enabled yes --cluster-config-file redis.conf --port 6380

docker run -d --name redis-slave-6381 --net host --privileged=true \

-v /usr/local/redis-cluster/slave-6381/data:/data \

redis:latest --cluster-enabled yes --cluster-config-file redis.conf --port 6381

docker run -d --name redis-slave-6382 --net host --privileged=true \

-v /usr/local/redis-cluster/slave-6382/data:/data \

redis:latest --cluster-enabled yes --cluster-config-file redis.conf --port 6382

 

# 也可能是这样的

 

# 因为我们在文档中的不同的创建redis容器的命令之间有回车,所以上图都是自动切换的。

# 2.查看创建的容器

docker ps

 

# 3.进入容器

# 这里我们进入100这台服务器的6380端口对应的redis容器

docker exec -it redis-master-6380 /bin/bash

# 或者

docker exec -it redis-master-6380 bash

# 4.创建主从集群(三主六从)

redis-cli --cluster create 192.168.222.100:6380 192.168.222.103:6380 192.168.222.104:6380 192.168.222.100:6381 192.168.222.103:6381 192.168.222.104:6381 192.168.222.100:6382 192.168.222.103:6382 192.168.222.104:6382  --cluster-replicas 2

# 此时我们又遇到了这个错误:

[ERR] Node 192.168.222.100:6380 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

# 解决方案:

# (1)删除对应节点的appendonly.aof、dump.rdb、redis.conf文件

rm -rf master-6380/data/*

rm -rf slave-6381/data/*

rm -rf slave-6382/data/*

# (2)清除redis数据库,如果是主从模式,则进入主数据库执行清除操作

# 进入容器

docker exec -it redis-master-6380 bash

# 进入redis

redis-cli -h 192.168.222.100 -p 6380

# 清除数据库

flushdb

 

# 清除数据库后继续执行4

>>> Performing hash slots allocation on 9 nodes...

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

Adding replica 192.168.222.103:6381 to 192.168.222.100:6380

Adding replica 192.168.222.104:6381 to 192.168.222.100:6380

Adding replica 192.168.222.100:6382 to 192.168.222.103:6380

Adding replica 192.168.222.104:6382 to 192.168.222.103:6380

Adding replica 192.168.222.103:6382 to 192.168.222.104:6380

Adding replica 192.168.222.100:6381 to 192.168.222.104:6380

M: 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f 192.168.222.100:6380

   slots:[0-5460] (5461 slots) master

M: f42465b62e889facf2ab37f92a36566dec0aa419 192.168.222.103:6380

   slots:[5461-10922] (5462 slots) master

M: 665fa7b34846eebee7d18e9aa2f75576a97bdca4 192.168.222.104:6380

   slots:[10923-16383] (5461 slots) master

S: bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db 192.168.222.100:6381

   replicates 665fa7b34846eebee7d18e9aa2f75576a97bdca4

S: 245cfdac475fe50d6ef1a37c43e042d280fecca2 192.168.222.103:6381

   replicates 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

S: ca008f89db1d7ade8fa474a4545a310c881997da 192.168.222.104:6381

   replicates 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

S: d06230f7438a45927d7bba6aa56cec0b7337ed27 192.168.222.100:6382

   replicates f42465b62e889facf2ab37f92a36566dec0aa419

S: 2290e52c0933bcac9261b213553b738937d0e6e8 192.168.222.103:6382

   replicates 665fa7b34846eebee7d18e9aa2f75576a97bdca4

S: d712f9e3331d83412f83107be779f0e51a8d08b3 192.168.222.104:6382

   replicates f42465b62e889facf2ab37f92a36566dec0aa419

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join

......

>>> Performing Cluster Check (using node 192.168.222.100:6380)

M: 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f 192.168.222.100:6380

   slots:[449],[4576] (2 slots) master

   2 additional replica(s)

M: d06230f7438a45927d7bba6aa56cec0b7337ed27 192.168.222.100:6382

   slots:[12706] (1 slots) master

M: bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db 192.168.222.100:6381

   slots:[8455] (1 slots) master

M: f42465b62e889facf2ab37f92a36566dec0aa419 192.168.222.103:6380

   slots:[5461-8454],[8456-10922] (5461 slots) master

   1 additional replica(s)

S: ca008f89db1d7ade8fa474a4545a310c881997da 192.168.222.104:6381

   slots: (0 slots) slave

   replicates 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

M: 665fa7b34846eebee7d18e9aa2f75576a97bdca4 192.168.222.104:6380

   slots:[10923-12705],[12707-16383] (5460 slots) master

   1 additional replica(s)

S: 2290e52c0933bcac9261b213553b738937d0e6e8 192.168.222.103:6382

   slots: (0 slots) slave

   replicates 665fa7b34846eebee7d18e9aa2f75576a97bdca4

S: d712f9e3331d83412f83107be779f0e51a8d08b3 192.168.222.104:6382

   slots: (0 slots) slave

   replicates f42465b62e889facf2ab37f92a36566dec0aa419

S: 245cfdac475fe50d6ef1a37c43e042d280fecca2 192.168.222.103:6381

   slots: (0 slots) slave

   replicates 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[ERR] Not all 16384 slots are covered by nodes.

# 用图片显示如下:

 

 

我们看上图最后一行红色字体,再看上图中的slots中括弧里面的哈希槽索引,可以发现是有不少遗漏的。

[ERR] Not all 16384 slots are covered by nodes.

# 这个往往是由于主node移除了,但是并没有移除node上面的slot,从而导致了slot总数# 没有达到16384,其实也就是slots分布不正确。所以在删除节点的时候一定要注意

# 删除的是否是Master主节点。

# 实际上,我们并没有删除主节点,只是在创建的时候本来是三主六从,但是给我们创建成# 了五主四从。就是这个原因导致的。

# 下面我们通过命令来修复集群

redis-cli --cluster fix 192.168.222.100:6380

 

 

# 下面还有很多,将这些哈希槽覆盖到某一个节点上

# 如果我们使用 cluster nodes 命令查看集群节点情况,会发现,确实是随机给我们分配了哈希槽

 

# 下面会将9个节点全部列出来,我们这里不再一一展示

# 查看集群情况

cluster info

 

# 修复完成后再用check命令检查下是否正确

redis-cli --cluster check 192.168.222.100:6380

# 又很长,我们截取重要信息

# 如果分布不均匀那可以使用下面的方式重新分配slot

# 我们上面的未分配的插槽再分配时是随机的,这里重新分配(重新分片)

redis-cli --cluster reshard 192.168.222.100:6380

# 又很长

# 直到这样一句话:

How many slots do you want to move (from 1 to 16384)?

# 意思是你想移动多少个插槽

# 也就是说你想移动多少个槽位到某个主节点

# 如果我们输入一个数字5000的话,又让我们输入节点ID

# 我们输入100的6380这个节点的id后又有提示了,这次我们直接输入all

# 又很长

 

# 接着又很长,有个提示:

 

Do you want to proceed with the proposed reshard plan (yes/no)? yes

# 意思是,是否要继续执行既定的重新分片计划

# 我们选择是

# 下面的操作都是从某一个节点开始移动哈希槽到另一个节点上

# 查看哈希槽信息

redis-cli -h 192.168.222.100 -p 6380

cluster slots

 

# 太多我们就不看了

# 下面说一下槽位定位算法

Redis 集群总共的槽位数是 16384 个,每一个主节点负责维护一部分槽以及槽所映射的键值数据,Redis 集群默认会对要存储的 key 值使用 CRC16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位,公式为

slot = CRC16(key) % 16383

# 负载均衡

在 Redis 集群负载不均衡的情况下,我们可以使用 rebalance 命令重新分配各个节点负责的槽数量,从而使得各个节点的负载压力趋于平衡,从而提高 Redis 集群的整体运行效率。

redis-cli --cluster rebalance 192.168.222.100:6380

 

# 我们看到确实执行了重新负载的命令

需要注意的是,即使输入 rebalance 命令,但它可能不会执行,当它认为没有必要进行分配时会直接退出,如下所示:

$ redis-cli --cluster rebalance 127.0.0.1:6381

>>> Performing Cluster Check (using node 127.0.0.1:6381)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

*** No rebalancing needed! All nodes are within the 2.00% threshold.

# 输入命令验证

 

# 上面我们看到12706这个槽位已经被移动到100的6382节点,所以执行set k1 v1命令时直接报错。这是什么原因呢?因为我们上面进入redis命令行的时候使用的命令是

redis-cli -h 192.168.222.100 -p 6380

这个命令连接的redis是单机版的,而非以集群模式连接。根据哈希槽定位算法,k1这key的哈希槽被分配到100的6382节点,所以set值的时候无法成功。

要解决这个办法,我们只需要采用集群模式连接即可,命令如下:

redis-cli -c -h 192.168.222.103 -p 6380

同样道理,我们采用redis客户端工具连接的时候,也需要指定是否以集群模式连接,如图:

 

# 退出redis命令行和容器

Ctrl + c

Ctrl + pq

# 到redis集群安装的一个配置文件目录查看

cd /usr/local/redis-cluster/master-6380/data

cat redis.conf

# 这次就比较乱了

 

该文件的主要信息是:

节点id

节点ip:端口@端口+10000

master或者slave

主节点id(如果本身是主节点就以-代替)

0

然后这一串不知道了

多少个已连接的

# 下面讲一下redis的端口

在redis cluster架构下,每个redis要放开两个端口号,比如一个是6379,另外一个就是加10000的端口号,比如16379

16379端口号是用来进行节点间通信的,也就是cluster bus的东西,集群总线。cluster bus的通信,用来进行故障检测,配置更新,故障转移授权

cluster bus用了另外一种二进制的协议,主要用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

# 上面我们创建并运行redis的时候没有设置自动重启功能

docker container update --restart=always redis-master-6380 redis-slave-6381 redis-slave-6382

# 查看redis的节点信息

info replication

192.168.222.100:6382> info replication

# Replication

role:master

connected_slaves:0

master_failover_state:no-failover

master_replid:9d16b7c4b9f484fb748ff837ca9992276e32bd54

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

role后面会显示该节点是master或者slave,如果该节点为slave节点,那么还会显示主节点的ip和端口号,master_link_status的值为up表示从节点和主节点的关系已经连接上,为down则表示关系未连接。

我们的redis集群虽然搭建成功了,但是并没有达到我们要的效果,也就是三主六从的效果。实际效果是:

主节点

从节点

100:6380

104:6381

100:6381

103:6381

100:6382

103:6380

104:6382

104:6380

103:6382

下面我们移除100:6382master节点,并分配到100:6380节点上。

# 查看节点信息

cluster nodes

# 找到100:6382节点的id和100:6380节点的id

# 删除100:6382节点

redis-cli --cluster del-node 192.168.222.100:6382 d06230f7438a45927d7bba6aa56cec0b7337ed27

 

主要是最后一句话:

[ERR] Node 192.168.222.100:6382 is not empty! Reshard data away and try again.

意思是该节点不为空,请重新分片数据并重试。

因为100:6382节点上有数据,我们将100:6382上的所有哈希槽都移动到100:6380上

redis-cli --cluster reshard 192.168.222.100:6382 --cluster-from d06230f7438a45927d7bba6aa56cec0b7337ed27 --cluster-to 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f --cluster-slots 4096 --cluster-yes

# 这里的4096不一定准确,因为分配的太松散了,我不可能一个一个的数一下到底多少个

# 而且我也没有找到命令如何查看redis集群某一节点的哈希槽的数量的

 

# 再次查看节点情况

cluster nodes

 

100:6382节点已经没有分配哈希槽了,此时应该可以执行删除命令了。

# 也可以使用如下命令查看该节点信息:

redis-cli --cluster info 192.168.222.100:6382

 

上图是我后面找到的命令。该命令也显示,集群中已经没有了100:6382节点,只剩下四个了。

上图也说明我们将一个主节点的哈希槽重新分片到其他主节点之后,其实可以通过上面的命令查看该节点的哈希槽是否全部重新分片完成。当然,再重新分片的时候也可以使用该命令来查看所有节点的哈希槽分配情况。

看上图,我们可以知道,该命令是在docker容器内部执行的,也就是说要先进入redis容器中,通过指定某一个master节点的ip和端口即可查看全部集群的哈希槽分配情况以及key的简单情况。

而cluster info命令是在连接redis命令行中执行的,显示的是集群的一些简单信息,如下:

 

执行该命令时,不能在登入该节点当中,否则不能正常移除该节点。同时,如果该节点是master节点且还有slave节点的时候,不能先移除该master节点,因为会触发故障自动切换,从节点会变成master节点。

redis-cli --cluster del-node 192.168.222.100:6382 d06230f7438a45927d7bba6aa56cec0b7337ed27

 

由此可见,节点100:6382已经移除完毕!

我们还可以使用其他命令查看

cluster nodes

或者

cluster info

 

已知的集群节点数量为8。

或者

redis-cli --cluster info 192.168.222.103:6380

这些命令的执行地方可以看截图,这里再重申一下

凡是redis-cli(不包括redis-cli --cluster)类的命令都要在进入redis容器之后再连接redis命令行才可以执行,其他的都要在进入redis容器中执行。

不过也不尽然,在redis容器之外,也就是在虚拟机上其实也可以执行,只是需要安装redis-cli命令行工具

此时我们的集群就变成了这样的:

主节点

从节点

100:6380

104:6381

100:6381

103:6381

100:6382

103:6380

104:6382

104:6380

103:6382

变成了四主四从的集群。

你是不是也以为是这样的,我们删除了100:6382master节点,就变成了上图的集群模式。实际上不是这样的,我是在后面删除

100:6381

103:6381

这个节点的时候发现,原来的集群它变了,为了确认我没有看错,我翻看了之前集群信息。

d06230f7438a45927d7bba6aa56cec0b7337ed27 192.168.222.100:6382@16382 master

665fa7b34846eebee7d18e9aa2f75576a97bdca4 192.168.222.104:6380@16380 master

245cfdac475fe50d6ef1a37c43e042d280fecca2 192.168.222.103:6381@16381 slave bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db 192.168.222.100:6381@16381 master

f42465b62e889facf2ab37f92a36566dec0aa419 192.168.222.103:6380@16380 myself,slave d712f9e3331d83412f83107be779f0e51a8d08b3

d712f9e3331d83412f83107be779f0e51a8d08b3 192.168.222.104:6382@16382 master

ca008f89db1d7ade8fa474a4545a310c881997da 192.168.222.104:6381@16381 slave 3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

2290e52c0933bcac9261b213553b738937d0e6e8 192.168.222.103:6382@16382 slave 665fa7b34846eebee7d18e9aa2f75576a97bdca4

3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f 192.168.222.100:6380@16380 master

我们看到原来的master节点分别是:

Master节点

Master节点id

100:6382

d06230f7438a45927d7bba6aa56cec0b7337ed27

104:6380

665fa7b34846eebee7d18e9aa2f75576a97bdca4

100:6381

bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

104:6382

d712f9e3331d83412f83107be779f0e51a8d08b3

100:6380

3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

Slave节点分别是:

Slave节点

Slave节点id

所属master节点id

所属master节点

103:6381

245cfdac475fe50d6ef1a37c43e042d280fecca2

bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

100:6381

103:6380

f42465b62e889facf2ab37f92a36566dec0aa419

d712f9e3331d83412f83107be779f0e51a8d08b3

104:6382

104:6381

ca008f89db1d7ade8fa474a4545a310c881997da

3f7dad8c7c9eabae3a8aa17d8756ca136b8ce54f

100:6380

103:6382

2290e52c0933bcac9261b213553b738937d0e6e8

665fa7b34846eebee7d18e9aa2f75576a97bdca4

104:6380

和我们最初那张图做一个对比

下图是我对上面的图做了修改,发现可能是最初我们搞错了。

主节点

从节点

100:6380

104:6381

100:6381

103:6381

100:6382

104:6382

103:6380

104:6380

103:6382

原来并没有变化。

这不是我们想要的,我们下一步要将100:6381主节点和103:6381从节点以及104:6382和103:6380从集群中移除,最终实现的要求是6380为主节点的端口,6381和6382为从节点的端口。

# 进入192.168.222.100:6380节点容器

docker exec -it redis-master-6380 bash

# 连接redis命令行

redis-cli -c -h 192.168.222.100 -p 6380

# 查看redis集群节点情况

cluster nodes

# 获取到100:6381和103:6381节点id

bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

245cfdac475fe50d6ef1a37c43e042d280fecca2

# 退出redis连接

Ctrl + c

# 将100:6381主节点的哈希槽分配给

# 删除100:6381主节点

redis-cli --cluster del-node 192.168.222.100:6381 bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

 

# 此时我们需要对100:6381进行重新分片,将它的哈希槽分配给其他主节点。

# 但是我们看到104:6382和103:6380这一对主从集群中的从节点正是我们需要最终要的主节点,那么我们可以把104:6382宕机,然后103:6380自动进行故障主从自动切换。此时103:6380变成了主节点,当把104:6382重新启动的时候103:6380依然是主节点。

我们进入104:6382容器中,执行如下命令:

redis-cli -h 192.168.222.104 -p 6382 shutdown

如果我们当初设置的有密码,则需要:

redis-cli -h 192.168.222.104 -p 6382 -a '123456' shutdown

但是我们发现这种方式是不行的,为什么呢?在我们最开始创建运行容器的时候没有添加 --restart=always参数,但是后面我们通过如下命令修改了redis自动重启的命令:

docker container update --restart=always redis-master-6380 redis-slave-6381 redis-slave-6382

所以我们的104:6382宕机之后就自动重启,此时依然是主节点。

 

 

我们看到104:6382依然是主节点,而且还是拥有一个从节点。

既然这样不行,那我们就直接停掉这个容器。

docker stop redis-slave-6382

docker ps

redis-cli --cluster info 192.168.222.104:6380

 

*** WARNING: 192.168.222.103:6380 claims to be slave of unknown node ID d712f9e3331d83412f83107be779f0e51a8d08b3.

这句话的意思是:

***警告:192.168.222.103:6380声称是未知节点ID d712f9e3331d83412f83107be779f0e51a8d08b3的从属节点。

我丢!

竟然没有故障自动进行主从切换。

而且上图中原来的4个主节点被我们干掉一个,就剩余一个了,确实没有自动故障切换。

等我百度了一番之后,回来再查看集群信息:

redis-cli --cluster info 192.168.222.104:6380

 

此时竟然发现103:6380变成了主节点。

那这是什么缘故呢?

可能的原因是,故障自动切换是需要时间的,主节点刚宕掉的时候,从节点没有了主节点就准备进行切换主节点。但是不一定会立马进行主从切换,比如在副本漂移的情况下,是可能不存在单主机节点,也不存在单从节点。此时成对出现的主节点就会自动执行主节点的读写任务,或者指定的节点变成主节点,那么此时我们的103:6380可能就不会启动切换成主节点了。

所以等待一定的时间,大概几分钟时间,如果不存在那些情况,103:6380就自动切换成了主节点。

此时我们的集群情况是:

主节点

从节点

100:6380

104:6381

100:6381

103:6381

100:6382

103:6380

104:6382(宕掉)

104:6380

103:6382

那我们继续删除节点100:6381和103:6381

对100:6381进行reshard,将该节点的哈希槽分配给103:6380

redis-cli --cluster reshard 192.168.222.100:6381 --cluster-from bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db --cluster-to f42465b62e889facf2ab37f92a36566dec0aa419 --cluster-slots 3276 --cluster-yes

上图第一个id是100:6381的主节点id,第二个id是103:6380被分配的主节点的id,3276是我们上图中看到的103:6380中的哈希槽的个数。

再查看集群信息

redis-cli --cluster info 192.168.222.104:6380

 

删除100:6381节点

redis-cli --cluster del-node 192.168.222.100:6381 bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

失败了

 

执行其他命令也有错误:

将100:6381切换成104:6380的从节点

redis-cli -h 192.168.222.100 -p 6381 slaveof 192.168.222.104  6380

 

将当前节点设置为指定nodeid节点的从节点

cluster replicate 665fa7b34846eebee7d18e9aa2f75576a97bdca4

(error) ERR To set a master the node must be empty and without assigned slots.

# 列出某个节点slave列表

cluster slaves 665fa7b34846eebee7d18e9aa2f75576a97bdca4

删除对应节点下的data目录下的配置文件,然后重启该容器

重新删除该节点

redis-cli --cluster del-node 192.168.222.100:6381 bfda95bc9abbed4d4e4c86a4fe6ab8f76a9716db

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38531.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cloud-computing 实验镜像 chinaskills_cloud_iaas.iso chinaskills_cloud_paas.iso

Cloud-computing 实验镜像 最近因新项目再次进行云计算环境的搭建, 找这两个镜像( 找chinaskills_cloud_paas.iso chinaskills_cloud_iaas.iso)颇为费劲,用尽九牛二虎之力总算找到了,该大侠还分享了诸多系统镜像和完…

Centos7搭建SVN代码控制服务器

Centos7搭建SVN代码控制服务器检查SVN是否安装创建SVN版本库配置代码库设置允许访问远程仓库的用户帐号密码设置权限控制设置SVN服务配置启动svn与停止启动SVN关闭SVN访问拉取远程仓库代码检查SVN是否安装 1、centos7系统自带SVN rpm -qa subversion2、如果没有则通过yum安装 …

Day15--加入购物车-初始化vuex

1.加入购物车: 我的操作: ************************************************************************************************************* 2.购物车里面的商品数据在多个页面都会用到。所以把购物车里面的商品数据存储在vuex里面, 我的…

Windows10安装配置allure

1、allure官方文档: https://docs.qameta.io/allure/#_about 官方文档中,windows部署allure步骤: 奈何提示scoop不是內部命令 2、安装scoop scoop官方文档:https://scoop.sh/ 需要打开power shell,执行提示的两条…

外汇天眼:英国研究人员与南非合作应对气候变化

随着南非对气候变化的担忧加剧,英国卫生部已同意与南非就九个不同项目组建一个合作研究团队,旨在拯救生命。 南非总统西里尔拉马福萨 (Cyril Ramaphosa) 与英国卫生大臣在克里克研究所会面后达成了合作协议,克里克研究所如今被称为欧洲最大的…

BUUCTF Misc 来首歌吧 荷兰宽带数据泄露 面具下的flag 九连环

来首歌吧 下载文件 使用Audacity打开 可以发现框出来的一串,放大查看 有长有短有空格,大概率是摩斯密码 ...../-.../-.-./----./..---/...../-..../....-/----./-.-./-.../-----/.----/---../---../..-./...../..---/./-..../.----/--.../-../--.../-----/----./.…

汽车蓄电池低压报警设计

目 录 摘 要 I Abstract II 第一章 绪论 1 1.1 选题背景及意义 1 1.2 国内外发展状况 2 1.2.1国内发展现状 2 1.2.2 国外蓄电池监测系统研究现状 2 1.3 研究主要内容 4 第2章 系统总体设计与算法确定 5 2.1 监测系统总体设计原理 5 2.2 主控芯片的选择 6 2.2.1 89C51单片机的概…

IPv6进阶:IPv6 过渡技术之IPv6 over IPv4 手动隧道

实验拓扑 R1-R3-R2之间的网络为IPv4环境;PC1及PC2处于IPv6孤岛。 实验需求 R1及R2为IPv6/IPv4双栈设备;在R1及R2上部署IPv6 over IPv4手工隧道使得PC1及PC2能够互相访问。 配置及实现 R3的配置如下 [R3] interface GigabitEthernet0/0/0 [R3-Gigabi…

集合框架----源码解读LikedHashSet篇

1.官方介绍 Hash表和链表实现了Set接口,具有可预测的迭代顺序。该实现与HashSet的不同之处在于它维护了一个贯穿其所有条目的双向链表。该链表定义了迭代顺序,即元素插入集合的顺序(插入顺序)。注意,如果一个元素重新插入到集合中&#xff0c…

【JAVA案例】作业管理系统(控制台版本)

博主:👍不许代码码上红 欢迎:🐋点赞、收藏、关注、评论。 格言: 大鹏一日同风起,扶摇直上九万里。 文章目录一、JAVA面向对象程序设计1.1 工程分包1.2 各类属性及功能二、数据初始化三、学生模块四、教师…

传奇单机架设登录器配置教程

传奇单机顾名思义就是在本地电脑上架设传奇,限制同一个局域网才能一起玩,我接触到几个朋友不明白外网和单机的区别 架设单机需要准备以下程序: 传奇服务端(版本Mirserver) DBC2000 (百度可直接下载) 配套登…

基于SpringBoot的会员制医疗预约服务管理信息系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SpringBoot 前端:Vue、HTML 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#…

Apifox:成熟的测试工具要学会自己写接口文档

好家伙, 在开发过程中,我们总是避免不了进行接口的测试, 而相比手动敲测试代码,使用测试工具进行测试更为便捷,高效 今天发现了一个非常好用的接口测试工具Apifox 相比于Postman,他还拥有一个非常nb的功…

【毕业设计】26-基于单片机心跳体温血压系统仿真设计(原理图+仿真+演示视频+论文)

【毕业设计】基于单片机心跳体温血压系统仿真设计(原理图仿真演示视频论文) 文章目录【毕业设计】基于单片机心跳体温血压系统仿真设计(原理图仿真演示视频论文)任务书设计说明书摘要设计说明书及设计文件任务书 以单片机为控制核…

【虚幻引擎UE】UE5 材质动态修改的2种方法(含工程源码)

演示效果: 示例工程源码 一、直接材质参数变量 1、贴图变量: 在材质蓝图中右键,创建变量TextureSampeParameter2D(贴图变量)。 输入RGB到基础颜色 2、单色变量: 在材质蓝图中右键,创建变量…

牛顿法,高斯牛顿法,列文伯格-马夸尔特(LM)法

文章目录一:牛顿法 (Newtons method)1:概述2:牛顿方向与牛顿法3:牛顿法的基本步骤4:举例二:高斯牛顿法 (Gauss–Newton algorithm)1:概述2&#x…

Metabase学习教程:仪表盘-5

SQL查询仪表盘添加筛选器 如何将过滤器小部件添加到仪表盘,并将它们连接到多个SQL查询中的字段过滤器变量。 本文介绍如何创建仪表盘小工具到过滤器数据输入SQL查询。图1显示了我们将要构建的仪表盘: 图1。我们将要构建的:一个仪表盘&#…

在el-table表头上引入组件不能实时传参bug

文章目录场景还原解决方法出现原因场景还原 产品要求&#xff1a;点击表格的表头&#xff0c;能触发一个下拉的列表&#xff0c;列表能携带表格的筛选条件&#xff0c;获取相应的数据 写了一个demo&#xff0c;来还原一下bug出现的场景&#xff1a; <div id"demo&qu…

分省/市政府性债务数据财政收支数据财政透明度

&#xff08;1&#xff09;30省地方政府债务面板数据 1、数据来源&#xff1a;自身 2、时间跨度&#xff1a;2012-2018年 3、区域范围&#xff1a;全国30各省&#xff08;西藏除外&#xff09; 4、指标说明&#xff1a; 部分指标如下&#xff1a; 负债率&#xff08;地方…

【性能|优化】TB级flink任务报错分析:Could not compute the container Resource

文章目录一. 问题引入1. 场景描述2. 日志简析二. 初级问题分析与解决1. 问题分析1.1. yarn的调度器设置1.2. 程序设置2. 问题解决三. &#xff08;性能&#xff09;新的问题1. 问题描述2. 理想化的最优方案3. "PlanB"的解决方案四. 反思与迭代一. 问题引入 1. 场景描…