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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations