目前通常的设计思路:
利用replication机制来弥补aof、snapshot性能上的不足,达到了数据可持久化。
即master上RDB和AOF都不开启,来保证master的读写性能,
而slave上则同时开启RDB和AOF来进行持久化,保证数据的安全性。
如果数据要做持久化,又想保证稳定性,建议留一半的物理内存。
因为在进行snapshot时,fork出来进行dump操作的子进程会占用与父进程一样的内存,
真正的copy-on-write,对性能的影响和内存的耗用都是比较大的。
环境描述:
master:192.168.2.100 不开启RDB和AOF
slave:192.168.2.200 开启RDB和AOF
配置信息:
master:
# vim etc/redis.conf
#save 600 5 //禁用RDB
appendonly no //禁用AOF
requirepass 123456 //指定验证密码
slave:
# vim etc/redis.conf
save 600 5 //开启RDB
dbfilename "dump_6379.rdb" //RDB文件
dir "/usr/local/redis-3.0.6-6379" //RDB文件路径
appendonly yes //开启AOF
appendfilename "appendonly.aof" //指定AOF文件
appendfsync everysec //每秒强制写入磁盘一次
no-appendfsync-on-rewrite no //在日志重写时,不进行命令追加操作
auto-aof-rewrite-percentage 100 //当前AOF超过上一次AOF大小100%时重写
auto-aof-rewrite-min-size 64mb //日志重写最小值
slaveof 192.168.2.100 6379 //指定主库IP和端口
masterauth 123456 //指定主库登录密码
启动redis:
master:# redis-server etc/redis.conf
slave:# redis-server etc/redis.conf
master创建key:
# redis-cli -a 123456
127.0.0.1:6379> info replication //查看主从关系是否正确
127.0.0.1:6379> keys * //此时,master安装目录下是没有RDB文件的
(empty list or set)
127.0.0.1:6379> set name zhagnsan //创建3个key
OK
127.0.0.1:6379> set age 26
OK
127.0.0.1:6379> set home beijing
OK
slave检查同步情况:
# redis-cli
127.0.0.1:6379> keys * //数据已同步
1) "age"
2) "home"
3) "name"
模拟master故障:
# ps -ef |grep redis
root 126472 1 0 21:58 ? 00:00:02 redis-server *:6379
root 127714 2844 0 22:29 pts/0 00:00:00 grep --color=auto redis
# kill -9 126472
# rm -rf dump_6379.rdb
slave查看主从状态:
# redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.2.100
master_port:6379
master_link_status:down //我们看到master已经不可访问了,slave正常
master_last_io_seconds_ago:-1
... ...
灾难恢复:
1、取消slave的同步状态
避免master未完成数据恢复就重启,导致覆盖掉slave上的数据,最终数据丢失。
127.0.0.1:6379> SLAVEOF no one //动态修改配置文件,将slavof设置为no
OK
127.0.0.1:6379> info repolication //查看主从信息,已经没有了
127.0.0.1:6379>
2、启动master的redis,确认数据不存在(这步可以忽略,我只是想确认下有没有数据)
# redis-server etc/redis.conf
# redis-cli -a 123456
127.0.0.1:6379> keys *
(empty list or set)
# ps -ef |grep redis
root 128031 1 0 22:45 ? 00:00:00 redis-server *:6379
root 128050 2844 0 22:46 pts/0 00:00:00 grep --color=auto redis
# kill -9 128031 //再次异常关闭redis
# rm -rf dump_6379.rdb //再次删除RDB文件
3、拷贝RDB文件和AOF文件给master
# scp dump_6379.rdb 192.168.2.100:/usr/local/redis-3.0.6-6379/
# scp appendonly.aof 192.168.2.100:/usr/local/redis-3.0.6-6379/
4、master开启RDB、开启AOF
# vim etc/redis.conf
save 600 5 //开启RDB
dbfilename "dump_6379.rdb" //RDB文件
dir "/usr/local/redis-3.0.6-6379" //RDB文件路径
appendonly yes //开启AOF
appendfilename "appendonly.aof" //指定AOF文件
... ...
5、master启动redis,查看库,数据已恢复
# redis-server etc/redis.conf
# redis-cli -a 123456
127.0.0.1:6379> keys *
1) "home"
2) "name"
3) "age"
6、master数据恢复后,需要关闭RDB和AOF,来保证自身的读写性能。
但是RDB文件和AOF文件要保留(不能恢复数据后给删除了)
虽然RDB文件和AOF文件存在,但大小不会增加,依然只是salve的AOF文件增加。
# kill [redis PID] //关闭redis
# vim etc/redis.conf //关闭RDB和AOF
#save 600 5
appendonly no
# redis-server etc/redis.conf //启动redis
# redis-cli -a 123456
127.0.0.1:6379> keys * //关闭RDB和AOF功能,库中的数据依然存在
1) "home"
2) "name"
3) "age"
7、slave开启同步状态
127.0.0.1:6379> SLAVEOF 192.168.2.100 6379 //开启同步状态
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.2.100
master_port:6379
master_link_status:up //master可以正常访问了
master_last_io_seconds_ago:5
master_sync_in_progress:0
... ...
8、master创建key
127.0.0.1:6379> set abc 123 //新增一个key
OK
127.0.0.1:6379> keys *
1) "abc"
2) "home"
3) "name"
4) "age"
9、slave查看同步情况
127.0.0.1:6379> keys *
1) "abc"
2) "age"
3) "home"
4) "name"
总结:
在此次恢复的过程中,我们同时使用了AOF和RDB文件,那么到底是哪个文件完成了恢复呢?
1、如果只配置了RDB,启动时加载的是RDB文件;
2、如果只配置了AOF,启动时加载的是AOF文件;
3、如果同时配置了RDB和AOF,由于AOF优先级高于RDB,所以使用的是AOF文件。
而且,AOF文件的数据完整性要高于RDB文件,因为RDB是按照周期性策略进行保存的。
如果在下个周期来临前故障,那么将丢失上个周期到故障点的数据。