redis集群启动流程关键类源码分析

redis集群启动流程关键类(源码版)

以Spring集成redis为例来说明,版本是2.8.2。

 

一,RedisProperties

 

解析配置文件中的配置项,这个class上加了一个@ConfigurationProperties注解,指定了prefix为spring.redis,也就是说处理配置文件中前缀为spring.redis的配置项。

RedisProperties定义的属性如下:

int database = 0

String url

String host = "localhost"

String password

int port = 6379

boolean ssl

int timeout

RedisProperties.Pool:封装了maxIdle、minIdle、maxActive、maxWait这4个配置项。

RedisProperties.Sentinel:封装了master、nodes配置项。

RedisProperties.Cluster:封装了nodes、maxRedirects配置项。

 

二,Jedis

 

jedis包下提供的一个类,封装了redis的常用命令,1700多行代码,基本的redis操作都封装了。

 

三,JedisConnection

 

JedisConnection继承了抽象类

AbstractRedisConnection,AbstractRedisConnection并没有提供什么额外功能。AbstractRedisConnection实现了RedisConnection接口,这个接口定义了8个方法:

// 关闭连接

void close()

// 查看连接是否关闭

boolean isClosed();

// 获取JedisCluster

Object getNativeConnection();

// 判断是否是队列,相对于redis管道来说的

boolean isQueueing();

// 判断是否支持管道命令

boolean isPipeline();

// 获取管道命令执行结果

List<Object> closePioeline();

// 获取哨兵连接,jedis2.8.2不支持哨兵连接

RedisSentinelConnection getSentinelConnection();

 

然后RedisConnection接口实现了RedisCommands接口,RedisCommands接口只有一个方法,那就是执行redis命令。

综合来看,JedisConnection的功能其实就是:

1,建立和关闭与redis集群的连接。

2,判断如何执行redis命令,管道方式执行还是非管道方式执行。

3,执行redis命令。

 

四,RedisOperations接口和RedisTemplate

 

封装了对redis的5种数据类型的操作。这个接口的实现类就是大名鼎鼎的RedisTemplate,我们操作redis数据的入口。

 

五,RedisAutoConfiguration

 

RedisAutoConfiguration包含2个内部类:

1,RedisConfiguration

提供了创建redisTemplate的方法。

2,RedisConnectionConfiguration

提供了配置redis连接和创建redis连接的一些方法。

 

六,RedisConnectionFactory

 

RedisConnectionFactory接口的实现类有2个:

JedisConnectionFactory

LettuceConnectionFactory

Spring boot2.x默认使用LettuceConnectionFactory,LettuceConnectionFactory支持redis的管道特性,但是JedisConnectionFactory默认是不支持的。

 

JedisConnectionFactory有下面这段代码:

return poolConfig != null ? new JedisCluster(...) : new JedisCluster(...);

括号中的参数这里省略了,我对比了几遍,一模一样。这应该是Spring开发者留下的一个bug了。这个spring-data-redis的版本是1.7.8.RELEASE。

 

七,JedisPoolConfig

 

redis连接池配置,设置redis连接池的相关参数,例如:

maxTotal:最大连接数,默认值8。

maxIdle:最大闲置连接数,默认值8。

minIdle:最小闲置连接数,默认值0。

 

八,RedisSentinelConfiguration

 

RedisSentinelConfiguration主要的功能就是:redis哨兵节点配置项解析。解析完成以后会放到Set<RedisNode>集合中。

 

九,RedisClusterConfiguration

 

RedisClusterConfiguration主要的功能就是:redis集群节点配置项解析。解析完成以后会放到Set<RedisNode>集合中。

 

十,JedisCluster

 

定义集群的各种原子操作,比如hset(),所有的这些集群原子操作都是经过了JedisClusterCommand的包装,也就是说借助JedisClusterCommand来实现的。

接下来我们有必要来了解一下这个JedisClusterCommand。

JedisClusterCommand主要提供了4个方法:

1,run(String key):执行单个类型为String的key的操作。

2,run(int keyCount, String… keys):执行多个类型为String的key的操作。

3,runBinary(byte[] key):执行单个类型为byte数组的key的操作。

4,runBinary(int keyCount, byte[] … keys):执行多个类型为byte数组的key的操作。

我们看run(String key)的源码:

return this.runWithRetries(key, this.maxAttempts, false, false);

this.runWithRetries方法的四个入参如下:

key:键

this.maxAttempts:最大重试次数,这个参数必须大于0。

tryRandomNode:重试策略,随机连接redis集群中的节点。具体逻辑是:获取redis集群缓存JedisClusterInfoCache,然后从缓存拿到redis连接池JedisPool,遍历JedisPool,获取一个Jedis实例,ping一下,ping通了,就直接返回。

asking:重试策略,asking重试策略很特殊,只有当重定向的槽处于迁移状态时,才会使用asking重定向。与asking相对应的,还有一个moved重定向,指的是当前访问的key迁移到了其他槽,这里是迁移完成状态。

OK,搞清楚了这几个参数的含义,这个方法就好理解了。

this.runWithRetries首先会判断是否是asking重试策略,如果是,则执行下面的逻辑连接集群的某个节点:

connection = (Jedis)this.askConnection.get();

connection.asking();

asking = false;

这里需要注意,this.askConnection是ThreadLocal<Jedis>。

然后判断是否是随机重试策略,如果是,则执行下面的逻辑连接集群的某个节点:

connection = this.connectionHandler.getConnection();

如果既不是重试策略,又不是随机重试策略,则说明有可能是第一次访问redis节点,也有可能是重试访问redis节点,总之,使用

JedisClusterCRC16哈希算法计算key的hash值,找到对应的槽,然后连接,源码如下:

connection = this.connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(key));

连接上redis节点以后,根据key执行对于的操作,然后返回:

return this.execute(connection);

这里的this.execute方法是JedisClusterCommand定于的一个抽象方法,具体实现在JedisCluster中。最终是调用了Jedis中定于的各种redis命令的实现。

好了,什么这些分析就是JedisClusterCommand的具体实现,说白了,JedisClusterCommand其实就是一个模板,redis集群执行各种redis命令实现的操作模板。

 

十一,JedisClusterCRC16

 

JedisClusterCRC16是Spring对redis哈希算法CRC16的实现。感兴趣的朋友可以看看。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值