redis 主从复制的问题



Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:



1,一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。



2,扩展主节点的读能力,分担主节点读压力。



问题:



1,一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。



2,主节点的写能力受到单机的限制。



3,主节点的存储能力受到单机的限制。



 



 



Redis Sentinel 高可用方案



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



 



1 部署主节点



#主节点配置文件



port 6379 



daemonize yes 



logfile "6379.log" 



dbfilename "dump-6379.rdb" 



dir "/var/redis/data/"



#启动主节点



redis-server redis-6379.conf



#检测主节点是否启动



➜ redis-cli -h 127.0.0.1 -p 6379 ping



PONG



2 部署从节点



port 6380 



daemonize yes 



logfile "6380.log" 



dbfilename "dump-6380.rdb"



 dir "/var/redis/data/" 



slaveof 127.0.0.1 6379 // 从属主节点   新版本的使用  replicaof <masterip><masterport>



#启动两个从节点



➜ redis-server redis-6380.conf



➜ redis-server redis-6381.conf



3 查看主从信息



➜   redis-cli -h 127.0.0.1 -p 6379 INFO replication



# Replication



role:master



connected_slaves:2



slave0:ip=127.0.0.1,port=6380,state=online,offset=85,lag=0



slave1:ip=127.0.0.1,port=6381,state=online,offset=85,lag=0



➜   redis-cli -h 127.0.0.1 -p 6380 INFO replication



# Replication



role:slave



master_host:127.0.0.1



master_port:6379



master_link_status:up



4 部署sentinel 节点



// Sentinel节点的端口



port 26379  



dir /var/redis/data/



logfile "26379.log"



 



// 当前Sentinel节点监控 127.0.0.1:6379 这个主节点



// 2代表判断主节点失败至少需要2个Sentinel节点节点同意



// mymaster是主节点的别名



sentinel monitor mymaster 127.0.0.1 6379 2



 



//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达



sentinel down-after-milliseconds mymaster 30000



 



//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1



sentinel parallel-syncs mymaster 1



 



//故障转移超时时间为180000毫秒



sentinel failover-timeout mymaster 180000



 



启动sentinel



redis-sentinel sentinel-26379.conf --sentinel



 



 



查看sentinel



➜   redis-cli -h 127.0.0.1 -p 26379 INFO Sentinel



# Sentinel



sentinel_masters:1



sentinel_tilt:0



sentinel_running_scripts:0



sentinel_scripts_queue_length:0



sentinel_simulate_failure_flags:0



master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=1 //sentinels=1表示启动了1个Sentinel



当启动所有的sentinel后配置文件变化



port 26379



dir "/var/redis/data"



sentinel myid 70a3e215c1**8



sentinel monitor mymaster 127.0.0.1 6379 2



sentinel config-epoch mymaster 0



sentinel leader-epoch mymaster 0



daemonize yes



logfile "26379.log"



// 发现了两个从节点



sentinel known-slave mymaster 127.0.0.1 6381



sentinel known-slave mymaster 127.0.0.1 6380



// 发现了两个Sentinel节点



sentinel known-sentinel mymaster 127.0.0.1 26381 e1148ad6ca***



sentinel known-sentinel mymaster 127.0.0.1 26380 39db5b040***



sentinel current-epoch 0



 



 



故障转移试验



1,干掉6379 主节点



127.0.0.1:26379> sentinel masters



1)  1) "name"



    2) "mymaster"



    3) "ip"



    4) "127.0.0.1"



    5) "port"



    6) "6380"           //可以看到主节点已经成为6380端口的节点



    7) "runid"



    8) "084850ab4ff6***"



    9) "flags"



   10) "master"



    ..............



 



 



27.0.0.1:26379> sentinel slaves mymaster



1)  1) "name"



    2) "127.0.0.1:6379"             //ip:port



    3) "ip"



    4) "127.0.0.1"



    5) "port"



    6) "6379"



    7) "runid"



    8) ""



    9) "flags"



   10) "s_down,slave,disconnected"  //端口6379的原主节点已经断开了连接



   ..............



2)  1) "name"



    2) "127.0.0.1:6381"             



    3) "ip"



    4) "127.0.0.1"



    5) "port"



    6) "6381"



    7) "runid"



    8) "24495fe180e4fd64ac4***"



    9) "flags"



   10) "slave"                      //本来的从节点,还是从节点的role



    ..............



2,重启之前的6379节点



127.0.0.1:26379> sentinel slaves mymaster



1)  1) "name"



    2) "127.0.0.1:6379"     //6379端口的节点重启后,变成了"活"的从节点



    3) "ip"



    4) "127.0.0.1"



    5) "port"



    6) "6379"



    7) "runid"



    8) "de1b5c28483cf150****"



    9) "flags"



   10) "slave"



    ..............



2)  1) "name"               //6381端口的节点没有变化,仍是从节点



    2) "127.0.0.1:6381"