redis主从
持久化的开启与主从集群是否生效无关系
Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据(注意初次同步则会阻塞)。
Replication的工作原理:
如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
缺点主节点挂了,那么就只能提供读操作了。
应用示例:
这里我们假设Master-Slave已经建立。
#启动master服务器。
[root@Stephen-PC redis]# redis-cli -p 6379
redis 127.0.0.1:6379>
#清空Master当前数据库中的所有Keys。
redis 127.0.0.1:6379> flushdb
OK
#在Master中创建新的Keys作为测试数据。
redis 127.0.0.1:6379> set mykey hello
OK
redis 127.0.0.1:6379> set mykey2 world
OK
#查看Master中存在哪些Keys。
redis 127.0.0.1:6379> keys *
1) "mykey"
2) "mykey2"
#启动slave服务器。
[root@Stephen-PC redis]# redis-cli -p 6380
#查看Slave中的Keys是否和Master中一致,从结果看,他们是相等的。
redis 127.0.0.1:6380> keys *
1) "mykey"
2) "mykey2"
#在Master中删除其中一个测试Key,并查看删除后的结果。
redis 127.0.0.1:6379> del mykey2
(integer) 1
redis 127.0.0.1:6379> keys *
1) "mykey"
#在Slave中查看是否mykey2也已经在Slave中被删除。
redis 127.0.0.1:6380> keys *
1) "mykey"
哨兵模式
哨兵模式就是监控redis系统的运行情况,主要功能有两点:
1,监控主数据库和从数据库是否正常运行。
2,主数据库出现故障时,可以自动将从数据库转换为主数据库,实现自动切换。
实现步骤
在其中一台从服务器(比如192.168.19.131)中配置sentinel.conf
vi sentinel.conf
sentinel monitor name(监控的主从集群的名称) 192.168.19.131 8089 1 #名称,ip,端口(主从集群中master的地址),投票选举次数
sentinel down-after-milliseconds name 5000 #默认1s检测一次,这里配置超时5000毫秒为宕机
sentinel failover-timeout name 900000
sentinel parallel-syncs name 2
sentinel can-fallover name yes
port 26379 #哨兵默认的端口
启动哨兵
/user/intsmaze/redis/bin/redis-server /user/intsmaze/redis/etc/sentinel.conf --sentinel &
查看哨兵相关信息
/user/intsmaze/redis/bin/redis-cli -h 192.168.19.131 -p 26379 Info sentinell
关闭主服务器查看集群信息
/user/intsmaze/redis/bin/redis-cli -h 192.168.19.131 -p 8089 shutdonwn
缺点:主节点宕机了,再切换节点时,中间有几秒无法提供服务,这几秒是用来切换的,且是无法解决的。这个时候只能在java代码中对redis的操作进行异常捕获,如果发现是宕机异常,则在catch中睡眠一秒,在重试几次即可。
或者使用两个哨兵集群进行解决,每个集群一个主,几个从。使用keepalive进行漂移,如果某个主宕机了,则keepalive则将ip飘到另一个主节点上。不需要等待从节点变为主节点。
Redis Sentinel是一个分布式系统,可以部署多个Sentinel实例来监控同一组Redis实例,它们通过Gossip协议来确定一个主实例宕机,通过Agreement协议来执行故障恢复和配置变更,一般在生产环境中部署多个实例来提高系统可用性,只要有一个Sentinel实例运行正常,就能保证被监控的Redis实例运行正常(类似Zookeeper,通过多个Zookeeper来提高系统可用性);
redis的主从读写
redis的主从读写,redis自己是无法做到的,即我们要在java客户端通过代码指定写操作请求master,读操作请求slave。
jedis提供的连接池不支持主从读写的,只支持哨兵模式。就是连接池地址是哨兵,然后所有的读写请求都是走向master,只是做到了当主节点宕机,从升级为主后,jedis的连接池会自动更改当前master的地址。
HA的关键在于避免单点故障及故障恢复
在Redis Cluster未发布之前,Redis一般以主/从方式部署(这里讨论的应用从实例主要用于备份,主实例提供读写,有不少应用是读写分离的,读写操作需要取不同的Redis实例,该方案也可用于此种应用,原理都是相通的,区别在于数据操作层如何封装),该方式要实现HA主要有如下几种方案:
1,keepalived:通过keepalived的虚拟IP,提供主从的统一访问,在主出现问题时,通过keepalived运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟IP不变),坏处是引入keepalived增加部署复杂性;
2,zookeeper:通过zookeeper来监控主从实例,维护最新有效的IP,应用通过zookeeper取得IP,对Redis进行访问;
3,sentinel:通过Sentinel监控主从实例,自动进行故障恢复,该方案有个缺陷:因为主从实例地址(IP&PORT)是不同的,当故障发生进行主从切换后,应用程序无法知道新地址,故在Jedis2.2.2中新增了对Sentinel的支持,应用通过redis.clients.jedis.JedisSentinelPool.getResource()取得的Jedis实例会及时更新到新的主实例地址。
笔者所在的公司先使用了方案1一段时间后,发现keepalived在有些情况下会导致数据丢失,keepalived通过shell脚本进行主从切换,配置复杂,而且keepalived成为新的单点,后来选用了方案3,使用Redis官方解决方案;(方案2需要编写大量的监控代码,没有方案3简便,网上有人使用方案2读者可自行查看)
1,keepalived:通过keepalived的虚拟IP,提供主从的统一访问,在主出现问题时,通过keepalived运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟IP不变),坏处是引入keepalived增加部署复杂性;
2,zookeeper:通过zookeeper来监控主从实例,维护最新有效的IP,应用通过zookeeper取得IP,对Redis进行访问;
3,sentinel:通过Sentinel监控主从实例,自动进行故障恢复,该方案有个缺陷:因为主从实例地址(IP&PORT)是不同的,当故障发生进行主从切换后,应用程序无法知道新地址,故在Jedis2.2.2中新增了对Sentinel的支持,应用通过redis.clients.jedis.JedisSentinelPool.getResource()取得的Jedis实例会及时更新到新的主实例地址。
笔者所在的公司先使用了方案1一段时间后,发现keepalived在有些情况下会导致数据丢失,keepalived通过shell脚本进行主从切换,配置复杂,而且keepalived成为新的单点,后来选用了方案3,使用Redis官方解决方案;(方案2需要编写大量的监控代码,没有方案3简便,网上有人使用方案2读者可自行查看)