①. 概念:主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower)数据的复制是单向的!只能由主节点复制到从节点(主节点以写为主、从节点以读为主)
②. 默认情况下,每台Redis服务器都是主节点,一个主节点可以有0个或者多个从节点,但每个从节点只能有一个主节点
③. 主从复制作用

127.0.0.1:6379> info replication
# Replication
role:master # 角色 master:主节点
connected_slaves:0 # 从机数量:0
master_replid:425bbc84c7141a0738b5d0d6cd6920a756e334e4
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
127.0.0.1:6379>
[root@TANG2021 kconfig]# # redis.conf 【备份不使用,不修改】
[root@TANG2021 kconfig]# cp redis.conf redis_master79.conf
[root@TANG2021 kconfig]# cp redis.conf redis_sub80.conf
[root@TANG2021 kconfig]# cp redis.conf redis_sub81.conf
[root@TANG2021 kconfig]# ls
redis.conf redis_master79.conf redis_sub80.conf redis_sub81.conf
[root@TANG2021 kconfig]#
[root@TANG2021 kconfig]# vi redis_master79.conf
[root@TANG2021 kconfig]# vi redis_sub80.conf
[root@TANG2021 kconfig]# vi redis_sub81.conf
# redis.conf 【备份不使用,不修改】
# 端口号
port 6379
# 日志文件名
logfile ""
# pid文件名
pidfile /var/run/redis_6379.pid
# rdb文件名
dbfilename dump.rdb
# redis_master79.conf 【做主节点】
port 6379
logfile "6379.log"
pidfile /var/run/redis_6379.pid
dbfilename dump6379.rdb
# redis_sub80.conf 【做从节点1】
port 6380
logfile "6380.log"
pidfile /var/run/redis_6380.pid
dbfilename dump6380.rdb
# redis_sub81.conf 【做从节点2】
port 6381
logfile "6381.log"
pidfile /var/run/redis_6381.pid
dbfilename dump6381.rdb
[root@TANG2021 bin]# redis-server /usr/local/bin/kconfig/redis_master79.conf
[root@TANG2021 bin]# redis-server /usr/local/bin/kconfig/redis_sub80.conf
[root@TANG2021 bin]# redis-server /usr/local/bin/kconfig/redis_sub81.conf
[root@TANG2021 bin]# ps -ef |grep redis
polkitd 4770 4750 0 10:27 ? 00:00:00 redis-server *:6379
root 5717 1 0 10:37 ? 00:00:00 redis-server *:6380
root 5724 1 0 10:37 ? 00:00:00 redis-server *:6381
root 5729 4366 0 10:37 pts/0 00:00:00 grep --color=auto redis
[root@TANG2021 bin]#
# 6380
# SLAVEOF host port
# 二个从机 都 认 127.0.0.1 6379 为老大
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
# Replication
role:slave # 角色:奴隶(从属)
master_host:127.0.0.1 # 老大的ip
master_port:6379 # 老大的端口
# 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
# 6378 [主机]
# 然后主机上也能看到从机的状态:
127.0.0.1:6379> info replication
# Replication
role:master # 角色:主机
connected_slaves:2 # 从机数量
slave0:ip=127.0.0.1,port=6381,state=online,offset=322,lag=1 # 从机2信息
slave1:ip=127.0.0.1,port=6380,state=online,offset=322,lag=0 # 从机1信息
# 从服务器写入操作报错
127.0.0.1:6381> set name tang
(error) READONLY You can't write against a read only replica.

################################# REPLICATION #################################
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 配置主机信息
# replicaof
replicaof 127.0.0.1 6379
# 如果 Redis 有密码需要在配置文件设置主机密码 masterauth ******
# masterauth
# === 主机【6379】 ===
127.0.0.1:6379> set name 张三
OK
127.0.0.1:6379> set age 25
OK
127.0.0.1:6379> keys *
age
name
127.0.0.1:6379>
# === 主机【6380】 ===
127.0.0.1:6380> keys *
name
age
# === 主机【6381】 ===
127.0.0.1:6381> keys *
name
age
127.0.0.1:6380> set name 张三 # 从机【6380】写入失败
READONLY You can't write against a read only replica.
127.0.0.1:6381> set name 张三 # 从机【6381】写入失败
READONLY You can't write against a read only replica.
127.0.0.1:6379> set name 张三 # 主机【6379】写入成功
OK
127.0.0.1:6379> get name # 主机【6379】读取成功
张三
127.0.0.1:6381> get name # 从机【6380】读取成功
张三
127.0.0.1:6381> get name # 从机【6381】读取成功
张三
③. 当主机断电宕机后,默认情况下从机的角色不会发生变化 ,集群中只是失去了写操作,当主机恢复以后,又会连接上从机恢复原状
④. 当从机断电宕机后,若不是使用配置文件配置的从机,再次启动后作为主机是无法获取之前主机的数据的,若此时重新配置称为从机,又可以获取到主机的所有数据。这里就要提到一个同步原理
⑤. 第二条中提到,默认情况下,主机故障后,不会出现新的主机,有两种方式可以产生新的主机
⑥. 反客为主(谋朝篡位):如果主机断开了连接,我们可以使用SLAVEOF no one让自己变成主机!其他的节点就可以手动连接到最新的主节点(手动),如果这个时候老大修复了,也不能让失去的从节点回归
⑦. 薪火相传:上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险

①. 主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel(哨兵) 架构来解决这个问题。 谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
②. 概述:哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例
③. 单哨兵模式


# sentinel monitor 被监控的名称 host port 1
# 其中mymaster为监控对象起的服务器名称,1 为至少有多少个哨兵同意迁移的数量。
sentinel monitor mymaster 127.0.0.1 6379 1
[root@TANG2021 bin]# redis-sentinel sentinel.conf
18585:X 04 Sep 2022 13:35:09.729 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
18585:X 04 Sep 2022 13:35:09.729 # Redis version=5.0.8, bits=64, commit=00000000, modified=0, pid=18585, just started
18585:X 04 Sep 2022 13:35:09.729 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 18585
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
18585:X 04 Sep 2022 13:35:09.731 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18585:X 04 Sep 2022 13:35:09.734 # Sentinel ID is 4a9ef6f1269e0848f76284eaf9808c6d4eb95303
18585:X 04 Sep 2022 13:35:09.734 # +monitor master mymaster 127.0.0.1 16379 quorum 1
18585:X 04 Sep 2022 13:35:09.735 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:35:09.736 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 18585
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
18585:X 04 Sep 2022 13:35:09.731 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18585:X 04 Sep 2022 13:35:09.734 # Sentinel ID is 4a9ef6f1269e0848f76284eaf9808c6d4eb95303
18585:X 04 Sep 2022 13:35:09.734 # +monitor master mymaster 127.0.0.1 16379 quorum 1
18585:X 04 Sep 2022 13:35:09.735 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:35:09.736 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.806 # +sdown master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.806 # +odown master mymaster 127.0.0.1 16379 #quorum 1/1
18585:X 04 Sep 2022 13:36:19.806 # +new-epoch 1
18585:X 04 Sep 2022 13:36:19.806 # +try-failover master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.811 # +vote-for-leader 4a9ef6f1269e0848f76284eaf9808c6d4eb95303 1
18585:X 04 Sep 2022 13:36:19.811 # +elected-leader master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.811 # +failover-state-select-slave master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.902 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.902 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:19.969 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:20.167 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:20.167 # +failover-state-reconf-slaves master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:20.256 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:21.210 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:21.210 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:21.310 # +failover-end master mymaster 127.0.0.1 16379
18585:X 04 Sep 2022 13:36:21.310 # +switch-master mymaster 127.0.0.1 16379 127.0.0.1 6381
18585:X 04 Sep 2022 13:36:21.310 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
18585:X 04 Sep 2022 13:36:21.310 * +slave slave 127.0.0.1:16379 127.0.0.1 16379 @ mymaster 127.0.0.1 6381
18585:X 04 Sep 2022 13:36:51.333 # +sdown slave 127.0.0.1:16379 127.0.0.1 16379 @ mymaster 127.0.0.1 6381

②. Redis集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N
③. 制作6个实例,16379,16380,16381,16389,16390,16391
# 开启daemonize yes
daemonize yes
# Pid文件名字
pidfile /var/run/redis_16379.pid
# 指定端口
port 16379
# Log文件名字
logfile "16379.log"
# Dump.rdb名字
dbfilename dump16379.rdb
# redis cluster配置修改
# 打开集群模式
cluster-enabled yes
# 设定节点配置文件名
cluster-config-file nodes-6379.conf
# 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
cluster-node-timeout 15000
[root@TANG2021 cluster]# cp redis.conf redis16380.conf
[root@TANG2021 cluster]# cp redis.conf redis16381.conf
[root@TANG2021 cluster]# cp redis.conf redis16389.conf
[root@TANG2021 cluster]# cp redis.conf redis16390.conf
[root@TANG2021 cluster]# cp redis.conf redis16391.conf
[root@TANG2021 cluster]# ll
总用量 448
-rw-r--r-- 1 root root 61779 9月 4 16:12 redis16379.conf
-rw-r--r-- 1 root root 61779 9月 4 16:12 redis16380.conf
-rw-r--r-- 1 root root 61779 9月 4 16:13 redis16381.conf
-rw-r--r-- 1 root root 61779 9月 4 16:13 redis16389.conf
-rw-r--r-- 1 root root 61779 9月 4 16:13 redis16390.conf
-rw-r--r-- 1 root root 61779 9月 4 16:13 redis16391.conf
-rw-r--r-- 1 root root 61779 9月 4 16:12 redis.conf
[root@TANG2021 cluster]# ../redis-server redis16381.conf
[root@TANG2021 cluster]# ps -ef |grep redis
root 5229 1 0 16:25 ? 00:00:00 ../redis-server *:16389 [cluster]
root 5237 1 0 16:25 ? 00:00:00 ../redis-server *:16390 [cluster]
root 5244 1 0 16:25 ? 00:00:00 ../redis-server *:16391 [cluster]
root 5249 1 0 16:25 ? 00:00:00 ../redis-server *:16379 [cluster]
root 5263 1 0 16:25 ? 00:00:00 ../redis-server *:16380 [cluster]
root 5501 1 0 16:28 ? 00:00:00 ../redis-server *:16381 [cluster]
root 5508 3575 0 16:28 pts/0 00:00:00 grep --color=auto redis


[root@TANG2021 src]# ll |grep *.rb
-rwxrwxr-x 1 root root 3600 3月 12 2020 redis-trib.rb
[root@TANG2021 src]# redis-cli --cluster create --cluster-replicas 1 192.168.68.143:16379 192.168.68.143:16380 192.168.68.143:16381 192.168.68.143:16389 192.168.68.143:16390 192.168.68.143:16391
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.68.143:16390 to 192.168.68.143:16379
Adding replica 192.168.68.143:16391 to 192.168.68.143:16380
Adding replica 192.168.68.143:16389 to 192.168.68.143:16381
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 050f426fbbe0c68882a3c2fe1e9a8c0fede020e9 192.168.68.143:16379
slots:[0-5460] (5461 slots) master
M: 6cf02daaa7797e506a788acf0ceca2bc7387d284 192.168.68.143:16380
slots:[5461-10922] (5462 slots) master
M: b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0 192.168.68.143:16381
slots:[10923-16383] (5461 slots) master
S: 7754ce5033cef06c3844969878a1b64f17ab5dbb 192.168.68.143:16389
replicates 050f426fbbe0c68882a3c2fe1e9a8c0fede020e9
S: a856a2fab10f875511e63aa5e2a52a9837c80176 192.168.68.143:16390
replicates 6cf02daaa7797e506a788acf0ceca2bc7387d284
S: 3ae80e542decefa2ca19568d3a3a89eb8fd26207 192.168.68.143:16391
replicates b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0
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.68.143:16379)
M: 050f426fbbe0c68882a3c2fe1e9a8c0fede020e9 192.168.68.143:16379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 7754ce5033cef06c3844969878a1b64f17ab5dbb 192.168.68.143:16389
slots: (0 slots) slave
replicates 050f426fbbe0c68882a3c2fe1e9a8c0fede020e9
S: a856a2fab10f875511e63aa5e2a52a9837c80176 192.168.68.143:16390
slots: (0 slots) slave
replicates 6cf02daaa7797e506a788acf0ceca2bc7387d284
M: 6cf02daaa7797e506a788acf0ceca2bc7387d284 192.168.68.143:16380
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0 192.168.68.143:16381
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 3ae80e542decefa2ca19568d3a3a89eb8fd26207 192.168.68.143:16391
slots: (0 slots) slave
replicates b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@TANG2021 src]#
[root@TANG2021 cluster]# ../redis-cli -p 16379
127.0.0.1:16379> keys *
(empty list or set)
127.0.0.1:16379> set name tang
(error) MOVED 5798 192.168.68.143:16380
127.0.0.1:16379> exit
[root@TANG2021 cluster]# ../redis-cli -c -p 16379
127.0.0.1:16379> keys *
(empty list or set)
127.0.0.1:16379> set name tang
-> Redirected to slot [5798] located at 192.168.68.143:16380
OK
192.168.68.143:16380> cluster nodes
3ae80e542decefa2ca19568d3a3a89eb8fd26207 192.168.68.143:16391@26391 slave b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0 0 1662280767952 6 connected
6cf02daaa7797e506a788acf0ceca2bc7387d284 192.168.68.143:16380@26380 myself,master - 0 1662280767000 2 connected 5461-10922
a856a2fab10f875511e63aa5e2a52a9837c80176 192.168.68.143:16390@26390 slave 6cf02daaa7797e506a788acf0ceca2bc7387d284 0 1662280766942 5 connected
b994fb96b5a6e9b9aeb4d9ca9be0e5e7f0ac3df0 192.168.68.143:16381@26381 master - 0 1662280766000 3 connected 10923-16383
050f426fbbe0c68882a3c2fe1e9a8c0fede020e9 192.168.68.143:16379@26379 master - 0 1662280768962 1 connected 0-5460
7754ce5033cef06c3844969878a1b64f17ab5dbb 192.168.68.143:16389@26389 slave 050f426fbbe0c68882a3c2fe1e9a8c0fede020e9 0 1662280765934 4 connected
192.168.68.143:16380> exit

# 主服务器有数据
[root@TANG2021 cluster]# ../redis-cli -c -p 16380
127.0.0.1:16380> keys *
1) "name"
127.0.0.1:16380> exit
# 从服务器没有数据
[root@TANG2021 cluster]# ../redis-cli -c -p 16389
127.0.0.1:16389> keys *
(empty list or set)


[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
③. 如果主节点下线?从节点能否自动升为主节点?注意:15秒超时

④. 主节点恢复后,主从关系会如何?主节点回来变成从机
⑤. 如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?