Skip to content

Commit 562c42c

Browse files
HDFS-17242. Make congestion backoff time configurable. (#6227)
Reviewed-by: Xing Lin <xinglin@linkedin.com> Reviewed-by: Ayush Saxena <ayushsaxena@apache.org> Signed-off-by: Tao Li <tomscut@apache.org>
1 parent 19b9e6a commit 562c42c

File tree

4 files changed

+65
-7
lines changed

4 files changed

+65
-7
lines changed

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DataStreamer.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.apache.hadoop.classification.VisibleForTesting;
4747
import org.apache.hadoop.classification.InterfaceAudience;
4848
import org.apache.hadoop.fs.StorageType;
49+
import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys;
4950
import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.BlockWrite;
5051
import org.apache.hadoop.hdfs.client.impl.DfsClientConf;
5152
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
@@ -528,9 +529,8 @@ boolean doWaitForRestart() {
528529
// are congested
529530
private final List<DatanodeInfo> congestedNodes = new ArrayList<>();
530531
private final Map<DatanodeInfo, Integer> slowNodeMap = new HashMap<>();
531-
private static final int CONGESTION_BACKOFF_MEAN_TIME_IN_MS = 5000;
532-
private static final int CONGESTION_BACK_OFF_MAX_TIME_IN_MS =
533-
CONGESTION_BACKOFF_MEAN_TIME_IN_MS * 10;
532+
private int congestionBackOffMeanTimeInMs;
533+
private int congestionBackOffMaxTimeInMs;
534534
private int lastCongestionBackoffTime;
535535
private int maxPipelineRecoveryRetries;
536536
private int markSlowNodeAsBadNodeThreshold;
@@ -564,6 +564,35 @@ private DataStreamer(HdfsFileStatus stat, ExtendedBlock block,
564564
this.addBlockFlags = flags;
565565
this.maxPipelineRecoveryRetries = conf.getMaxPipelineRecoveryRetries();
566566
this.markSlowNodeAsBadNodeThreshold = conf.getMarkSlowNodeAsBadNodeThreshold();
567+
congestionBackOffMeanTimeInMs = dfsClient.getConfiguration().getInt(
568+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME,
569+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME_DEFAULT);
570+
congestionBackOffMaxTimeInMs = dfsClient.getConfiguration().getInt(
571+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME,
572+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME_DEFAULT);
573+
if (congestionBackOffMeanTimeInMs <= 0) {
574+
LOG.warn("Configuration: {} is not appropriate, using default value: {}",
575+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME,
576+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME_DEFAULT);
577+
}
578+
if (congestionBackOffMaxTimeInMs <= 0) {
579+
LOG.warn("Configuration: {} is not appropriate, using default value: {}",
580+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME,
581+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME_DEFAULT);
582+
}
583+
if (congestionBackOffMaxTimeInMs < congestionBackOffMeanTimeInMs) {
584+
LOG.warn("Configuration: {} can not less than {}, using their default values.",
585+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME,
586+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME);
587+
}
588+
if (congestionBackOffMeanTimeInMs <= 0 || congestionBackOffMaxTimeInMs <= 0 ||
589+
congestionBackOffMaxTimeInMs < congestionBackOffMeanTimeInMs) {
590+
congestionBackOffMeanTimeInMs =
591+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME_DEFAULT;
592+
congestionBackOffMaxTimeInMs =
593+
HdfsClientConfigKeys.DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME_DEFAULT;
594+
}
595+
567596
}
568597

569598
/**
@@ -1998,10 +2027,10 @@ private void backOffIfNecessary() throws InterruptedException {
19982027
sb.append(' ').append(i);
19992028
}
20002029
int range = Math.abs(lastCongestionBackoffTime * 3 -
2001-
CONGESTION_BACKOFF_MEAN_TIME_IN_MS);
2030+
congestionBackOffMeanTimeInMs);
20022031
int base = Math.min(lastCongestionBackoffTime * 3,
2003-
CONGESTION_BACKOFF_MEAN_TIME_IN_MS);
2004-
t = Math.min(CONGESTION_BACK_OFF_MAX_TIME_IN_MS,
2032+
congestionBackOffMeanTimeInMs);
2033+
t = Math.min(congestionBackOffMaxTimeInMs,
20052034
(int)(base + Math.random() * range));
20062035
lastCongestionBackoffTime = t;
20072036
sb.append(" are congested. Backing off for ").append(t).append(" ms");

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/client/HdfsClientConfigKeys.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ public interface HdfsClientConfigKeys {
287287
"dfs.client.output.stream.uniq.default.key";
288288
String DFS_OUTPUT_STREAM_UNIQ_DEFAULT_KEY_DEFAULT = "DEFAULT";
289289

290+
String DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME =
291+
"dfs.client.congestion.backoff.mean.time";
292+
int DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME_DEFAULT = 5000;
293+
294+
String DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME =
295+
"dfs.client.congestion.backoff.max.time";
296+
int DFS_CLIENT_CONGESTION_BACKOFF_MAX_TIME_DEFAULT =
297+
DFS_CLIENT_CONGESTION_BACKOFF_MEAN_TIME_DEFAULT * 10;
298+
290299
/**
291300
* These are deprecated config keys to client code.
292301
*/

hadoop-hdfs-project/hadoop-hdfs/src/main/resources/hdfs-default.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6559,6 +6559,22 @@
65596559
If the namespace is DEFAULT, it's best to change this conf to other value.
65606560
</description>
65616561
</property>
6562+
<property>
6563+
<name>dfs.client.congestion.backoff.mean.time</name>
6564+
<value>5000</value>
6565+
<description>
6566+
The mean time in milliseconds which is used to compute
6567+
client congestion backoff sleep time.
6568+
</description>
6569+
</property>
6570+
<property>
6571+
<name>dfs.client.congestion.backoff.max.time</name>
6572+
<value>50000</value>
6573+
<description>
6574+
The max time in milliseconds which is used to restrict
6575+
the upper limit backoff sleep time for client.
6576+
</description>
6577+
</property>
65626578
<property>
65636579
<name>dfs.client.rbf.observer.read.enable</name>
65646580
<value>false</value>

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSOutputStream.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ private void runAdjustChunkBoundary(
275275
public void testCongestionBackoff() throws IOException {
276276
DfsClientConf dfsClientConf = mock(DfsClientConf.class);
277277
DFSClient client = mock(DFSClient.class);
278+
Configuration conf = mock(Configuration.class);
279+
when(client.getConfiguration()).thenReturn(conf);
278280
when(client.getConf()).thenReturn(dfsClientConf);
279281
when(client.getTracer()).thenReturn(FsTracer.get(new Configuration()));
280282
client.clientRunning = true;
@@ -306,6 +308,8 @@ public void testCongestionBackoff() throws IOException {
306308
public void testCongestionAckDelay() {
307309
DfsClientConf dfsClientConf = mock(DfsClientConf.class);
308310
DFSClient client = mock(DFSClient.class);
311+
Configuration conf = mock(Configuration.class);
312+
when(client.getConfiguration()).thenReturn(conf);
309313
when(client.getConf()).thenReturn(dfsClientConf);
310314
when(client.getTracer()).thenReturn(FsTracer.get(new Configuration()));
311315
client.clientRunning = true;
@@ -325,7 +329,7 @@ public void testCongestionAckDelay() {
325329
ArrayList<DatanodeInfo> congestedNodes = (ArrayList<DatanodeInfo>)
326330
Whitebox.getInternalState(stream, "congestedNodes");
327331
int backOffMaxTime = (int)
328-
Whitebox.getInternalState(stream, "CONGESTION_BACK_OFF_MAX_TIME_IN_MS");
332+
Whitebox.getInternalState(stream, "congestionBackOffMaxTimeInMs");
329333
DFSPacket[] packet = new DFSPacket[100];
330334
AtomicBoolean isDelay = new AtomicBoolean(true);
331335

0 commit comments

Comments
 (0)