Jedis 源码分析

本文深入分析了JedisSentinelPool的实现,包括其属性、构造器、Sentinel的初始化过程和MasterListener监听者线程。此外,还探讨了ShardedJedis的一致性哈希分片机制,包括其构造、哈希环初始化和数据定位流程。
摘要由CSDN通过智能技术生成

原文链接:《Jedis 源码分析》http://www.ytbean.com/posts/jedis-source-walk/

概述

Jedis是Redis官方推荐的Java客户端,更多Redis的客户端可以参考Redis官网客户端列表

JedisSentinelPool

简介

Redis-Sentinel作为官方推荐的HA解决方案,Jedis也在客户端角度实现了对Sentinel的支持,主要实现在JedisSentinelPool.java这个类中,下文会分析这个类的实现。

属性

JedisSentinelPool类里有以下的属性:

    //基于apache的commom-pool2的对象池配置
    protected GenericObjectPoolConfig poolConfig;
    
    //超时时间,默认是2000
    protected int timeout = Protocol.DEFAULT_TIMEOUT;
    
    //sentinel的密码
    protected String password;

    //redis数据库的数目
    protected int database = Protocol.DEFAULT_DATABASE;

    //master监听器,当master的地址发生改变时,会触发这些监听者
    protected Set<MasterListener> masterListeners = new HashSet<MasterListener>();

    protected Logger log = Logger.getLogger(getClass().getName());
    
    //Jedis实例创建工厂
    private volatile JedisFactory factory;
    
    //当前的master,HostAndPort是一个简单的包装了ip和port的模型类
    private volatile HostAndPort currentHostMaster;

构造器

构造器的代码如下:

public JedisSentinelPool(String masterName, Set<String> sentinels, final GenericObjectPoolConfig poolConfig, int timeout, final String password, final int database) {
   

        this.poolConfig = poolConfig;
        this.timeout = timeout;
        this.password = password;
        this.database = database;

        HostAndPort master = initSentinels(sentinels, masterName);
        initPool(master);
}

构造器一开始对实例变量进行赋值,参数sentinels是客户端所需要打交道的Redis-Sentinel,允许有多个,用一个集合来盛装。

然后通过initSentinels方法与sentinel沟通后,确定当前sentinel所监视的master是哪一个。然后通过master来创建好对象池,以便后续从对象池中取出一个Jedis实例,来对master进行操作。

initSentinels方法

initSentinels方法的代码如下所示,我加了一些注释:

    private HostAndPort initSentinels(Set<String> sentinels, final String masterName) {
   

        HostAndPort master = null;
        boolean sentinelAvailable = false;

        log.info("Trying to find master from available Sentinels...");

        // 有多个sentinels,遍历这些个sentinels
        for (String sentinel : sentinels) {
   
            // host:port表示的sentinel地址转化为一个HostAndPort对象。
            final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel.split(":")));

            log.fine("Connecting to Sentinel " + hap);

            Jedis jedis = null;
            try {
   
                // 连接到sentinel
                jedis = new Jedis(hap.getHost(), hap.getPort());

                // 根据masterName得到master的地址,返回一个list,host= list[0], port =
                // list[1]
                List<String> masterAddr = jedis.sentinelGetMasterAddrByName(masterName);

                // connected to sentinel...
                sentinelAvailable = true;

                if (masterAddr == null || masterAddr.size() != 2) {
   
                    log.warning("Can not get master addr, master name: " + masterName
                            + ". Sentinel: " + hap + ".");
                    continue;
                }

                master = toHostAndPort(masterAddr);
                log.fine("Found Redis master at " + master);
                // 如果在任何一个sentinel中找到了master,不再遍历sentinels
                break;
            } catch (JedisConnectionException e) {
   
                log.warning("Cannot connect to sentinel running @ " + hap
                        + ". Trying next one.");
            } finally {
   
                // 关闭与sentinel的连接
                if (jedis != null) {
   
                    jedis.close();
                }
            }
        }

        // 到这里,如果master为null,则说明有两种情况,一种是所有的sentinels节点都down掉了,一种是master节点没有被存活的sentinels监控到
        if (master == null) {
   
            if (sentinelAvailable) {
   
                // can connect to sentinel, but master name seems to not
                // monitored
                throw new JedisException("Can connect to senti
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值