Search in sources :

Example 1 with IdempotentConfirmer

use of com.sohu.cache.util.IdempotentConfirmer in project cachecloud by sohutv.

the class RedisClusterReshard method clusterMeet.

/**
     * 节点meet
     * @param masterHostAndPostList
     * @param host
     * @param port
     * @return
     */
private boolean clusterMeet(List<HostAndPort> masterHostAndPostList, final String host, final int port) {
    boolean isSingleNode = redisCenter.isSingleClusterNode(host, port);
    if (!isSingleNode) {
        logger.error("{}:{} isNotSingleNode", host, port);
        return false;
    } else {
        logger.warn("{}:{} isSingleNode", host, port);
    }
    for (HostAndPort hostAndPort : masterHostAndPostList) {
        String clusterHost = hostAndPort.getHost();
        int clusterPort = hostAndPort.getPort();
        final Jedis jedis = new Jedis(clusterHost, clusterPort, defaultTimeout);
        try {
            boolean isClusterMeet = new IdempotentConfirmer() {

                @Override
                public boolean execute() {
                    //将新节点添加到集群当中,成为集群中已知新节点
                    String meet = jedis.clusterMeet(host, port);
                    return meet != null && meet.equalsIgnoreCase("OK");
                }
            }.run();
            if (isClusterMeet) {
                return true;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (jedis != null)
                jedis.close();
        }
    }
    return false;
}
Also used : IdempotentConfirmer(com.sohu.cache.util.IdempotentConfirmer) JedisException(redis.clients.jedis.exceptions.JedisException)

Example 2 with IdempotentConfirmer

use of com.sohu.cache.util.IdempotentConfirmer in project cachecloud by sohutv.

the class RedisClusterReshard method moveSlotData.

/**
     * 迁移slot数据,并稳定slot配置
     * @throws Exception
     */
private int moveSlotData(final Jedis source, final Jedis target, final int slot, boolean isPipelineMigrate) throws Exception {
    int num = 0;
    while (true) {
        final Set<String> keys = new HashSet<String>();
        boolean isGetKeysInSlot = new IdempotentConfirmer() {

            @Override
            public boolean execute() {
                List<String> perKeys = source.clusterGetKeysInSlot(slot, migrateBatch);
                if (perKeys != null && perKeys.size() > 0) {
                    keys.addAll(perKeys);
                }
                return true;
            }
        }.run();
        if (!isGetKeysInSlot) {
            throw new RuntimeException(String.format("get keys failed slot=%d num=%d", slot, num));
        }
        if (keys.isEmpty()) {
            break;
        }
        for (final String key : keys) {
            boolean isKeyMigrate = new IdempotentConfirmer() {

                // 失败后,迁移时限加倍
                private int migrateTimeOutFactor = 1;

                @Override
                public boolean execute() {
                    String response = source.migrate(target.getClient().getHost(), target.getClient().getPort(), key, 0, migrateTimeout * (migrateTimeOutFactor++));
                    return response != null && (response.equalsIgnoreCase("OK") || response.equalsIgnoreCase("NOKEY"));
                }
            }.run();
            if (!isKeyMigrate) {
                throw new RuntimeException("migrate key=" + key + failedInfo(source, slot));
            } else {
                num++;
                logger.info("migrate key={};response=OK", key);
            }
        }
    }
    final String targetNodeId = getNodeId(target);
    boolean isClusterSetSlotNode;
    //设置 slot新归属节点
    isClusterSetSlotNode = new IdempotentConfirmer() {

        @Override
        public boolean execute() {
            boolean isOk = false;
            List<HostAndPort> masterNodesList = getMasterNodeList();
            for (HostAndPort hostAndPort : masterNodesList) {
                Jedis jedis = null;
                try {
                    jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
                    String response = jedis.clusterSetSlotNode(slot, targetNodeId);
                    isOk = response != null && response.equalsIgnoreCase("OK");
                    if (isOk) {
                        response = source.clusterSetSlotNode(slot, targetNodeId);
                        isOk = response != null && response.equalsIgnoreCase("OK");
                    } else {
                        logger.error("clusterSetSlotNode-{}={}", getNodeId(target), response);
                        break;
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                } finally {
                    if (jedis != null)
                        jedis.close();
                }
            }
            return isOk;
        }
    }.run();
    if (!isClusterSetSlotNode) {
        throw new RuntimeException("clusterSetSlotNode:" + failedInfo(target, slot));
    }
    return num;
}
Also used : JedisException(redis.clients.jedis.exceptions.JedisException) IdempotentConfirmer(com.sohu.cache.util.IdempotentConfirmer)

Example 3 with IdempotentConfirmer

use of com.sohu.cache.util.IdempotentConfirmer in project cachecloud by sohutv.

the class RedisDeployCenterImpl method startCluster.

private boolean startCluster(Map<Jedis, Jedis> clusterMap) {
    final Jedis jedis = new ArrayList<Jedis>(clusterMap.keySet()).get(0);
    //meet集群节点
    for (final Jedis master : clusterMap.keySet()) {
        boolean isMeet = new IdempotentConfirmer() {

            @Override
            public boolean execute() {
                boolean isMeet = clusterMeet(jedis, master.getClient().getHost(), master.getClient().getPort());
                if (!isMeet) {
                    return false;
                }
                return true;
            }
        }.run();
        if (!isMeet) {
            return false;
        }
        final Jedis slave = clusterMap.get(master);
        if (slave != null) {
            isMeet = new IdempotentConfirmer() {

                @Override
                public boolean execute() {
                    boolean isMeet = clusterMeet(jedis, slave.getClient().getHost(), slave.getClient().getPort());
                    if (!isMeet) {
                        return false;
                    }
                    return true;
                }
            }.run();
            if (!isMeet) {
                return false;
            }
        }
    }
    int masterSize = clusterMap.size();
    int perSize = (int) Math.ceil(16384 / masterSize);
    int index = 0;
    int masterIndex = 0;
    final ArrayList<Integer> slots = new ArrayList<Integer>();
    List<Jedis> masters = new ArrayList<Jedis>(clusterMap.keySet());
    //分配slot
    for (int slot = 0; slot <= 16383; slot++) {
        slots.add(slot);
        if (index++ >= perSize || slot == 16383) {
            final int[] slotArr = new int[slots.size()];
            for (int i = 0; i < slotArr.length; i++) {
                slotArr[i] = slots.get(i);
            }
            final Jedis masterJedis = masters.get(masterIndex++);
            boolean isSlot = new IdempotentConfirmer() {

                @Override
                public boolean execute() {
                    String response = masterJedis.clusterAddSlots(slotArr);
                    boolean isSlot = response != null && response.equalsIgnoreCase("OK");
                    if (!isSlot) {
                        return false;
                    }
                    return true;
                }
            }.run();
            if (!isSlot) {
                logger.error("{}:{} set slots:{}", masterJedis.getClient().getHost(), masterJedis.getClient().getPort(), slots);
                return false;
            }
            slots.clear();
            index = 0;
        }
    }
    //设置从节点
    for (Jedis masterJedis : clusterMap.keySet()) {
        final Jedis slaveJedis = clusterMap.get(masterJedis);
        if (slaveJedis == null) {
            continue;
        }
        final String nodeId = getClusterNodeId(masterJedis);
        boolean isReplicate = new IdempotentConfirmer() {

            @Override
            public boolean execute() {
                try {
                    //等待广播节点
                    TimeUnit.SECONDS.sleep(2);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
                String response = null;
                try {
                    response = slaveJedis.clusterReplicate(nodeId);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
                boolean isReplicate = response != null && response.equalsIgnoreCase("OK");
                if (!isReplicate) {
                    try {
                        //等待广播节点
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    return false;
                }
                return true;
            }
        }.run();
        if (!isReplicate) {
            logger.error("{}:{} set replicate:{}", slaveJedis.getClient().getHost(), slaveJedis.getClient().getPort());
            return false;
        }
    }
    return true;
}
Also used : Jedis(redis.clients.jedis.Jedis) IdempotentConfirmer(com.sohu.cache.util.IdempotentConfirmer)

Example 4 with IdempotentConfirmer

use of com.sohu.cache.util.IdempotentConfirmer in project cachecloud by sohutv.

the class RedisIsolationPersistenceInspector method parseMap.

private Map<String, String> parseMap(final Jedis jedis) {
    final StringBuilder builder = new StringBuilder();
    boolean isInfo = new IdempotentConfirmer() {

        @Override
        public boolean execute() {
            String persistenceInfo = null;
            try {
                persistenceInfo = jedis.info("Persistence");
            } catch (Exception e) {
                logger.warn(e.getMessage() + "-{}:{}", jedis.getClient().getHost(), jedis.getClient().getPort(), e.getMessage());
            }
            boolean isOk = StringUtils.isNotBlank(persistenceInfo);
            if (isOk) {
                builder.append(persistenceInfo);
            }
            return isOk;
        }
    }.run();
    if (!isInfo) {
        logger.error("{}:{} info Persistence failed", jedis.getClient().getHost(), jedis.getClient().getPort());
        return Collections.emptyMap();
    }
    String persistenceInfo = builder.toString();
    if (StringUtils.isBlank(persistenceInfo)) {
        return Collections.emptyMap();
    }
    Map<String, String> map = new LinkedHashMap<String, String>();
    String[] array = persistenceInfo.split("\r\n");
    for (String line : array) {
        String[] cells = line.split(":");
        if (cells.length > 1) {
            map.put(cells[0], cells[1]);
        }
    }
    return map;
}
Also used : IdempotentConfirmer(com.sohu.cache.util.IdempotentConfirmer) LinkedHashMap(java.util.LinkedHashMap)

Example 5 with IdempotentConfirmer

use of com.sohu.cache.util.IdempotentConfirmer in project cachecloud by sohutv.

the class RedisDeployCenterImpl method sentinelFailover.

@Override
public boolean sentinelFailover(long appId) throws Exception {
    Assert.isTrue(appId > 0);
    AppDesc appDesc = appDao.getAppDescById(appId);
    Assert.isTrue(appDesc != null);
    int type = appDesc.getType();
    if (!TypeUtil.isRedisSentinel(type)) {
        logger.warn("app={} is not sentinel", appDesc);
        return false;
    }
    final List<InstanceInfo> instanceList = instanceDao.getInstListByAppId(appId);
    if (instanceList == null || instanceList.isEmpty()) {
        logger.warn("app={} instances is empty");
        return false;
    }
    for (InstanceInfo instanceInfo : instanceList) {
        int instanceType = instanceInfo.getType();
        if (TypeUtil.isRedisSentinel(instanceType)) {
            final String host = instanceInfo.getIp();
            final int port = instanceInfo.getPort();
            final String masterName = instanceInfo.getCmd();
            if (StringUtils.isBlank(masterName)) {
                logger.warn("{} cmd is null", instanceInfo);
                continue;
            }
            boolean isRun = redisCenter.isRun(host, port);
            if (!isRun) {
                logger.warn("{} is not run");
                continue;
            }
            boolean isSentinelFailOver = new IdempotentConfirmer() {

                @Override
                public boolean execute() {
                    Jedis jedis = new Jedis(host, port, Protocol.DEFAULT_TIMEOUT);
                    try {
                        String response = jedis.sentinelFailover(masterName);
                        return response != null && response.equalsIgnoreCase("OK");
                    } finally {
                        jedis.close();
                    }
                }
            }.run();
            if (!isSentinelFailOver) {
                logger.warn("{}:{} sentienl isSentinelFailOver error", host, port);
                return false;
            } else {
                logger.warn("SentinelFailOver done! ");
                break;
            }
        }
    }
    return true;
}
Also used : Jedis(redis.clients.jedis.Jedis) IdempotentConfirmer(com.sohu.cache.util.IdempotentConfirmer) AppDesc(com.sohu.cache.entity.AppDesc) InstanceInfo(com.sohu.cache.entity.InstanceInfo)

Aggregations

IdempotentConfirmer (com.sohu.cache.util.IdempotentConfirmer)13 Jedis (redis.clients.jedis.Jedis)7 JedisException (redis.clients.jedis.exceptions.JedisException)4 AppDesc (com.sohu.cache.entity.AppDesc)3 InstanceInfo (com.sohu.cache.entity.InstanceInfo)3 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1