java jediscluster_JedisCluster 源码分析

public abstract class JedisClusterConnectionHandler {

protected final JedisClusterInfoCache cache;

public JedisClusterConnectionHandler(Set nodes,

final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {

this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout);

//通过slot 初始化集群信息

initializeSlotsCache(nodes, poolConfig);

}

abstract Jedis getConnection();

abstract Jedis getConnectionFromSlot(int slot);

public Jedis getConnectionFromNode(HostAndPort node) {

cache.setNodeIfNotExist(node);

return cache.getNode(JedisClusterInfoCache.getNodeKey(node)).getResource();

}

public class JedisClusterInfoCache {

private Map nodes = new HashMap();

private Map slots = new HashMap();

private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

private final Lock r = rwl.readLock();

private final Lock w = rwl.writeLock();

private final GenericObjectPoolConfig poolConfig;

private int connectionTimeout;

private int soTimeout;

private static final int MASTER_NODE_INDEX = 2;

public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig, int timeout) {

this(poolConfig, timeout, timeout);

}

public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,

final int connectionTimeout, final int soTimeout) {

this.poolConfig = poolConfig;

this.connectionTimeout = connectionTimeout;

this.soTimeout = soTimeout;

}

public void discoverClusterNodesAndSlots(Jedis jedis) {

w.lock();

try {

this.nodes.clear();

this.slots.clear();

List slots = jedis.clusterSlots();

for (Object slotInfoObj : slots) {

List slotInfo = (List) slotInfoObj;

if (slotInfo.size() <= MASTER_NODE_INDEX) {

continue;

}

List slotNums = getAssignedSlotArray(slotInfo);

// hostInfos

int size = slotInfo.size();

for (int i = MASTER_NODE_INDEX; i 

List hostInfos = (List) slotInfo.get(i);

if (hostInfos.size() <= 0) {

continue;

}

HostAndPort targetNode = generateHostAndPort(hostInfos);

setNodeIfNotExist(targetNode);

if (i == MASTER_NODE_INDEX) {

assignSlotsToNode(slotNums, targetNode);

}

}

}

} finally {

w.unlock();

}

}

//初始化集群信息

public void discoverClusterSlots(Jedis jedis) {

w.lock();

try {

this.slots.clear();

//通过 slots 命令获取集群信息

List slots = jedis.clusterSlots();

for (Object slotInfoObj : slots) {

List slotInfo = (List) slotInfoObj;

if (slotInfo.size() <= 2) {

continue;

}

List slotNums = getAssignedSlotArray(slotInfo);

// hostInfos

List hostInfos = (List) slotInfo.get(2);

if (hostInfos.size() <= 0) {

continue;

}

// at this time, we just use master, discard slave information

HostAndPort targetNode = generateHostAndPort(hostInfos);

setNodeIfNotExist(targetNode);

assignSlotsToNode(slotNums, targetNode);

}

} finally {

w.unlock();

}

}

private HostAndPort generateHostAndPort(List hostInfos) {

return new HostAndPort(SafeEncoder.encode((byte[]) hostInfos.get(0)),

((Long) hostInfos.get(1)).intValue());

}

public void setNodeIfNotExist(HostAndPort node) {

w.lock();

try {

String nodeKey = getNodeKey(node);

if (nodes.containsKey(nodeKey)) return;

JedisPool nodePool = new JedisPool(poolConfig, node.getHost(), node.getPort(),

connectionTimeout, soTimeout, null, 0, null);

nodes.put(nodeKey, nodePool);

} finally {

w.unlock();

}

}

public void assignSlotToNode(int slot, HostAndPort targetNode) {

w.lock();

try {

JedisPool targetPool = nodes.get(getNodeKey(targetNode));

if (targetPool == null) {

setNodeIfNotExist(targetNode);

targetPool = nodes.get(getNodeKey(targetNode));

}

slots.put(slot, targetPool);

} finally {

w.unlock();

}

}

public void assignSlotsToNode(List targetSlots, HostAndPort targetNode) {

w.lock();

try {

JedisPool targetPool = nodes.get(getNodeKey(targetNode));

if (targetPool == null) {

setNodeIfNotExist(targetNode);

targetPool = nodes.get(getNodeKey(targetNode));

}

for (Integer slot : targetSlots) {

slots.put(slot, targetPool);

}

} finally {

w.unlock();

}

}

public JedisPool getNode(String nodeKey) {

r.lock();

try {

return nodes.get(nodeKey);

} finally {

r.unlock();

}

}

public JedisPool getSlotPool(int slot) {

r.lock();

try {

return slots.get(slot);

} finally {

r.unlock();

}

}

public Map getNodes() {

r.lock();

try {

return new HashMap(nodes);

} finally {

r.unlock();

}

}

public static String getNodeKey(HostAndPort hnp) {

return hnp.getHost() + ":" + hnp.getPort();

}

public static String getNodeKey(Client client) {

return client.getHost() + ":" + client.getPort();

}

public static String getNodeKey(Jedis jedis) {

return getNodeKey(jedis.getClient());

}

private List getAssignedSlotArray(List slotInfo) {

List slotNums = new ArrayList();

for (int slot = ((Long) slotInfo.get(0)).intValue(); slot <= ((Long) slotInfo.get(1))

.intValue(); slot++) {

slotNums.add(slot);

}

return slotNums;

}

}

public Map getNodes() {

return cache.getNodes();

}

private void initializeSlotsCache(Set startNodes, GenericObjectPoolConfig poolConfig) {

for (HostAndPort hostAndPort : startNodes) {

Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());

try {

cache.discoverClusterNodesAndSlots(jedis);

break;

} catch (JedisConnectionException e) {

// try next nodes

} finally {

if (jedis != null) {

jedis.close();

}

}

}

for (HostAndPort node : startNodes) {

cache.setNodeIfNotExist(node);

}

}

public void renewSlotCache() {

for (JedisPool jp : getShuffledNodesPool()) {

Jedis jedis = null;

try {

jedis = jp.getResource();

cache.discoverClusterSlots(jedis);

break;

} catch (JedisConnectionException e) {

// try next nodes

} finally {

if (jedis != null) {

jedis.close();

}

}

}

}

public void renewSlotCache(Jedis jedis) {

try {

cache.discoverClusterSlots(jedis);

} catch (JedisConnectionException e) {

renewSlotCache();

}

}

protected List getShuffledNodesPool() {

List pools = new ArrayList();

pools.addAll(cache.getNodes().values());

Collections.shuffle(pools);

return pools;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值