From 952907a43aba7c96e3b80d850558e670b853f7f3 Mon Sep 17 00:00:00 2001
From: thetumbled <843221020@qq.com>
Date: Thu, 23 May 2024 11:50:30 +0800
Subject: [PATCH 1/3] add conf.
---
.../common/collections/HourRange.java | 58 +++++++++++++++++++
.../bookkeeper/conf/ServerConfiguration.java | 21 +++++++
2 files changed, 79 insertions(+)
create mode 100644 bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
new file mode 100644
index 00000000000..376d1676ebf
--- /dev/null
+++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
@@ -0,0 +1,58 @@
+package org.apache.bookkeeper.common.collections;
+
+import java.util.List;
+
+/**
+ * Represents a range of hours.
+ *
The range is defined as a comma-separated list of ranges. Each range is defined as a start hour and an end hour
+ * separated by a dash. For example, "0-5, 10-15" represents the range of hours from 0 to 5 and 10 to 15.
+ *
The range is inclusive, i.e. the start and end hours are included in the range.
+ *
The range is defined in 24-hour format, i.e. the hours are in the range of 0 to 23.
+ *
we require that the start hour is less than or equal to the end hour.
+ */
+public class HourRange {
+ private List ranges;
+
+ public HourRange(String range) {
+ String[] parts = range.split(",");
+ for (String part : parts) {
+ String[] rangeParts = part.split("-");
+ if (rangeParts.length != 2) {
+ throw new IllegalArgumentException("Invalid range: " + part);
+ }
+ int startHour = Integer.parseInt(rangeParts[0]);
+ int endHour = Integer.parseInt(rangeParts[1]);
+ ranges.add(new Range(startHour, endHour));
+ }
+ }
+
+ public boolean contains(int hour) {
+ for (Range range : ranges) {
+ if (range.contains(hour)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static HourRange parse(String range) {
+ return new HourRange(range);
+ }
+}
+
+class Range {
+ private int startHour;
+ private int endHour;
+
+ public Range(int startHour, int endHour) {
+ if (startHour > endHour | startHour < 0 || startHour > 23 || endHour < 0 || endHour > 23) {
+ throw new IllegalArgumentException("Invalid hour range: " + startHour + " - " + endHour);
+ }
+ this.startHour = startHour;
+ this.endHour = endHour;
+ }
+
+ public boolean contains(int hour) {
+ return hour >= startHour && hour <= endHour;
+ }
+}
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java
index 51e45dc6f80..c693ab0f415 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java
@@ -30,6 +30,7 @@
import org.apache.bookkeeper.bookie.LedgerStorage;
import org.apache.bookkeeper.bookie.SortedLedgerStorage;
import org.apache.bookkeeper.bookie.storage.ldb.DbLedgerStorage;
+import org.apache.bookkeeper.common.collections.HourRange;
import org.apache.bookkeeper.common.conf.ConfigDef;
import org.apache.bookkeeper.common.conf.ConfigException;
import org.apache.bookkeeper.common.conf.ConfigKey;
@@ -105,6 +106,7 @@ public class ServerConfiguration extends AbstractConfiguration
Date: Thu, 23 May 2024 16:45:39 +0800
Subject: [PATCH 2/3] support skipping compaction at busy times.
---
.../bookkeeper/bookie/GarbageCollectorThread.java | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
index e58064cfd90..e324a60d6c3 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
@@ -28,6 +28,7 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.io.IOException;
+import java.time.LocalTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.Executors;
@@ -43,6 +44,7 @@
import org.apache.bookkeeper.bookie.stats.GarbageCollectorStats;
import org.apache.bookkeeper.bookie.storage.EntryLogger;
import org.apache.bookkeeper.bookie.storage.ldb.PersistentEntryLogMetadataMap;
+import org.apache.bookkeeper.common.collections.HourRange;
import org.apache.bookkeeper.common.util.MathUtils;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.meta.LedgerManager;
@@ -125,6 +127,7 @@ public class GarbageCollectorThread implements Runnable {
private static final AtomicLong threadNum = new AtomicLong(0);
final AbstractLogCompactor.Throttler throttler;
+ final HourRange skipCompactionHourRange;
/**
* Create a garbage collector thread.
@@ -223,6 +226,7 @@ public void removeEntryLog(long logToRemove) {
}
this.throttler = new AbstractLogCompactor.Throttler(conf);
+ this.skipCompactionHourRange = conf.getSkipCompactionHourRange();
if (minorCompactionInterval > 0 && minorCompactionThreshold > 0) {
if (minorCompactionThreshold > 1.0d) {
throw new IOException("Invalid minor compaction threshold "
@@ -430,7 +434,7 @@ public void runWithFlags(boolean force, boolean suspendMajor, boolean suspendMin
long curTime = System.currentTimeMillis();
if (((isForceMajorCompactionAllow && force) || (enableMajorCompaction
&& (force || curTime - lastMajorCompactionTime > majorCompactionInterval)))
- && (!suspendMajor)) {
+ && (!suspendMajor) && (!skipCompactionHourRange.contains(LocalTime.now().getHour()))) {
// enter major compaction
LOG.info("Enter major compaction, suspendMajor {}", suspendMajor);
majorCompacting.set(true);
@@ -445,7 +449,7 @@ public void runWithFlags(boolean force, boolean suspendMajor, boolean suspendMin
}
} else if (((isForceMinorCompactionAllow && force) || (enableMinorCompaction
&& (force || curTime - lastMinorCompactionTime > minorCompactionInterval)))
- && (!suspendMinor)) {
+ && (!suspendMinor) && (!skipCompactionHourRange.contains(LocalTime.now().getHour()))) {
// enter minor compaction
LOG.info("Enter minor compaction, suspendMinor {}", suspendMinor);
minorCompacting.set(true);
@@ -577,7 +581,7 @@ void doCompactEntryLogs(double threshold, long maxTimeMillis) throws EntryLogMet
}
if ((usage >= threshold
|| (maxTimeMillis > 0 && timeDiff.getValue() >= maxTimeMillis)
- || !running)) {
+ || !running || skipCompactionHourRange.contains(LocalTime.now().getHour()))) {
// We allow the usage limit calculation to continue so that we get an accurate
// report of where the usage was prior to running compaction.
return;
@@ -607,7 +611,8 @@ void doCompactEntryLogs(double threshold, long maxTimeMillis) throws EntryLogMet
timeDiff.setValue(end.getValue() - start);
}
- if ((maxTimeMillis > 0 && timeDiff.getValue() >= maxTimeMillis) || !running) {
+ if ((maxTimeMillis > 0 && timeDiff.getValue() >= maxTimeMillis) || !running
+ || skipCompactionHourRange.contains(LocalTime.now().getHour())) {
// We allow the usage limit calculation to continue so that we get an accurate
// report of where the usage was prior to running compaction.
break stopCompaction;
From c2bb55a5e8abe21f47090f7f1078bafc1ec2552c Mon Sep 17 00:00:00 2001
From: thetumbled <843221020@qq.com>
Date: Thu, 23 May 2024 17:15:43 +0800
Subject: [PATCH 3/3] fix.
---
.../bookkeeper/common/collections/HourRange.java | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
index 376d1676ebf..dc1405222b2 100644
--- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
+++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/collections/HourRange.java
@@ -1,5 +1,6 @@
package org.apache.bookkeeper.common.collections;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -11,12 +12,18 @@
* we require that the start hour is less than or equal to the end hour.
*/
public class HourRange {
+ private static final String RANGE_SEPARATOR = ",";
+ private static final String RANGE_PART_SEPARATOR = "-";
private List ranges;
public HourRange(String range) {
- String[] parts = range.split(",");
+ ranges = new ArrayList<>();
+ if (range == null || range.isEmpty()) {
+ return;
+ }
+ String[] parts = range.split(RANGE_SEPARATOR);
for (String part : parts) {
- String[] rangeParts = part.split("-");
+ String[] rangeParts = part.split(RANGE_PART_SEPARATOR);
if (rangeParts.length != 2) {
throw new IllegalArgumentException("Invalid range: " + part);
}