|
@@ -24,6 +24,7 @@ import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
|
|
+import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
@@ -96,16 +97,10 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
|
|
|
|
public static final int DEFAULT_TICK_TIME = 3000;
|
|
public static final int DEFAULT_TICK_TIME = 3000;
|
|
protected int tickTime = DEFAULT_TICK_TIME;
|
|
protected int tickTime = DEFAULT_TICK_TIME;
|
|
-
|
|
|
|
- public static final int commitLogCount = 500;
|
|
|
|
- public int commitLogBuffer = 700;
|
|
|
|
- public final LinkedList<Proposal> committedLog = new LinkedList<Proposal>();
|
|
|
|
- public long minCommittedLog, maxCommittedLog;
|
|
|
|
- private DataTreeBuilder treeBuilder;
|
|
|
|
- public DataTree dataTree;
|
|
|
|
protected SessionTracker sessionTracker;
|
|
protected SessionTracker sessionTracker;
|
|
private FileTxnSnapLog txnLogFactory = null;
|
|
private FileTxnSnapLog txnLogFactory = null;
|
|
- protected ConcurrentHashMap<Long, Integer> sessionsWithTimeouts;
|
|
|
|
|
|
+ private ConcurrentHashMap<Long, Integer> sessionsWithTimeouts;
|
|
|
|
+ private ZKDatabase zkDb;
|
|
protected long hzxid = 0;
|
|
protected long hzxid = 0;
|
|
public final static Exception ok = new Exception("No prob");
|
|
public final static Exception ok = new Exception("No prob");
|
|
protected RequestProcessor firstProcessor;
|
|
protected RequestProcessor firstProcessor;
|
|
@@ -128,7 +123,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
private final ServerStats serverStats;
|
|
private final ServerStats serverStats;
|
|
|
|
|
|
void removeCnxn(ServerCnxn cnxn) {
|
|
void removeCnxn(ServerCnxn cnxn) {
|
|
- dataTree.removeCnxn(cnxn);
|
|
|
|
|
|
+ zkDb.removeCnxn(cnxn);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -140,27 +135,38 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
*/
|
|
*/
|
|
public ZooKeeperServer() {
|
|
public ZooKeeperServer() {
|
|
serverStats = new ServerStats(this);
|
|
serverStats = new ServerStats(this);
|
|
- treeBuilder = new BasicDataTreeBuilder();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* Creates a ZooKeeperServer instance. It sets everything up, but doesn't
|
|
* Creates a ZooKeeperServer instance. It sets everything up, but doesn't
|
|
* actually start listening for clients until run() is invoked.
|
|
* actually start listening for clients until run() is invoked.
|
|
- *
|
|
|
|
|
|
+ *
|
|
* @param dataDir the directory to put the data
|
|
* @param dataDir the directory to put the data
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
- public ZooKeeperServer(FileTxnSnapLog txnLogFactory, int tickTime,
|
|
|
|
- DataTreeBuilder treeBuilder) throws IOException {
|
|
|
|
|
|
+ public ZooKeeperServer(FileTxnSnapLog txnLogFactory, int tickTime,
|
|
|
|
+ DataTreeBuilder treeBuilder, ZKDatabase zkDb) throws IOException {
|
|
serverStats = new ServerStats(this);
|
|
serverStats = new ServerStats(this);
|
|
- this.treeBuilder = treeBuilder;
|
|
|
|
-
|
|
|
|
this.txnLogFactory = txnLogFactory;
|
|
this.txnLogFactory = txnLogFactory;
|
|
|
|
+ this.zkDb = zkDb;
|
|
this.tickTime = tickTime;
|
|
this.tickTime = tickTime;
|
|
|
|
|
|
- LOG.info("Created server");
|
|
|
|
|
|
+ LOG.info("Created server with tickTime " + tickTime + " datadir " +
|
|
|
|
+ txnLogFactory.getDataDir() + " snapdir " + txnLogFactory.getSnapDir());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * creates a zookeeperserver instance.
|
|
|
|
+ * @param txnLogFactory the file transaction snapshot logging class
|
|
|
|
+ * @param tickTime the ticktime for the server
|
|
|
|
+ * @param treeBuilder the datatree builder
|
|
|
|
+ * @throws IOException
|
|
|
|
+ */
|
|
|
|
+ public ZooKeeperServer(FileTxnSnapLog txnLogFactory, int tickTime,
|
|
|
|
+ DataTreeBuilder treeBuilder) throws IOException {
|
|
|
|
+ this(txnLogFactory, tickTime, treeBuilder, new ZKDatabase(txnLogFactory));
|
|
|
|
+ }
|
|
|
|
+
|
|
public ServerStats serverStats() {
|
|
public ServerStats serverStats() {
|
|
return serverStats;
|
|
return serverStats;
|
|
}
|
|
}
|
|
@@ -172,7 +178,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
*/
|
|
*/
|
|
public ZooKeeperServer(File snapDir, File logDir, int tickTime)
|
|
public ZooKeeperServer(File snapDir, File logDir, int tickTime)
|
|
throws IOException {
|
|
throws IOException {
|
|
- this(new FileTxnSnapLog(snapDir,logDir),
|
|
|
|
|
|
+ this( new FileTxnSnapLog(snapDir, logDir),
|
|
tickTime,new BasicDataTreeBuilder());
|
|
tickTime,new BasicDataTreeBuilder());
|
|
}
|
|
}
|
|
|
|
|
|
@@ -182,84 +188,51 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
public ZooKeeperServer(FileTxnSnapLog txnLogFactory,DataTreeBuilder treeBuilder) throws IOException {
|
|
public ZooKeeperServer(FileTxnSnapLog txnLogFactory,DataTreeBuilder treeBuilder) throws IOException {
|
|
- this(txnLogFactory, DEFAULT_TICK_TIME, treeBuilder);
|
|
|
|
|
|
+ this(txnLogFactory, DEFAULT_TICK_TIME, treeBuilder, new ZKDatabase(txnLogFactory));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * get the zookeeper database for this server
|
|
|
|
+ * @return the zookeeper database for this server
|
|
|
|
+ */
|
|
|
|
+ public ZKDatabase getZKDatabase() {
|
|
|
|
+ return this.zkDb;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * set the zkdatabase for this zookeeper server
|
|
|
|
+ * @param zkDb
|
|
|
|
+ */
|
|
|
|
+ public void setZKDatabase(ZKDatabase zkDb) {
|
|
|
|
+ this.zkDb = zkDb;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Restore sessions and data
|
|
* Restore sessions and data
|
|
*/
|
|
*/
|
|
public void loadData() throws IOException, InterruptedException {
|
|
public void loadData() throws IOException, InterruptedException {
|
|
- PlayBackListener listener=new PlayBackListener(){
|
|
|
|
- public void onTxnLoaded(TxnHeader hdr,Record txn){
|
|
|
|
- Request r = new Request(null, 0, hdr.getCxid(),hdr.getType(),
|
|
|
|
- null, null);
|
|
|
|
- r.txn = txn;
|
|
|
|
- r.hdr = hdr;
|
|
|
|
- r.zxid = hdr.getZxid();
|
|
|
|
- addCommittedProposal(r);
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- sessionsWithTimeouts = new ConcurrentHashMap<Long, Integer>();
|
|
|
|
- dataTree = treeBuilder.build();
|
|
|
|
- setZxid(txnLogFactory.restore(dataTree,sessionsWithTimeouts,listener));
|
|
|
|
|
|
+ zkDb.loadDataBase();
|
|
|
|
+ setZxid(zkDb.loadDataBase());
|
|
// Clean up dead sessions
|
|
// Clean up dead sessions
|
|
LinkedList<Long> deadSessions = new LinkedList<Long>();
|
|
LinkedList<Long> deadSessions = new LinkedList<Long>();
|
|
- for (long session : dataTree.getSessions()) {
|
|
|
|
|
|
+ for (long session : zkDb.getSessions()) {
|
|
|
|
+ sessionsWithTimeouts = zkDb.getSessionWithTimeOuts();
|
|
if (sessionsWithTimeouts.get(session) == null) {
|
|
if (sessionsWithTimeouts.get(session) == null) {
|
|
deadSessions.add(session);
|
|
deadSessions.add(session);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- dataTree.initialized = true;
|
|
|
|
|
|
+ zkDb.setDataTreeInit(true);
|
|
for (long session : deadSessions) {
|
|
for (long session : deadSessions) {
|
|
// XXX: Is lastProcessedZxid really the best thing to use?
|
|
// XXX: Is lastProcessedZxid really the best thing to use?
|
|
- killSession(session, dataTree.lastProcessedZxid);
|
|
|
|
|
|
+ killSession(session, zkDb.getDataTreeLastProcessedZxid());
|
|
}
|
|
}
|
|
// Make a clean snapshot
|
|
// Make a clean snapshot
|
|
takeSnapshot();
|
|
takeSnapshot();
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * maintains a list of last 500 or so committed requests. This is used for
|
|
|
|
- * fast follower synchronization.
|
|
|
|
- *
|
|
|
|
- * @param request committed request
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- public void addCommittedProposal(Request request) {
|
|
|
|
- synchronized (committedLog) {
|
|
|
|
- if (committedLog.size() > commitLogCount) {
|
|
|
|
- committedLog.removeFirst();
|
|
|
|
- minCommittedLog = committedLog.getFirst().packet.getZxid();
|
|
|
|
- }
|
|
|
|
- if (committedLog.size() == 0) {
|
|
|
|
- minCommittedLog = request.zxid;
|
|
|
|
- maxCommittedLog = request.zxid;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
- BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
|
|
|
|
- try {
|
|
|
|
- request.hdr.serialize(boa, "hdr");
|
|
|
|
- if (request.txn != null) {
|
|
|
|
- request.txn.serialize(boa, "txn");
|
|
|
|
- }
|
|
|
|
- baos.close();
|
|
|
|
- } catch (IOException e) {
|
|
|
|
- LOG.error("This really should be impossible", e);
|
|
|
|
- }
|
|
|
|
- QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid,
|
|
|
|
- baos.toByteArray(), null);
|
|
|
|
- Proposal p = new Proposal();
|
|
|
|
- p.packet = pp;
|
|
|
|
- p.request = request;
|
|
|
|
- committedLog.add(p);
|
|
|
|
- maxCommittedLog = p.packet.getZxid();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public void takeSnapshot(){
|
|
public void takeSnapshot(){
|
|
try {
|
|
try {
|
|
- txnLogFactory.save(dataTree, sessionsWithTimeouts);
|
|
|
|
|
|
+ txnLogFactory.save(zkDb.getDataTree(), zkDb.getSessionWithTimeOuts());
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
LOG.fatal("Severe unrecoverable error, exiting", e);
|
|
LOG.fatal("Severe unrecoverable error, exiting", e);
|
|
// This is a severe error that we cannot recover from,
|
|
// This is a severe error that we cannot recover from,
|
|
@@ -268,18 +241,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public void serializeSnapshot(OutputArchive oa) throws IOException,
|
|
|
|
- InterruptedException {
|
|
|
|
- SerializeUtils.serializeSnapshot(dataTree, oa, sessionsWithTimeouts);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void deserializeSnapshot(InputArchive ia) throws IOException {
|
|
|
|
- sessionsWithTimeouts = new ConcurrentHashMap<Long, Integer>();
|
|
|
|
- dataTree = treeBuilder.build();
|
|
|
|
-
|
|
|
|
- SerializeUtils.deserializeSnapshot(dataTree,ia,sessionsWithTimeouts);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* This should be called from a synchronized block on this!
|
|
* This should be called from a synchronized block on this!
|
|
*/
|
|
*/
|
|
@@ -312,7 +274,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
}
|
|
}
|
|
|
|
|
|
protected void killSession(long sessionId, long zxid) {
|
|
protected void killSession(long sessionId, long zxid) {
|
|
- dataTree.killSession(sessionId, zxid);
|
|
|
|
|
|
+ zkDb.killSession(sessionId, zxid);
|
|
if (LOG.isTraceEnabled()) {
|
|
if (LOG.isTraceEnabled()) {
|
|
ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK,
|
|
ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK,
|
|
"ZooKeeperServer --- killSession: 0x"
|
|
"ZooKeeperServer --- killSession: 0x"
|
|
@@ -358,7 +320,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
MBeanRegistry.getInstance().register(jmxServerBean, null);
|
|
MBeanRegistry.getInstance().register(jmxServerBean, null);
|
|
|
|
|
|
try {
|
|
try {
|
|
- jmxDataTreeBean = new DataTreeBean(dataTree);
|
|
|
|
|
|
+ jmxDataTreeBean = new DataTreeBean(zkDb.getDataTree());
|
|
MBeanRegistry.getInstance().register(jmxDataTreeBean, jmxServerBean);
|
|
MBeanRegistry.getInstance().register(jmxDataTreeBean, jmxServerBean);
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
LOG.warn("Failed to register with JMX", e);
|
|
LOG.warn("Failed to register with JMX", e);
|
|
@@ -371,7 +333,11 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
}
|
|
}
|
|
|
|
|
|
public void startup() throws IOException, InterruptedException {
|
|
public void startup() throws IOException, InterruptedException {
|
|
- if (dataTree == null) {
|
|
|
|
|
|
+ //check to see if zkDb is not null
|
|
|
|
+ if (zkDb == null) {
|
|
|
|
+ zkDb = new ZKDatabase(this.txnLogFactory);
|
|
|
|
+ }
|
|
|
|
+ if (!zkDb.isInitialized()) {
|
|
loadData();
|
|
loadData();
|
|
}
|
|
}
|
|
createSessionTracker();
|
|
createSessionTracker();
|
|
@@ -395,7 +361,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
}
|
|
}
|
|
|
|
|
|
protected void createSessionTracker() {
|
|
protected void createSessionTracker() {
|
|
- sessionTracker = new SessionTrackerImpl(this, sessionsWithTimeouts,
|
|
|
|
|
|
+ sessionTracker = new SessionTrackerImpl(this, zkDb.getSessionWithTimeOuts(),
|
|
tickTime, 1);
|
|
tickTime, 1);
|
|
((SessionTrackerImpl)sessionTracker).start();
|
|
((SessionTrackerImpl)sessionTracker).start();
|
|
}
|
|
}
|
|
@@ -416,8 +382,8 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
if (firstProcessor != null) {
|
|
if (firstProcessor != null) {
|
|
firstProcessor.shutdown();
|
|
firstProcessor.shutdown();
|
|
}
|
|
}
|
|
- if (dataTree != null) {
|
|
|
|
- dataTree.clear();
|
|
|
|
|
|
+ if (zkDb != null) {
|
|
|
|
+ zkDb.clear();
|
|
}
|
|
}
|
|
|
|
|
|
unregisterJMX();
|
|
unregisterJMX();
|
|
@@ -638,7 +604,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
* datatree
|
|
* datatree
|
|
*/
|
|
*/
|
|
public long getLastProcessedZxid() {
|
|
public long getLastProcessedZxid() {
|
|
- return dataTree.lastProcessedZxid;
|
|
|
|
|
|
+ return zkDb.getDataTreeLastProcessedZxid();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -658,17 +624,9 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
public void truncateLog(long zxid) throws IOException {
|
|
public void truncateLog(long zxid) throws IOException {
|
|
- this.txnLogFactory.truncateLog(zxid);
|
|
|
|
|
|
+ this.zkDb.truncateLog(zxid);
|
|
}
|
|
}
|
|
-
|
|
|
|
- /**
|
|
|
|
- * the snapshot and logwriter for this instance
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- public FileTxnSnapLog getLogWriter() {
|
|
|
|
- return this.txnLogFactory;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+
|
|
public int getTickTime() {
|
|
public int getTickTime() {
|
|
return tickTime;
|
|
return tickTime;
|
|
}
|
|
}
|
|
@@ -677,14 +635,6 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
this.tickTime = tickTime;
|
|
this.tickTime = tickTime;
|
|
}
|
|
}
|
|
|
|
|
|
- public DataTreeBuilder getTreeBuilder() {
|
|
|
|
- return treeBuilder;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void setTreeBuilder(DataTreeBuilder treeBuilder) {
|
|
|
|
- this.treeBuilder = treeBuilder;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public int getClientPort() {
|
|
public int getClientPort() {
|
|
return serverCnxnFactory != null ? serverCnxnFactory.ss.socket().getLocalPort() : -1;
|
|
return serverCnxnFactory != null ? serverCnxnFactory.ss.socket().getLocalPort() : -1;
|
|
}
|
|
}
|
|
@@ -700,4 +650,6 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
|
|
public String getState() {
|
|
public String getState() {
|
|
return "standalone";
|
|
return "standalone";
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|