在Redis 3.0 之后,引入了Cluster模式,对于集群模式下的相关操作,也是需要大家在学习当中去逐步掌握的。今天的大数据开发学习分享,我们就主要来讲讲Redis Cluster模式连接原理。

这里主要以jedis客户端为例,说明在redis cluster模式中客户端应当如何去连接redis服务端。
一般在配置redis连接时伪代码大致如下,在对JedisCluster进行初始化时代码最终会调到discoverClusterNodesAndSlots方法中,在初始化时会将slot与jedisPool进行映射。
Set<HostAndPort> sets = new HashSet<>();
sets.add(new HostAndPort("ip",6379));
sets.add(new HostAndPort("ip2",6380));
JedisCluster jedisCluster = new JedisCluster(sets);
jedisCluster.set("key","value");
其实可以看出无论配置了几台机器的ip最终只会用一台获取服务端node与槽信息,那么在往redis里存数据时是如何知道该往那个节点上存?
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig, String password) {
for (HostAndPort hostAndPort : startNodes) {
Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
if (password != null) {
jedis.auth(password);
}
try {
cache.discoverClusterNodesAndSlots(jedis);
break;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
public void discoverClusterNodesAndSlots(Jedis jedis) {
w.lock();
try {
reset();
//获取服务端所有节点的槽信息
//{[0,5460, 6378, 6379],[5461,10922,6380,6381],[10923,16383,6382,6383]}
List<Object> slots = jedis.clusterSlots();
for (Object slotInfoObj : slots) {
//槽信息 //主端口 //从端口
//slotInfo [0, 5460, 6378, 6379]
List<Object> slotInfo = (List<Object>) slotInfoObj;
//小于等于2表示没有分配slot
if (slotInfo.size() <= MASTER_NODE_INDEX) {
continue;
}
//获取分配到当前master节点的数据槽 例如6378节点 {0,1,2,3...5460}
List<Integer> slotNums = getAssignedSlotArray(slotInfo);
// hostInfos
int size = slotInfo.size();
//遍历第3位第4位主从端口信息
for (int i = MASTER_NODE_INDEX; i < size; i++) {
List<Object> hostInfos = (List<Object>) slotInfo.get(i);
if (hostInfos.size() <= 0) {
continue;
}
//根据IP端口生成HostAndPort实例
HostAndPort targetNode = generateHostAndPort(hostInfos);
//将解析出来的ip:port作为,并从缓存中获取JedisPool,如果没有JedisPool则会构建
//JedisPool并放入缓存中,缓存中存放nodeKey与JedisPool的关系
setupNodeIfNotExist(targetNode);
if (i == MASTER_NODE_INDEX) {
//将slot与JedisPool缓存起来(16384个),key为slot,value为JedisPool
assignSlotsToNode(slotNums, targetNode);
}
}
}
} finally {
w.unlock();
}
}
当通过key进行操作redis时则首先通过key用CRC16算法进行计算,然后再%16384,这时会得到一个余数,也就是该key计算得到的slot,再通过该slot从缓存中获取JedisPool
JedisCluster jedisCluster = new JedisCluster();
jedisCluster.set("123","");
set方法最终会调到下面方面里面,可以看出是通过slot首先获取到初始化时映射好的jedisPool
public Jedis getConnectionFromSlot(int slot) {
JedisPool connectionPool = cache.getSlotPool(slot);
if (connectionPool != null) {
// It can't guaranteed to get valid connection because of node
// assignment
return connectionPool.getResource();
} else {
renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state
connectionPool = cache.getSlotPool(slot);
if (connectionPool != null) {
return connectionPool.getResource();
} else {
//no choice, fallback to new connection to random node
return getConnection();
}
}
}
关于大数据开发学习,Redis Cluster模式连接原理,以上就为大家做了具体的操作讲解了,也结合到代码进行了展示,大家可以多理解理解。
网友评论