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

news2024/10/5 18:29:40

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业数字化转型的核心是什么?

如今&#xff0c;各行各业都在布局数字化转型&#xff0c;而对于中国传统制造业来说&#xff0c;数字化转型更是当务之急&#xff0c;但由于制造企业组织、业务、产品和价值链的复杂性&#xff0c;为数字化转型带来诸多障碍。这篇就来重点分享下&#xff0c;制造业如何做好数字…

传智教育院校邦首期图灵计划—黑马菁英班正式开班!

7月30日&#xff0c;大家期待已久的首期图灵计划——黑马菁英班正式开班&#xff01;班级开班的那一刻&#xff0c;同学们的学习热情立即被点燃&#xff01; 这个班级匹配当代大学生特点&#xff0c;在课程设置、讲师团队、班级管理等方面做到顶配&#xff0c;建立课程教学与人…

使用Logistic回归预测心脏病 -- 机器学习项目基础篇(4)

世界卫生组织估计&#xff0c;五分之四的心血管疾病&#xff08;CVD&#xff09;死亡是由于心脏病发作。本研究旨在精确确定有很好机会受CVD影响的患者的比例&#xff0c;并使用Logistic回归预测总体风险。 Logistic回归是一种统计和机器学习技术&#xff0c;基于输入字段的值对…

YOLOv8-pose姿态模型笔记1

YOLOv8-pose关键点模型输出&#xff0c;每个框输出51个信息&#xff0c;即17个关键点以及每个关键点的得分 COCO的annotation一共有17个关节点。 分别是&#xff1a;“nose”,“left_eye”, “right_eye”,“left_ear”, “right_ear”,“left_shoulder”, “right_shoulder”…

18款奔驰S320升级后排座椅加热功能,提升后排乘坐舒适性

奔驰座椅加热就简单多了&#xff0c;是在原车座椅海绵表面安装一层加热垫&#xff0c;加热垫里面是加热丝&#xff0c;通过电机热的原理&#xff0c;快速升温&#xff0c;把热量传递给车主。 奔驰的座椅加热系统是通过车门按键来控制&#xff0c;3档调节&#xff0c;温度从低到…

Michael.W基于Foundry精读Openzeppelin第18期——DoubleEndedQueue.sol

Michael.W基于Foundry精读Openzeppelin第18期——DoubleEndedQueue.sol 0. 版本0.1 DoubleEndedQueue.sol 1. 目标合约2. 代码精读2.1 结构体Bytes32Deque2.2 length(Bytes32Deque storage deque) && empty(Bytes32Deque storage deque)2.3 at(Bytes32Deque storage de…

【Java可执行命令】(十三)策略工具policytool:界面化创建、编辑和管理策略文件中的权限和配置 ~

Java可执行命令之policytool 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 使用方式3.2 使用技巧3.3 注意事项 4️⃣ 应用场景&#x1f33e; 总结 1️⃣ 概念 在Java平台上&#xff0c;安全性是至关重要的。为了提供细粒度的安全管理机制&#xff0c;Java引入了policytool命令。p…

LuckyFrameweb LuckyFrameClient 自动化测试平台 安装部署 使用教程

LuckyFrameweb 自动化测试平台 jdk安装 maven安装 LuckyFrameweb安装 仓库地址 使用maven 打包jar包 docker-compose安装mysql #cat mysql-start.yml version: "3" services:mysql:image: mysql:5.7restart: alwaysenvironment:- TZAsia/Shanghaiports:- 3306:3…

分享:交流负载箱 0~9.999A 可调 步进1mA

前言 最近去客户那边&#xff0c;发现一个问题&#xff0c;他们的交流供电单元 测试很不方便。 需求 供电单元输出&#xff1a; AC220V 50HZ&#xff1b;漏电保护保护功能过载报警功能&#xff1b;超载保护功能&#xff1b; 总而言之&#xff0c;他们需要一台 交流的电子负…

Unity 画线OnPopulateMesh函数VertexHelper

一个画图表&#xff08;折线图&#xff0c;树状图&#xff0c;饼状图&#xff0c;雷达图&#xff09;的插件。 底层使用UGUI中的重写了OnPopulateMesh这个方法&#xff0c; 用来实现鼠标画线的功能。 OnPopulateMesh(VertexHelper vh) {} using System; using System.Collec…

Elisp之buffer-substring-no-properties用法(二十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

冲突域 和 广播域

冲突域&#xff1a; 在传统的以粗同轴电缆为传输介质的以太网中&#xff0c;同一介质上的多个节点共享链路的带宽&#xff0c;争用链路的使用权&#xff0c;这样就会发生冲突&#xff0c;CSMA/CD机制中当冲突发生时&#xff0c;网络就要进行回退&#xff0c;这段回退的时间内链…

SpringBoot复习:(15)Spring容器的核心方法refresh是在哪里被调用的?

在SpringApplication的run方法&#xff1a; refreshContext代码如下&#xff1a; 其中调用的refresh方法代码如下&#xff1a; 其中调用的refresh方法代码如下&#xff1a; 其中调用的fresh方法代码如下&#xff1a; 其中调用了super.refresh();而这个super.refresh()就是…

AP5179 高端电流采样降压恒流驱动IC SOP8 LED车灯电源驱动

产品描述 AP5179是一款连续电感电流导通模式的降压恒流源&#xff0c;用于驱动一颗或多颗串联LED输入电压范围从 5 V 到 60V&#xff0c;输出电流 最大可达 2.0A 。根据不同的输入电压和外部器件&#xff0c; 可以驱动高达数十瓦的 LED。内置功率开关&#xff0c;采用高端电流…

AI赋能下的“数字人”与“数智人”:异同解析

由于人工智能技术的快速发展&#xff0c;我们逐渐进入了一个数字化的时代。在这个时代中&#xff0c;两个概念引起了广泛的关注和讨论&#xff0c;那就是“数字人”和“数智人”。虽然这两个概念都与人工智能有关&#xff0c;但它们在含义和应用上存在一些不同之处。在本文中&a…

使用elementplus实现文本框的粘贴复制

需求&#xff1a; 文本框仅用于显示展示数据并且用户可以进行复制&#xff0c;并不会进行修改和编辑&#xff0c; 注意点&#xff1a; 1.首先且文本为多行。所以不能使用普通的el-input&#xff0c;这种一行超出就会隐藏了&#xff0c;如果多行超出行数也会隐藏&#xff08;…

《评论文章-无线纳米技术可以降低脊髓刺激成本和并发症,传统设备与无线刺激设备费用相比的回顾》

SCS治疗可能会出现并发症&#xff0c;并且管理这些并发症的费用很高。 慢性疼痛是促使人们寻求缓解的主要因素&#xff0c;也是阿片类药物研究的主要方向。 SCS治疗取得了突破性进展&#xff0c;在治疗背部手术失败综合征、神经性疼痛障碍、复杂区域疼痛综合征以及血管缺血引…

51单片机学习--蜂鸣器播放音乐

由原理图可知&#xff0c;蜂鸣器BEEP与P1_5 相关&#xff0c;但其实这个原理图有错&#xff0c;实测接的是P2_5 下面这个代码就是以500HZ的频率响500ms的例子 sbit Buzzer P2^5;unsigned char KeyNum; unsigned int i;void main() {while(1){KeyNum Key();if(KeyNum){for(i …

后端进阶之路——综述Spring Security认证,授权(一)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ 解决算法&#xff0c;一个专栏就够了★ ★ 架…

人脸检测之给照片加上眼镜

人脸检测 文章目录 人脸检测一、背景二、UV空间融合法三、总结与不足四、参考 一、背景 给人脸图像加眼镜在很多领域都有应用。比如修图换造型、眼镜店眼镜试戴、戴眼镜人脸识别等。 给人脸加眼镜的难点在于难以做到自然逼真&#xff0c;且人脸多种多样&#xff0c;角度多变&a…