You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by GitBox <gi...@apache.org> on 2019/01/15 01:37:16 UTC
[zookeeper] Diff for: [GitHub] enixon closed pull request #770:
ZOOKEEPER-3244: Add option to snapshot based on log size
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/SyncRequestProcessor.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/SyncRequestProcessor.java
index 57cca9c3c4..02d0dd61db 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/SyncRequestProcessor.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/SyncRequestProcessor.java
@@ -67,6 +67,17 @@
*/
private static int snapCount = ZooKeeperServer.getSnapCount();
+ /**
+ * The total size of log entries before starting a snapshot
+ */
+ private static long snapSize = ZooKeeperServer.getSnapSize();
+
+ /**
+ * Random numbers used to vary snapshot timing
+ */
+ private int randRoll;
+ private long randSize;
+
private final Request requestOfDeath = Request.requestOfDeath;
public SyncRequestProcessor(ZooKeeperServer zks,
@@ -95,6 +106,18 @@ public static int getSnapCount() {
return snapCount;
}
+ private boolean shouldSnapshot() {
+ int logCount = zks.getZKDatabase().getTxnCount();
+ long logSize = zks.getZKDatabase().getTxnSize();
+ return (logCount > (snapCount / 2 + randRoll)) ||
+ (logSize > (snapSize / 2 + randSize));
+ }
+
+ private void resetSnapshotStats() {
+ randRoll = r.nextInt(snapCount/2);
+ randSize = Math.abs(r.nextLong() % (snapSize/2));
+ }
+
@Override
public void run() {
try {
@@ -102,7 +125,7 @@ public void run() {
// we do this in an attempt to ensure that not all of the servers
// in the ensemble take a snapshot at the same time
- int randRoll = r.nextInt(snapCount/2);
+ resetSnapshotStats();
while (true) {
Request si = null;
if (toFlush.isEmpty()) {
@@ -120,9 +143,8 @@ public void run() {
if (si != null) {
// track the number of records written to the log
if (zks.getZKDatabase().append(si)) {
- logCount++;
- if (logCount > (snapCount / 2 + randRoll)) {
- randRoll = r.nextInt(snapCount/2);
+ if (shouldSnapshot()) {
+ resetSnapshotStats();
// roll the log
zks.getZKDatabase().rollLog();
// take a snapshot
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZKDatabase.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZKDatabase.java
index 753461a5e6..251859e170 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZKDatabase.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZKDatabase.java
@@ -28,6 +28,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
@@ -88,6 +89,11 @@
protected ReentrantReadWriteLock logLock = new ReentrantReadWriteLock();
volatile private boolean initialized = false;
+ /**
+ * Number of txn since last snapshot;
+ */
+ private AtomicInteger txnCount = new AtomicInteger(0);
+
/**
* the filetxnsnaplog that this zk database
* maps to. There is a one to one relationship
@@ -581,6 +587,7 @@ public void serializeSnapshot(OutputArchive oa) throws IOException,
* @return true if the append was succesfull and false if not
*/
public boolean append(Request si) throws IOException {
+ txnCount.incrementAndGet();
return this.snapLog.append(si);
}
@@ -589,6 +596,7 @@ public boolean append(Request si) throws IOException {
*/
public void rollLog() throws IOException {
this.snapLog.rollLog();
+ resetTxnCount();
}
/**
@@ -661,4 +669,26 @@ public boolean removeWatch(String path, WatcherType type, Watcher watcher) {
public DataTree createDataTree() {
return new DataTree();
}
+
+ /**
+ * Reset the number of txn since last rollLog
+ */
+ public void resetTxnCount() {
+ txnCount.set(0);
+ snapLog.setTotalLogSize(0);
+ }
+
+ /**
+ * Get the number of txn since last snapshot
+ */
+ public int getTxnCount() {
+ return txnCount.get();
+ }
+
+ /**
+ * Get the size of txn since last snapshot
+ */
+ public long getTxnSize() {
+ return snapLog.getTotalLogSize();
+ }
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java
index 20ab023ec5..1355e0f6b0 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java
@@ -873,6 +873,10 @@ public int getGlobalOutstandingLimit() {
return limit;
}
+ public static long getSnapSize() {
+ return Long.getLong("zookeeper.snapSize", 4294967296L); // 4GB by default
+ }
+
public void setServerCnxnFactory(ServerCnxnFactory factory) {
serverCnxnFactory = factory;
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
index c739152799..195ec56fed 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java
@@ -157,6 +157,12 @@
private volatile long syncElapsedMS = -1L;
+ /**
+ * A running total of all complete log files
+ * This does not include the current file being written to
+ */
+ private long prevLogsRunningTotal;
+
/**
* constructor for FileTxnLog. Take the directory
* where the txnlogs are stored
@@ -202,6 +208,14 @@ public synchronized long getCurrentLogSize() {
return 0;
}
+ public synchronized void setTotalLogSize(long size) {
+ prevLogsRunningTotal = size;
+ }
+
+ public long getTotalLogSize() {
+ return prevLogsRunningTotal + getCurrentLogSize();
+ }
+
/**
* creates a checksum algorithm to be used
* @return the checksum used for this txnlog
@@ -217,8 +231,11 @@ protected Checksum makeChecksumAlgorithm(){
public synchronized void rollLog() throws IOException {
if (logStream != null) {
this.logStream.flush();
+ prevLogsRunningTotal += getCurrentLogSize();
this.logStream = null;
oa = null;
+
+ // Roll over the current log file into the running total
}
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
index e6d299831c..7409af8503 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java
@@ -491,7 +491,7 @@ public File findMostRecentSnapshot() throws IOException {
/**
* append the request to the transaction logs
* @param si the request to be appended
- * returns true iff something appended, otw false
+ * @return true iff something appended, otw false
* @throws IOException
*/
public boolean append(Request si) throws IOException {
@@ -554,4 +554,12 @@ public SnapDirContentCheckException(String msg) {
super(msg);
}
}
+
+ public void setTotalLogSize(long size) {
+ txnLog.setTotalLogSize(size);
+ }
+
+ public long getTotalLogSize() {
+ return txnLog.getTotalLogSize();
+ }
}
diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLog.java
index 9781f45307..184b59df1f 100644
--- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLog.java
+++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLog.java
@@ -46,7 +46,7 @@
* Append a request to the transaction log
* @param hdr the transaction header
* @param r the transaction itself
- * returns true iff something appended, otw false
+ * @return true iff something appended, otw false
* @throws IOException
*/
boolean append(TxnHeader hdr, Record r) throws IOException;
@@ -100,6 +100,17 @@
* close the transactions logs
*/
void close() throws IOException;
+
+ /**
+ * Sets the total size of all log files
+ */
+ void setTotalLogSize(long size);
+
+ /**
+ * Gets the total size of all log files
+ */
+ long getTotalLogSize();
+
/**
* an iterating interface for reading
* transaction logs.
With regards,
Apache Git Services