概述
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的实现。感兴趣的朋友可以看看。
最后
以上就是满意西装为你收集整理的redis集群启动流程关键类源码分析的全部内容,希望文章能够帮你解决redis集群启动流程关键类源码分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复