Skip to content

Commit accaa3d

Browse files
committed
Count the connection failure as the condition of quarantine (#4727)
* Count the connection failure as the condition of quarantine --- ### Motivation Currently, the BookieClient quarantine mechanism primarily triggers based on read and write error responses from Bookies. However, in multi-region deployments, a common failure mode is the Network Partition or DNS Resolution Failure at the Region level. In such scenarios: A Bookie remains registered in ZooKeeper (it can still heartbeat to its local ZK observer). The Client (Broker) cannot resolve the Bookie's IP or establish a TCP connection. The EnsemblePlacementPolicy (especially RegionAwareEnsemblePlacementPolicy) sees the Bookie as "Available" and repeatedly selects it to satisfy minRack or E/Qw constraints. The LedgerHandle fails to write because it cannot initialize a connection handle, triggering an Ensemble Change. Because the connection failure didn't trigger a quarantine, the placement policy picks the same problematic Bookie again in the next iteration. This creates an infinite Ensemble Change loop, causing the Ledger write to hang indefinitely and bloating the Ledger metadata in ZooKeeper with thousands of segments. * Add configuration to control the behavior (cherry picked from commit 497aa4e)
1 parent 1001f6a commit accaa3d

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ClientConfiguration.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ public class ClientConfiguration extends AbstractConfiguration<ClientConfigurati
140140
protected static final String BOOKIE_ERROR_THRESHOLD_PER_INTERVAL = "bookieErrorThresholdPerInterval";
141141
protected static final String BOOKIE_QUARANTINE_TIME_SECONDS = "bookieQuarantineTimeSeconds";
142142
protected static final String BOOKIE_QUARANTINE_RATIO = "bookieQuarantineRatio";
143+
protected static final String BOOKIE_CONNECTION_ERROR_QUARANTINE_ENABLED = "bookieConnectionErrorQuarantineEnabled";
143144

144145
// Bookie info poll interval
145146
protected static final String DISK_WEIGHT_BASED_PLACEMENT_ENABLED = "diskWeightBasedPlacementEnabled";
@@ -1479,6 +1480,28 @@ public ClientConfiguration setBookieErrorThresholdPerInterval(long thresholdPerI
14791480
return this;
14801481
}
14811482

1483+
1484+
/**
1485+
* Set if count the bookie connecting error into the quarantine condition. If this is enabled, the connection
1486+
* error will be counted into the BookieErrorThresholdPerInterval. So be careful to set the quarantine time.
1487+
*
1488+
* @param enabled
1489+
* @return
1490+
*/
1491+
public ClientConfiguration setBookieConnectionErrorQuarantineEnabled(boolean enabled) {
1492+
setProperty(BOOKIE_CONNECTION_ERROR_QUARANTINE_ENABLED, enabled);
1493+
return this;
1494+
}
1495+
1496+
/**
1497+
* Get if count the bookie connecting error into the quarantine condition.
1498+
*
1499+
* @return
1500+
*/
1501+
public boolean getBookieConnectionErrorQuarantineEnabled() {
1502+
return getBoolean(BOOKIE_CONNECTION_ERROR_QUARANTINE_ENABLED, false);
1503+
}
1504+
14821505
/**
14831506
* Get the time for which a bookie will be quarantined.
14841507
*

bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,9 @@ public void operationComplete(ChannelFuture future) {
18181818
if (state != ConnectionState.CLOSED) {
18191819
state = ConnectionState.DISCONNECTED;
18201820
}
1821+
if (conf.getBookieConnectionErrorQuarantineEnabled()) {
1822+
recordError();
1823+
}
18211824
failedConnectionCounter.inc();
18221825
}
18231826

0 commit comments

Comments
 (0)