在Redis主从复制架构中,如果master出现了故障,则需要人工将slave提升为master,同时,通知应用侧更新master的地址。这样方式比较低效,对应用侧影响较大。

为了解决这个问题,Redis 2.8中推出了自己的高可用方案Redis Sentinel。

Redis Sentinel架构图如下:

默认情况下,每个Sentinel节点会以每秒一次的频率对Redis节点和其它的Sentinel节点发送PING命令,并通过节点的回复来判断节点是否在线。

如果在down-after-millisecondes毫秒内,没有收到有效的回复,则会判定该节点为主观下线。

如果该节点为master,则该Sentinel节点会通过sentinel is-master-down-by-addr命令向其它sentinel节点询问对该节点的判断,如果超过<quorum>个数的节点判定master不可达,则该sentinel节点会将master判断为客观下线。

这个时候,各个Sentinel会进行协商,选举出一个领头Sentinel,由该领头Sentinel对master节点进行故障转移操作。

故障转移包含如下三个操作:

1. 在所有的slave服务器中,挑选出一个slave,并将其转换为master。

2. 让其它slave服务器,改为复制新的master。

3. 将旧master设置为新master的slave,这样,当旧的master重新上线时,它会成为新master的slave。

以上的所有操作对业务都是透明的,当新的master上线后,Sentinel会自动将这个变化实时通知给业务方。

那么,业务侧又该如何配置,才能扑捉到这个变化呢?

其实,这个主要取决于Redis客户端工具是否支持Redis Sentinel,对于支持的客户端工具来说,如Jedis,

只需将连接字符串设置为Sentinel地址即可。

下面,给出了一个测试代码,并模拟了master发生故障,业务侧是如何处理的?

代码如下:

package com.victor_02;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool; public class JedisSentinelTest { public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub Set<String> sentinels = new HashSet<String>();
sentinels.add("192.168.244.10:26379");
sentinels.add("192.168.244.10:26380");
sentinels.add("192.168.244.10:26381"); JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels);
Jedis jedis = null;
while (true) {
Thread.sleep(1000); try {
jedis = jedisSentinelPool.getResource(); Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String format_now = dateFormat.format(now); jedis.set("hello", "world");
String value = jedis.get("hello");
System.out.println(format_now + ' ' + value);
} catch (Exception e) {
System.out.println(e);
} finally {
if (jedis != null)
try {
jedis.close();
} catch (Exception e) {
System.out.println(e);
}
}
} }
}

模拟故障:

# ./redis-cli -p
127.0.0.1:> shutdown

上述代码的输出如下:

四月 16, 2017 10:39:44 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Trying to find master from available Sentinels...
四月 16, 2017 10:39:44 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Redis master running at 192.168.244.10:6380, starting Sentinel listeners...
四月 16, 2017 10:39:44 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 192.168.244.10:6380
2017/04/16 22:39:45 world
2017/04/16 22:39:46 world
2017/04/16 22:39:47 world
2017/04/16 22:39:48 world
2017/04/16 22:39:49 world
2017/04/16 22:39:50 world
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Software caused connection abort: recv failed
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
四月 16, 2017 10:40:21 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 192.168.244.10:6381
四月 16, 2017 10:40:21 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 192.168.244.10:6381
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
2017/04/16 22:40:22 world
2017/04/16 22:40:23 world
2017/04/16 22:40:24 world
2017/04/16 22:40:25 world
2017/04/16 22:40:26 world

从上述输出可以看出,在master发生故障前,业务侧最后一次正常处理(22:39:50),到再次正常处理是(22:40:22),中间经过了32s。

而其中30s被用来判断master节点是否主观下线(由down-after-milliseconds来指定),整个切换的过程还是比较高效的。

在Redis Sentinel环境下,jedis该如何配置的更多相关文章

  1. Redis Sentinel 情况下bind地址设置

    Redis Sentinel 情况下bind地址设置 1个master,2个slave,3个sentinel的情况下,注意bind地址的时候不要写0.0.0.0,会导致绑定多个地址, 然后sentin ...

  2. redis 在Linux下的安装与配置

    redis在Linux下的安装与配置 by:授客  QQ:1033553122 测试环境 redis-3.0.7.tar.gz 下载地址: http://redis.io/download http: ...

  3. libCURL开源库在VS2010环境下编译安装,配置详解

    libCURL开源库在VS2010环境下编译安装,配置详解 转自:http://my.oschina.net/u/1420791/blog/198247 http://blog.csdn.net/su ...

  4. 联想电脑win7旗舰版环境下的如何成功配置AppServ

    联想电脑win7旗舰版环境下的如何成功配置AppServ 毕业设计中需要用Mysql数据库,并且想找一个方便Mysql数据库编程的开发工具,百度搜索了一下,AppServ集成环境安装包能快速搭建环境. ...

  5. 实验七:Xen环境下cirrOS的安装配置

    实验名称: Xen环境下cirrOS的安装配置 实验环境: 这里的cirrOS和实验六中的busybox的启动方式相同,唯一的区别就是我们使用的cirrOS镜像中,已经包含了根文件系统.内核文件以及r ...

  6. 【转】mysql8.0 在window环境下的部署与配置

    [转]mysql8.0 在window环境下的部署与配置 今天在阿里云window服务器上配置mysql环境,踩了一些坑,分享出来.需要的朋友可以看看.额,或许有人要吐槽我为什么不在linux上去配置 ...

  7. Linux环境下NodeJS的安装配置(HelloWorld)

    Linux环境下NodeJS的安装配置(HelloWorld) 最简单的环境安装,测试helloworld.给初学者!! 安装脚本,请仔细阅读逐行执行: #!/bin/bash #检查是否已经安装 r ...

  8. GITHUB个人博客搭建-Pelican 在Windows环境下的安装及配置

    GITHUB个人博客搭建-Pelican 在Windows环境下的安装及配置 前言 此篇博客主要为Pelican在Windows平台下的配置安装所写,在此过程中主要参考资料烟雨林博客.poem_of_ ...

  9. Mac 环境下svn服务器的配置

    Mac 环境下svn服务器的配置 本文目录 • 一.创建代码仓库,用来存储客户端所上传的代码 • 二.配置svn的用户权限 • 三.使用svn客户端功能 在Windows环境中,我们一般使用Torto ...

随机推荐

  1. springMVC源码分析--容器初始化(二)DispatcherServlet

    在上一篇博客springMVC源码分析--容器初始化(一)中我们介绍了spring web初始化IOC容器的过程,springMVC作为spring项目中的子项目,其可以和spring web容器很好 ...

  2. iOS中 支付宝钱包详解/第三方支付 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! iOS开发者交流QQ群: 446310206 一.在app中成功完成支付宝支付的过程 1.申请支付宝钱包.参考网址 ...

  3. UNIX环境高级编程——线程属性之并发度

    并发度控制着用户级线程可以映射的内核线程或进程的数目.如果操作系统的实现在内核级的线程和用户级的线程之间保持一对一的映射,那么改变并发度并不会有什么效果,因为所有的用户级线程都可能被调度到.但是,如果 ...

  4. python类:属性

    http://blog.csdn.net/pipisorry/article/details/50708616 Python 中的 property 属性 Python中有个很赞的概念,叫做prope ...

  5. Android的图片,字符串,demin,color,以及Array,boolean,Integer资源的使用-android学习之旅(五十四)

    总体介绍 颜色值的定义 定义字符串,颜色,尺寸资源 字符串 颜色资源 尺寸资源 使用字符串,颜色,尺寸资源 boolean的定义与使用 整形常量的定义与使用 数组资源的定义与使用 图片资源的使用

  6. iOS平台添加Google Admob -2/2(Unity3D开发之八)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=572 在上一篇文章中主要是编写了 ...

  7. Mybatis源码分析之结果封装ResultSetHandler和DefaultResultSetHandler

    ResultSetHandler负责处理两件事: (1)处理Statement执行后产生的结果集,生成结果列表 (2)处理存储过程执行后的输出参数ResultSetHandler是一个接口,提供了两个 ...

  8. UNIX环境高级编程——system V信号量

    1. 信号量(semaphore)主要用于保护临界资源.进程可以根据它判断是否能访问某些共享资源.信号量除了用于访问控制外,还可用于进程同步,也就是进程间通信.2. 信号量分类:a. 二值信号量: 信 ...

  9. Gradle 笔记——Java构建入门

    Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建代 ...

  10. 打包自己的aar库

    在比较大的 Android 项目的开发中,我们经常会遇到工程.jar 包等等之间相互引用的方式.一般我们通过在 gradle 文件中配置依赖来解决,但是如果通过include的方式来引入第三方库的时候 ...