一、主从复制
这儿采用docker
进行安装redis
,比较简单不过多解释了。
# 这儿安装的是7.0.5版本,也是最此时的新版
docker pull redis:7.0.5
#也可直接使用
docker pull redis
1、新建修改配置文件
在/user/local
目录下新建文件夹,并在此文件夹下建了三个文件对应一主二从。
cd /user/local
mkdir redis_replication
cd redis_replication
mkdir master
mkdir slave01
mkdir slave02
修改redis.conf
配置文件
主节点 配置文件
1、修改bind或注释掉
bind 0.0.0.0
2、保护模式关闭,因为用docker否则无法访问
protected-mode no
3、设置密码
requirepass 设置密码
4、开启aof日志
appendonly yes
从节点 配置文件
在上述的主节点配置的基础上
1、修改自己的端口号(二从的端口号不要相同)
port 6380和6381
2、配置与主节点验证的密码
masterauth 设置密码
3、配置主节点的ip端口,认证主节点主从复制
replicaof 主机IP 主机端口
注意:
- 主节点与从节点的密码要保持一致,方便后面的
哨兵模式
。 -
daemonize
这个配置设置为no,因为要用docker -d
命令,这两个有冲突,若不用docker的话可以开启。
将配置文件分别复制到一主二从的conf
文件夹下。
2、执行命令启动redis
# 主节点
docker run -d --privileged=true -v /usr/local/redis_replication/master/data:/data -v /usr/local/redis_replication/master/conf:/etc/redis -p 6379:6379 --name redis_master redis:7.0 redis-server /etc/redis/redis.conf
# 从节点01
docker run -d --privileged=true -v /usr/local/redis_replication/slave01/data:/data -v /usr/local/redis_replication/slave01/conf:/etc/redis -p 6380:6380 --name redis_slave01 redis:7.0 redis-server /etc/redis/redis.conf
# 从节点02
docker run -d --privileged=true -v /usr/local/redis_replication/slave02/data:/data -v /usr/local/redis_replication/slave02/conf:/etc/redis -p 6381:6381 --name redis_slave02 redis:7.0 redis-server /etc/redis/redis.conf
若出现报错
docker logs tail 200 容器id或名称
3、启动客户端测试
进入主从docker容器内:
docker exec -it 容器ID或名称 /bin/bash
# 运行客户端
redic_cli -p 6379 -a 密码
# 查看信息
info replication
# 展示如下信息
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1843834,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=1843414,lag=0
master_failover_state:no-failover
master_replid:9fc3d09efced8e02a2b9204358ad53d94a25de1a
master_replid2:99c68add0e6fa1f508ed43b2dce3f0348672ae5b
master_repl_offset:1843834
second_repl_offset:7845
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:782860
repl_backlog_histlen:1060975
在主节点 set k v,在从节点查看是否同步成功 get k
二、哨兵模式Sentinel
哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis
服务器响应,从而监控运行的多个Redis
实例。
主要两步:
- 启动
redis
主从复制(前面已经启动了)。 - 配置
sentinel
并启动。
1、修改配置文件
sentinel.conf
配置文件
# 修改端口不要重复,这儿26379 26380 26381
port 26379
# 设置日志存储位置
logfile "/data/sentinel.log"
# 监控主节点的配置 mymaster名字随便起;2因为是三台哨兵,所以大于等于半数票数2
sentinel monitor mymaster 主节点IP 主节点端口 2
# 配置主节点密码
sentinel auth-pass mymaster 密码
修改主节点的redis.conf
配置文件,因为主节点也可能成为从节点。
所以前面要保持主从密码一致。
masterauth 设置密码
将配置文件分别复制到一主二从的conf
文件夹下。
注意: 配置密码时候看清是auth-pass
,笔者错配成了auth-user
耽误了并不少时间
2、启动sentinel进程
# 主节点sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/master/data:/data -v /usr/local/redis_replication/master/conf:/etc/redis -p 26379:26379 --name redis_sentinel redis:7.0 redis-sentinel /etc/redis/sentinel.conf
# 从节点01 sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/slave01/data:/data -v /usr/local/redis_replication/slave01/conf:/etc/redis -p 26380:26380 --name redis_sentinel01 redis:7.0 redis-sentinel /etc/redis/sentinel.conf
# 从节点02 sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/slave02/data:/data -v /usr/local/redis_replication/slave02/conf:/etc/redis -p 26381:26381 --name redis_sentinel02 redis:7.0 redis-sentinel /etc/redis/sentinel.conf
进入sentinel
docker exec -it redis_sentinel /bin/bash
# 运行客户端
redic_cli -p 26379
# 查看信息
info sentinel
# 展示如下信息
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1x:6379,slaves=2,sentinels=3
3、测试
- 关闭
master
节点
docker stop redis_master
- 观察
sentinel.log
信息
这儿有完整的从节点上位的过程
1:X 13 Dec 2022 02:54:17.611 # User requested shutdown...
1:X 13 Dec 2022 02:54:17.611 * Removing the pid file.
1:X 13 Dec 2022 02:54:17.611 # Sentinel is now ready to exit, bye bye...
1:X 13 Dec 2022 02:54:18.175 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 13 Dec 2022 02:54:18.175 # Redis version=7.0.5, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 13 Dec 2022 02:54:18.175 # Configuration loaded
1:X 13 Dec 2022 02:54:18.175 * monotonic clock: POSIX clock_gettime
1:X 13 Dec 2022 02:54:18.177 * Running mode=sentinel, port=26379.
1:X 13 Dec 2022 02:54:18.177 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:X 13 Dec 2022 02:54:18.178 # Sentinel ID is 0489f75140810f172f63af196e845bd8584e520e
1:X 13 Dec 2022 02:54:18.178 # +monitor master mymaster 127.0.0.1 6379 quorum 2
1:X 13 Dec 2022 02:54:44.805 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:54:44.810 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:54:44.810 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:55:35.521 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:55:35.521 # +new-epoch 21
1:X 13 Dec 2022 02:55:35.524 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:55:35.525 # +vote-for-leader ed60d0f591b217fe3361a019b9dd6398f3b1d833 21
1:X 13 Dec 2022 02:55:35.931 # +config-update-from sentinel ed60d0f591b217fe3361a019b9dd6398f3b1d833 172.17.0.8 26380 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:55:35.931 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.931 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.931 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.939 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:56:05.973 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:57:07.229 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
- 查看
6381
端口的信息,发现成功上位成主节点。 - 重启
6379
节点,发现该节点变成了从节点。
注意: 若重新启动sentinel
记得修改配置文件监控为主节点。
sentinel monitor mymaster 主节点IP 主节点端口 2
三、集群模式Cluster
1、搭建集群
1.1、创建集群挂载文件
在 /usr/local/redis_cluster
文件夹下 创建8个文件
mkdir master01
mkdir master02
mkdir master03
mkdir master04
mkdir slave01
mkdir slave02
mkdir slave03
mkdir slave04
并在对应的目录下创建conf
文件,把redis.conf
复制进conf
文件夹下。
1.2、修改配置文件
新建八个配置文件依次放入conf
文件夹下。
1、修改端口号,八个文件端口不要重复
port 6382
2、修改bind或注释掉
bind 0.0.0.0
3、保护模式关闭,因为用docker否则无法访问
protected-mode no
4、关闭后台运行
daemonize no
5、设置密码
requirepass 设置密码
6、配置与主节点验证的密码
masterauth 设置密码
7、开启aof日志
appendonly yes
8、开启集群模式
cluster-enabled yes
9、根据你启用的节点来命名,最好和端口保持一致,这个是用来保存其他节点的名称,状态等信息的
cluster-config-file nodes_6379.conf
10、超时时间
cluster-node-timeout 5000
11、集群节点 IP:服务器就填公网ip,或者内部对应容器的ip
cluster-announce-ip xx.xxx.xxx.xx
12、集群节点映射端口
cluster-announce-port 6382
13、总线监控ip默认端口+10000 如 6382 就是 16382
cluster-announce-bus-port 16382
1.3、docker 容器网络
- 创建虚拟网卡????
docker network create redis_cluster
- 查看Docker 网卡信息
docker network ls
- 查看dockerr网络详细信息
docker network inspect redis_cluster
- 补充(删除网卡信息、帮助命令)
docker network rm redis_cluster #删除网卡命令 多个中间 空格隔开
docker network --help #显示可带参数等
1.4、docker启动先六个redis实例
docker run -d --privileged=true -v /usr/local/redis_cluster/master01/data:/data -v /usr/local/redis_cluster/master01/conf:/etc/redis -p 6382:6382 -p 16382:16382 --name redis_cluster6382 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/master02/data:/data -v /usr/local/redis_cluster/master02/conf:/etc/redis -p 6383:6383 -p 16383:16383 --name redis_cluster6383 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/master03/data:/data -v /usr/local/redis_cluster/master03/conf:/etc/redis -p 6384:6384 -p 16384:16384 --name redis_cluster6384 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave01/data:/data -v /usr/local/redis_cluster/slave01/conf:/etc/redis -p 6385:6385 -p 16385:16385 --name redis_cluster6385 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave02/data:/data -v /usr/local/redis_cluster/slave02/conf:/etc/redis -p 6386:6386 -p 16386:16386 --name redis_cluster6386 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave03/data:/data -v /usr/local/redis_cluster/slave03/conf:/etc/redis -p 6387:6387 -p 16387:16387 --name redis_cluster6387 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
1.5、构建集群
redis-cli -a 密码 --cluster create xx.xxx.xx.xxx:6382 xx.xxx.xx.xxx:6383 xx.xxx.xx.xxx:6384 xx.xxx.xx.xxx:6385 xx.xxx.xx.xxx:6386 xx.xxx.xx.xxx:6387 --cluster-replicas 1
--cluster-replicas 1
:为每一个主节点创建一个副本所以这儿 3主3从
展示如下信息
1.5、查看集群状态
# 查看集群状态以及节点关系
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 进入redis-cli
redis-cli -p 6382 -a 密码 -c
# 查看cluster信息
cluster info
# 查看节点信息
cluster nodes
2、容错测试
2.1、数据存储
# 当设置不属于当前节点的槽位的key value时,发现会重定向到另一个槽位节点
set k1 v1
-> Redirected to slot [12706] located at xx.xxx.xx.xxx:6384
OK
2.2、关闭master节点,容错机制
- 停止6384主节点,观察从节点是否上位
docker stop redis_cluster6384
- 查看节点状态
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
这儿就不再截图啦,会发现6387节点上位,成为主节点
- 还原集群状态为原始状态
3、节点扩容
3.1、启动6388,6389节点
docker run -d --privileged=true -v /usr/local/redis_cluster/master04/data:/data -v /usr/local/redis_cluster/master04/conf:/etc/redis -p 6388:6388 -p 16388:16388 --name redis_cluster6388 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave04/data:/data -v /usr/local/redis_cluster/slave04/conf:/etc/redis -p 6389:6389 -p 16389:16389 --name redis_cluster6389 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
3.2、加入集群
- 6388节点加入集群
# 添加节点到集群
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6388 xx.xxx.xx.xxx:6382
- 6389节点加入集群并绑定6388主节点
# 绑定从节点与主节点
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6389 xx.xxx.xx.xxx:6388 --cluster-slave --cluster-master-id 204fbd5f8e9d71a865c75f34f4d48121e9d4cff2
--cluster-slave :
作为从节点。
--cluster-master-id:
指定关联的主节点,后面跟上 主节点 ID。
- 观察节点状态
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 展示如下
xx.xxx.xx.xxx:6382 (33b306d8...) -> 2 keys | 5461 slots | 1 slaves.-id 2a7494a93e
xx.xxx.xx.xxx:6383 (9a01058a...) -> 0 keys | 5462 slots | 1 slaves.
xx.xxx.xx.xxx:6384 (bb3b2354...) -> 1 keys | 5461 slots | 1 slaves.
xx.xxx.xx.xxx:6388 (2a7494a9...) -> 0 keys | 0 slots | 0 slaves.
还未对6388节点分配槽位。
3.2、分配槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
- How many slots do you want to move (from 1 to 16384)?
这儿是说要分配给目标多少槽位 ? 4096
(16384/4=4096)
- What is the receiving node ID?
分配给谁? 这儿填6388槽位的ID,2a7494a93ef14f755d2494afaefc4d91aae21f00
- Type ‘all’ to use all the nodes as source nodes for the hash slots.
Type ‘done’ once you entered all the source nodes IDs.
all :其他的所有节点的槽位会均匀分给6388节点
done:指定节点的槽位分给6388,需要先指定节点id,最后使用done
这儿选all
均匀分配。
-
后面直接
yes
。 -
在此检查集群状态。观察6388已经有4096个槽位了,并且取自另三个主节点。
4、节点缩容
将 6388和6389节点下线。
4.1、下线6389从节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6382 204fbd5f8e9d71a865c75f34f4d48121e9d4cff2
后面是6389的 ID。
- 检查集群状态
4.2、分配6388节点的槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
这儿原ID为6388的ID,接收者为6382的ID,然后done。意思是将所有的槽位分配给6382。
- 检查集群状态
4.3、删除6388节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6382 2a7494a93ef14f755d2494afaefc4d91aae21f00
- 检查集群状态
4.5、关闭 6388和6389节点
docker stop redis_cluster6388 redis_cluster6389
5、命令总结
# 查看节点关系
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 进入redis-cli
cluster info
cluster nodes
# 添加节点到集群
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6388 xx.xxx.xx.xxx:6382
# 绑定从节点与主节点
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6389 xx.xxx.xx.xxx:6388 --cluster-slave --cluster-master-id 2a7494a93ef14f755d2494afaefc4d91aae21f00
# 重新洗牌 槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
# 修复
redis-cli -a 密码 --cluster fix xx.xxx.xx.xxx:6382 --cluster-search-multiple-owners --cluster-fix-with-unreachable-masters
## 删除节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6388 14cdb77543100a21791797a68a8e23229efe8c23
四、遇到的问题
1、集群搭建过程时,一直卡在 Waiting for the cluster to join
这儿不动。
原因就是网络造成的。
1、使用docker时候记得加 --net xxxx
网络虚拟组进行链接。
2、若使用云服务器,如阿里云记得防火墙开放对应的端口,记得开放redis总线端口,默认是端口号+10000。
3、我这儿是直接自己指定IP端口 cluster-announce-ip
,没有使用默认的规则。