Redis 主从架构的一些知识点、持久化与异常恢复

 

以下是关于Redis复制功能的几个重要方面:

Ø Redis使用异步复制。从Redis 2.8开始,从服务器以每秒一次的频率向主服务器报告复制流(replication stream)的处理进度;

Ø 复制功能不会阻塞主服务器:即使有一个或者多个从服务器正在进行初次同步,主服务器也可以继续处理命令请求;

Ø 复制功能也不会阻塞从服务器:只要在redis.conf文件中进行相应的设置,即使从服务器正在进行初次同步,它一样可以使用未同步完成之前的数据集来处理命令查询;

Ø 从服务器在同步过程中,删除旧版本数据并且载入新版本数据集的时间内,连接请求会被阻塞。

 

复制功能的原理:

无论是初次连接还是重新连接,当建立一个从服务器时,从服务器会向主服务器发送一个SYNC命令;

接收到SYNC命令的主服务器会判断是否有正在进行快照,没有则立即开始执行BGSAVE,有则等待其结束。在保存快照期间,将所有新执行的写入命令都保存到一个缓冲区里面;

主服务器BGSAVE执行完毕后,主服务器将执行快照保存所得的.rdb文件发送给从服务器,从服务器接收到这个.rdb文件,然后清空内存表,重新读取.rdb文件,将数据载入到内存中;

之后主服务器会以Redis命令协议的格式,将写命令缓冲区积累的内容发送给从服务器。

 

现在来搭建一套主从架构,并且模拟崩溃恢复的情形:

 

1)、主库上关闭aof持久化和rdb持久化:

#save 900 1

#save 300 10

#save 60 10000

 

#appendonly yes

 

2)、从库上打开aof持久化和rdb:

save 900 1

save 300 10

save 60 10000

 

appendonly yes

 

3)、然后配置主从同步,配置过程省略,详见前面阐述。

 

4)、测试同步是否正常

主库上:

127.0.0.1:6379> KEYS *

(empty list or set)

 

从库上:

127.0.0.1:6379> KEYS *

(empty list or set)

 

在主库上添加键值:

127.0.0.1:6379> set name Nicholas

OK

127.0.0.1:6379> set age 0

OK

127.0.0.1:6379> set sex man

OK

 

从库上查看键值:

127.0.0.1:6379> KEYS *

1) "sex"

2) "age"

3) "name"

127.0.0.1:6379> GET name

"Nicholas"

127.0.0.1:6379> GET age

"0"

127.0.0.1:6379> GET sex

"man"

结果显示,数据已经同步到从库上。

 

在从服务器14.17.119.220上通过INFO命令查看主从复制相关信息:

127.0.0.1:6379> info

… … … … …

# Persistence

aof_enabled:1              #开启aof持久化

… … … … …

# Replication

role:slave                   #该实例是从服务器

master_host:115.231.33.222    #它的master115.231.33.222

master_port:6379            #master端口是6379

master_link_status:up         #复制连接当前的状态,up表示连接正常,down表示连接断开

master_last_io_seconds_ago:5

master_sync_in_progress:0

slave_repl_offset:841

slave_priority:100

slave_read_only:1

connected_slaves:0

master_repl_offset:0

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

 

在主服务器上115.231.33.222上通过INFO命令查看主从复制相关信息:

… … … … …

# Persistence

aof_enabled:0            #aof持久化关闭

… … … … …

# Replication

role:master               #该服务器为主服务器        

connected_slaves:1        #有一个从服务器在连接

slave0:ip=14.17.119.220,port=6379,state=online,offset=1849,lag=0  #slaveIP和端口,以及状态

master_repl_offset:1849

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:1848

 

4)、从库开启了aof和rdb持久化,而主库禁用的持久化。从库一般会有定时任务生成快照,这里手动触发快照

127.0.0.1:6379> BGSAVE

Background saving started

5)、模拟主库异常崩溃

root@ubuntu:~# kill  -9  19304

#主库崩溃后恢复

root@ubuntu:~#redis-server  redis-2.8.19/redis.conf &

# Replication

role:master

connected_slaves:1

slave0:ip=14.17.119.220,port=6379,state=online,offset=85,lag=1 #仍然是主库,从库仍然是14.17.119.220 6379

 

# Keyspace             #没有key信息,数据丢失了

 

127.0.0.1:6379> KEYS *

(empty list or set)

主库由于没有开启持久化,故崩溃恢复后,内存中的数据都丢失了…

 

看看从库的数据如何?

127.0.0.1:6379> KEYS *

(empty list or set)

127.0.0.1:6379> info

# Keyspace              #没有key信息,数据也丢失了

 

原来主库和从库都有相应的数据,为什么主库崩溃重启后,从库的数据也丢失了呢?

原因是Redis主从复制的一个缺陷引起的:

Slave由于网络原因或者其他原因与Master断开了连接(在这里是由于主库异常崩溃,导致主从连接失效),Slave重新连接Master的时候,需要重新获取Master的整个内存快照,Slave内存中的数据会被全部清空,然后重载快照文件。而Master由于没有开启持久化,崩溃重启后数据都丢失了,它传送给Slave的快照文件是空的,Slave重载空的快照文件,导致数据也被清空了。

 

故这里需要特别注意:

Ø 如果主库崩溃,并且主库没有做任何持久化,崩溃之后不要立即恢复主库。否则会导致从库的数据被清空。此时你应该要做的是,在从库上执行SLAVEOF NO ONE指令,将其切换为主库,并且知会业务方将业务切到新的主;

Ø 最简便的方式是主库开启持久化,这样在崩溃恢复之后,它会优先选择aof文件进行载入数据到内存,如果没有aof文件,则使用rdb文件进行恢复数据。

 

6)、如何进行主库崩溃恢复呢?

从上述主库崩溃开始,崩溃后先不要启动主库.

然后在从库上执行SLAVEOF NO ONE,断开主从同步,以避免从库数据也被清空:

127.0.0.1:6379> SLAVEOF NO ONE

OK

 

将从库的RDB文件复制到主库:

scp -P32200 /data/redis_6379/dump.rdb xiaohaoteng@xxx.xxx.xx.xxx:/home/xiaohaoteng/

\cp /home/xiaohaoteng/dump.rdb  /root/

 

重新启动主库:

/root/redis-2.8.19/src/redis-server /root/redis-2.8.19/redis.conf &

 

127.0.0.1:6379> KEYS *

1) "sex"

2) "age"

3) "name"

可以看到主库数据已经已经恢复了.

 

7)、重新设置主从关系

在从库上重新设置它的主为115.231.33.222  6379

127.0.0.1:6379> slaveof  115.231.33.222  6379

OK

 

总结:

本次实验,我们通过在slave上开启持久化,当master崩溃时,从slave上的持久化文件来恢复master上的数据。在大数据量的情况下,AOF文件的增长速度要比RDB文件增长快,如果对数据一致性要求不是很高,可以容忍丢失一些数据的话,建议只需要在从上开启snapshot来进行持久化,而不需要开启AOF。同时你应该将save的频率调高一些、或者直接采用定时任务来定期进行BGSAVE。

原文

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值