This is an automated email from the ASF dual-hosted git repository.
ayegorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/master by this push:
new 181a6dc Add throttle for rebuild entryMetadataMap
181a6dc is described below
commit 181a6dcd35485613d65fdf2bad082bc1ef97f313
Author: Hang Chen <[email protected]>
AuthorDate: Thu Mar 10 08:04:20 2022 +0800
Add throttle for rebuild entryMetadataMap
### Motivation
When a bookie restart, the garbageCollectorThread will rebuild
entryMetadataMap from all the entry log files in ledger directory. For normal
case, it will extract the EntryLogMetadata from the index in entry log file.
However, if there's no index, then fallback to scanning the entry log file.
In user's production environment, the log files without index occupied 4%.
The total entry log files is 80000, and the log files without index is 3000.
The default entry log file size is 2GB, and the garbageCollectorThread will
read 3000 * 2GB = 6TB data without speed limit, which will cause ledger disk IO
util runs high for dozens of minutes and affect ledger read and write latency.
### Modification
1. Add read speed rate limiter for scanning entry log file in
entryMetadataMap rebuild.
Reviewers: Nicolò Boschi <[email protected]>, Enrico Olivelli
<[email protected]>
This closes #2963 from
hangc0276/chenhang/add_throttle_for_build_entryMetadataMap
---
.../org/apache/bookkeeper/bookie/EntryLogger.java | 25 +++++++++++++++++++++-
.../bookkeeper/bookie/GarbageCollectorThread.java | 4 +++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
index 49a9ca4..8be995a 100644
---
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
+++
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
@@ -1055,7 +1055,7 @@ public class EntryLogger {
}
public EntryLogMetadata getEntryLogMetadata(long entryLogId) throws
IOException {
- // First try to extract the EntryLogMetada from the index, if there's
no index then fallback to scanning the
+ // First try to extract the EntryLogMetadata from the index, if
there's no index then fallback to scanning the
// entry log
try {
return extractEntryLogMetadataFromIndex(entryLogId);
@@ -1067,6 +1067,20 @@ public class EntryLogger {
}
}
+ public EntryLogMetadata getEntryLogMetadata(long entryLogId,
AbstractLogCompactor.Throttler throttler)
+ throws IOException {
+ // First try to extract the EntryLogMetadata from the index, if
there's no index then fallback to scanning the
+ // entry log
+ try {
+ return extractEntryLogMetadataFromIndex(entryLogId);
+ } catch (Exception e) {
+ LOG.info("Failed to get ledgers map index from: {}.log : {}",
entryLogId, e.getMessage());
+
+ // Fall-back to scanning
+ return extractEntryLogMetadataByScanning(entryLogId, throttler);
+ }
+ }
+
EntryLogMetadata extractEntryLogMetadataFromIndex(long entryLogId) throws
IOException {
Header header = getHeaderForLogId(entryLogId);
@@ -1151,12 +1165,21 @@ public class EntryLogger {
}
private EntryLogMetadata extractEntryLogMetadataByScanning(long
entryLogId) throws IOException {
+ return extractEntryLogMetadataByScanning(entryLogId, null);
+ }
+
+ private EntryLogMetadata extractEntryLogMetadataByScanning(long entryLogId,
+
AbstractLogCompactor.Throttler throttler)
+ throws IOException {
final EntryLogMetadata meta = new EntryLogMetadata(entryLogId);
// Read through the entry log file and extract the entry log meta
scanEntryLog(entryLogId, new EntryLogScanner() {
@Override
public void process(long ledgerId, long offset, ByteBuf entry)
throws IOException {
+ if (throttler != null) {
+ throttler.acquire(conf.getIsThrottleByBytes() ?
entry.readableBytes() : 1);
+ }
// add new entry size of a ledger to entry log meta
meta.addLedgerSize(ledgerId, entry.readableBytes() + 4);
}
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 6b559e0..6195169 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
@@ -126,6 +126,7 @@ public class GarbageCollectorThread extends SafeRunnable {
final LedgerDirsManager ledgerDirsManager;
private static final AtomicLong threadNum = new AtomicLong(0);
+ final AbstractLogCompactor.Throttler throttler;
/**
* Create a garbage collector thread.
*
@@ -216,6 +217,7 @@ public class GarbageCollectorThread extends SafeRunnable {
this.compactor = new EntryLogCompactor(conf, entryLogger,
ledgerStorage, remover);
}
+ this.throttler = new AbstractLogCompactor.Throttler(conf);
if (minorCompactionInterval > 0 && minorCompactionThreshold > 0) {
if (minorCompactionThreshold > 1.0f) {
throw new IOException("Invalid minor compaction threshold "
@@ -696,7 +698,7 @@ public class GarbageCollectorThread extends SafeRunnable {
try {
// Read through the entry log file and extract the entry log
meta
- EntryLogMetadata entryLogMeta =
entryLogger.getEntryLogMetadata(entryLogId);
+ EntryLogMetadata entryLogMeta =
entryLogger.getEntryLogMetadata(entryLogId, throttler);
removeIfLedgerNotExists(entryLogMeta);
if (entryLogMeta.isEmpty()) {
entryLogger.removeEntryLog(entryLogId);