概念
主从复制,就是从主机(master)的数据复制到从机(slave)。数据的复制是单向的,只能由主机到从机。主机以写为主,从机以读为主。
redis集群最低配置:一主二从
主从复制的作用主要包括:
- 容灾备份:当主节点出现问题时,可以由从节点服务,实现快速的故障恢复。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写redis数据时应用连接主节点,读redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高redis服务器的并发量。
- 高可用基石:除上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制时redis高可用的基础。
主从复制的缺点:
- 当主机宕机后,只能手动切换主机。
环境配置
默认每个redis都是主机
info replication:查看当前库主从复制的信息
127.0.0.1:6379> info replication
# Replication
role:master //角色
connected_slaves:0 //连接的从机个数
master_replid:371f67d3e9d127eb3f63292472c054f0df22bd8a
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
一台centos虚拟机配置一主二从:
1.将配置文件拷贝三份,端口分别为6379(master)、6380(slave-1)、6381(slave-2)
[root@localhost redis-config]# cp redis.conf redis-6379.conf
[root@localhost redis-config]# cp redis.conf redis-6380.conf
[root@localhost redis-config]# cp redis.conf redis-6381.conf
[root@localhost redis-config]# ls
redis-6379.conf redis-6381.conf redis-6380.conf redis.conf
2.主机配置文件修改:
:171定位到171行,修改如下:
logfile “redis-6379.log”
:253定位到253行,修改如下:
dbfilename dump-6379.rdb
3.从机配置文件修改(以6380端口举例)
:92定位到92行,修改端口:
port 6380
:158定位到158行,修改pid名字:
pidfile /var/run/redis_6380.pid
:171定位到171行,修改log日志文件名字:
logfile “redis-6380.log”
:253定位到253行,修改dump文件名字:
dbfilename dump-6380.rdb
4.ps -aux | grep redis
[root@localhost shell-cmd]# ps -aux | grep redis
root 6676 0.2 0.4 153980 7648 ? Ssl 15:34 0:01 redis-server 0.0.0.0:6379
root 6683 0.2 0.4 153980 7648 ? Ssl 15:35 0:00 redis-server 0.0.0.0:6380
root 6700 0.2 0.4 153980 7648 ? Ssl 15:37 0:00 redis-server 0.0.0.0:6381
root 6714 0.0 0.0 112824 976 pts/3 R+ 15:42 0:00 grep --color=auto redis
5.配置从机
slaveof host port:在从机的配置文件中配置主机的ip和port
启动后,主机:
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2 //有两个从机
slave0:ip=192.168.72.147,port=6380,state=online,offset=154,lag=0
slave1:ip=192.168.72.147,port=6381,state=online,offset=154,lag=0
master_replid:05a7d742edc871f1d51d7cb38c820cac914122d5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:154
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:154
6380从机:
127.0.0.1:6380> info replication
# Replication
role:slave //从机
master_host:192.168.72.147 //主机ip
master_port:6379 //主机端口
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1161
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:05a7d742edc871f1d51d7cb38c820cac914122d5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1161
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1161
测试
6379主机:
127.0.0.1:6379> mset name jarvis age 24
OK
6380从机:
127.0.0.1:6380> keys *
1) "name"
2) "age"
127.0.0.1:6380> get name
"jarvis"
127.0.0.1:6380> get age
"24"
6381从机:
127.0.0.1:6380> keys *
1) "name"
2) "age"
127.0.0.1:6380> get name
"jarvis"
127.0.0.1:6380> get age
"24"
从机不能写:
127.0.0.1:6380> set score 99
(error) READONLY You can't write against a read only replica.
主机断掉(宕机)后,重新启动后,依旧能够将数据从主机同步到从机!
主从复制原理
从机启动成功连接到主机后会发送一个sync同步命令。
主机接收到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,主机将传送整个数据文件到从机,并完成一次性完全同步。
全量复制:从机在接受到数据库文件之后,将其存盘并加载到内存中。
增量复制:主机继续将新的所有收集到的修改命令依次传给从机,完成同步。
但是只要从机重新连接主机,一次性完全同步(全量复制)将自动执行
宕机后手动配置主机
slaveof no one:当主机宕机了,该命令可以使某个从机成为主节点。其他从节点可以手动连接到该节点成为它的从节点
将6380从机改为主机
127.0.0.1:6380> slaveof no one
OK
将6381从机的主机改为6380
127.0.0.1:6381> slaveof 192.168.72.147 6380 //手动配置该从机的主机
OK
6380的主从情况:
127.0.0.1:6380> info replication
# Replication
role:master //6380此刻为主机
connected_slaves:1 //有一个从机,端口为6381
slave0:ip=192.168.72.147,port=6381,state=online,offset=42,lag=0
master_replid:dd1ad4af8f9bcfde6177b6ed11e9caf03c5173a3
master_replid2:b2b31113de11f63c712814031b31dc6a61ba33f7
master_repl_offset:42
second_repl_offset:43
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
6380:
127.0.0.1:6380> set k9 vv9
OK
6381:
127.0.0.1:6381> get k9
"vv9"
注:如果原先的主机6379修复了,此时只能重新连接恢复原先的主从关系
哨兵模式
宕机后手动配置主机的方式,需要人工干预,费时费力,还会造成一段时间内服务不可用。redis2.8开始正式提供了Sentinel(哨兵)来解决这个问题。
sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel可以监视任意多个主服务器以及主服务器属下的从服务器,并在被监视的主服务器下线时,自动执行故障转移操作。
假如主服务器宕机,哨兵1先检测到这个结果,系统不会立马进行failover(故障转移)过程,仅仅是哨兵1主观地认为主服务器不可用,这个现象称为主观下线。当其他哨兵也检测到这个主服务器不可用,并且数量达到一定值时,那么哨兵之间会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。
1.配置哨兵配置文件sentinel.conf
1. daemonize yes # 后台运行
2. sentinel monitor <master-name> <ip> <redis-port> <quorum> # 最重要的配置
告诉sentinel去监听地址为ip:port的一个master。
这里的master-name可以自定义,quorum是一个数字,
指明当有多少个sentinel认为一个master失效时,master才算真正失效
e.g.:sentinel monitor redis-6379 192.168.72.147 6379 1
3. .......
2.开启哨兵进程
redis-sentinel sentinel.conf
运行完后发现配置文件sentinel.conf被重写了:
3.故障转移:6379主节点断开
6380的主机从6379变成6381
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:192.168.72.147
master_port:6381 //主机端口变成了6381
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:12025
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:93d184294736a207ed68b9023dcfd681c0f99b79
master_replid2:c78a69999f63225ae5a8bdaad532bef0e1b136f9
master_repl_offset:12025
second_repl_offset:11423
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:43
repl_backlog_histlen:11983
6381自动成为主机
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.72.147,port=6380,state=online,offset=13648,lag=0
master_replid:93d184294736a207ed68b9023dcfd681c0f99b79
master_replid2:c78a69999f63225ae5a8bdaad532bef0e1b136f9
master_repl_offset:13648
second_repl_offset:11423
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:43
repl_backlog_histlen:13606
再看sentinel.conf,又被重写了!
4.如果原先的主机恢复了,也只能作为从机
哨兵模式缺点:在故障转移期间,服务不可用