HDFS-9305. Delayed heartbeat processing causes storm of subsequent heartbeats. (Contributed by Arpit Agarwal)

This commit is contained in:
Arpit Agarwal 2015-10-26 15:45:02 -07:00
parent f2fd011cc1
commit 653ef52ef2
3 changed files with 27 additions and 2 deletions

View File

@ -75,6 +75,9 @@ Release 2.7.2 - UNRELEASED
HDFS-9290. DFSClient#callAppend() is not backward compatible for slightly
older NameNodes. (Tony Wu via kihwal)
HDFS-9305. Delayed heartbeat processing causes storm of subsequent
heartbeats. (Arpit Agarwal)
Release 2.7.1 - 2015-07-06
INCOMPATIBLE CHANGES

View File

@ -539,6 +539,7 @@ class BPServiceActor implements Runnable {
}
HeartbeatResponse sendHeartBeat() throws IOException {
scheduler.scheduleNextHeartbeat();
StorageReport[] reports =
dn.getFSDataset().getStorageReports(bpos.getBlockPoolId());
if (LOG.isDebugEnabled()) {
@ -648,7 +649,6 @@ class BPServiceActor implements Runnable {
// -- Total capacity
// -- Bytes remaining
//
scheduler.scheduleNextHeartbeat();
if (!dn.areHeartbeatsDisabledForTests()) {
HeartbeatResponse resp = sendHeartBeat();
assert resp != null;
@ -1038,7 +1038,7 @@ class BPServiceActor implements Runnable {
long scheduleNextHeartbeat() {
// Numerical overflow is possible here and is okay.
nextHeartbeatTime += heartbeatIntervalMs;
nextHeartbeatTime = monotonicNow() + heartbeatIntervalMs;
return nextHeartbeatTime;
}

View File

@ -144,6 +144,28 @@ public class TestBpServiceActorScheduler {
}
}
/**
* Regression test for HDFS-9305.
* Delayed processing of a heartbeat can cause a subsequent heartbeat
* storm.
*/
@Test
public void testScheduleDelayedHeartbeat() {
for (final long now : getTimestamps()) {
Scheduler scheduler = makeMockScheduler(now);
scheduler.scheduleNextHeartbeat();
assertFalse(scheduler.isHeartbeatDue(now));
// Simulate a delayed heartbeat e.g. due to slow processing by NN.
scheduler.nextHeartbeatTime = now - (HEARTBEAT_INTERVAL_MS * 10);
scheduler.scheduleNextHeartbeat();
// Ensure that the next heartbeat is not due immediately.
assertFalse(scheduler.isHeartbeatDue(now));
}
}
private Scheduler makeMockScheduler(long now) {
LOG.info("Using now = " + now);
Scheduler mockScheduler = spy(new Scheduler(HEARTBEAT_INTERVAL_MS, BLOCK_REPORT_INTERVAL_MS));