[HDFS-16971] Add read metrics for remote reads in FileSystem Statistics #5534 (#5536)

This commit is contained in:
Melissa You 2023-04-13 09:07:42 -07:00 committed by GitHub
parent 06f9bdffa6
commit 2b60d0c1f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 11 deletions

View File

@ -3942,6 +3942,7 @@ public static class StatisticsData {
private volatile long bytesReadDistanceOfThreeOrFour; private volatile long bytesReadDistanceOfThreeOrFour;
private volatile long bytesReadDistanceOfFiveOrLarger; private volatile long bytesReadDistanceOfFiveOrLarger;
private volatile long bytesReadErasureCoded; private volatile long bytesReadErasureCoded;
private volatile long remoteReadTimeMS;
/** /**
* Add another StatisticsData object to this one. * Add another StatisticsData object to this one.
@ -3959,6 +3960,7 @@ void add(StatisticsData other) {
this.bytesReadDistanceOfFiveOrLarger += this.bytesReadDistanceOfFiveOrLarger +=
other.bytesReadDistanceOfFiveOrLarger; other.bytesReadDistanceOfFiveOrLarger;
this.bytesReadErasureCoded += other.bytesReadErasureCoded; this.bytesReadErasureCoded += other.bytesReadErasureCoded;
this.remoteReadTimeMS += other.remoteReadTimeMS;
} }
/** /**
@ -3977,6 +3979,7 @@ void negate() {
this.bytesReadDistanceOfFiveOrLarger = this.bytesReadDistanceOfFiveOrLarger =
-this.bytesReadDistanceOfFiveOrLarger; -this.bytesReadDistanceOfFiveOrLarger;
this.bytesReadErasureCoded = -this.bytesReadErasureCoded; this.bytesReadErasureCoded = -this.bytesReadErasureCoded;
this.remoteReadTimeMS = -this.remoteReadTimeMS;
} }
@Override @Override
@ -4025,6 +4028,10 @@ public long getBytesReadDistanceOfFiveOrLarger() {
public long getBytesReadErasureCoded() { public long getBytesReadErasureCoded() {
return bytesReadErasureCoded; return bytesReadErasureCoded;
} }
public long getRemoteReadTimeMS() {
return remoteReadTimeMS;
}
} }
private interface StatisticsAggregator<T> { private interface StatisticsAggregator<T> {
@ -4252,6 +4259,14 @@ public void incrementBytesReadByDistance(int distance, long newBytes) {
} }
} }
/**
* Increment the time taken to read bytes from remote in the statistics.
* @param durationMS time taken in ms to read bytes from remote
*/
public void increaseRemoteReadTime(final long durationMS) {
getThreadStatistics().remoteReadTimeMS += durationMS;
}
/** /**
* Apply the given aggregator to all StatisticsData objects associated with * Apply the given aggregator to all StatisticsData objects associated with
* this Statistics object. * this Statistics object.
@ -4399,6 +4414,25 @@ public long getBytesReadByDistance(int distance) {
return bytesRead; return bytesRead;
} }
/**
* Get total time taken in ms for bytes read from remote.
* @return time taken in ms for remote bytes read.
*/
public long getRemoteReadTime() {
return visitAll(new StatisticsAggregator<Long>() {
private long remoteReadTimeMS = 0;
@Override
public void accept(StatisticsData data) {
remoteReadTimeMS += data.remoteReadTimeMS;
}
public Long aggregate() {
return remoteReadTimeMS;
}
});
}
/** /**
* Get all statistics data. * Get all statistics data.
* MR or other frameworks can use the method to get all statistics at once. * MR or other frameworks can use the method to get all statistics at once.

View File

@ -47,7 +47,8 @@ public class FileSystemStorageStatistics extends StorageStatistics {
"bytesReadDistanceOfOneOrTwo", "bytesReadDistanceOfOneOrTwo",
"bytesReadDistanceOfThreeOrFour", "bytesReadDistanceOfThreeOrFour",
"bytesReadDistanceOfFiveOrLarger", "bytesReadDistanceOfFiveOrLarger",
"bytesReadErasureCoded" "bytesReadErasureCoded",
"remoteReadTimeMS"
}; };
private static class LongStatisticIterator private static class LongStatisticIterator
@ -107,6 +108,8 @@ private static Long fetch(StatisticsData data, String key) {
return data.getBytesReadDistanceOfFiveOrLarger(); return data.getBytesReadDistanceOfFiveOrLarger();
case "bytesReadErasureCoded": case "bytesReadErasureCoded":
return data.getBytesReadErasureCoded(); return data.getBytesReadErasureCoded();
case "remoteReadTimeMS":
return data.getRemoteReadTimeMS();
default: default:
return null; return null;
} }

View File

@ -52,7 +52,8 @@ public class TestFileSystemStorageStatistics {
"bytesReadDistanceOfOneOrTwo", "bytesReadDistanceOfOneOrTwo",
"bytesReadDistanceOfThreeOrFour", "bytesReadDistanceOfThreeOrFour",
"bytesReadDistanceOfFiveOrLarger", "bytesReadDistanceOfFiveOrLarger",
"bytesReadErasureCoded" "bytesReadErasureCoded",
"remoteReadTimeMS"
}; };
private FileSystem.Statistics statistics = private FileSystem.Statistics statistics =
@ -74,6 +75,7 @@ public void setup() {
statistics.incrementBytesReadByDistance(1, RandomUtils.nextInt(0, 100)); statistics.incrementBytesReadByDistance(1, RandomUtils.nextInt(0, 100));
statistics.incrementBytesReadByDistance(3, RandomUtils.nextInt(0, 100)); statistics.incrementBytesReadByDistance(3, RandomUtils.nextInt(0, 100));
statistics.incrementBytesReadErasureCoded(RandomUtils.nextInt(0, 100)); statistics.incrementBytesReadErasureCoded(RandomUtils.nextInt(0, 100));
statistics.increaseRemoteReadTime(RandomUtils.nextInt(0, 100));
} }
@Test @Test
@ -128,6 +130,8 @@ private long getStatisticsValue(String name) {
return statistics.getBytesReadByDistance(5); return statistics.getBytesReadByDistance(5);
case "bytesReadErasureCoded": case "bytesReadErasureCoded":
return statistics.getBytesReadErasureCoded(); return statistics.getBytesReadErasureCoded();
case "remoteReadTimeMS":
return statistics.getRemoteReadTime();
default: default:
return 0; return 0;
} }

View File

@ -3090,10 +3090,14 @@ public Peer newConnectedPeer(InetSocketAddress addr,
} }
} }
void updateFileSystemReadStats(int distance, int nRead) { void updateFileSystemReadStats(int distance, int readBytes, long readTimeMS) {
if (stats != null) { if (stats != null) {
stats.incrementBytesRead(nRead); stats.incrementBytesRead(readBytes);
stats.incrementBytesReadByDistance(distance, nRead); stats.incrementBytesReadByDistance(distance, readBytes);
if (distance > 0) {
//remote read
stats.increaseRemoteReadTime(readTimeMS);
}
} }
} }

View File

@ -851,8 +851,9 @@ protected synchronized int readWithStrategy(ReaderStrategy strategy)
locatedBlocks.getFileLength() - pos); locatedBlocks.getFileLength() - pos);
} }
} }
long beginReadMS = Time.monotonicNow();
int result = readBuffer(strategy, realLen, corruptedBlocks); int result = readBuffer(strategy, realLen, corruptedBlocks);
long readTimeMS = Time.monotonicNow() - beginReadMS;
if (result >= 0) { if (result >= 0) {
pos += result; pos += result;
} else { } else {
@ -861,7 +862,7 @@ protected synchronized int readWithStrategy(ReaderStrategy strategy)
} }
updateReadStatistics(readStatistics, result, blockReader); updateReadStatistics(readStatistics, result, blockReader);
dfsClient.updateFileSystemReadStats(blockReader.getNetworkDistance(), dfsClient.updateFileSystemReadStats(blockReader.getNetworkDistance(),
result); result, readTimeMS);
if (readStatistics.getBlockType() == BlockType.STRIPED) { if (readStatistics.getBlockType() == BlockType.STRIPED) {
dfsClient.updateFileSystemECReadStats(result); dfsClient.updateFileSystemECReadStats(result);
} }
@ -1184,6 +1185,7 @@ void actualGetFromOneDataNode(final DNAddrPair datanode, final long startInBlk,
ByteBuffer tmp = buf.duplicate(); ByteBuffer tmp = buf.duplicate();
tmp.limit(tmp.position() + len); tmp.limit(tmp.position() + len);
tmp = tmp.slice(); tmp = tmp.slice();
long beginReadMS = Time.monotonicNow();
int nread = 0; int nread = 0;
int ret; int ret;
while (true) { while (true) {
@ -1193,11 +1195,12 @@ void actualGetFromOneDataNode(final DNAddrPair datanode, final long startInBlk,
} }
nread += ret; nread += ret;
} }
long readTimeMS = Time.monotonicNow() - beginReadMS;
buf.position(buf.position() + nread); buf.position(buf.position() + nread);
IOUtilsClient.updateReadStatistics(readStatistics, nread, reader); IOUtilsClient.updateReadStatistics(readStatistics, nread, reader);
dfsClient.updateFileSystemReadStats( dfsClient.updateFileSystemReadStats(
reader.getNetworkDistance(), nread); reader.getNetworkDistance(), nread, readTimeMS);
if (readStatistics.getBlockType() == BlockType.STRIPED) { if (readStatistics.getBlockType() == BlockType.STRIPED) {
dfsClient.updateFileSystemECReadStats(nread); dfsClient.updateFileSystemECReadStats(nread);
} }

View File

@ -331,15 +331,17 @@ private void readOneStripe(CorruptedBlocks corruptedBlocks)
* its ThreadLocal. * its ThreadLocal.
* *
* @param stats striped read stats * @param stats striped read stats
* @param readTimeMS read time metrics in ms
*
*/ */
void updateReadStats(final StripedBlockUtil.BlockReadStats stats) { void updateReadStats(final StripedBlockUtil.BlockReadStats stats, long readTimeMS) {
if (stats == null) { if (stats == null) {
return; return;
} }
updateReadStatistics(readStatistics, stats.getBytesRead(), updateReadStatistics(readStatistics, stats.getBytesRead(),
stats.isShortCircuit(), stats.getNetworkDistance()); stats.isShortCircuit(), stats.getNetworkDistance());
dfsClient.updateFileSystemReadStats(stats.getNetworkDistance(), dfsClient.updateFileSystemReadStats(stats.getNetworkDistance(),
stats.getBytesRead()); stats.getBytesRead(), readTimeMS);
assert readStatistics.getBlockType() == BlockType.STRIPED; assert readStatistics.getBlockType() == BlockType.STRIPED;
dfsClient.updateFileSystemECReadStats(stats.getBytesRead()); dfsClient.updateFileSystemECReadStats(stats.getBytesRead());
} }

View File

@ -351,9 +351,12 @@ void readStripe() throws IOException {
// first read failure // first read failure
while (!futures.isEmpty()) { while (!futures.isEmpty()) {
try { try {
long beginReadMS = Time.monotonicNow();
StripingChunkReadResult r = StripedBlockUtil StripingChunkReadResult r = StripedBlockUtil
.getNextCompletedStripedRead(service, futures, 0); .getNextCompletedStripedRead(service, futures, 0);
dfsStripedInputStream.updateReadStats(r.getReadStats()); long readTimeMS = Time.monotonicNow() - beginReadMS;
dfsStripedInputStream.updateReadStats(r.getReadStats(), readTimeMS);
DFSClient.LOG.debug("Read task returned: {}, for stripe {}", DFSClient.LOG.debug("Read task returned: {}, for stripe {}",
r, alignedStripe); r, alignedStripe);
StripingChunk returnedChunk = alignedStripe.chunks[r.index]; StripingChunk returnedChunk = alignedStripe.chunks[r.index];