因为数据是存储在内存中的如果停电机器重启等数据就没了,为了使redis在重启之后仍能保证数据不丢失,需要将数据从内存中某种形式同步到硬盘中,这一过程就是持久化。
redis提供了两种持久化方式:RDB持久化和AOF持久化
以snapshot快照形式, 按事先定制的策略,周期性的将数据保存至磁盘,数据文件默认为dump.rdb;
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
记录每一次写操作至指定的文件尾部实现持久化,当redis重启时,可通过重新执行文件中的命令,在内存中重建数据库
当AOF文件过大时,会进行重写,
重写过成:
(1)redis主进程通过fork创建子进程
(2)子进程根据redis内存中的数据,创建数据库,重建命令序列于临时文件中
(3)父进程继承client的请求,并会把这些请求中的写操作继续追加至原来的AOF文件,额外的,这些新的写请求还会被放置于一个缓冲队列中
(4)子进程重写完成,会通知父进程,父进程会把缓冲中的命令写到临时文件中
(5)父进程用临时文件替换老的AOF文件
复制原理:
全量复制:salve启动成功连接到master后会发送一个sync命令,主数据库接收到sync命令后会开始在后台保存快照(即RDB持久化的过程)并将保存期间接收到的命令缓存起来。当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库,以完成一次完全同步全量复制。而slave服务在收到后,会载入快照文件并执行收到的缓存的命令。
结构:主-从-从
n1 192.168.231.60 主
n2 192.168.231.61 从
n3 192.168.231.62 从
安装redis
可参考CentOS7下编译安装redis5.0
修改配置文件
三个节点修改如下内容即可,持久化使用默认配置RDB
n1
[root@n1 ~]# vim /usr/local/redis/redis.conf
bind 192.168.231.60
protected-mode no
daemonize yes
logfile "n1_6379.log"
n2
[root@n2 ~]# vim /usr/local/redis/redis.conf
bind 192.168.231.61
protected-mode no
daemonize yes
logfile "n2_6379.log"
slaveof 192.168.231.60 6739
n3
[root@n3 ~]# vim /usr/local/redis/redis.conf
bind 192.168.231.62
protected-mode no
daemonize yes
logfile "n3_6379.log"
slaveof 192.168.231.60 6739
启动三个节点
执行相同操作
[root@n1 ~]# redis-server /usr/local/redis/redis.conf
[root@n1 ~]# redis-cli -h 192.168.231.60
查看
n1
192.168.231.60:6379> info Replication
# Replication
role:master #主库
connected_slaves:2
slave0:ip=192.168.231.61,port=6379,state=online,offset=154,lag=1
slave1:ip=192.168.231.62,port=6379,state=online,offset=154,lag=1
master_replid:d5c33e4630cb135527a64f2883e6bc118fc2401d
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
n2
192.168.231.61:6379> info Replication
# Replication
role:slave #从库
master_host:192.168.231.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:196
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:d5c33e4630cb135527a64f2883e6bc118fc2401d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:196
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:196
n3
192.168.231.62:6379> info Replication
# Replication
role:slave #从库
master_host:192.168.231.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:224
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:d5c33e4630cb135527a64f2883e6bc118fc2401d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:99
repl_backlog_histlen:126
测试数据是否同步:
192.168.231.60:6379> set name real
OK
192.168.231.61:6379> get name
"real"
192.168.231.62:6379> get name
"real"
模拟主节点n1停止服务
192.168.231.60:6379> SHUTDOWN
not connected>
然后发现n2,n3节点虽然可以查看数据,但是连接不上主服务器
master_link_status:down
提升n2为主服务器:
192.168.231.61:6379> SLAVEOF NO ONE
OK
192.168.231.61:6379> info Replication
# Replication
role:master
connected_slaves:0
master_replid:68d0f26c0318e767692de894e43dbe072376acd6
master_replid2:d5c33e4630cb135527a64f2883e6bc118fc2401d
master_repl_offset:926
second_repl_offset:927
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:926
让n3同步n2数据
192.168.231.62:6379> SLAVEOF 192.168.231.62 6379
OK
192.168.231.62:6379> get num
"1"
同步成功,但是手动修改进行主从切换实在太麻烦,可以用Sentinel。
sentinel是一个管理多个redis实例的工具,它可以实现对redis的监控、通知、自动故障转移。sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态,如果redis master不能工作,则会自动启动故障转移进程,将其中的一个slave提升为master,其他的slave重新设置新的master实例。
修改Sentinel配置文件:
在n1节点设置哨兵模式
[root@n1 ~]# egrep -v "^$|#" /usr/local/redis/sentinel.conf
port 26379
daemonize yes
pidfile /var/run/redis-sentinel.pid
logfile "sentinel.log"
dir /tmp
sentinel monitor mymaster 192.168.231.60 6379 1 #监控主节点IP
sentinel down-after-milliseconds mymaster 5000 #指定了 Sentinel 认为Redis实例已经失效所需的毫秒数。(5秒)
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000 #如果在该时间(ms)内未能完成failover操作,则认为该failover失败。
sentinel deny-scripts-reconfig yes
运行Sentinel的两种方式:
[root@n1 ~]# redis-server /usr/local/redis/sentinel.conf --sentinel
[root@n1 ~]# redis-sentinel /usr/local/redis/sentinel.conf
默认监听26379端口
主节点进入查看
[root@n1 ~]# redis-cli -h 192.168.231.60 -p 26379
info Sentinel
在n1上杀死redis进程
查看
发现master地址变为192.168.231.61,进行故障转移。