主从复制:
是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower), 数据的复制是单向的,只能由主节点复制到从节点(主节点以写为主、从节点只读)—— 读写分离。
默认情况下,每个Redis服务都是以Master角色启动,一个主节点可以有>=0个从节点,但是每个从节点只会有一个主节点。
架构图如下:
Redis中有一个命令可以查看当前库信息:info replication
127.0.0.1:6379> INFO replication
# Replication
role:master # 当前库角色:master主节点
connected_slaves:0 # 从节点个数
master_replid:70a2687320104ee8f8845acd2e0312e6597a425f
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>
注:本例配置为一主二从
# 1. 修改端口号,每个配置文件需要是一个独立且未被占用的端口
port 6379
# 2. 开启守护进程模式运行,默认是no
daemonize yes
# 3. 修改pid文件名
pidfile "/var/run/redis_6379.pid"
# 4.log文件名,如果出现问题便于查询日志
logfile "../logs/6379.log"
# 5. dump.rdb文件名,存储内存中的快照
dbfilename "dump_6379.rdb"
# 6. dump文件的目录
dir "/home/base/redis-6.0.7/dump"
#其他两个文件按照这个配置依次修改即可
[root@template src]# ./redis-server ../conf/redis-6379.conf
[root@template src]# ./redis-server ../conf/redis-6380.conf
[root@template src]# ./redis-server ../conf/redis-6381.conf
[root@template src]# ps -ef|grep redis #查看服务
root 15191 1 0 14:45 ? 00:00:00 ./redis-server *:6379
root 15198 1 0 14:45 ? 00:00:00 ./redis-server *:6380
root 15207 1 0 14:45 ? 00:00:00 ./redis-server *:6381
root 15217 14879 0 14:46 pts/0 00:00:00 grep --color=auto redis
注意,上文提到默认情况下,单个redis服务默认以master角色启动,所以我们只需要配置从机即可。
第一种方式:命令寻主
在两台从机进行连接后,进行认主:
[root@template src]# ./redis-cli -p 6380
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 # 绑定主机为本机的6379服务
OK
127.0.0.1:6380> INFO replication # 查看当前库信息
# Replication
role:slave # 角色为从机
master_host:127.0.0.1 # 主机的ip
master_port:6379 # 主机端口号
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1681283474
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:826f635d3d7f3aaa12990efe9f52885f19759ffc
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
同样的步骤操作6381端口的redis即可,此处不再贴命令。
在主机中查看信息:
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2 # 从机数量:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=56,lag=0 # 从机1
slave1:ip=127.0.0.1,port=6381,state=online,offset=56,lag=0 # 从机2
master_replid:e9f03b8ed7269a557d899281999c5b8617b87ec1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:56
注意:命令寻主方式还有一个问题,如果主机是设置了密码的,需要在从机的配置文件中的# masterauth
去掉#并且设置好自己的密码,否则主机是查看主机信息时会发现connected_slaves:0
第二种方式:配置文件寻主
命令寻主存在一个问题,那就是这种主从关系是暂时的,也就是说在重启服务之后主从关系就会丢失。所以在正式的开发中,都是在配置文件中指定主机的。
具体位置如下:
这样配置之后,从机重启时会自动寻主。
主机命令:
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> KEYS *
1) "name"
2) "age"
127.0.0.1:6379>
从机命令:
# 6380
127.0.0.1:6380> KEYS *
1) "name"
2) "age"
127.0.0.1:6380> get name
"zhangsan"
# 6381
127.0.0.1:6381> KEYS *
1) "name"
2) "age"
127.0.0.1:6381> get age
"20"
可以发现,两台从机都是可以读取到主机写入的数据的
那么这时就有一个问题,我们能不能用从机写数据,主机读数据?
127.0.0.1:6381> SET class 5
(error) READONLY You can't write against a read only replica.
不难发现,从机是不能进行写入操作的,其实配置文件中对此也有相关说明:官方解释是为了保证只读从机的安全性,具体如下:
在默认情况下,主机断电或者宕机后,从机的角色并不会发生变化,此时只能对数据库做读操作。直到主机恢复后,又会重新进行连接,恢复写操作。
那么此时就出现了一个新的问题,能不能在主机断电或者宕机的情况下,从机之间出现一个挑大梁的,担任起主机的角色,从而保证写操作的正常呢?
答案是有的,其实有两种方法可以达到此目的。
1、自我举荐
2、自动选举
什么叫自我举荐,就是我可以通过在从机上跑命令来任命当前从机为主机
# 6379
127.0.0.1:6379> SHUTDOWN save # 断开主机
not connected> exit
# 6380
127.0.0.1:6380> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down # 发现此时主机的状态是down,掉线状态
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:2316
master_link_down_since_seconds:55
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:e9f03b8ed7269a557d899281999c5b8617b87ec1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2316
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2316
127.0.0.1:6380> SLAVEOF no one # 设置此从机为新的主机
OK
127.0.0.1:6380> INFO replication
# Replication
role:master # 角色成为了master
connected_slaves:0
master_replid:4413ca55dd34deb7deff01191b7c48f1806b398c
master_replid2:e9f03b8ed7269a557d899281999c5b8617b87ec1
master_repl_offset:2316
second_repl_offset:2317
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2316
但是这种方式相对笨重,将6380变为主机之后,我们还需要手动操作6381认6380为主
所以此时就出现了一种更为高级的方式:自我选举,也就是大名鼎鼎的哨兵模式
哨兵模式(Sentinel):可以理解为是一个监控,开启后哨兵会一直巡逻监视各个节点的情况,当master节点挂掉的时候,会从存活的从机中通过投票选举的方式选出一个从机成为新的master
哨兵的作用:
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题(比如哨兵挂了),为此,我们可以使用多个哨兵进行监控。 各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一 定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover[故障转移]操作。 切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。
1、配置哨兵配置文件:sentinel.conf
sentinel monitor myRedis 127.0.0.1 6379 1
# myRedis表示hostname,你可以自己随意取名
# 最后的数字1表示当主机挂了之后,在从机中进行投票选主,票数大于1的晋升为主机
daemonize yes #设置为守护进程模式,为了更好的看哨兵的效果,可以先注释以观察投票选主的过程
2、启动哨兵
[root@template src]# ./redis-sentinel ../conf/sentinel.conf
[root@template src]# ps -ef|grep redis
root 9941 1 0 16:58 ? 00:00:01 ./redis-server *:6379
root 10015 1 0 16:58 ? 00:00:01 ./redis-server *:6380
root 10042 1 0 16:58 ? 00:00:01 ./redis-server *:6381
root 14274 3592 0 17:02 pts/2 00:00:00 ./redis-cli -p 6379
root 15412 1 0 17:27 ? 00:00:00 ./redis-sentinel *:26379 [sentinel]
root 15418 4006 0 17:28 pts/4 00:00:00 grep --color=auto redis
3、测试
按照一主二从启动79/80/81,查看状态
断开79,查看80/81的状态,会发现主机变成了80/81其中的一台,并且另一台成为了新主机的从机
优点:
缺点: