docker 哨兵模式和集群模式安装Redis7.0.12

docker 哨兵模式和集群模式安装Redis7.0.12

1.下载镜像

1.1 配置阿里云加速源

墙外能访问https://hub.docker.com/_/redis 的可跳过
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
登录后选择左侧的镜像工具=>镜像加速器,获取加速器地址,根据自己的系统选择对照操作文档操作
命令如下:
针对Docker客户端版本大于 1.10.0 的用户

您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://你的加速地址前缀.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

1.2 拉取镜像

docker pull redis:7.0.12

docker images

image-20230723172657954

2.配置主从复制

本次操作是在一台物理机上,分别开启redis-6379,redis-6380,redis-6381三个容器,如果有多个物理机或者云服务器,可均使用6379端口,要保证网络能互相ping通,防火墙端口开放或安全组规则开放端口

2.1 redis.conf 配置文件修改

# 是否后台程序,如果选择的是物理机或者虚拟机安装,这个地方是yes,docker场景下是no,因为使用-d命令了,这里避免冲突直接改成no
daemonize no 

# 绑定的ip,配置文件里写的是注释了就监听所有ip,这个默认是没有注释的,要注释掉
#bind 127.0.0.1 

#protected-mode默认情况下是启用的(protected-mode yes),这意味着只允许通过本地回环接口(127.0.0.1)访问Redis服务器。这是为了提供一定的安全性,防止未经授权的外部访问,这个改成no
protected-mode no 

#port 端口,只有一台机器的情况下需要更改端口和其他实例区分,这里slave 节点分别配置成6380,6381,多个机器可以都保持6379
port 6379 

#我这里设置容器进入的工作空间为/data/redis-6379,根据情况设置,但要和挂载的路径保持一致,slave节点分别是/data/redis-6380,/data/redis-6381
dir /data/redis-6379 

#pidfile 进程id文件,根据情况设置,为了区分slave节点分别是 /var/run/redis_6380.pid ,/var/run/redis_6381.pid
pidfile /var/run/redis_6379.pid

#logfile 日志文件,这里巨坑,**如果日志文件和启动文件同级,这里可以配置为./6379.log,否则这里一定要写绝对路径,是个巨坑!!!**
#我的工作空间dir是/data/redis-6379,我可以写成./logs/redis.log,但我还是用绝对路径,
slave节点分别是/data/redis-6380/logs/redis.log,/data/redis-6381/logs/redis.log
logfile "/data/redis-6379/logs/redis.log"

#requiredpass  密码,这自己定义,别太简单,我司安全部门有漏洞扫描,太简单会被扫出来,回头还要改,麻烦
requiredpass  xxxxxx 

#dbfilename 持久化rdb文件名称,默认即可,别改
dbfilename dump.rdb

#appendonly 开启aof持久化
appendonly yes

#appendfilename aof持久化的文件名,别改,默认即可
appendfilename "appendonly.aof"

#appenddirname  aof持久化的目录。没必要改,默认即可
appenddirname "appendonlydir"


#masterauth slave访问master的通行密码,非哨兵模式master不用配置,哨兵模式都需要配置,因为master可能变成slave
masterauth xxxxxx

# replicaof <masterip> <masterport> 配置是谁的副本 replicaof 主库IP 主库端口  master节点不用配置
replicaof 192.168.240.10 6379

2.2 启动redis实例

–net=host 参数用于将容器与主机共享网络命名空间,说白了,不使用docker内部的网络,容器将使用与主机相同的网络配置

–restart=always 自动重启

-p 6379:6379 外部端口6379映射到容器内部端口6379,同理6380:6380,6381:6381

–name redis-6379 实例名称

-v /data/redis-6379/data:/data/redis-6379/data 将容器内部的data目录挂载到外部,以防实例销毁数据丢失

-v /data/redis-6379/conf/redis.conf:/etc/redis/redis.conf 外置配置文件

-v /data/redis-6379/logs/redis.log:/data/redis-6379/logs/redis.log 外置日志文件方便查看

-d 后台运行,别和daemonize yes 一起使用

redis:7.0.12 镜像

redis-server bin程序

/etc/redis/redis.conf 容器内部的配置文件

docker run --net=host --restart=always -p 6379:6379 --name redis-6379 \
-v /data/redis-6379/data:/data/redis-6379/data \
-v /data/redis-6379/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6379/logs/redis.log:/data/redis-6379/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf


docker run --net=host --restart=always -p 6380:6380 --name redis-6380 \
-v /data/redis-6380/data:/data/redis-6380/data \
-v /data/redis-6380/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6380/logs/redis.log:/data/redis-6380/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf


docker run --net=host --restart=always -p 6381:6381 --name redis-6381 \
-v /data/redis-6381/data:/data/redis-6381/data \
-v /data/redis-6381/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6381/logs/redis.log:/data/redis-6381/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

启动完成,docker ps

image-20230723190430117

使用docker 命令进入容器或者登录redis

docker exec -it redis-6379 redis-cli -p 6379
docker exec -it redis-6380 redis-cli -p 6380
docker exec -it redis-6381 redis-cli -p 6381

输入auth 密码登录redis

info replication  #可以查看复制结点的主从关系和配置信息

对redis 进行写操作,可以看见slave节点可以同步master节点的数据,但是在slave节点写数据,是不被允许的

主从复制配置完毕

3.配置哨兵高可用

主从同步并不能保证高可用,哨兵模式则会进行主从切换,将其中一个slave作为新master

3.1 sentinel配置文件修改

#是否以后台daemon方式运行
daemonize:no

#安全保护模式
protected-model:no

#端口  26379 slave 26380 26381
port:26379

#日志文件路径,slave节点同理
logfile "/data/sentinel-6379/logs/sentinel26379.log"

#pid文件路径,slave节点同理
pidfile /var/run/redis-sentinel26379.pid

#工作目录,slave节点同理
dir /data/sentinel-6379

#设置要监控的master服务器quorum表示最少有几个哨兵认可客观下线,同意故障迁移的法定票数
#sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 192.168.240.10 6379 2

#连接master服务的密码 sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster xxxxxx

其他参数,按需设置

sentinel down-after-milliseconds 指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为主节点下线
sentinel parallel-syncs 表示允许并行同步的slave个数,当Master挂了后,哨兵会选出新的Master,此时,剩余的slave会向新的master发起同步数据
sentinel failover-timeout 故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,表示故障转移失败
sentinel notification-script 配置当某一事件发生时所需要执行的脚本
sentinel client-reconfig-script 客户端重新配置主节点参数脚本

我在本机分别将实例放在了/data/redis-6379/conf/sentinel.conf,/data/redis-6380/conf/sentinel.conf,/data/redis-6380/conf/sentinel.conf,按需设置

3.2 启动sentinel实例

docker run --net=host --name sentinel-6379  \
-v  /data/redis-6379/conf/sentinel.conf:/etc/sentinel-6379/sentinel.conf \
-v  /data/redis-6379/logs/sentinel26379.log:/data/sentinel-6379/logs/sentinel26379.log \
-d  redis:7.0.12 redis-sentinel /etc/sentinel-6379/sentinel.conf


docker run --net=host --name sentinel-6380  \
-v  /data/redis-6380/conf/sentinel.conf:/etc/sentinel-6380/sentinel.conf \
-v  /data/redis-6380/logs/sentinel26380.log:/data/sentinel-6380/logs/sentinel26380.log \
-d  redis:7.0.12 redis-sentinel /etc/sentinel-6380/sentinel.conf


docker run --net=host --name sentinel-6381  \
-v  /data/redis-6381/conf/sentinel.conf:/etc/sentinel-6381/sentinel.conf \
-v  /data/redis-6381/logs/sentinel26381.log:/data/sentinel-6381/logs/sentinel26381.log \
-d  redis:7.0.12 redis-sentinel /etc/sentinel-6381/sentinel.conf

使用docker 命令进入容器或者登录redis-cli

docker exec -it sentinel-6379 redis-cli -p 26379
docker exec -it sentinel-6380 redis-cli -p 26380
docker exec -it sentinel-6380 redis-cli -p 26381

进入后查看哨兵信息

info Sentinel

image-20230723192734005

进入redis-6389,先登录

info replication

image-20230723192940689

如图所示,6379role是maser,有两个slave

salve节点6380,6381

image-20230723194145304

image-20230723194005990

image-20230723194050215

3.3 测试高可用

1.模拟主节点挂掉

docker stop redis-6379

image-20230723194246991

2.分别查看redis-6380,redis-6381(等30秒,心跳是30秒),可以通过sentinel down-after-milliseconds mymaster 30000 设置

重新登录redis-6380,redis-6381,发现redis-6381变成了主节点,只有一个slave节点6380

docker exec -it redis-6380 redis-cli -p 6380
docker exec -it redis-6381 redis-cli -p 6381
info replication

image-20230723194559586

image-20230723194427408

3.重启redis-6379节点,发现redis-6379变成slave节点

docker start redis-6379

image-20230723194818823

docker exec -it redis-6379 redis-cli -p 6379

image-20230723194921995

4.多次反复stop master节点,发现master节点挂掉之后会将另外的slave节点选举为主节点

至此哨兵模式高可用配置完毕

4.主从复制原理

4.1 slave启动,同步首清

slave启动成功连接到master后会发送一个sync命令

slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除

4.2 首次连接,全量复制

master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据集的命令并缓存起来,master节点执行RDB持久化完后,master将RDB快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步

而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化

4.3 心跳持续,保持通信

master 发出ping心跳周期默认是10秒 通过 repl-ping-replica-period 10 可以设置

4.3 进入平稳,增量复制

master继续将新的所有收集到的修改命令自动依次传送给slave,完成同步

4.4 从机下线,重连续传

master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的。

master只会把已经缓存的offset后面的数据复制给slave,类似断点续传

4.5 复制的缺点

复制延时,信号衰减

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

5.哨兵模式高可用原理

当一个主从配置中master失效后,sentinel可以选举出一个新的master用于自动接替原master的工作,主从配置中的其他redis服务器自动指向新的master同步数据,一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换

三个哨兵监控一主二从,正常运行中

image-20230723200711239

5.1 下线依据

SDown主观下线(Subjectively Down)

1. SDOWN(主观不可用)是单个sentinel自己主观上检测到的关于master的状态,从sentinel的角度来看,如果发送了PING心跳后,在一定时间内没有收到合法的回复,就达到了SDOWN的条件。
2. sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度

ODown客观下线(Objectively Down)

1.ODOWN需要一定数量的sentinel,多个哨兵达成一致意见 才能认为一个master客观上已经宕机
2. sentinel配置文件中的 sentinel monitor <master-name> <ip> <redis-port> <quorum> 设置法定票数,这个参数是进行客观下线的一个依据,法定人数/法定票数意思是至少有quorum个sentinel认为这个master有故障才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

5.2 选举流程

  1. 启动哨兵:在 Redis Sentinel 集群中,每个哨兵都会运行一个独立的进程。
  2. 哨兵监控主服务器:每个哨兵会定期向主服务器发送心跳检测。
  3. 发现主服务器故障:当一个哨兵检测到主服务器无响应,并在配置的时间内未收到心跳回复时,它会将主服务器标记为故障。
  4. 哨兵进入选举状态:一旦哨兵确认主服务器故障,它会与其他哨兵进行通信以达成共识,确定新的主服务器。
  5. 选举领导者:哨兵之间会通过PAXOS算法或Raft算法等共识算法来选举新的主服务器。选举过程中,哨兵会交换信息,比较主服务器的配置纪元(config epoch)、优先级(priority)等属性来决定新的主服务器。
  6. 选举结果通知客户端:一旦新的主服务器选出,哨兵会将选举结果广播给所有的客户端和其他哨兵。
  7. 客户端重定向:在选举完成后,被选举为主服务器的哨兵会将新的主服务器信息通知给连接到其他哨兵的客户端,这样客户端就可以与新的主服务器建立连接。
  8. 故障恢复:一旦选举完成,被选为主服务器的哨兵会尝试对故障主服务器进行故障恢复,如进行自动故障转移等操作。

6.哨兵使用建议

  1. 哨兵节点的数量应为多个,哨兵本身应该集群,保证高可用
  2. 哨兵节点的数量应该是奇数
  3. 各个哨兵节点的配置应一致
  4. 如果哨兵节点部署在Docker等容器里面,尤其要注意端口的正确映射
  5. 哨兵集群+主从复制,并不能保证数据零丢失,所以需要使用集群

7.集群模式

7.1 实例创建

新建六个redis 实例,以6382为例,其他几个配置一样

bind 0.0.0.0
daemonize yes
protected-mode no
port 6381
logfile "/data/redis-6382/logs/redis.log"
pidfile /var/run/redis_cluster_6382.pid
dir /myredis/cluster
dbfilename dump.rdb
appendonly yes
appendfilename "appendonly.aof"
requirepass tan!@#
masterauth tan!@#

cluster-enabled yes
#每个集群节点都有一个集群配置文件。这个文件不应手动编辑。它是由Redis节点创建和更新的,看注释,所以这里你只需要取个名就好,不能重复
cluster-config-file nodes-6382.conf  
cluster-node-timeout 5000

7.2 启动实例

docker run --net=host --restart=always -p 6382:6382 --name redis-6382 \
-v /data/redis-6382/data:/data/redis-6382/data \
-v /data/redis-6382/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6382/logs/redis.log:/data/redis-6382/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf


docker run --net=host --restart=always -p 6383:6383 --name redis-6383 \
-v /data/redis-6383/data:/data/redis-6383/data \
-v /data/redis-6383/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6383/logs/redis.log:/data/redis-6383/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf


docker run --net=host --restart=always -p 6384:6384 --name redis-6384 \
-v /data/redis-6384/data:/data/redis-6381/data \
-v /data/redis-6384/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6384/logs/redis.log:/data/redis-6384/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

docker run --net=host --restart=always -p 6385:6385 --name redis-6385 \
-v /data/redis-6385/data:/data/redis-6381/data \
-v /data/redis-6385/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6385/logs/redis.log:/data/redis-6385/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

docker run --net=host --restart=always -p 6386:6386 --name redis-6386 \
-v /data/redis-6386/data:/data/redis-6381/data \
-v /data/redis-6386/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6386/logs/redis.log:/data/redis-6386/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

docker run --net=host --restart=always -p 6387:6387 --name redis-6387 \
-v /data/redis-6387/data:/data/redis-6381/data \
-v /data/redis-6387/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6387/logs/redis.log:/data/redis-6387/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

image-20230801165222859

7.3 构建集群关系

通过redis-cli 命令为6台机器构建集群关系

–cluster- replicas 1 表示为每个master创建一一个slave节点

进入其中一个客户端

docker exec -it redis-6382 redis-cli -p 6382
输入密码
auth tan!@#
输入cluster nodes
集群本身只有自己,切换6383 6384 ... 6387 结果一致

image-20230801170057611

image-20230801170156340

进入容器内部

docker exec -it redis-6382 /bin/bash

复制以下命令加入集群,这里-a 密码,我这里用了!@#,要用单引号包着

redis-cli -a 'tan!@#' --cluster create --cluster-replicas 1 192.168.240.10:6382 192.168.240.10:6383 192.168.240.10:6384 192.168.240.10:6385 192.168.240.10:6386 192.168.240.10:6387

image-20230801171335998

上面的图可以看到集群的对应关系

6382  负责槽位:[0-5460] (5461 slots)       master  副本6386
6383  负责槽位:[5461-10922] (5462 slots)   master  副本6387
6384  负责槽位:[10923-16383] (5461 slots)  master  副本6385

再次进入redis客户端

docker exec -it redis-6382 redis-cli -p 6382 -a 'tan!@#'

image-20230801171855369

7.4 集群读写

docker exec -it redis-6382 redis-cli -p 6382 -a 'tan!@#'

写入 set k1 v1,我在6382 和6383 均不能让写入,提示moved … 6384 ,进入6384客户端,却提示成功

image-20230801172310301

docker exec -it redis-6384 redis-cli -p 6384 -a 'tan!@#'

image-20230801172522945

是因为做了集群后每个master负责不同的槽位

image-20230801172903297

客户端加-c 表示集群模式即可解决,不用自己找到对应的客户端

docker exec -it redis-6382 redis-cli -p 6382 -a 'tan!@#' -c

image-20230801173649889

查看某个key该属于对应的槽位值

cluster keyslot 键名称

image-20230801173936989

7.5 主从切换

容错切换迁移

主6382和从机切换,先停止主机6382,6386作为从机上位,以实际情况为准,7.3里是6386作为6382的从机

docker stop redis-6382

stop之前集群的信息在7.4中可以看到

查看集群信息

docker exec -it redis-6384 redis-cli -p 6384 -a 'tan!@#' -c

cluster nodes

image-20230801174737800

6382 原来是master 但是状态是fail,6386角色变成了master

节点恢复

docker start redis-6382

进入客户端,6382虽然恢复了,但是并不会是master,是slave角色

image-20230801175328416

从属调整

cluster failover

在Redis Cluster中,failover指的是当主节点(master)不可用时,自动切换为使用备份节点(slave)作为新的主节点的过程。这是一种高可用性机制,旨在确保Redis Cluster在主节点故障时仍然能够继续正常运行。

当主节点故障或不可用时,Redis Cluster中的其他备份节点会通过一个集体决策的过程选举出一个新的主节点。选举的过程通常基于内部的集群状态信息和算法来进行,选举完成后,新的主节点会接管主节点的角色,提供读写操作的服务。

在Redis Cluster中,failover是自动进行的,集群中的节点会自动检测主节点的故障,并且在必要时进行选举和切换。这意味着当主节点故障时,Redis Cluster可以快速自动地恢复,并继续处理客户端的请求,从而实现高可用性和持续的服务可用性。

需要注意的是,当发生failover时,会产生一定的服务中断(通常是几毫秒到几秒钟),直到新的主节点选举完成并开始提供服务。这是因为在切换期间,正在执行的操作需要被暂时中断,以便进行状态同步和重新分配数据的过程。

总结起来,Redis Cluster中的failover是指在主节点故障时,自动选择并切换为备份节点作为新的主节点,以确保系统的高可用性和持续的服务可用性。
docker exec -it redis-6382 redis-cli -p 6382 -a 'tan!@#' -c

image-20230801175813279

7.5 主从扩容

1.新增6388,6389 两个实例。配置文件和7.1保持一致即可

docker run --net=host --restart=always -p 6388:6388 --name redis-6388 \
-v /data/redis-6388/data:/data/redis-6388/data \
-v /data/redis-6388/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6388/logs/redis.log:/data/redis-6388/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

docker run --net=host --restart=always -p 6389:6389 --name redis-6389 \
-v /data/redis-6389/data:/data/redis-6389/data \
-v /data/redis-6389/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis-6389/logs/redis.log:/data/redis-6389/logs/redis.log \
-d redis:7.0.12 redis-server /etc/redis/redis.conf

2.进入客户端,将新增的6388作为master节点加入集群,后面的6382是集群中的主节点,可以换成其他主节点

docker exec -it redis-6388 /bin/bash
redis-cli -a 'tan!@#' -p 6388  --cluster add-node 192.168.240.10:6388 192.168.240.10:6382

或者

先登录到6388
redis-cli -a 'tan!@#' -p 6388
然后使用metting命令,参考7.7.2其他命令,cluster meet <ip> <port> :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster meet 192.168.240.10 6382

image-20230801182351963

3.查看集群信息,6388加入了集群,并成为主节点

image-20230801182506841

4.重新分派槽位(reshard)

docker exec -it redis-6382 /bin/bash
redis-cli -a 'tan!@#' -p 6382 --cluster reshard 192.168.240.10:6382

image-20230801183159388

5.查看集群信息

6388作为master已经负责有槽位

#docker exec -it redis-6382 /bin/bash
redis-cli -a 'tan!@#' -p 6382
cluster info

image-20230801183456199

6.为6388分配从节点

docker exec -it redis-6389 /bin/bash
redis-cli -a 'tan!@#' --cluster add-node 192.168.240.10:6389 192.168.240.10:6388 --cluster-slave --cluster-master-id 3ccda8f593a4bd86a268824479449c2d00b41ec9

image-20230801191602553

7.检查集群信息

redis-cli -a 'tan!@#' --cluster check 192.168.240.10:6389

image-20230801191856751

7.6 主从缩容

1.将6388 和6389下线

先将6389从集群中移除

docker exec -it redis-6389 /bin/bash
redis-cli -a 'tan!@#' --cluster del-node 192.168.240.10:6389 3ccda8f593a4bd86a268824479449c2d00b41ec9

image-20230801192315843

提示节点有数据,需要重新分配槽位,将6388的槽号清空,重新分配,将清出来的槽号都给6382

docker exec -it redis-6388 /bin/bash
redis-cli -a 'tan!@#' --cluster reshard 192.168.240.10:6382
输入是选择接受节点为6382

参考7.5.4

image-20230801192734040

#6388的槽位数为0时可以移除节点
redis-cli -a 'tan!@#' --cluster del-node 192.168.240.10:6388 3ccda8f593a4bd86a268824479449c2d00b41ec9

redis-cli -a 'tan!@#' --cluster del-node 192.168.240.10:6389 c3b0fccc9934e08681a5073dc69bf184b67b4e2c

再次检查集群信息

redis-cli -a 'tan!@#' --cluster check 192.168.240.10:6382

image-20230801224745891

缩容完毕,停止redis-6388,redis-6389

docker stop redis-6388 redis-6389

7.7 其他命令

#集群修复
redis-cli -a 'tan!@#' --cluster fix 192.168.240.10:6382
#设置集群超时
redis-cli -a 'tan!@#' --cluster set-timeout 192.168.240.10:6382 10000
#查看集群信息
redis-cli -a 'tan!@#' --cluster info 192.168.240.10:6382
#检查集群状态
redis-cli -a 'tan!@#' --cluster check 192.168.240.10:6382

#集群的任意一节点进行平衡集群节点slot数量
redis-cli -a 'tan!@#' --cluster rebalance 192.168.240.10:6382
#槽位平衡,指定源节点和目标节点
redis-cli -a 'tan!@#' --cluster reshard  192.168.240.10:6382 \
       --cluster-from a6a0b1be77ac380f1b8e430593d58d52603af096 \
       --cluster-to 6d9b8b70caf659c702e3fea245a48cfa46755437 \
       --cluster-slots 1000 --cluster-yes --cluster-pipeline 10 --cluster-replace

7.7.1 –cluster-help

redis-cli --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN   #创建集群
                 --cluster-replicas <arg>      #从节点个数
  check          host:port                     #检查集群
                 --cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点
  info           host:port                     #查看集群状态
  fix            host:port                     #修复集群
                 --cluster-search-multiple-owners #修复槽的重复分配问题
  reshard        host:port                     #指定集群的任意一节点进行迁移slot,重新分slots
                 --cluster-from <arg>          #需要从哪些源节点上迁移slot,可以逗号隔开从多个源节点完成迁移,参数是nodeid
                                               #还可以直接传递--from all这样源节点就是集群的所有节点不传递该参数,则会在迁移过程中提示用户输入
                 --cluster-to <arg>            #slot需要迁移的目的节点nodeid,目的节点只能填写一个,不传递该参数,则会在迁移过程中提示用户输入
                 --cluster-slots <arg>         #需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
                 --cluster-yes                 #指定迁移时的确认输入
                 --cluster-timeout <arg>       #设置migrate命令的超时时间
                 --cluster-pipeline <arg>      #定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
                 --cluster-replace             #是否直接replace到目标节点
  rebalance      host:port                                      #指定集群的任意一节点进行平衡集群节点slot数量 
                 --cluster-weight <node1=w1...nodeN=wN>         #指定集群节点的权重
                 --cluster-use-empty-masters                    #设置可以让没有分配slot的主节点参与,默认不允许
                 --cluster-timeout <arg>                        #设置migrate命令的超时时间
                 --cluster-simulate                             #模拟rebalance操作,不会真正执行迁移操作
                 --cluster-pipeline <arg>                       #定义cluster getkeysinslot命令一次取出的key数量,默认值为10
                 --cluster-threshold <arg>                      #迁移的slot阈值超过threshold,执行rebalance操作
                 --cluster-replace                              #是否直接replace到目标节点
  add-node       new_host:new_port existing_host:existing_port  #添加节点,把新节点加入到指定的集群,默认添加主节点
                 --cluster-slave                                #新节点作为从节点,默认随机一个主节点
                 --cluster-master-id <arg>                      #给新节点指定主节点
  del-node       host:port node_id                              #删除给定的一个节点,成功后关闭该节点服务
  call           host:port command arg arg .. arg               #在集群的所有节点执行相关命令
  set-timeout    host:port milliseconds                         #设置cluster-node-timeout
  import         host:port                                      #将外部redis数据导入集群
                 --cluster-from <arg>                           #将指定实例的数据导入到集群
                 --cluster-copy                                 #migrate时指定copy
                 --cluster-replace                              #migrate时指定replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

7.7.2 Redis Cluster

(客户端命令:redis-cli -c -p port -h ip)
redis-cli -c -p 6382 -h 192.168.240.10 -a 'tan!@#'    
192.168.10.240.10:6382>  #登录redis后,在里面可以进行下面命令操作
#集群
cluster info #打印集群的信息
cluster nodes #列出集群当前已知的所有节点( node),以及这些节点的相关信息。
#节点
cluster meet <ip> <port> #将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> #从集群中移除 node_id 指定的节点。
cluster replicate <master_node_id> #将当前从节点设置为 node_id 指定的master节点的slave节点。只能针对slave节点操作。
cluster saveconfig #将节点的配置文件保存到硬盘里面。
#槽(slot)
cluster addslots <slot> [slot ...] #将一个或多个槽( slot)指派( assign)给当前节点。
cluster delslots <slot> [slot ...] #移除一个或多个槽对当前节点的指派。
cluster flushslots #移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
cluster setslot <slot> node <node_id> #将槽slot指派给node_id指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。
cluster setslot <slot> migrating <node_id> #将本节点的槽 slot 迁移到 node_id 指定的节点中。
cluster setslot <slot> importing <node_id> #从 node_id 指定的节点中导入槽 slot 到本节点。
cluster setslot <slot> stable #取消对槽 slot 的导入( import)或者迁移( migrate)。
#键
cluster keyslot <key> #计算键 key 应该被放置在哪个槽上。
cluster countkeysinslot <slot> #返回槽 slot 目前包含的键值对数量。
cluster getkeysinslot <slot> <count> #返回 count 个 slot 槽中的键 。

8.集群总结

8.1 Redis Cluster特点

  • 多主多从,去中心化:从节点作为备用,复制主节点,不做读写操作,不提供服务
  • 不支持处理多个key:因为数据分散在多个节点,在数据量大高并发的情况下会影响性能;
  • 支持动态扩容节点:这是我认为算是Rerdis Cluster最大的优点之一;
  • 节点之间相互通信,相互选举,不再依赖sentinel:准确来说是主节点之间相互“监督”,保证及时故障转移

8.2 其它集群模式的区别

  • 相比较sentinel模式,多个master节点保证主要业务(比如master节点主要负责写)稳定性,不需要搭建多个sentinel实例监控一个master节点
  • 相比较一主多从的模式,不需要手动切换**,具有自我故障检测,故障转移的特点**;
  • 相比较其他两个模式而言,对数据进行分片(sharding),不同节点存储的数据是不一样的
  • 从某种程度上来说,Sentinel模式主要针对高可用(HA),而Cluster模式是不仅针对大数据量,高并发,同时也支持HA。

8.3集群的故障转移流程

当一个从节点发现自己正在复制的主节点下线时,从节点将开始对下线主节点进行故障转移:

1) 在该下线主节点的所有从节点中,选择一个做主节点

2) 被选中的从节点会执行SLAVEOF no one命令,成为新的主节点;

3) 新的主节点会撤销对所有对已下线主节点的槽指派,并将这些槽全部派给自己。

4) 新的主节点向集群广播一条PONG消息,让其他节点知道“我已经变成主节点了,并且我会接管已下线节点负责的处理的槽”;

5) 新主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。

8.4 master的选举流程

1)集群配置纪元是一个自增计数器,它的初始值为0;

2)当集群里的某个节点开始一次故障转移时,集群配置纪元的值会被增加1

3)对于每个配置纪元,集群里的每个负责处理槽的主节点都有一次投票的机会,而第一个向主节点要求投票的从节点将获得主节点的投票。

4)当从节点发现自己正在复制的主节点进入已下线状态时从节点会向集群广播消息:要求所有收到这条消息、并且具有投票权的主节点向这个从节点投票。

5)如果一个主节点具有投票权并且这个主节点尚未投票跟其它从节点,那么主节点将要求投票的从节点返回一条ACK消息表示支持该从节点成为新的主点。

6)每个主节点只有一次投票机会,有N个主节点的话,那么具有大于N/2+1张支持票的从节点只有一个。

7)如果在一个配置纪元里没有从节点能收集到足够多的支持票,那么集群进入一个新的配置纪元,并再次进行选举,直到选出新的主节点为止。

总结:这跟sentinel模式下的选举类似,两个都是基于Raft算法的领头选举方法来实现。

8.5 集群的故障检测

集群中每个节点都会定期地向集群中的其他节点发送PING消息,以此检测对方是否在线;如果接收PING消息的节点没有在规定的时间内,向发送PING消息的节点返回PONG消息,那么发送PING消息的节点就会将PING消息节点标记为疑似下线(possible fail,PFAIL)。

如果在集群中,超过半数以上负责处理槽的主节点都将某个节点X标记为PFAIL,则某个主节点就会将这个主节点X就会被标记为已下线(FAIL),并且广播到这条消息,这样其他所有的节点都会立即将主节点X标记为FAIL。

image-20230802113453516

假设:

  • Redis Cluster有四个主节点:7000-7003,两个从节点:7004与7005
  • 此时7000已下线,并且主节点7001认为主节点7000进入PFAIL
  • 同时主节点7002、7003也认为主节点7000进入下线状态

这样一来超过半数的主节点都认为7000节点FAIL,那么7001便会标记7000为FAIL状态,并向集群广播主节点7000已经FAIL消息。

image-20230802113618731

参考文章

1.一致性哈希算法原理详解

2.Hash一致性算法是如何解决数据倾斜问题的?

3.redis6 redis-cli cluster的使用总结

4.认识Redis集群——Redis Cluster - JJian - 博客园 (cnblogs.com)

5.Redis集群原理详解_张维鹏的博客-CSDN博客

6.尚硅谷阳哥redis7

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

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

相关文章

Vue3和typeScript路由传参

1 params传的参数&#xff0c;页面刷新就消失,而query传的参数&#xff0c;页面刷新还会存在&#xff0c;所以通常用query。 query传参 跳转页面&#xff1a;拿到router对象,调用push方法做跳转. import { useRoute,useRouter} from "vue-router"; export default…

GPIO简介

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 实验步骤 以L…

图文演示:如何三分钟极速搭建一个元宇宙3D虚拟展厅

引言&#xff1a; 元宇宙3D虚拟展厅时代已经来临。元宇宙是一个虚拟的、立体的数字空间&#xff0c;可以让用户沉浸在其中进行交互操作&#xff0c;并体验无限可能。如何快速搭建一个属于自己的虚拟展厅则受到越来越多人的关注。 一&#xff0e;虚拟展厅类型 1.党建展馆 实现…

小研究 - 微服务系统服务依赖发现技术综述(一)

微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…

mysql月统计数据,没有的填充为0

要按时间戳字段按月份分组查询记录表&#xff0c;可以使用DATE_FORMAT函数将时间戳字段格式化为年月格式&#xff0c;然后将结果按照该字段进行分组。 SELECT a.month month,ifnull(b.count, 0) count FROM (SELECT 1 month UNION ALL SELECT 2 month UNION ALL SELECT 3 mont…

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位

效果&#xff1a;点击表格可实现选中地图点位&#xff0c;删除按钮点击可删除对应点位并且重新绘制线段&#xff0c;点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 完整的组件代码如下 文件名称为&#xff1a; leafletMakePointYt <!--* Descripti…

小红书APP出现闪退问题,电商erp系统接口测试怎么做?(一)

7月27日凌晨&#xff0c;部分网友反馈小红书APP出现闪退问题。对此&#xff0c;小红书客服微博发文称&#xff0c;如遇到小红书APP无法启动的情况&#xff0c;用户可前往AppStore下载最新版本。 大家在讨论崩溃原因时&#xff0c;提到大概是接口出现了问题&#xff0c;对于软件…

05-向量的意义_n维欧式空间

线性代数 什么是向量&#xff1f;究竟为什么引入向量&#xff1f; 为什么线性代数这么重要&#xff1f;从研究一个数拓展到研究一组数 一组数的基本表示方法——向量&#xff08;Vector&#xff09; 向量是线性代数研究的基本元素 e.g. 一个数&#xff1a; 666&#xff0c;…

企业大数据可视化案例专题分享-入门

一、什么是数据可视化&#xff1f; 基本概念&#xff1a;数据可视化是以图示或图形格式表示的数据。让决策者可以看到以直观方式呈现的分析&#xff0c;以便他们可以掌握困难的概念或识别新的模式。借助交互式可视化&#xff0c;可以使用技术深入挖掘图表和图形以获取更多详细…

Pytorch基础

文章目录 一、Pytorch简介二、安装2.1 安装GPU环境2.2 安装Pytorch2.3 测试 三、Tensor3.1 Tensor创建3.1.1 torch.tensor() && torch.tensor([])3.1.2 torch.randn && torch.randperm3.1.3 torch.range(begin,end,step)3.1.4 指定numpy 3.2 Tensor运算3.2.1 A…

开源Blazor UI组件库精选:让你的Blazor项目焕然一新!

今天给大家推荐一些开源、美观的Blazor UI组件库&#xff0c;这些优秀的开源框架和项目不仅能够帮助开发者们提高开发效率&#xff0c;还能够为他们的项目带来更加丰富的用户体验。 注&#xff1a;排名不分先后&#xff0c;都是十分优秀的开源框架和项目 ​Ant Design Blazor…

深度学习(34)—— StarGAN(1)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09; 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;1&#xff09;1. 背景2. 基本思路3. 整体流程4. StarGAN v2(1) 网络结构(2) mapping network(3) style encoder(4)Loss 和之前…

【机器学习】西瓜书习题3.5Python编程实现线性判别分析,并给出西瓜数据集 3.0α上的结果

参考代码 结合自己的理解&#xff0c;添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt导入数据&#xff0c;进行数据处理和特征工程 得到数据集 D { ( x i , y i ) } i 1 m , y i ∈ { 0 ,…

安装企业级高负载web服务器tomcat,并部署应用

web服务器Tocamt 1.Tocmat简介2.Tocmat安装1.安装jdk2.部署Tomcat1.配置环境变量2.启动tocmat3.Tomcat web管理功能 3.部署jpress应用 1.Tocmat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由…

C. Binary String Copying - 思维

分析&#xff1a; 赛时我是直接模拟的&#xff0c;tle然后mle&#xff0c;补提&#xff0c;发现规律&#xff0c;每一个改变的字符串都只会对应一个需要改变的区间&#xff0c;例如第一个样例前两个101100 -> 011100和101100 -> 011100&#xff0c;对应区间在确定改变的范…

paddle实现获取pdf的内容

paddle实现获取pdf的内容 1. 环境安装2. 实现代码 源码链接 1. 环境安装 安装paddlepaddle gpu版本python -m pip install paddlepaddle-gpu -i https://pypi.tuna.tsinghua.edu.cn/simplecpu版本&#xff1a;python -m pip install paddlepaddle -i https://pypi.tuna.tsing…

实战:Prometheus+Grafana监控Linux服务器及Springboot项目

文章目录 前言知识积累什么是Prometheus什么是Grafana怎样完成数据采集和监控 环境搭建docker与docker-compose安装docker-compose编写 监控配置grafana配置prometheus数据源grafana配置dashboardLinux Host Metrics监控Spring Boot 监控 写在最后 前言 相信大家都知道一个项目…

云原生全栈体系(二)

Kubernetes实战入门 第一章 Kubernetes基础概念 一、是什么 我们急需一个大规模容器编排系统kubernetes具有以下特性&#xff1a; 服务发现和负载均衡 Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器&#xff0c;如果进入容器的流量很大&#xff0c;Kubernetes 可以负…

SSL 证书过期巡检脚本 (Python 版)

哈喽大家好&#xff0c;我是咸鱼 之前写了个 shell 版本的 SSL 证书过期巡检脚本 &#xff08;文章&#xff1a;《SSL 证书过期巡检脚本》&#xff09;&#xff0c;后台反响还是很不错的 那么今天咸鱼给大家介绍一下 python 版本的 SSL 证书过期巡检脚本 &#xff08;完整代码…

王道《操作系统》学习(二)—— 进程管理(二)

2.1 处理机调度的概念、层次 2.1.1 调度的基本概念 2.1.2 调度的三个层次 &#xff08;1&#xff09;高级调度&#xff08;作业调度&#xff09; &#xff08;2&#xff09;中级调度&#xff08;内存调度&#xff09; 补充知识&#xff1a;进程的挂起状态和七状态模型 &#x…