上篇文章介绍了如何在多台机器上快速部署多个redis服务实例。在此基础上,本文继续玩转redis集群——搭建redis哨兵模式。

一、搭建目标

    本文要搭建一主两从的sentinel服务集群,准备好三台虚拟机,每台机器部署一个redis实例服务和一个sentinel哨兵服务,其中选定10.7.3.88机器上的redis服务为Master,其他两台机器的redis服务为Slave。具体如下:

机器IP | redis实例 | sentinel服务
---|---|---
10.7.3.88 | 实例1(6379),主 | yes
10.7.3.50 | 实例1(6379),从 | yes
10.7.3.60 | 实例1(6379),从 | yes

    集群搭建后,其中任意一个redis服务down掉后,该集群继续可用。本文最后通过Java程序代码来验证其高可用性。

二、搭建步骤

1、设置主从服务

    redis主从配置非常简单,有两种方式:文件配置和命令配置。文件配置是永久性的,命令配置是临时有效的。不过,这两种方法的共同点是只需要对从服务进行设置。下面分别介绍两种方式:

  • 文件配置,修改从redis服务的配置文件,加上如下内容:
slaveof 10.7.3.88 6379
  • 命令配置,连接从redis服务,执行如下命令即可:
slaveof 10.7.3.88 6379
# slaveof no one #取消主从配置

    按照上述方法分别对10.7.3.50和10.7.3.60上的redis服务进行设置,设置完成之后可以通过如下命令进行查看主从配置信息:

redis-cli info replication

    主从配置,主服务可写可读,从服务只能读取。

    主从配置测试,可以先通过在主服务写入数据,然后再登录其服务查看刚才写入的数据,如果一致,则表示主从配置顺利完成。如果数据不一致,请先检查是否因为防火墙导致数据传输失败。

2、配置sentinel服务

    配置内容入下:

## sentinel实例之间的通讯端口,不同的sentinel服务实例不同端口号,本文选取26379,26479,26579
port 26379 
protected-mode yes
bind 0.0.0.0
daemonize yes
logfile "/var/redis/sentinel.log"
## 此指令最后一个参数为<quorum>,表示选举时至少有quorum个sentinel实例推选某redis,它才能成为master
sentinel monitor mymaster 10.7.3.88 6379 2
## 如果服务器在给定的毫秒数之内没有响应,那么 Sentinel 将这个服务器标记为主观下线(subjectively down,简称 SDOWN )
sentinel down-after-milliseconds mymaster 5000
## 不同sentinel并不会同时对同一个master做failover操作,failover操作间隔时间设置
sentinel failover-timeout mymaster 15000
## 指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
sentinel parallel-syncs mymaster 1

    上节已经确定主redis服务为10.7.3.88:6379,所以配置文件中定义该服务为主服务,服务名mymaster。其他从服务的sentinel配置,只需要修改port即可。

3、命令测试sentinel服务

    输入如下命令,强制主服务失效,然后观察日志。

redis-cli -p 10.7.3.88 -p 26379
sentinel failover mymaster

    日志输出信息:

1.png

如上图,10.7.3.50上的redis服务成为主服务,其他两台机器上的redis服务变为从服务,表示主服务失效后,从服务成功升级为主服务,保证了sentinel集群可用性。

4、Java代码测试sentinel服务

    直接上代码,喜欢研究的同学可以阅读源码。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

/**
 * 对Sentinel集群进行测试
 *
 * @author xiaoh
 * @create 2018-01-23 9:36
 **/
public class SentinelTest {
    public static void main(String[] args) {
        Set<String> sentinels = new HashSet<>();
        sentinels.add("10.7.3.88:26379");
        sentinels.add("10.7.3.50:26479");
        sentinels.add("10.7.3.60:26579");
        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);

        Jedis jedis = pool.getResource();
        String value = jedis.get("tt");
        if(value == null) {
            jedis.set("tt", "c++");
        } else {
            System.out.println(value);
        }

        jedis.close();
        pool.destroy();
    }
}

    首先,正常情况下运行一次该代码。然后kill掉10.3.7.88上的sentinel服务,运行一次代码,再将10.3.7.88上的redis服务停掉,运行一次代码。如果三次代码都能正确运行,则表示我们的目标已经达成,给自己点个赞吧!

文章作者:xiaohui249
本文链接:http://javatech.wang/index.php/archives/105/
版本所有 ©转载时必须以链接形式注明作者和原始出处