Redis-sentinel

Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance),Redis 的 Sentinel 为Redis提供了高可用性。使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis部署。

该系统执行以下三个任务:

监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否允许正常。
提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): (1)当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,他会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;
(2)客户端试图连接失败的主服务器时,集群也会向客服端返回新主服务器的地址,是的集群可以使用新主服务器代替失效服务器。
 sentinel的分布式特性
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。

单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:

有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;

如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);

如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息

一个健壮的部署至少需要三个哨兵实例。

关于redis主从复制的一些特点:
1.一个master可以有多个slave
2.除了多个slave连到相同的master外,slave也可以连接其他slave形成图状结构
3.主从复制不会阻塞master。也就是说当一个或多个slave与master进行初次同步数据时,master可以继续处理client发来的请求。相反slave在初次同步数据时则会阻塞不能处理client的请求。
4.主从复制可以用来提高系统的可伸缩性,我们可以用多个slave 专门用于client的读请求,比如sort操作可以使用slave来处理。也可以用来做简单的数据冗余
5.可以在master禁用数据持久化,只需要注释掉master 配置文件中的所有save配置,然后只在slave上配置数据持久化。
6.可以用于读写分离和容灾恢复。

新建sentinel.conf文件

# 这个是Redis6379配置内容,其他文件同理新增然后改一下端口即可,26380
#当前Sentinel服务运行的端口
protected-mode no
port 26381
# 哨兵监听的主服务器 后面的1表示主机挂掉以后进行投票,只需要1票就可以从机变主机
sentinel monitor mymaster 127.0.0.1 6379 2
# 3s内mymaster无响应,则认为mymaster宕机了
sentinel down-after-milliseconds mymaster 3000
#如果10秒后,mysater仍没启动过来,则启动failover  
sentinel failover-timeout mymaster 10000  
# 执行故障转移时, 最多有1个从服务器同时对新的主服务器进行同步
sentinel parallel-syncs mymaster 1
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码,没有的话不用设置
sentinel auth-pass mymaster 123456

在2个文件夹下面都放入此文件,只是端口不同分别启动2个redis以及2个哨兵,

哨兵启动命令为redis-server.exe sentinel.conf --sentinel我们会发现报错

Creating Server TCP listening socket *:26379: listen: UnKnown error

经过网上查询得知是没有配置bind参数的原因,增加bind参数后sentinel.conf文件如下

# 这个是Redis6379配置内容,其他文件同理新增然后改一下端口即可,26380 26381
#当前Sentinel服务运行的端口
port 26381
bind 127.0.0.1
# 哨兵监听的主服务器 
sentinel monitor mymaster 127.0.0.1 6379 2
# 3s内mymaster无响应,则认为mymaster宕机了
sentinel down-after-milliseconds mymaster 3000
#如果10秒后,mysater仍没启动过来,则启动failover  
sentinel failover-timeout mymaster 10000  
# 执行故障转移时, 最多有1个从服务器同时对新的主服务器进行同步
sentinel parallel-syncs mymaster 1
 

 sentinel monitor [master-group-name] [ip] [port] [quorum]

  • master-group-name:master名称(可以自定义)
  • ip port : IP地址和端口号
  • quorun:票数,Sentinel需要协商同意master是否可到达的数量。

第一行配置指示 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 127.0.0.1 , 端口号为 6379 , 而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意 (只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)。
票数在本文中:redis集群中有3个sentinel实例,其中master挂掉啦,这里设置票数为2,表示有2个sentinel认为master挂掉啦,才能被认为是正真的挂掉啦
 

分别启动2个redis以及2个哨兵,哨兵启动命令为redis-server.exe sentinel.conf --sentinel 

Jedis客户端使用Sentinel

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

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

public class RedisManagerUtil {

    private static JedisSentinelPool pool = null;
    // 自带的哨兵模式 JedisSentinelPool, 并在一开始初始化连接池
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            // 控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
            // 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
            config.setMaxTotal(Integer.valueOf(1000));
            // 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
            config.setMaxIdle(Integer.valueOf(20));
            // 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
            config.setMinEvictableIdleTimeMillis(Integer.valueOf(-1));
            // 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
            config.setTestOnBorrow(Boolean.valueOf(true));

            // master名称和配置文件中配置的要一样
            String master = "mymaster";
            //setinel客户端提供了master自动发现功能
            Set<String> sentinels = new HashSet<String>();
            sentinels.add("127.0.0.1:26379");
            sentinels.add("127.0.0.1:26380");
            sentinels.add("127.0.0.1:26381");

            pool = new JedisSentinelPool(master, sentinels, config);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 构建redis连接池
     * 
     * @return JedisPool
     */
    public static JedisSentinelPool getPool() {
        return pool;
    }

    /**
     * 返还到连接池
     * 
     * @param pool
     * @param redis
     */
    public static void returnResource(JedisSentinelPool pool, Jedis redis) {
        if (redis != null) {
            try {
                pool.returnResource(redis);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 测试redis线程池是否正常
     * @param args
     */
    public static void main(String[] args) {
        JedisSentinelPool pool = RedisPoolAPIManager.getPool();
        Jedis redis = pool.getResource();
        System.out.println("redis = " + redis);

        if(redis != null){
            returnResource(pool,redis);
        }
    }
}


 

 总结:
Redis-Sentinel是Redis官方推荐的高可用性(HA) 解决方案,Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel可以监视任意多个主服务器(复用),以及主服务器属下的从服务器,并在被监视的主服务器下线时,自动执行故障转移操作。

为了防止sentinel的单点故障,可以对sentinel进行集群化,创建多个sentinel。
 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值