Skip to content

Commit c346720

Browse files
authored
Feature/rebalance keeper (#744)
* add keeper container comparator * add keeper instance in check action * add keeper info stats action * get all dc meta from console * add info action for redis * add redis instance for used memory * add redis info action when leader changes * temp * auto migrate keepers * add overload migration pages * fix keeper cotainer meta comparator test fail * fix DefaultDcMetaChangeManagerTest fail * add test for keeper info stats action * add test for redisInfoAction * add test for keeperContainerMetaComparator * temp * temp * add test for DefaultKeeperContainerUsedInfoAnalyzer * add test for AutoMigrateOverloadKeeperContainerAction * add keeper session manager * fix bean circle * add keeper related action when start * fix checker not report keeper result * add log and update choose redis strategy * add keeper session manager * adjust interval of keeper related actions * add alert when keeper migrate * clean expired keeper container used info * update session manager * update all dc meta of current dc with metacache
1 parent 42109dd commit c346720

File tree

139 files changed

+5691
-515
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+5691
-515
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ hs_err_pid*
4040

4141
# npm
4242
node_modules
43+
*.js

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/CheckerConsoleService.java

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.ctrip.xpipe.redis.checker.healthcheck.RedisHealthCheckInstance;
88
import com.ctrip.xpipe.redis.checker.model.CheckerStatus;
99
import com.ctrip.xpipe.redis.checker.model.HealthCheckResult;
10+
import com.ctrip.xpipe.redis.checker.model.KeeperContainerUsedInfoModel;
1011
import com.ctrip.xpipe.redis.checker.model.ProxyTunnelInfo;
1112
import com.ctrip.xpipe.redis.core.entity.SentinelMeta;
1213
import com.ctrip.xpipe.redis.core.entity.XpipeMeta;
@@ -25,12 +26,16 @@ public interface CheckerConsoleService {
2526
XpipeMeta getXpipeMeta(String console, int clusterPartIndex) throws SAXException, IOException;
2627

2728
XpipeMeta getXpipeAllMeta(String console) throws SAXException, IOException;
29+
30+
XpipeMeta getXpipeDcAllMeta(String console, String dcName) throws SAXException, IOException;
2831

2932
List<ProxyTunnelInfo> getProxyTunnelInfos(String console);
3033

3134
void ack(String console, CheckerStatus checkerStatus);
3235

3336
void report(String console, HealthCheckResult result);
37+
38+
void reportKeeperContainerInfo(String console, List<KeeperContainerUsedInfoModel> keeperContainerUsedInfoModels, int index);
3439

3540
boolean isClusterOnMigration(String console, String clusterId);
3641

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/alert/ALERT_TYPE.java

+33
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,41 @@ public boolean reportRecovery() {
570570
public DetailDesc detailDesc() {
571571
return new DetailDesc("keepers should in different available zones", "keepers in the same available zone found");
572572
}
573+
},
574+
KEEPER_MIGRATION_SUCCESS("keeper migration success", EMAIL_XPIPE_ADMIN) {
575+
@Override
576+
public boolean urgent() {
577+
return false;
578+
}
579+
580+
@Override
581+
public boolean reportRecovery() {
582+
return false;
583+
}
584+
585+
@Override
586+
public DetailDesc detailDesc() {
587+
return new DetailDesc("keeper migration success", "keeper migration success");
588+
}
589+
},
590+
KEEPER_MIGRATION_FAIL("keeper migration fail", EMAIL_XPIPE_ADMIN) {
591+
@Override
592+
public boolean urgent() {
593+
return false;
594+
}
595+
596+
@Override
597+
public boolean reportRecovery() {
598+
return false;
599+
}
600+
601+
@Override
602+
public DetailDesc detailDesc() {
603+
return new DetailDesc("keeper migration fail", "keeper migration fail");
604+
}
573605
};
574606

607+
575608
private String simpleDesc;
576609

577610
private int alertMethod;

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/config/CheckerConfig.java

+8
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public interface CheckerConfig {
8383

8484
String KEY_CHECKER_META_REFRESH_INTERVAL = "checker.meta.refresh.interval.milli";
8585

86+
String KEY_CHECKER_CURRENT_DC_ALL_META_REFRESH_INTERVAL = "checker.current_dc_all_meta.refresh.interval.milli";
87+
8688
String KEY_CONSOLE_ADDRESS = "console.address";
8789

8890
String KEY_CHECKER_ACK_INTERVAL = "checker.ack.interval.milli";
@@ -101,8 +103,12 @@ public interface CheckerConfig {
101103

102104
String KEY_SUBSCRIBE_TIMEOUT_MILLI = "checker.subscribe.timeout.milli";
103105

106+
String KEY_KEEPER_CHECKER_INTERVAL = "keeper.checker.interval";
107+
104108
int getRedisReplicationHealthCheckInterval();
105109

110+
int getCheckerCurrentDcAllMetaRefreshIntervalMilli();
111+
106112
int getClusterHealthCheckInterval();
107113

108114
int getDownAfterCheckNums();
@@ -201,4 +207,6 @@ public interface CheckerConfig {
201207

202208
Set<String> getMigrationUnsupportedClusters();
203209

210+
int getKeeperCheckerIntervalMilli();
211+
204212
}

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/controller/CheckerHealthController.java

+40
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import com.ctrip.xpipe.redis.checker.healthcheck.actions.interaction.DefaultDelayPingActionCollector;
99
import com.ctrip.xpipe.redis.checker.healthcheck.actions.interaction.HEALTH_STATE;
1010
import com.ctrip.xpipe.redis.checker.healthcheck.actions.interaction.HealthStatusDesc;
11+
import com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper.info.RedisUsedMemoryCollector;
12+
import com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper.infoStats.KeeperFlowCollector;
1113
import com.ctrip.xpipe.redis.checker.healthcheck.actions.redisconf.AbstractRedisConfigRuleAction;
1214
import com.ctrip.xpipe.redis.checker.healthcheck.stability.StabilityHolder;
15+
import com.ctrip.xpipe.redis.checker.model.DcClusterShard;
1316
import com.google.common.collect.Lists;
1417
import org.springframework.beans.factory.annotation.Autowired;
1518
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -18,6 +21,7 @@
1821
import java.util.Collections;
1922
import java.util.List;
2023
import java.util.Map;
24+
import java.util.concurrent.ConcurrentMap;
2125

2226
/**
2327
* @author lishanglin
@@ -31,6 +35,12 @@ public class CheckerHealthController {
3135
@Autowired
3236
private DefaultDelayPingActionCollector defaultDelayPingActionCollector;
3337

38+
@Autowired
39+
private RedisUsedMemoryCollector redisUsedMemoryCollector;
40+
41+
@Autowired
42+
private KeeperFlowCollector keeperFlowCollector;
43+
3444
@Autowired
3545
private HealthCheckInstanceManager instanceManager;
3646

@@ -66,6 +76,26 @@ public String getClusterHealthCheckInstance(@PathVariable String clusterId) {
6676
return Codec.DEFAULT.encode(model);
6777
}
6878

79+
@RequestMapping(value = "/health/check/keeper/{ip}/{port}", method = RequestMethod.GET)
80+
public String getHealthCheckKeeper(@PathVariable String ip, @PathVariable int port) {
81+
KeeperHealthCheckInstance instance = instanceManager.findKeeperHealthCheckInstance(new HostPort(ip, port));
82+
if(instance == null) {
83+
return "Not found";
84+
}
85+
HealthCheckInstanceModel model = buildHealthCheckInfo(instance);
86+
return Codec.DEFAULT.encode(model);
87+
}
88+
89+
@RequestMapping(value = "/health/check/redis-for-assigned-action/{ip}/{port}", method = RequestMethod.GET)
90+
public String getHealthCheckRedisInstanceForAssignedAction(@PathVariable String ip, @PathVariable int port) {
91+
RedisHealthCheckInstance instance = instanceManager.findRedisInstanceForAssignedAction(new HostPort(ip, port));
92+
if(instance == null) {
93+
return "Not found";
94+
}
95+
HealthCheckInstanceModel model = buildHealthCheckInfo(instance);
96+
return Codec.DEFAULT.encode(model);
97+
}
98+
6999
@RequestMapping(value = "/health/redis/info/{ip}/{port}", method = RequestMethod.GET)
70100
public ActionContextRetMessage<Map<String, String>> getRedisInfo(@PathVariable String ip, @PathVariable int port) {
71101
return ActionContextRetMessage.from(redisInfoManager.getInfoByHostPort(new HostPort(ip, port)));
@@ -82,6 +112,16 @@ public Map<HostPort, HealthStatusDesc> getAllHealthStatusDesc() {
82112
else return Collections.emptyMap();
83113
}
84114

115+
@GetMapping("/health/keeper/status/all")
116+
public ConcurrentMap<String, Map<DcClusterShard, Long>> getAllKeeperFlows() {
117+
return keeperFlowCollector.getHostPort2InputFlow();
118+
}
119+
120+
@GetMapping("/health/redis/used-memory/all")
121+
public ConcurrentMap<DcClusterShard, Long> getAllDclusterShardUsedMemory() {
122+
return redisUsedMemoryCollector.getDcClusterShardUsedMemory();
123+
}
124+
85125
private HealthCheckInstanceModel buildHealthCheckInfo(HealthCheckInstance<?> instance) {
86126
HealthCheckInstanceModel model = new HealthCheckInstanceModel(instance.toString());
87127
for(HealthCheckAction action : instance.getHealthCheckActions()) {

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/healthcheck/AbstractHealthCheckAction.java

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public void doStart() {
5151

5252
@Override
5353
public void doStop() {
54+
logger.debug("[stopped][{}][{}], listener:{}, future:{}", getClass().getSimpleName(), instance.getCheckInfo(), listeners, future);
5455
if(future != null) {
5556
future.cancel(true);
5657
}

redis/redis-checker/src/main/java/com/ctrip/xpipe/redis/checker/healthcheck/HealthCheckInstanceManager.java

+17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.ctrip.xpipe.endpoint.HostPort;
44
import com.ctrip.xpipe.redis.core.entity.ClusterMeta;
5+
import com.ctrip.xpipe.redis.core.entity.KeeperMeta;
56
import com.ctrip.xpipe.redis.core.entity.RedisMeta;
67

78
import java.util.List;
@@ -15,18 +16,34 @@ public interface HealthCheckInstanceManager {
1516

1617
RedisHealthCheckInstance getOrCreate(RedisMeta redis);
1718

19+
RedisHealthCheckInstance getOrCreateRedisInstanceForAssignedAction(RedisMeta redis);
20+
21+
KeeperHealthCheckInstance getOrCreate(KeeperMeta keeper);
22+
1823
ClusterHealthCheckInstance getOrCreate(ClusterMeta cluster);
1924

2025
RedisHealthCheckInstance findRedisHealthCheckInstance(HostPort hostPort);
2126

27+
RedisHealthCheckInstance findRedisInstanceForAssignedAction(HostPort hostPort);
28+
29+
KeeperHealthCheckInstance findKeeperHealthCheckInstance(HostPort hostPort);
30+
2231
ClusterHealthCheckInstance findClusterHealthCheckInstance(String clusterId);
2332

2433
RedisHealthCheckInstance remove(HostPort hostPort);
2534

35+
KeeperHealthCheckInstance removeKeeper(HostPort hostPort);
36+
37+
RedisHealthCheckInstance removeRedisInstanceForAssignedAction(HostPort hostPort);
38+
2639
ClusterHealthCheckInstance remove(String cluster);
2740

2841
List<RedisHealthCheckInstance> getAllRedisInstance();
2942

43+
List<KeeperHealthCheckInstance> getAllKeeperInstance();
44+
45+
List<RedisHealthCheckInstance> getAllRedisInstanceForAssignedAction();
46+
3047
List<ClusterHealthCheckInstance> getAllClusterInstance();
3148

3249
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck;
2+
3+
public interface KeeperHealthCheckActionFactory <T extends HealthCheckAction> extends HealthCheckActionFactory<T, KeeperHealthCheckInstance>{
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck;
2+
3+
public interface KeeperHealthCheckActionListener <T extends ActionContext> extends HealthCheckActionListener<T, HealthCheckAction<KeeperHealthCheckInstance>> {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck;
2+
3+
import com.ctrip.xpipe.api.endpoint.Endpoint;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.session.RedisSession;
5+
6+
public interface KeeperHealthCheckInstance extends HealthCheckInstance<KeeperInstanceInfo>{
7+
8+
Endpoint getEndpoint();
9+
10+
RedisSession getRedisSession();
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck;
2+
3+
import com.ctrip.xpipe.endpoint.ClusterShardHostPort;
4+
import com.ctrip.xpipe.endpoint.HostPort;
5+
6+
7+
public interface KeeperInstanceInfo extends CheckInfo {
8+
9+
ClusterShardHostPort getClusterShardHostport();
10+
11+
String getShardId();
12+
13+
String getDcId();
14+
15+
boolean isActive();
16+
17+
HostPort getHostPort();
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck;
2+
3+
public interface KeeperSupport {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper;
2+
3+
import com.ctrip.xpipe.redis.checker.healthcheck.AbstractActionContext;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.KeeperHealthCheckInstance;
5+
import com.ctrip.xpipe.redis.core.protocal.cmd.InfoResultExtractor;
6+
import org.slf4j.Logger;
7+
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.ScheduledExecutorService;
10+
11+
public abstract class AbstractKeeperInfoCommand<T extends AbstractActionContext> extends KeeperStatsCheckAction<String, InfoResultExtractor> {
12+
13+
public AbstractKeeperInfoCommand(ScheduledExecutorService scheduled, KeeperHealthCheckInstance instance, ExecutorService executors) {
14+
super(scheduled, instance, executors);
15+
}
16+
17+
@Override
18+
protected Logger getHealthCheckLogger() {
19+
return logger;
20+
}
21+
22+
@Override
23+
protected T generateActionContext(String result) {
24+
return createActionContext(result);
25+
}
26+
27+
protected abstract T createActionContext(String extractor);
28+
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper;
2+
3+
import com.ctrip.xpipe.redis.checker.healthcheck.KeeperHealthCheckInstance;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.actions.redisstats.AbstractInfoListener;
5+
import com.ctrip.xpipe.redis.checker.healthcheck.leader.AbstractKeeperLeaderAwareHealthCheckActionFactory;
6+
import com.ctrip.xpipe.redis.checker.healthcheck.leader.SiteLeaderAwareHealthCheckAction;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
9+
import java.util.List;
10+
11+
public abstract class AbstractKeeperInfoCommandActionFactory<T extends AbstractInfoListener, C extends AbstractKeeperInfoCommand>
12+
extends AbstractKeeperLeaderAwareHealthCheckActionFactory {
13+
@Autowired
14+
private List<T> listeners;
15+
16+
@Override
17+
public SiteLeaderAwareHealthCheckAction create(KeeperHealthCheckInstance instance) {
18+
C action = createAction(instance);
19+
action.addListeners(listeners);
20+
return action;
21+
}
22+
23+
protected abstract C createAction(KeeperHealthCheckInstance instance);
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper;
2+
3+
import com.ctrip.xpipe.redis.checker.healthcheck.AbstractActionContext;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.KeeperHealthCheckInstance;
5+
import com.ctrip.xpipe.redis.core.protocal.cmd.InfoResultExtractor;
6+
7+
public abstract class AbstractKeeperInfoContext extends AbstractActionContext<InfoResultExtractor, KeeperHealthCheckInstance> {
8+
public AbstractKeeperInfoContext(KeeperHealthCheckInstance instance, InfoResultExtractor infoResultExtractor) {
9+
super(instance, infoResultExtractor);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper;
2+
3+
import com.ctrip.xpipe.redis.checker.healthcheck.KeeperHealthCheckInstance;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.actions.redisstats.AbstractInstanceStatsCheckAction;
5+
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.ScheduledExecutorService;
8+
9+
public abstract class KeeperStatsCheckAction<T, K> extends AbstractInstanceStatsCheckAction<T, K , KeeperHealthCheckInstance> {
10+
11+
public KeeperStatsCheckAction(ScheduledExecutorService scheduled, KeeperHealthCheckInstance instance, ExecutorService executors) {
12+
super(scheduled, instance, executors);
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.ctrip.xpipe.redis.checker.healthcheck.actions.keeper.info;
2+
3+
import com.ctrip.xpipe.api.command.CommandFuture;
4+
import com.ctrip.xpipe.redis.checker.healthcheck.RedisHealthCheckInstance;
5+
import com.ctrip.xpipe.redis.checker.healthcheck.actions.redisstats.AbstractInfoCommandAction;
6+
import com.ctrip.xpipe.redis.checker.healthcheck.session.Callbackable;
7+
8+
import java.util.concurrent.ExecutorService;
9+
import java.util.concurrent.ScheduledExecutorService;
10+
11+
public class RedisInfoAction extends AbstractInfoCommandAction<RedisInfoActionContext> {
12+
13+
public RedisInfoAction(ScheduledExecutorService scheduled, RedisHealthCheckInstance instance, ExecutorService executors) {
14+
super(scheduled, instance, executors);
15+
}
16+
17+
@Override
18+
protected RedisInfoActionContext createActionContext(String extractor) {
19+
return new RedisInfoActionContext(instance, extractor);
20+
}
21+
22+
@Override
23+
protected CommandFuture<String> executeRedisCommandForStats(Callbackable<String> callback) {
24+
return getActionInstance().getRedisSession().info("", callback);
25+
}
26+
27+
@Override
28+
protected int getBaseCheckInterval() {
29+
return getActionInstance().getHealthCheckConfig().getKeeperCheckerIntervalMilli();
30+
}
31+
}

0 commit comments

Comments
 (0)