package com.taobao.tddl.repo.bdb.spi;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sleepycat.je.Durability;
import com.sleepycat.je.Durability.ReplicaAckPolicy;
import com.sleepycat.je.Durability.SyncPolicy;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.rep.InsufficientLogException;
import com.sleepycat.je.rep.NetworkRestore;
import com.sleepycat.je.rep.NetworkRestoreConfig;
import com.sleepycat.je.rep.NoConsistencyRequiredPolicy;
import com.sleepycat.je.rep.QuorumPolicy;
import com.sleepycat.je.rep.ReplicatedEnvironment;
import com.sleepycat.je.rep.ReplicationConfig;
import com.sleepycat.je.rep.UnknownMasterException;
/**
* @author jianxing <jianxing.qx@taobao.com>
*/
public class JE_HA_Repository extends JE_Repository {
public static final Log logger = LogFactory.getLog(JE_HA_Repository.class.getName());
// public JE_HA_Repository(CommandExecutorFactory commandExecutorFactory) {
// super(commandExecutorFactory);
// }
// public JE_HA_Repository(ServerConfig config,CommandExecutorFactory
// commandExecutorFactory) {
// super(config, commandExecutorFactory);
// }
@Override
public void doInit() {
File repo_dir = new File(config.getRepoDir());
repo_dir.delete();// 删除空目录
ReplicationConfig repConfig = new ReplicationConfig();
repConfig.setGroupName(config.getGroupName());
repConfig.setNodeName(config.getNodeName());
repConfig.setNodePriority(config.getPriority());
repConfig.setConsistencyPolicy(new NoConsistencyRequiredPolicy());
repConfig.setReplicaAckTimeout(5, TimeUnit.SECONDS);
// TODO shenxun:无效
repConfig.setConfigParam(ReplicationConfig.CONSISTENCY_POLICY, "NoConsistencyRequiredPolicy");
// 设置为1小时
repConfig.setConfigParam(ReplicationConfig.REP_STREAM_TIMEOUT, "1 H");
String nodes = config.getGroupNodes();
// nodeName1:ip:port,
Map<String, String> nodesMap = new HashMap<String, String>();
String firstNode = null;
String[] ss = nodes.split(",");
for (String s : ss) {
String[] _s = s.split(":");
if (_s.length == 3) {
nodesMap.put(_s[0], _s[1] + ":" + _s[2]);
if (firstNode == null) {
firstNode = _s[0];
}
}
}
String helperHosts = "";
if (config.getNodeName().equals(firstNode) && !repo_dir.exists()) {
StringBuilder sb = new StringBuilder();
sb.append("I am master Node . My node name is ").append(config.getNodeName());
sb.append(" ip/port is ").append(nodesMap.get(config.getNodeName()));
sb.append(", while first node is ").append(firstNode);
logger.warn(sb.toString());
helperHosts = nodesMap.get(firstNode);
} else {
for (Entry<String, String> entry : nodesMap.entrySet()) {
helperHosts += entry.getValue() + ",";
}
StringBuilder sb = new StringBuilder();
sb.append("I am not master node , My node name is (")
.append(config.getNodeName())
.append("-->")
.append(nodesMap.get(config.getNodeName()))
.append(")")
.append(", first node is (");
sb.append(firstNode).append("-->").append(nodesMap.get(config.getNodeName())).append(")");
sb.append(" . helper hosts :").append(helperHosts);
logger.warn(sb.toString());
}
repConfig.setHelperHosts(helperHosts);
repConfig.setNodeHostPort(nodesMap.get(config.getNodeName()));
EnvironmentConfig envConfig = new EnvironmentConfig();
commonConfig(envConfig, config);
envConfig.setAllowCreate(true);
String[] _durability = config.getDurability();
this.durability = new Durability(SyncPolicy.valueOf(_durability[0]),
SyncPolicy.valueOf(_durability[1]),
ReplicaAckPolicy.valueOf(_durability[2]));
envConfig.setCachePercent(config.getCachePercent());
if (config.isTransactional()) {
envConfig.setTransactional(config.isTransactional());
envConfig.setTxnTimeout(config.getTxnTimeout(), TimeUnit.SECONDS);
envConfig.setDurability(durability);
}
if (!repo_dir.exists()) {
repo_dir.mkdirs();
}
int REP_HANDLE_RETRY_MAX = 100;
for (int i = 0; i < REP_HANDLE_RETRY_MAX; i++) {
try {
logger.info(repConfig.getHelperHosts());
env = new ReplicatedEnvironment(repo_dir,
repConfig,
envConfig,
new NoConsistencyRequiredPolicy(),
QuorumPolicy.SIMPLE_MAJORITY);
logger.info("nodeName:" + config.getNodeName() + ", ReplicatedEnvironment init successful.");
logger.info("state:" + ((ReplicatedEnvironment) env).getState());
break;
} catch (UnknownMasterException ume) {
try {
logger.info("UnknownMasterException,sleep 5s.");
Thread.sleep(5 * 1000);
} catch (InterruptedException ex) {
logger.warn("", ex);
}
continue;
} catch (InsufficientLogException ile) {
/* A network restore is required, make the necessary calls */
NetworkRestore restore = new NetworkRestore();
NetworkRestoreConfig conf = new NetworkRestoreConfig();
conf.setRetainLogFiles(false); // delete obsolete log files.
restore.execute(ile, conf);
// retry
continue;
} /*
* catch (EnvironmentFailureException efe) { A network restore is
* required, make the necessary calls
* System.err.println("catch EnvironmentFailureException"); if
* (efe.getCause() instanceof InsufficientLogException) {
* System.err.println("efe is InsufficientLogException");
* NetworkRestore restore = new NetworkRestore();
* NetworkRestoreConfig conf = new NetworkRestoreConfig();
* conf.setRetainLogFiles(true); // delete obsolete log files.
* restore.execute((InsufficientLogException) efe.getCause(),
* conf); } else { System.out.println("execute backup... "); for
* (Entry<String, String> entry : nodesMap.entrySet()) {
* if(entry.getKey().equals(config.getNodeName())){ continue; }
* InetSocketAddress addr = new
* InetSocketAddress(entry.getValue().split(":")[0],
* Integer.parseInt(entry.getValue().split(":")[1]));
* System.out.println(addr); FileManager fm = new
* FileManager(env.getEnvironmentImpl(), repo_dir, false);
* NetworkBackup backup = new NetworkBackup(addr, repo_dir,
* NameIdPair.NOCHECK, true, fm); try { backup.execute(); } catch
* (Exception ex) { ex.printStackTrace(); } }
* System.out.println("backup end"); } // retry continue; }
*/
catch (Throwable e) {
System.err.println("error " + e + ". class" + e.getClass());
}
}
if (env == null) {
throw new IllegalStateException("getEnvironment: reached max retries");
}
cef = new CommandHandlerFactoryBDBImpl();
cursorFactoryBDBImp = new CursorFactoryBDBImp();
}
@Override
public boolean isWriteAble() {
return ((ReplicatedEnvironment) env).getState().isMaster();
}
public int cleanLog() {
return env.cleanLog();
}
}