sentinel、JedisSentinelPool实战

一、最小sentinel集群配置

Redis 2.8,其Sentinel版本称为Sentinel 2,是在Sentinel 1的基础上重写的。因为Sentinel 1已经废弃而且BUG太多,所以强烈建议将Redis和Sentinel均升级到2.8版本,本文中安装的版本为最新的2.8.23。

1、环境:

  • centos主机的IP:172.30.37.73
  • 在centos上安装redis软件,然后添加配置文件,启动三个redis实例;再配置成一主两从的架构;
  • 添加配置文件,启动三个sentinel实例,让这三个sentinel实例共同监控主redis实例,当主redis实例发生宕机后,进行failover;

2、redis实例、主从配置:

1)在centos上安装redis软件,然后配制成多实例:

  • 安装redis软件;
  • 在/etc/redis目录中建立6379.conf、6380.conf和6381.conf配置文件,修改其中的port、pid路径、日志、数据文件路径(配置成多实例);
  • 使用redis-server /etc/redis/*.conf 依次启动redis实例;

2)主从配置(6379为Master,其余两个为Slave):

  • 在6380和6381的配置文件中(从服务器配置文件)添加如下命令,slaveof 172.30.37.73 6379 这样重启从redis实例后就配置好了主从架构;
  • 配置Slave的slave-priority参数:6380实例该配置参数为50,6381实例该配置参数为100,这样当Master挂掉的时候Sentinel会优先选择slave-priority值较小的作为新的Master。(不同的slave其值一定要不一样,否则jedis测试时无法选取新的master)

补充:slave-priority 100配置

适用Sentinel模块(unstable,M-S集群管理和监控),需要额外的配置文件支持。slave的权重值,默认100.当master失效后,Sentinel将会从slave列表中找到权重值最低(>0)的slave,并提升为master。如果权重值为0,表示此slave为”观察者”,不参与master选举

2、sentinel实例配置:

1)分别在26379、26380和26381三个本地端口上启动三个Sentinel实例,这三个Sentinel实例用来监控上面已经启动的主Redis实例。

  • sentinel实例本质也是redis实例,由于上一步安装好了redis服务软件,所以不需要再单独安装,只需要下面的配置即可;
  • 在/etc/redis目录下建立sentinel_26379.conf、sentinel_26380.conf、sentinel_26381.conf配置文件,其内容如下(sentinel的最小配置);
  • 提前建立好sentinel的工作目录(/var/redis/sentinels/26379),然后使用命令启动sentinel实例:

    redis-sentinel /etc/redis/sentinel*.conf

    redis-server /etc/redis/sentinel
    *.conf –sentinel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
port 26379  #端口
dir /var/redis/sentinels/26379 #指定工作目录
sentinel monitor mymaster 172.30.37.73 6379 2
sentinel down-after-milliseconds mymaster 5000 #表示如果5s内mymaster没响应,就认为SDOWN
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 15000 #表示如果15秒后,mysater仍没活过来,则启动failover,从剩下的slave中选一个升级为master
logfile "/var/redis/log/sentinel_26379.log" #sentinel日志位置


port 26380
dir /var/redis/sentinels/26380
sentinel monitor mymaster 172.30.37.73 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 15000
logfile "/var/redis/log/sentinel_26380.log"


port 26381
dir /var/redis/sentinels/26381
sentinel monitor mymaster 172.30.37.73 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 15000
logfile "/var/redis/log/sentinel_26381.log"

说明:

第三行表示:监控master节点的ip和端口,最后一个数字表示投票需要的”最少法定人数”,比如有10个sentinal哨兵都在监控某一个master节点,如果需要至少6个哨兵发现master挂掉后,才认为master真正down掉,那么这里就配置为6,最小配置1台master,1台slave,在二个机器上都启动sentinal的情况下,哨兵数只有2个,如果一台机器物理挂掉,只剩一个sentinal能发现该问题,所以这里配置成1,至于mymaster只是一个名字,可以随便起,但要保证5-8行都使用同一个名字

第五行:表示如果master重新选出来后,其它slave节点能同时并行从新master同步缓存的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保定的设置为1,只同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。

2)注意:

  • 一个sentinal可同时监控多个master,如果要一个sentinel监控多个master,只要把上面6行重复多段,加以修改即可。
  • sentinel配置文件中,sentinel monitor mymaster 172.30.37.73 6379 2。 ,中的ip不能用localhost或127.0.0.1(虽然sentinel和redis实例在一台本地服务器上),否则使用jedis远程访问redis服务时就无法连接.

3、分析:

1)当启动了redis实例、sentinel实例后,各个Sentinel实例都会更新了自己的配置文件,以记录目前最新的配置信息,此时每个Sentinel实例的配置文件内容与启动之前就大不相同了。

2)当把master redis实例kill掉后,sentinel会选举一个新的master,这时redis实例的配置文件中slaveof信息也会发生变化;此外,sentinel的配置文件中sentinel monitor信息也会发生变化;

二、JedisSentinelPool使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RedisSentinelClient {

/**
* @param args
*/

public static void main(String[] args) {
Set sentinels = new HashSet();
sentinels.add(new HostAndPort("172.30.37.73", 26379).toString());
sentinels.add(new HostAndPort("172.30.37.73", 26380).toString());
sentinels.add(new HostAndPort("172.30.37.73", 26381).toString());
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);
System.out.println("Current master: " + sentinelPool.getCurrentHostMaster().toString());

Jedis master = sentinelPool.getResource();
master.set("username","liangzhichao");
sentinelPool.returnResource(master);

Jedis master2 = sentinelPool.getResource();
String value = master2.get("username");
System.out.println("username: " + value);
master2.close();
sentinelPool.destroy();
}

}

日志如下:

1
2
3
4
5
6
7
8
十二月 29, 2015 4:12:35 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Trying to find master from available Sentinels...
十二月 29, 2015 4:12:35 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Redis master running at 172.30.37.73:6379, starting Sentinel listeners...
十二月 29, 2015 4:12:36 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 172.30.37.73:6379
Current master: 172.30.37.73:6379
username: liangzhichao

当把master redis实例kill掉后,再次运行程序:

1
2
3
4
5
6
7
8
十二月 29, 2015 4:53:37 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Trying to find master from available Sentinels...
十二月 29, 2015 4:53:38 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Redis master running at 172.30.37.73:6380, starting Sentinel listeners...
十二月 29, 2015 4:53:38 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 172.30.37.73:6380
Current master: 172.30.37.73:6380
username: liangzhichao