redis分布式

概述

Redis哨兵为Redis提供了高可用性。可以使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis部署。

哨兵模式还提供了其他的附加功能,如监控,通知,为客户端提供配置。

下面是在宏观层面上哨兵模式的功能列表:

  • 监控:哨兵不断的检查master和slave是否正常的运行。
  • 通知:当监控的某台Redis实例发生问题时,可以通过API通知系统管理员和其他的应用程序。
  • 自动故障转移:如果一个master不正常运行了,哨兵可以启动一个故障转移进程,将一个slave升级成为master,其他的slave被重新配置使用新的master,并且应用程序使用Redis服务端通知的新地址。
  • 配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址。

特性

Redis哨兵是一个分布式系统:

哨兵自身设计成和多个哨兵进程一起合作运行。这样做的好处有:

  • 当多个哨兵对一个master不再可用达成一致时执行故障检测。这会降低错误判断的概率。
  • 只要大多数哨兵正常运行就可以,增强系统健壮性。毕竟在故障系统里单点故障没有什么意义。

哨兵部署和故障转移过程

下面以部署三个哨兵为例(配置quorum = 2):

  • Box:代表服务器
  • Redis:代表Redis实例
  • Sentinel:代表Redis哨兵实例
  • Client:代表连接到Redis的客户端
  • Redis1:为master
  • Redis2和Redis3为Redis1的Slave
  • 其中三个哨兵都监控Master1;

下面是Box1主机发生故障之后的转移过程:

  1. Sentinel2检测到Box1故障,标记状态为SDOWN;
  2. Sentinel3检测到Box1故障,标记状态为SDOWN;
  3. 因标记SDOWN状态数量 >= 配置的quorum ,标记Redis实例状态为ODOWN,触发故障转移;
  4. 通过算法选举出一个Leader(如Sentinel2);
  5. Sentinel2请求其他Sentinel(Sentinel3)的授权(注意这里需要得到半数以上的哨兵授权);
  6. Sentinel2得到授权后通过算法选举出合适的Slave(如Slave2)晋升为Master;
  7. Sentinel更改配置监听新Master,并把其他的Redis配置为新Master的Slave;
  8. 通知客户端连接新Master。

使用

使用之前需要知道的事情

  • 一个健壮的部署至少需要三个哨兵实例
  • 三个哨兵实例最好放在三个不同的物理机上
  • 使用的客户端必须支持哨兵(一般流行的都支持)

服务端配置(运维部同事需仔细看看)

sentinel.conf(注意所有哨兵配置都相同)
# port <sentinel port>
#
# 哨兵实例运行端口
port 26379
# sentinel monitor <master- name > <ip> <redis-port> <quorum>
#
# 配置监控master
#
# <master- name >:配置监控master实例名字
# <ip>:Redis master所在IP
# <redis-port>:Redis master运行端口
# <quorum>: 至少<quorum>个同意,master才能进入o_down状态触发故障转移
#
# 示例:
sentinel monitor mymaster 192.168.45.136 6379 2
#
# sentinel auth-pass <master- name > < password >
# 配置连接master的授权密码
#
# <master- name >:配置监控master实例名字
# < password >:Redis master密码
#
# 示例:
sentinel auth-pass mymaster 123456
# sentinel down- after -milliseconds <master- name > <milliseconds>
#
# 配置master被认为是不可用的时间,超过这个时间即标为S_DOWN
#
# <master- name >:监控master实例名字
# <milliseconds>:毫秒,默认30秒
#
# 示例:
sentinel down- after -milliseconds mymaster 1000
# sentinel failover-timeout <master- name > <milliseconds>
#
# 设置故障转移超时时间,默认3分钟
#
# <master- name >:master实例名字
# <milliseconds>:毫秒,默认3分钟
#
# 示例:
sentinel failover-timeout mymaster 5000
# sentinel parallel-syncs <master- name > <numslaves>
#
# 故障转移的同时,重新配置slave指向的数量。
#
# <master- name >:master实例名字
# <numslaves>:Slave数量
#
# 示例:
sentinel parallel-syncs mymaster 1
# sentinel client-reconfig-script <master- name > <script-path>
#
# 发生故障转移后执行的脚本
# 输出参数:<master- name > <role> <state> < from -ip> < from -port> < to -ip> < to -port>
# <master- name >:master实例名字
# <script-path>:shell脚本绝对路径
#
# 示例:
sentinel client-reconfig-script mymaster /home/mjw/testfunc.sh
redis.conf
//配置master授权密码
masterauth  123456
//配置master密码
requirepass  123456
//配置slave(注意master不用此配置)
slaveof <masterip> <masterport>
 

 

客户端代码示例

使用哨兵代码非常简单,只需要在客户端改动一下连接方式即可(注意连接的是哨兵的地址

连接哨兵客户端示例
public  static  void  testSentinel(){
         Set<String> sentinels =  new  HashSet<String>();
         //注意,这里是哨兵的地址
         sentinels.add( "192.168.45.142:26379" );
         sentinels.add( "192.168.45.143:26379" );
         sentinels.add( "192.168.45.144:26379" );
         
         GenericObjectPoolConfig config =  new  GenericObjectPoolConfig();
         config.setMinIdle( 1 );
         config.setTestOnBorrow( true );
         
         //mymaster:哨兵配置监控的Redis实例名字
         //123456:密码
         JedisSentinelPool pool =  new  JedisSentinelPool( "mymaster" , sentinels,config, "123456" );
         
             
             for ( int  i =  0 ;i <  100000 ;i++){
                 Jedis jedis =  null ;
                 try  {
                     Thread.sleep( 1000 );
                     jedis = pool.getResource();
                     jedis.set( "testSentinel"  + i,  "testSentinelValue"  + i);
                     System.out.println(jedis.get( "testSentinel"  + i));
                     
                 catch  (Exception e) {
                     System.out.println( new  SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new  Date()));
                     System.out.println( "error!" + e.getMessage());
                 } finally {
                     if  (jedis !=  null ) {
                         try  {
                             jedis.close();
                         catch  (Exception e) {
                             e.printStackTrace();
                         }
                     }
                 }
             }
         
     }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值