redis主从设置

一、配置Redis主从注意事项

1、Redis Slave 也需要开启RDB持久化
2、配置与Master同样的连接密码    #因为后期slave会有提升为master的可能,Slave端切换master同步后会丢失之前的所有数据
3、配置主从前,redis只有配置文件以及命令执行文件,删除其他所有文件
4、slave服务器一般为read-only

一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的所有数据并将master的数据导入到自己的内存。
但是断开同步关系后不会删除当前已经同步过的数据,不然slave就没有数据了。 

redis的主可以读写,redis从只可以读。

二、配置主从(命令方式或修改配置文件 二选一)
只需要在slave服务器上配置即可,master不需要配置。

2.1 命令方式配置主从
#版本4(包括版本4)之前命令为slaveof,版本4之后为REPLICAOF
10.0.0.32:6379> SLAVEOF 10.0.0.31 6379
OK
10.0.0.32:6379> CONFIG SET masterauth 123456
OK

2.2 修改配置文件方式配置主从
root@ubuntu1804:~# vim /apps/redis/etc/redis.conf
########### REPLICATION ###########
slaveof 10.0.0.31 6379
masterauth 123456
 

三、查看matser和slave的info信息

10.0.0.31:6379> INFO
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.32,port=6379,state=online,offset=616,lag=0

10.0.0.32:6379> INFO
# Replication
role:slave
master_host:10.0.0.31
master_port:6379
master_link_status:up

 四、同步日志

slave的redis日志文件
redis主从设置_第1张图片

五、主从复制详细过程
Redis支持主从复制分为全量同步和增量同步,首次同步是全量同步。
redis 的主从同步是非阻塞的,master收到从服务器的sync(2.8版本之前是PSYNC)命令会fork一个子进程在后台执行bgsave命令,并将新写入的数据写入到一个缓冲区里面,bgsave执行完成之后并生成的将RDB文件发送给客户端,客户端将收到后的RDB文件载入自己的内存,然后redis master再将缓冲区的内容在全部发送给redis slave。
之后的同步slave服务器会发送一个offset的位置(等同于MySQL的binlog的位置)给主服务器,主服务器检查后位置没有错误将此位置之后的数据包括写在缓冲区的积压数据发送给redis从服务器,从服务器将主服务器发送的导入数据写入内存,这样一次完整的数据同步,再之后再同步的时候从服务器只要发送当前的offset位 置给主服务器,然后主服务器根据相应的位置将之后的数据发送给从服务器保存到其内存即可。

Redis全量复制一般发生在Slave首次初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体主从同
步骤如下:
1)从服务器连接主服务器,发送SYNC命令; 
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的所有写命令; 
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令; 
7)后期同步会先发送自己slave_repl_offset位置,只同步新增加的数据,不再全量同步。

 redis主从设置_第2张图片

六、主从同步配置参数优化

repl-diskless-sync no #是否使用无盘同步RDB文件,默认为no,no为不使用无盘,将rdb保存到磁盘再发给slave
repl-diskless-sync-delay 5 #Master准备好RDB文件后等等待传输时间
repl-ping-slave-period 10 #slave端向server端发送ping的时间区间设置,默认为10秒 
repl-timeout 60 #设置超时时间
repl-disable-tcp-nodelay no #是否启用TCP_NODELAY,如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成master与slave数据不一致,假如设置成no,则redis master会立即发送同步数据,没有延迟,前者关注性能,后者关注redis服务中的数据一致性。
repl-backlog-size 3072mb #master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令。
repl-backlog-ttl 3600 #如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则表示永远不释放这部份内存。
slave-priority 100 #slave端的优先级设置,值是一个整数,数字越小表示优先级越高。当master故障时将会按照优先级来选择slave端进行恢复,如果值设置为0,则表示该slave永远不会被选择。

min-slaves-to-write 1 #设置一个master端的可用slave少于多少个 
min-slaves-max-lag 20 #设置所有slave延迟时间都大于多少秒时,master不接收写操作(拒绝写入)。

七、主从切换
关掉master的redis

10.0.0.31:6379> SHUTDOWN

slave的redis目前为只读,没办法写入数据

10.0.0.32:6379> set a b
(error) READONLY You can't write against a read only slave.

需要将slave角色提升为master

10.0.0.32:6379> SLAVEOF no one
OK
10.0.0.32:6379> set a b
OK
10.0.0.32:6379> INFO
# Replication
role:master
connected_slaves:0

无法连接的问题


1确保所有机器ping 得通

2 如果设置在主中设置了密码,从中应该配置密码

3 bind ip地址  表示可以那些机器可以访问

设置为 0.0.0.0 表示都可以访问

如果是127.0.0.1 表示localhost访问 

如果不设置从就没有访问主的权限

修改方法修改redis 的redis.conf 配置文件

#bind 127.0.0.1 ::1
bind 0.0.0.0

常见问题汇总
1 master密码不对
配置的master密码不对,导致验证不通过而无法建立主从同步关系

redis主从设置_第3张图片
2 Redis版本不一致
不同的redis 版本之间存在兼容性问题,因此各master和slave之间必须保持版本一致。
RDB文件互相识别不了,无法加载RDB文件

redis主从设置_第4张图片

下面没实践就当是增长知识吧

三、Redis Sentinel(哨兵)架构下的高可用
Redis的主从复制下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方法是无法接受的。但是Redis从2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。

        Redis Sentinel是一个分布式架构,其中包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行“协商”,当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化通知给Redis应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了Redis的高可用问题。

实现原理:

三个定时监控任务
1)每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。

2)每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息,同时每个Sentinel节点也会订阅该频道,来了解其他Sentinel节点以及它们对主节点的判断。

3)每隔一秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达。

主观下线
因为每隔一秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,当这些节点超过down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。

客观下线
当Sentinel主观下线的节点是主节点时,该Sentinel节点会向其他Sentinel节点询问对主节点的判断,当超过个数,那么意味着大部分的Sentinel节点都对这个主节点的下线做了同意的判定,于是该Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定。

领导者Sentinel节点选举
Raft算法:假设s1(sentinel-1)最先完成客观下线,它会向其余Sentinel节点发送命令,请求成为领导者;收到命令的Sentinel节点如果没有同意过其他Sentinel节点的请求,那么就会同意s1的请求,否则拒绝;如果s1发现自己的票数已经大于等于某个值,那么它将成为领导者。

故障转移
1)领导者Sentinel节点在从节点列表中选出一个节点作为新的主节点

2)上一步的选取规则是与主节点复制相似度最高的从节点

3)领导者Sentinel节点让剩余的从节点成为新的主节点的从节点

4)Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点

1.实验环境 (首先搭建好Redis环境并可以进行主从同步)
系统版本:rhel6.5

server3:172.25.254.103  redis-slave

server4:172.25.254.104 redis-slave

server2:172.25.254.101  redis-master

2.主节点操作
1)在安装包中将 sentinel 文件复制到/etc/redis/下

[root@server2 ~]# cd redis-4.0.1
[root@server2 redis-4.0.1]# cp sentinel.conf /etc/redis/
[root@server2 redis-4.0.1]# cd /etc/redis/

2)修改配置文件
[root@server2 redis]# vim sentinel.conf

关闭保护模式

 

第98 行  Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的IP 地址为 172.25.154.101,端口号为 6379 ,而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意 (只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)
如:

sentinel monitor mymaster 172.25.254.101 6379 2

3)将配置好的文件发送给所有从节点

[root@server2 redis]# scp sentinel.conf [email protected]:/etc/redis/
sentinel.conf                                    100% 7609     7.4KB/s   00:00    
[root@server2 redis]# scp sentinel.conf [email protected]:/etc/redis/
sentinel.conf                                    100% 7609     7.4KB/s   00:00

4)三台redis 开启 sentinel 服务

[root@server2 redis]# redis-sentinel /etc/redis/sentinel.conf

 

两台slave
[root@server3 ~]# redis-sentinel /etc/redis/sentinel.conf

 

[root@server4 ~]# redis-sentinel /etc/redis/sentinel.conf

 

+slave 表示 :一个新的从服务器已经被 Sentinel 识别并关联 可以看到片此时 master 是 server2;server3和 server4 是 slave。

3.测试
1)停掉现在的Redis-master  info 查看 replication 信息

[root@server2 ~]# redis-cli -p 26379
127.0.0.1:26379> info
master0:name=mymaster,status=ok,address=172.25.254.101:6379,slaves=2,sentinels=3[root@server2 ~]# redis-cli
127.0.0.1:6379> SHUTDOWN
not connected>
[root@server2 ~]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
[root@server2 ~]# redis-cli -p 26379
127.0.0.1:26379> info
master0:name=mymaster,status=ok,address=172.25.254.102:6379,slaves=2,sentinels=3
127.0.0.1:26379>

2)查看任意一台redis主机的监控日志

[root@server4 ~]# redis-sentinel /etc/redis/sentinel.conf

 

+switch-master :配置变更,主服务器的 IP 和地址已经改变 由之前的172.25.254.101 更改为172.25.254.102。
+sdown :给定的实例 server2现在处于主观下线状态。
在原先的master被停掉后,通过选举产生新的master 172.25.254.102 6379

实际现在只有一个slave 可以使用

四、Redis Cluster(集群)下的高可用
实现原理:

主观下线
       集群中每个节点都会定期向其他节点发送ping消息,接受节点回复ping消息作为响应。如果在cluster-node-timeout时间内通信一直失败,则发送节点会认为接收节点存在故障,把接受节点标记为主观下线(pfail)状态。

客观下线
1)当某个节点判断另一个节点主观下线后,相应的节点状态会跟随消息在集群内传播。

2)假设节点a标记节点b为主观下线,一段时间后节点a通过消息把节点b的状态发送到其他节点,当其他节点收到消息并解析出消息体中含有b的pfail状态,把节点b加入下线报告链表;

3)当某一节点c收到节点b的pfail状态时,此时有超过一半的槽主节点都标记了节点b为pfail状态时,则标记故障节点b为客观下线;

4)向集群广播一条pfail消息,通知集群内的所有节点标记故障节点b为客观下线状态并立刻生效,同时通知故障节点b的从节点触发故障转移流程。

故障恢复
1)资格检查

若从节点与主节点断线时间超过一定时间,则不具备资格
2)准备选举时间

当从节点符合故障转移资格后,要等待一段选举时间后才开始选举

在故障节点的所有从节点中,复制偏移量最大的那个从节点最先开始(与主节点的数据最一致)进行选举,然后是次大的节点开始选举.....剩下其余的从节点等待到它们的选举时间到达后再进行选举
3)发起选举
4)选举投票

只有持有槽的主节点才具有一张唯一的选票,从从节点收集到N/2 + 1个持有槽的主节点投票时,从节点可以执行替换主节点操作
5)替换主节点

当从节点收集到足够的选票之后,触发替换主节点操作

当前从节点取消复制变为主节点
撤销故障主节点负责的槽,并把这些槽委派给自己
向集群广播自己的pong消息,通知集群内所有的节点当前从节点变为主节点并接管了故障主节点的槽信息
1.实验环境:
使用任意一台redis 主机 

2.部署高可用
1)搭建环境

[root@server2 redis]# /etc/init.d/redis_6379 stop

cd /usr/local/ mkdir cluster ##建立集群目录

[root@server2 local]# cd cluster/
[root@server2 cluster]# pwd
/usr/local/cluster
[root@server2 cluster]# mkdir 700{1..6}
[root@server2 cluster]# ll
total 24
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7001
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7002
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7003
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7004
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7005
drwxr-xr-x 2 root root 4096 Oct  9 11:02 7006
[root@server2 cluster]# cd 7001/

[root@server2 7001]# vim redis.conf
[root@server2 ~]# cat /usr/local/cluster/7001/redis.conf
port 7001
cluster-enabled yes        #打开集群设备

cluster-config-file nodes.conf
cluster-node-timeout 5000     #延时时间
appendonly yes
daemonize yes

pidfile /usr/local/cluster/7001/redis.pid ##pid文件存放目录

logfile /usr/local/cluster/7001/redis.log ##日志存放目录

[root@server2 7001]# redis-server redis.conf          ###打开集群服务

 

[root@server2 cluster]# cp 7001/redis.conf 7002/
[root@server2 cluster]# cp 7001/redis.conf 7003/
[root@server2 cluster]# cp 7001/redis.conf 7004/
[root@server2 cluster]# cp 7001/redis.conf 7005/
[root@server2 cluster]# cp 7001/redis.conf 7006/

[root@server2 cluster]# cd 7002/

[root@server2 7002]# vim redis.conf  ###将文件中的端口号改为7002和存放目录的更改

redis-server redis.conf ###打开集群的redis

cd ..

cd 7003/ vim redis.conf ###将文件中的端口号改为7003和存放目录的更改

redis-server redis.conf ###打开集群的redis

cd ..

cd 7004/ vim redis.conf ###将文件中的端口号改为7004和存放目录的更改

redis-server redis.conf ###打开集群的redis

cd ..

cd 7005/

vim redis.conf ###将文件中的端口号改为7005和存放目录的更改

redis-server redis.conf ###打开集群的redis

cd ..

cd 7006/ vim redis.conf ###将文件中的端口号改为7006和存放目录的更改

redis-server redis.conf ###打开集群的redis
ps ax ##查看进程是否都打开了
netstat -antlp ##查看端口号是否开启

[root@server2 ~]# cd redis-4.0.1
[root@server2 redis-4.0.1]# cd src/
[root@server2 src]# cp redis-trib.rb /usr/local/bin/
[root@server2 src]# yum install -y ruby
[root@server2 ~]# yum install -y rubygems-1.3.7-5.el6.noarch.rpm

[root@server2 ~]# rpm -Uvh ruby-2.2.3-1.el6.x86_64.rpm
[root@server2 ~]# yum install -y  ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server2 ~]# gem install --local redis-4.0.1.gem

 

2)创建集群

[root@server2 ~]# redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

 

 

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> set name linux
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002>

[root@server2 ~]# redis-cli -c -p 7006
127.0.0.1:7006> set name kb
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"kb"
127.0.0.1:7002>

redis-cli -c -p 7001
登录,set name linux 写入内容,会提示写入内容传到2上
redis-cli -c -p 7002

输入info,发现2是master,他的slave是6

3)测试

停掉master 2

[root@server2 ~]# redis-cli -c -p 7002
127.0.0.1:7002> SHUTDOWN
not connected>

redis-trib.rb check 127.0.0.1:7001 ##查看集群的状态

 

可以查看之前的内容

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> get name
-> Redirected to slot [5798] located at 127.0.0.1:7005
"kb"
127.0.0.1:7005>

再关掉一个master

[root@server2 ~]# redis-cli -c -p 7005
127.0.0.1:7005> SHUTDOWN
not connected>

查看信息

 

关闭掉两个master后,集群的功能会破坏

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> get name
(error) CLUSTERDOWN The cluster is down
127.0.0.1:7001>

4)恢复关闭的两个节点

[root@server2 ~]# cd /usr/local/cluster/
[root@server2 cluster]# ls
7001  7002  7003  7004  7005  7006
[root@server2 cluster]# cd 7002
[root@server2 7002]# redis-server redis.conf
1292:C 09 Oct 11:40:46.513 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1292:C 09 Oct 11:40:46.513 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1292, just started
1292:C 09 Oct 11:40:46.513 # Configuration loaded
[root@server2 7002]# cd ..
[root@server2 cluster]# cd 7005
[root@server2 7005]# redis-server redis.conf
1298:C 09 Oct 11:41:15.609 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1298:C 09 Oct 11:41:15.609 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1298, just started
1298:C 09 Oct 11:41:15.609 # Configuration loaded

 

高可用搭建成功
 

 

你可能感兴趣的:(redis,数据库)