您的位置:首页 > 数据库 > Redis

集群与负载均衡系列(8)——redis主从复制+哨兵实现高可用性架构

2017-05-31 21:15 1216 查看



     主从复制

        redis主从复制非常简单,只需要在从数据节点配置slaveof master-ip master-port即可。我就不多说了。

     举个例子,分别创建3个配置文件,redis-6379.conf,redis-6380.conf,redis-6381.conf。在6380和6381中配置slaveof属性即可。

     启动三个redis实例

    


     查看主节点的信息

    


      随便查看1个从节点的信息

     


      这样既表示主从配置成功了。

      需要注意的是,实际环境中三个redis实例分布在不同的机器上。

      关于读写分离,可能有人注意到了,这样配置以后,在从节点是不能做写操作的,因此从节点只能读,那么这是否是意味着可以读写分离呢?说的没错,但是这样的读写分离粗糙了一点,原因是,如果从节点挂了,不能自动故障转移。这一点将在后续的文章中进行介绍。

      关于高可用性,这样做以后,简单的实现了热备,但还不具备高可用性,因为如果主节点挂了,从节点不能自动顶替主节点,而是需要人工操作,接下来介绍高可用性的实现方式——哨兵。

      哨兵

      为了解决高可用性,主节点挂了以后,从节点可以自动转换成新的主节点,redis提供了哨兵。值得注意的是,redis的版本最好是2.8及以上,不然要么不支持哨兵,要么哨兵存在bug。

      我们创建三个哨兵做一个集群,我们分别创建redis-sentinel-26379.conf、redis-sentinel-26380.conf、redis-sentinel-26381.conf三个文件做为三个哨兵的配置文件。

      一般需要配置如下配置项

     
sentinel monitor master01 127.0.0.1 6379 2 #master01为集群名称
#最后的2表示投票数,及必须有2个哨兵认为主节点挂了,才认为挂了
sentinel down-after-milliseconds master01 30000 #30000ms表示认为主节点挂了的超时时间
sentinel parallel-syncs master01 1 #表示切换主从节点时同时有多少个从节点进行复制
sentinel failover-timeout master01 180000 #表示切换主从节点超时时间

      注意:实际环境中哨兵应该部署在不同的机子上。就算是单机做实验,也最好换成实际ip,包括主从复制中的ip,不要使用127.0.0.1,原因是后续客户端代码如果不在本机上,那么通过哨兵连接池获得的主节点ip会变成127.0.0.1
      先启动一个哨兵

     



      看看是否可以顺利工作

     



      我们发现投票需要两个哨兵,现在还差一个

      把剩下的哨兵启动,再看一下是否可以顺利工作

     



      随便看一个哨兵的信息

     



      我们发现哨兵之间也是可见的。

      到此为止,哨兵就已经配置好了,整个架构如下:

     



      接下来,我们来试一下主从自动切换

      我们看一下主节点为6379

     



      我们把它关闭

     



      过一会,我们发现主节点变成6381了

     



      再开启6379节点,发现变成从节点了

     


      说明通过哨兵自动完成了主从切换。

      其实我们还可以发现,配置文件也发生了相应的变化,比如哨兵的配置文件

     


      数据节点的配置文件的slaveof也发生了变化,我就不截图了

      最后一点,高可用性还要求在主从自动切换时,能够及时地反映到客户端。

      我们可以用以下代码测试

@Test
public void sentinel(){
Set<String> sentinels=new HashSet<String>();
sentinels.add("192.168.58.145:26379");
sentinels.add("192.168.58.145:26380");
sentinels.add("192.168.58.145:26381");
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("master01",sentinels,poolConfig);
Jedis jedis=null;
try{
jedis=jedisSentinelPool.getResource();
jedis.set("hello", "world");
System.out.println(jedis.get("hello"));
}catch (Exception e) {
e.printStackTrace();
}finally{
jedis.close();
}
}

       不论怎么切换主从节点,通过哨兵连接池JedisSentinePool始终可以返回当前的主节点连接。
       注意:该代码,需要在之前的配置文件中都是用实际ip,不能是127.0.0.1或者代码运行的机子和redis机子相同。

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java web redis