diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/ScanAndCompareGarbageCollector.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/ScanAndCompareGarbageCollector.java index 6f67baec024..4c778a13b35 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/ScanAndCompareGarbageCollector.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/ScanAndCompareGarbageCollector.java @@ -231,8 +231,12 @@ private Set removeOverReplicatedledgers(Set bkActiveledgers, final G for (final Long ledgerId : bkActiveledgers) { try { - // check if the ledger is being replicated already by the replication worker - if (lum.isLedgerBeingReplicated(ledgerId)) { + // check ledger ensembles before creating lock nodes. + // this is to reduce the number of lock node creations and deletions in ZK. + // the ensemble check is done again after the lock node is created. + // also, check if the ledger is being replicated already by the replication worker + Versioned preCheckMetadata = ledgerManager.readLedgerMetadata(ledgerId).get(); + if (!isNotBookieIncludedInLedgerEnsembles(preCheckMetadata) || lum.isLedgerBeingReplicated(ledgerId)) { latch.countDown(); continue; } @@ -245,23 +249,12 @@ private Set removeOverReplicatedledgers(Set bkActiveledgers, final G .whenComplete((metadata, exception) -> { try { if (exception == null) { - // do not delete a ledger that is not closed, since the ensemble might - // change again and include the current bookie while we are deleting it - if (!metadata.getValue().isClosed()) { - return; + if (isNotBookieIncludedInLedgerEnsembles(metadata)) { + // this bookie is not supposed to have this ledger, + // thus we can delete this ledger now + overReplicatedLedgers.add(ledgerId); + garbageCleaner.clean(ledgerId); } - SortedMap> ensembles = - metadata.getValue().getAllEnsembles(); - for (List ensemble : ensembles.values()) { - // check if this bookie is supposed to have this ledger - if (ensemble.contains(selfBookieAddress)) { - return; - } - } - // this bookie is not supposed to have this ledger, - // thus we can delete this ledger now - overReplicatedLedgers.add(ledgerId); - garbageCleaner.clean(ledgerId); } } finally { semaphore.release(); @@ -302,4 +295,22 @@ private static MetadataBookieDriver instantiateMetadataDriver(ServerConfiguratio } } + private boolean isNotBookieIncludedInLedgerEnsembles(Versioned metadata) { + // do not delete a ledger that is not closed, since the ensemble might + // change again and include the current bookie while we are deleting it + if (!metadata.getValue().isClosed()) { + return false; + } + + SortedMap> ensembles = + metadata.getValue().getAllEnsembles(); + for (List ensemble : ensembles.values()) { + // check if this bookie is supposed to have this ledger + if (ensemble.contains(selfBookieAddress)) { + return false; + } + } + + return true; + } }