REDIS主从复制:
1、复制特性
使用异步复制
一个主服务器可以有多个从服务器
一个从服务器可以有自己的从服务器
复制功能不会阻塞主服务器
可以通过复制功能来让主服务器免于执行持久化操作,由从服务器去执行持久化操作即可。
关闭主服务器持久化时,复制功能的数据是安全的。
当配置redis复制功能时,强烈建议打开主服务器的持久化功能,否则的话,由于延迟等问题应该要避免部署服务自动拉起。
redis主从复制的原理:
redis主从同步有两种方式(或者有两个阶段:全同步和部分同步)
主从刚刚连接时,进行全同步,全同步结束后。进行部分同步。
当然,如果有需要,slave在任何时候都可以发起全同步。
redis的策略:
无论如何,首先会尝试进行部分同步,如不成功,要求从服务器进行全同步,并启动BGSAVE…..BGSAVE结束后,传输RDB文件;如果成功,允许从服务器进行部分同步,并传输积压空间中的数据。
主从同步的机制:
从服务器向主服务器发送SYNC命令。
接到SYNV命令的主服务器会调用BGSAVE命令,创建一个RDB文件,并使用缓冲区记录接下来执行的所有写命令。
当主服务器执行完BGSAVE命令时,它会向从服务器发送RDB文件,而从服务器则会接受并载入这个文件。
主服务器将缓冲区储存的所有写命令发送给从服务器执行。
Redis命令的传播:
在从服务器完成同步之后,主服务器每执行一个写命令,它都会将被执行的写命令发送给从服务器执行,这个操作被称为“命令传播”(command propagate)
客户端——>发送写命令——>主服务器——->发送写命令——->从服务器
命令传播是一个持续的过程:只要复制仍再继续,命令传播就会一直进行,是的主从服务器的状态可以一直保持一致。
Redis复制的一致性问题:
在读写分离环境下,客户端向主服务器发送写命令SET n 10086 , 主服务器在执行这个写命令之后,向客户端返回回复,并将这个写命令传播给从服务器。
接到回复的客户端继续向从服务器发送读命令GET n , 并且因为网络状态的原因,客户端的GET命令比主服务器传播的SET命令更快到达了从服务器。
因为从服务器键 n 的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的 n 值。
Redis复制安全性提升:
主服务器只在至少N个从服务器的情况下,才执行写操作从Redis2.8开始,为了保证数据的安全性,可以通过配置,让主服务器只在由至少N个当前已连接从服务器的情况下,才执行写命令。
不过,因为Redis使用异步复制,所以主服务器发送的写数据并不一定会被从服务器接收到,因此,数据丢失的可能性仍然时存在的。
通过以下两个参数保证数据的安全:
min-slaves-to-write
min-slaves-max-lag
解释:
要求至少有一个slave,数据复制和同步的延迟不能超过10秒,如果一旦所有的slave,数据复制和同步的延迟都超过了十秒钟,那么这个时候,master就不会再接受任何请求了。
减少异步复制的数据丢失:
有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master down机后损失的数据太多了,那么就拒绝写请求,这样可以把master down机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内。
减少脑裂的数据丢失:
如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求,这样脑裂后的旧master就不会接受client的新数据,也就避免了数据的丢失。
上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝清的写请求。因此在脑裂场景下,最多就丢失10秒的数据。
Redis主从复制实践:
环境准备:三台服务器
一台master 两台slave
保证环境的干净,每台服务器使用yum安装的redis
保证网络通畅,base、epel仓库可用,firewalld、selinux关闭
下载服务:(三台都要下,已下过请忽略)
yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum -y —enablerepo=remi install redis
修改配置文件:
master机:
vim /etc/redis.conf
全部删除后复制一下内容进配置文件:
bind 172.17.0.5 127.0.0.1 #这里填写的是本机ip 而127.0.0.1代表了本地访问0.0.0.0代表全部可访问
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis #指定密码为redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename “appendonly.aof”
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events “”
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
做完修改后保存退出
来到slave-1机进行配置:
vim /etc/redis.conf
删除全部复制以下内容进配置文件内:
bind 172.17.0.6 #写的是slave-1机器的ip 也就是本机ip
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replicaof 172.17.0.5 6379 #这里指定的是master机的ip地址以及端口号
masterauth redis #这里写的密码要和master机指定的密码一致
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename “appendonly.aof”
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events “”
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
修改完之后保存退出
进入slave-2进行配置:
vim /etc/redis.conf
删除全部,复制以下内容进配置文件:
bind 172.17.0.7 #这里指定的是slave-2的IP地址 也就是本机ip地址
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir /var/lib/redis
replicaof 172.17.0.5 6379 #这里指定的是master机的ip地址以及端口号
masterauth redis #这里指定的密码,要与master机指定的一致
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
requirepass redis
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename “appendonly.aof”
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events “”
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
做完修改后保存退出
随后依次重启或启动服务
验证:
主服务器:
redis-cli -a redis -h 本机ip -p 6379
ping
INFO replication #查看集群信息
set name dijia
get name
随后来到从服务器:
redis-cli -a redis -h 本机ip
ping
INFO replication #只能查看本机与master机连接的信息
get name #查看是否能够获取到数据
两台都可以验证一下,若出现数据,则代表部署成功
Redis HA Sentinel集群:
Redis-Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
Sentinel的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移(failover)、主从切换。Redis的Sentinel最小配置是一主一从。 Redis的Sentinel系统可以用来管理多个Redis服务器,该系统可以执行以下四个任务:
监控
Sentinel会不断的检查主服务器和从服务器是否正常运行。
通知
当被监控的某个Redis服务器出现问题,Sentinel通过API脚本向管理员或者其他的应用程序发送通知。
自动故障转移
当主节点不能正常工作时,Sentinel会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点, 并且将其他的从节点指向新的主节点。
配置提供者
在Redis Sentinel模式下,客户端应用在初始化时连接的是Sentinel节点集合,从中获取主节点的信息。
Sentinel 通过向主服务器发送 INFO 命令来自动获得所有从服务器的地址。
跟主服务器一样,Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接。
Redis哨兵部署:
基于刚做的redis主从复制进行
与我们redis主从复制操作的配置文件不同,部署哨兵更改的配置文件是/etc/redis-sentinel.conf
一定要保证我们的防火墙、selinux关闭
首先来到主服务器进行部署
vim /etc/redis-sentinel.conf
删除所有内容后粘贴以下内容进配置文件内
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
dir /tmp
sentinel monitor mymaster 10.0.1.12 6379 2 #这里指定的是主服务器的ip地址、端口、2代表了需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
保存退出
从服务器部署:(slave-1以及slave-2)
关闭防火墙以及selinux
vim /etc/redis-sentinel.conf
删除所有内容后复制粘贴以下内容:
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile /var/log/redis/sentinel.log
dir /tmp
sentinel monitor mymaster 10.0.1.12 6379 2 #这里指定的是主服务器的ip地址、端口、2代表了需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
保存退出
之后依次启动
启动的顺序:主Redis —> 从Redis —> Sentinel1/2/3
systemctl restart redis
systemctl restart redis-sentinel.service
测试:
redis-cli -p 26379
sentinel master mymaster
来到主服务器上模拟master down掉会不会自动转移
主服务器:>systemctl stop redis
从服务器:>tailf /var/log/redis/sentinel.log #在日志内可以查看到我们的master端down掉的信息,以及新的master端被指定的信息
注意:
当我们的旧master端重新恢复连接后,配置文件内并没有指定密码,所以并不知道密码是多少,从而不能从新的master同步数据,随之导致info replication的时候,同步状态为down,所以只需要修改redis.conf中的masterauth为对应的密码即可。
具体操作:
来到旧的master端:
vim /etc/redis-sentinel.conf
添加:
masterauth 指定的密码
保存退出即可
