前言
系统环境:Mac OS
Redis版本:redis-6.2.5
Redis主从配置
redis安装目录
AntonyZhang:redis-6.2.5 zwq$ pwd
/usr/local/redis-6.2.5
master
主节点redis.conf需要核对或修改的配置如下:
pidfile "/var/run/redis_6379.pid" # 把pid进程号写入pidfile配置的文件
dir "/usr/local/redis-6.2.5" # 主节点数据文件放在安装目录下
daemonize yes #后台启动
protected-mode no #关闭保护模式; 开启的话,只有本机才可以访问redis
# 需要注释掉bind
#bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)
logfile "6379.log" # 日志文件名称,没有指定路径,默认在安装目录下
slave1
在安装目录下创建第一个slave节点的配置文件:
cp redis.conf slave1.conf
slave1.conf做如下配置:
port 6380 # 第一个从节点实例的端口为6380
pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件
logfile "6380.log" # 日志文件名称,没有指定路径,默认在安装目录下
dir /usr/local/redis-5.0.3/data/6380 # 指定数据存放目录,必须手动创建
# bind 127.0.0.1 # 需要注释掉bind
protected-mode no #关闭保护模式; 开启的话,只有本机才可以访问redis
# 主从配置
replicaof 192.168.1.104 6379 # 从本机(IP:192.168.1.104 端口:6379)的redis master实例复制数据,Redis 5.0之前使用slaveof
replica-read-only yes # 配置从节点只读
slave2
在安装目录下创建第二个slave节点的配置文件:
cp redis.conf slave2.conf
slave2.conf做如下配置:
port 6381 # 第二个从节点实例的端口为6380
pidfile /var/run/redis_6381.pid # 把pid进程号写入pidfile配置的文件
logfile "6381.log" # 日志文件名称,没有指定路径,默认在安装目录下
dir /usr/local/redis-5.0.3/data/6381 # 指定数据存放目录,必须手动创建
# bind 127.0.0.1 # 需要注释掉bind
protected-mode no #关闭保护模式; 开启的话,只有本机才可以访问redis
# 主从配置
replicaof 192.168.1.104 6379 # 从本机(IP:192.168.1.104 端口:6379)的redis master实例复制数据,Redis 5.0之前使用slaveof
replica-read-only yes # 配置从节点只读
创建两个slave节点的数据存放目录
AntonyZhang:redis-6.2.5 zwq$ pwd
/usr/local/redis-6.2.5
mkdir -p ./data/6380
mkdir -p ./data/6381
启动主从节点
AntonyZhang:redis-6.2.5 zwq$ pwd
/usr/local/redis-6.2.5
AntonyZhang:redis-6.2.5 zwq$ redis-server redis.conf
AntonyZhang:redis-6.2.5 zwq$ redis-server slave1.conf
AntonyZhang:redis-6.2.5 zwq$ redis-server slave2.conf
AntonyZhang:redis-6.2.5 zwq$ ps -ef|grep redis
501 59100 1 0 3:59下午 ?? 0:00.99 redis-server *:6379
501 59102 1 0 3:59下午 ?? 0:00.96 redis-server *:6380
501 59105 1 0 3:59下午 ?? 0:00.93 redis-server *:6381
验证主从配置
AntonyZhang:redis-6.2.5 zwq$ pwd
/usr/local/redis-6.2.5
查看主节点的replication信息
登录主节点客户端,执行命令info replication
AntonyZhang:redis-6.2.5 zwq$ redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.1.104,port=6380,state=online,offset=112,lag=1
slave1:ip=192.168.1.104,port=6381,state=online,offset=112,lag=0
master_failover_state:no-failover
master_replid:bc402926cc9fd2805633cd2d2d3404806d1157b9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
其中:
role:master: 当前实例为主节点
connected_slaves:2 已连接2个slave节点
slave0: 第一个slave节点的IP + 端口
slave1: 第二个slave节点的IP + 端口
set数据验证主从同步
# 在主节点set一个key
AntonyZhang:redis-6.2.5 zwq$ redis-cli
127.0.0.1:6379> set master aaa
OK
127.0.0.1:6379> quit
# 登录salve节点客户端,获取主节点set的key
AntonyZhang:redis-6.2.5 zwq$ redis-cli -p 6380
127.0.0.1:6380> get master
"aaa"
Redis哨兵集群配置
哨兵1
修改安装目录下 sentinel.conf文件配置:
port 26379
daemonize yes
in "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.3/data"
# sentinel monitor <master-redis-name> <master-redis-ip> <master-redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.168.1.104 6379 2 # mymaster这个名字随便取,客户端访问时会用到
# redis-6.2.5中,sentinel myid是没有打 '#' 的,此处最好注释调,让哨兵实例启动时自动创建;目的是防止复制该配置文件后,
# 创建的哨兵集群都是同样的sentinel myid,这样启动哨兵集群后,会导致26379端口的哨兵无法感知到其他哨兵
# sentinel myid 3addf29c538ef985c3d96a16b2fab03c196ffd83
哨兵2
复制安装目录下 sentinel.conf文件:
cp sentinel.conf sentinel-26380.conf
修改sentinel-26380.conf文件配置:
port 26380 # 修改端口
daemonize yes
in "/var/run/redis-sentinel-26380.pid"
logfile "26380.log"
dir "/usr/local/redis-5.0.3/data"
sentinel monitor mymaster 192.168.1.104 6379 2
# 每个哨兵的sentinel myid必须不相同,因此注释掉Redis默认设置的,启动哨兵实例时,自动生成
# sentinel myid 3addf29c538ef985c3d96a16b2fab03c196ffd83
哨兵3
复制安装目录下 sentinel.conf文件:
cp sentinel.conf sentinel-26381.conf
修改sentinel-26381.conf文件配置:
port 26381 # 修改端口
daemonize yes
in "/var/run/redis-sentinel-26381.pid"
logfile "26381.log"
dir "/usr/local/redis-5.0.3/data"
sentinel monitor mymaster 192.168.1.104 6379 2
# 每个哨兵的sentinel myid必须不相同,因此注释掉Redis默认设置的,启动哨兵实例时,自动生成
# sentinel myid 3addf29c538ef985c3d96a16b2fab03c196ffd83
启动哨兵
AntonyZhang:redis-6.2.5 zwq$ pwd
/usr/local/redis-6.2.5
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel.conf
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel-26380.conf
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel-26381.conf
AntonyZhang:redis-6.2.5 zwq$ ps -ef|grep redis
501 59100 1 0 3:59下午 ?? 0:00.99 redis-server *:6379
501 59102 1 0 3:59下午 ?? 0:00.96 redis-server *:6380
501 59105 1 0 3:59下午 ?? 0:00.93 redis-server *:6381
501 59135 1 0 4:01下午 ?? 0:00.85 redis-sentinel *:26379 [sentinel]
501 59146 1 0 4:02下午 ?? 0:00.67 redis-sentinel *:26380 [sentinel]
501 59149 1 0 4:02下午 ?? 0:00.62 redis-sentinel *:26381 [sentinel]
验证哨兵集群配置
查看自动追加的元数据信息
启动哨兵各个实例后,redis会将哨兵监听的 Redis实例
和 与当前哨兵
通信的其它哨兵示例
的元数据信息追加到文件尾部。
vim sentinel.conf
追加的信息如下:
sentinel known-replica mymaster 192.168.1.104 6381
sentinel current-epoch 2
sentinel known-replica mymaster 192.168.1.104 6380
sentinel myid 8a49e8914e4cf104d387d318e1ea7a38e52002dd
sentinel known-sentinel mymaster 192.168.1.104 26381 5e57edfeb5a27ada50a9a0ad9cde0c12bc99c107
sentinel known-sentinel mymaster 192.168.1.104 26380 c09ea07e704bff50fba125527ec62d65626b8fdf
同理,sentinel-26380.conf 文件尾部自动追加的元数据信息如下:
sentinel known-replica mymaster 192.168.1.104 6380
sentinel current-epoch 2
sentinel known-replica mymaster 192.168.1.104 6381
sentinel myid c09ea07e704bff50fba125527ec62d65626b8fdf
sentinel known-sentinel mymaster 192.168.1.104 26381 5e57edfeb5a27ada50a9a0ad9cde0c12bc99c107
sentinel known-sentinel mymaster 192.168.1.104 26379 8a49e8914e4cf104d387d318e1ea7a38e52002dd
同理,sentinel-26381.conf 文件尾部自动追加的元数据信息如下:
sentinel known-replica mymaster 192.168.1.104 6381
sentinel current-epoch 2
sentinel known-replica mymaster 192.168.1.104 6380
sentinel myid 5e57edfeb5a27ada50a9a0ad9cde0c12bc99c107
sentinel known-sentinel mymaster 192.168.1.104 26379 8a49e8914e4cf104d387d318e1ea7a38e52002dd
sentinel known-sentinel mymaster 192.168.1.104 26380 c09ea07e704bff50fba125527ec62d65626b8fdf
查看哨兵的日志
在启动了端口为26379的哨兵实例后,查看其日志:
AntonyZhang:data zwq$ tail -1000f sentinel-26379.log
59135:X 01 Aug 2021 16:01:48.032 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
59135:X 01 Aug 2021 16:01:48.033 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=59135, just started
59135:X 01 Aug 2021 16:01:48.033 # Configuration loaded
59135:X 01 Aug 2021 16:01:48.034 * Increased maximum number of open files to 10032 (it was originally set to 256).
59135:X 01 Aug 2021 16:01:48.035 * monotonic clock: POSIX clock_gettime
59135:X 01 Aug 2021 16:01:48.036 * Running mode=sentinel, port=26379.
59135:X 01 Aug 2021 16:01:48.037 # Sentinel ID is 8a49e8914e4cf104d387d318e1ea7a38e52002dd
59135:X 01 Aug 2021 16:01:48.037 # +monitor master mymaster 192.168.1.104 6379 quorum 2
59135:X 01 Aug 2021 16:02:24.947 * +sentinel sentinel c09ea07e704bff50fba125527ec62d65626b8fdf 192.168.1.104 26380 @ mymaster 192.168.1.104 6379
59135:X 01 Aug 2021 16:02:37.002 * +sentinel sentinel 5e57edfeb5a27ada50a9a0ad9cde0c12bc99c107 192.168.1.104 26381 @ mymaster 192.168.1.104 6379
分析:倒数第三行显示了当前哨兵监听到了Redis的master节点;
最后两行,显示了当前哨兵与其它两个同样监听Redis的master节点的哨兵建立了通信。
查看sentinel信息
登录哨兵客户端:
AntonyZhang:redis-6.2.5 zwq$ redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.104:6379,slaves=2,sentinels=3
最关键的一条数据时最后一行信息,监听的master实例名为mymaster;地址和端口为192.168.1.104:6379;监听到master的从节点有2个;哨兵共计3个
可能出现的问题
问题
1、在三个哨兵启动后,查看其中一个哨兵的配置文件,发现只有监听的Redis实例信息,没有其它哨兵的信息:
sentinel myid 3addf29c538ef985c3d96a16b2fab03c196ffd83
sentinel known-replica mymaster 192.168.1.104 6381
sentinel current-epoch 2
sentinel known-replica mymaster 192.168.1.104 6380
原因就在于在配置第一个哨兵的配置文件sentinel.conf时,没有注释掉sentinel myid,复制该文件为其它哨兵的配置文件后,3个哨兵的sentinel myid一模一样,所以,3个哨兵示例启动后,登录哨兵客户端就会发现只有一个哨兵实例存在:
AntonyZhang:redis-6.2.5 zwq$ redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.104:6379,slaves=2,sentinels=1
最后一行,sentinels=1,表示只有一个哨兵。
解决方案
注释掉3个哨兵配置文件中,相同的sentinel myid:
# sentinel myid 3addf29c538ef985c3d96a16b2fab03c196ffd83
具体原因:参考博主[只管努力,剩下的交给时间]的搭建redis哨兵集群时,哨兵无法感知到其他哨兵
Redis主从节点切换
1、3个Redis 实例启动后,启动3个哨兵实例。
信息如下:
AntonyZhang:redis-6.2.5 zwq$ redis-server redis.conf
AntonyZhang:redis-6.2.5 zwq$ redis-server slave1.conf
AntonyZhang:redis-6.2.5 zwq$ redis-server slave2.conf
AntonyZhang:redis-6.2.5 zwq$
AntonyZhang:redis-6.2.5 zwq$
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel.conf
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel-26380.conf
AntonyZhang:redis-6.2.5 zwq$ redis-sentinel sentinel-26381.conf
AntonyZhang:redis-6.2.5 zwq$
AntonyZhang:redis-6.2.5 zwq$ ps -ef|grep redis
501 59100 1 0 3:59下午 ?? 0:00.99 redis-server *:6379
501 59102 1 0 3:59下午 ?? 0:00.96 redis-server *:6380
501 59105 1 0 3:59下午 ?? 0:00.93 redis-server *:6381
501 59135 1 0 4:01下午 ?? 0:00.85 redis-sentinel *:26379 [sentinel]
501 59146 1 0 4:02下午 ?? 0:00.67 redis-sentinel *:26380 [sentinel]
501 59149 1 0 4:02下午 ?? 0:00.62 redis-sentinel *:26381 [sentinel]
501 59168 46039 0 4:04下午 ttys000 0:00.00 grep redis
501 59154 46187 0 4:02下午 ttys001 0:00.01 redis-cli -p 26379
2、此时,master是6379的实例,关闭master 6379实例:
kill 59100
3、查看哨兵1(port:26379)的log:
59135:X 01 Aug 2021 16:08:34.077 # +sdown master mymaster 192.168.1.104 6379
59135:X 01 Aug 2021 16:08:34.163 # +new-epoch 1
59135:X 01 Aug 2021 16:08:34.164 # +vote-for-leader c09ea07e704bff50fba125527ec62d65626b8fdf 1
59135:X 01 Aug 2021 16:08:34.179 # +odown master mymaster 192.168.1.104 6379 #quorum 2/2
59135:X 01 Aug 2021 16:08:34.179 # Next failover delay: I will not start a failover before Sun Aug 1 16:14:34 2021
59135:X 01 Aug 2021 16:08:35.170 # +config-update-from sentinel c09ea07e704bff50fba125527ec62d65626b8fdf 192.168.1.104 26380 @ mymaster 192.168.1.104 6379
59135:X 01 Aug 2021 16:08:35.170 # +switch-master mymaster 192.168.1.104 6379 192.168.1.104 6381
59135:X 01 Aug 2021 16:08:35.171 * +slave slave 192.168.1.104:6380 192.168.1.104 6380 @ mymaster 192.168.1.104 6381
59135:X 01 Aug 2021 16:08:35.171 * +slave slave 192.168.1.104:6379 192.168.1.104 6379 @ mymaster 192.168.1.104 6381
倒数第3行:重新选举master节点为6381的实例
+switch-master mymaster 192.168.1.104 6379 192.168.1.104 6381
4、登录slave为6380端口的redis实例客户端
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:192.168.1.104
master_port:6381
可以看到,此时master节点的端口号为6381
5、重新启动端口号为6379的redis实例
redis-server redis.conf
6、登录master为6381端口的redis实例客户端
AntonyZhang:redis-6.2.5 zwq$ redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.1.104,port=6380,state=online,offset=175124,lag=1
slave1:ip=192.168.1.104,port=6379,state=online,offset=175124,lag=1
master_failover_state:no-failover
master_replid:03b8b249448f18d2811cc5409b299e3070ee078c
master_replid2:bc402926cc9fd2805633cd2d2d3404806d1157b9
master_repl_offset:175265
second_repl_offset:74156
可以看到,此时6379的实例为slave从节点。