From 4883c1bfcc74cce57bf7e47eebff7c844edc52da Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Sun, 13 Mar 2022 11:21:04 +0530 Subject: [PATCH 01/19] Changes made --- .../freon/WriteFileThroughputBenchmark.java | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java new file mode 100644 index 000000000000..393782daf9b0 --- /dev/null +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -0,0 +1,199 @@ +package org.apache.hadoop.ozone.freon; + +import com.codahale.metrics.Timer; +import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; +import picocli.CommandLine.Option; +import org.slf4j.Logger; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.URI; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@CommandLine.Command(name = "wtb", + aliases = "write-throughput-benchmark", + description = "Benchmark for creating a file", + versionProvider = HddsVersionProvider.class, + mixinStandardHelpOptions = true, + showDefaultValues = true) +public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements Callable{ + + @Option(names = {"-o"}, + description = "Ozone filesystem path", + defaultValue = "o3fs://bucket1.vol1") + private String rootPath; + + @Option(names = {"-s", "--size"}, + description = "Size of each generated files (in GB)", + defaultValue = "1") + private long fileSize; + + @Option(names = {"-b", "--block"}, + description = "Specify the Block Size in MB", + defaultValue = "128") + private long blockSize; + + @Option(names = {"-i", "--buffer"}, + description = "Size of buffer used store the generated key content", + defaultValue = "10240") + private int bufferSize; + + @Option(names = {"-th", "--throttle"}, + description = "Specify the Delay in Input/Output", + defaultValue = "0") + private int throttle; + + @Option(names = {"-re", "--replication"}, + description = "Specify the Replication factor", + defaultValue = "3") + private short replication; + + @Option(names= {"--sync"}, + description = "Optionally Issue hsync after every write Cannot be used with hflush", + defaultValue = "false" + ) + private boolean hSync; + + @Option(names= {"--flush"}, + description = "Optionally Issue hsync after every write Cannot be used with hflush", + defaultValue = "false" + ) + private boolean hFlush; + + // For Generating the content of the files + private ContentGenerator contentGenerator; + // For Creating the required configurations for the file system + private OzoneConfiguration configuration; + + private URI uri; + + private boolean isThrottled; + + long expectedIoTimeNs; + + private Timer timer; + + private final ThreadLocal threadLocalFileSystem = + ThreadLocal.withInitial(this::createFS); + + public static final Logger LOG = + LoggerFactory.getLogger(WriteFileThroughputBenchmark.class); + + // Checking whether an output directory is created inside the bucket + private static void ensureOutputDirExists(FileSystem fs, Path outputDir) + throws IOException { + if (!fs.exists(outputDir)) { + LOG.error("No Such Output Directory exists : {}", outputDir); + System.exit(1); + } + } + + + public Void call() throws Exception{ + + LOG.info("NumFiles=" + getTestNo()); + LOG.info("Total FileSize=" + fileSize); + LOG.info("BlockSize=" + blockSize); + LOG.info("BufferSize=" + bufferSize); + LOG.info("Replication=" + replication); + LOG.info("Threads=" + getThreadNo()); + LOG.info("URI Scheme Used=" + uri.getScheme()); + if(hSync){ + LOG.info("Hsync after every write= True"); + } + else if(hFlush){ + LOG.info("Hflush after every write= True"); + } + + // Initialize the configuration variable + configuration = createOzoneConfiguration(); + + //Constructs a URI by parsing the given string rootPath + // We Initialize the uri variable with the path + uri = URI.create(rootPath); + + // Disabling the file system cache + String disableCacheName = String.format("fs.%s.impl.disable.cache", + uri.getScheme()); + print("Disabling FS cache: " + disableCacheName); + configuration.setBoolean(disableCacheName, true); + + Path file = new Path(rootPath + "/" + generateObjectName(0)); + try (FileSystem fileSystem = threadLocalFileSystem.get()) { + fileSystem.mkdirs(file.getParent()); + } + // Checks whether output directory exists + ensureOutputDirExists(createFS(),file); + + // Initialize the size of the file to be written in Bytes + long filesizeinBytes = fileSize*1_000_000_000; + contentGenerator = new ContentGenerator(filesizeinBytes, bufferSize, + hSync, hFlush); + + expectedIoTimeNs = + (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) + : 0); + + timer = getMetrics().timer("file-create"); + + runTests(this::createFile); + + return null; + } + + + private void createFile(long counter) throws Exception { + Path file = new Path(rootPath + "/" + generateObjectName(counter)); + FileSystem fileSystem = threadLocalFileSystem.get(); + + final long ioStartTimeNs = (isThrottled ? System.nanoTime() : 0); + + timer.time(() -> { + try ( FSDataOutputStream outputStream = fileSystem.create(file, + false, bufferSize,replication,blockSize);) { + contentGenerator.write(outputStream); + + // Enforcing throttle delay + final long ioEndTimeNs = (isThrottled ? System.nanoTime() : 0); + enforceThrottle(ioEndTimeNs - ioStartTimeNs, expectedIoTimeNs); + } + return null; + }); + } + + + + private FileSystem createFS() { + try { + return FileSystem.get(uri, configuration); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + static void enforceThrottle(long ioTimeNs, long expectedIoTimeNs) + throws InterruptedException { + if (ioTimeNs < expectedIoTimeNs) { + // The IO completed too fast, so sleep for some time. + long sleepTimeNs = expectedIoTimeNs - ioTimeNs; + Thread.sleep(sleepTimeNs / 1_000_000, (int) (sleepTimeNs % 1_000_000)); + } + } + @Override + protected void taskLoopCompleted() { + FileSystem fileSystem = threadLocalFileSystem.get(); + try { + fileSystem.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} + From 628593c2ea856e31719acc5f6c60ed3c4b838ce1 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Sun, 13 Mar 2022 11:24:32 +0530 Subject: [PATCH 02/19] Made a few changes --- hadoop-ozone/tools/pom.xml | 4 ++ .../hadoop/ozone/freon/ContentGenerator.java | 42 ++++++++++-- .../freon/WriteFileThroughputBenchmark.java | 68 ++++++++++--------- 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/hadoop-ozone/tools/pom.xml b/hadoop-ozone/tools/pom.xml index 47501795307b..67cc0b8789ea 100644 --- a/hadoop-ozone/tools/pom.xml +++ b/hadoop-ozone/tools/pom.xml @@ -124,6 +124,10 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd"> mockito-core test + + org.apache.hadoop + hadoop-common + diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java index 542634c4884b..10c959cda844 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java @@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.hadoop.fs.FSDataOutputStream; /** * Utility class to write random keys from a limited buffer. @@ -48,18 +49,37 @@ public class ContentGenerator { private final byte[] buffer; + /** + * Issue Hsync after every write ( Cannot be used with Hflush ) + */ + private final boolean hSync; + + /** + * Issue Hflush after every write ( Cannot be used with Hsync ) + */ + private final boolean hFlush; + ContentGenerator(long keySize, int bufferSize) { - this(keySize, bufferSize, bufferSize); + this(keySize, bufferSize, bufferSize,false,false); + } + + ContentGenerator(long keySize, int bufferSize, int copyBufferSize){ + this(keySize, bufferSize, copyBufferSize,false,false); } - ContentGenerator(long keySize, int bufferSize, int copyBufferSize) { + ContentGenerator(long keySize, int bufferSize, boolean hsync, boolean hflush) { + this(keySize, bufferSize, bufferSize,hsync,hflush); + } + + ContentGenerator(long keySize, int bufferSize, int copyBufferSize, boolean hSync, boolean hFlush) { this.keySize = keySize; this.bufferSize = bufferSize; this.copyBufferSize = copyBufferSize; - buffer = RandomStringUtils.randomAscii(bufferSize) - .getBytes(StandardCharsets.UTF_8); - } + this.hSync = hSync; + this.hFlush = hFlush; + buffer = RandomStringUtils.randomAscii(bufferSize).getBytes(StandardCharsets.UTF_8); + } /** * Write the required bytes to the output stream. */ @@ -70,16 +90,28 @@ public void write(OutputStream outputStream) throws IOException { if (copyBufferSize == 1) { for (int i = 0; i < curSize; i++) { outputStream.write(buffer[i]); + flushOrSync(outputStream); } } else { for (int i = 0; i < curSize; i += copyBufferSize) { outputStream.write(buffer, i, Math.min(copyBufferSize, curSize - i)); + flushOrSync(outputStream); } } } } + private void flushOrSync(OutputStream outputStream) throws IOException { + if (outputStream instanceof FSDataOutputStream) { + if (hSync) { + ((FSDataOutputStream)outputStream).hsync(); + } else if (hFlush) { + ((FSDataOutputStream)outputStream).hflush(); + } + } + } + @VisibleForTesting byte[] getBuffer() { return buffer; diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 393782daf9b0..d747a1f08028 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -15,8 +15,7 @@ import java.io.UncheckedIOException; import java.net.URI; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; + @CommandLine.Command(name = "wtb", aliases = "write-throughput-benchmark", @@ -24,7 +23,8 @@ versionProvider = HddsVersionProvider.class, mixinStandardHelpOptions = true, showDefaultValues = true) -public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements Callable{ +public class WriteFileThroughputBenchmark extends BaseFreonGenerator + implements Callable{ @Option(names = {"-o"}, description = "Ozone filesystem path", @@ -36,13 +36,14 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements defaultValue = "1") private long fileSize; - @Option(names = {"-b", "--block"}, + @Option(names = {"-bl", "--block"}, description = "Specify the Block Size in MB", defaultValue = "128") private long blockSize; - @Option(names = {"-i", "--buffer"}, - description = "Size of buffer used store the generated key content", + @Option(names = {"-bu", "--buffer"}, + description = "Size of buffer used store the generated " + + "key content", defaultValue = "10240") private int bufferSize; @@ -53,17 +54,19 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements @Option(names = {"-re", "--replication"}, description = "Specify the Replication factor", - defaultValue = "3") + defaultValue = "1") private short replication; @Option(names= {"--sync"}, - description = "Optionally Issue hsync after every write Cannot be used with hflush", + description = "Optionally Issue hsync after every write " + + "Cannot be used with hflush", defaultValue = "false" ) private boolean hSync; @Option(names= {"--flush"}, - description = "Optionally Issue hsync after every write Cannot be used with hflush", + description = "Optionally Issue hsync after every write " + + "Cannot be used with hflush", defaultValue = "false" ) private boolean hFlush; @@ -75,6 +78,7 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements private URI uri; + // variable to check if the user wants a delay private boolean isThrottled; long expectedIoTimeNs; @@ -87,15 +91,6 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements public static final Logger LOG = LoggerFactory.getLogger(WriteFileThroughputBenchmark.class); - // Checking whether an output directory is created inside the bucket - private static void ensureOutputDirExists(FileSystem fs, Path outputDir) - throws IOException { - if (!fs.exists(outputDir)) { - LOG.error("No Such Output Directory exists : {}", outputDir); - System.exit(1); - } - } - public Void call() throws Exception{ @@ -113,11 +108,11 @@ else if(hFlush){ LOG.info("Hflush after every write= True"); } - // Initialize the configuration variable + // Initialize the configuration variable with + // OzoneFS configuration configuration = createOzoneConfiguration(); - //Constructs a URI by parsing the given string rootPath - // We Initialize the uri variable with the path + //Constructs a URI object by parsing the given string rootPath uri = URI.create(rootPath); // Disabling the file system cache @@ -126,7 +121,8 @@ else if(hFlush){ print("Disabling FS cache: " + disableCacheName); configuration.setBoolean(disableCacheName, true); - Path file = new Path(rootPath + "/" + generateObjectName(0)); + Path file = new Path(rootPath + "/" + + generateObjectName(0)); try (FileSystem fileSystem = threadLocalFileSystem.get()) { fileSystem.mkdirs(file.getParent()); } @@ -135,8 +131,8 @@ else if(hFlush){ // Initialize the size of the file to be written in Bytes long filesizeinBytes = fileSize*1_000_000_000; - contentGenerator = new ContentGenerator(filesizeinBytes, bufferSize, - hSync, hFlush); + contentGenerator = new ContentGenerator(filesizeinBytes, + bufferSize, hSync, hFlush); expectedIoTimeNs = (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) @@ -169,8 +165,6 @@ private void createFile(long counter) throws Exception { }); } - - private FileSystem createFS() { try { return FileSystem.get(uri, configuration); @@ -178,14 +172,27 @@ private FileSystem createFS() { throw new UncheckedIOException(e); } } - static void enforceThrottle(long ioTimeNs, long expectedIoTimeNs) - throws InterruptedException { + + // Method to cause the delay of a certain amount + static void enforceThrottle(long ioTimeNs, long expectedIoTimeNs) throws + InterruptedException { if (ioTimeNs < expectedIoTimeNs) { // The IO completed too fast, so sleep for some time. long sleepTimeNs = expectedIoTimeNs - ioTimeNs; - Thread.sleep(sleepTimeNs / 1_000_000, (int) (sleepTimeNs % 1_000_000)); + Thread.sleep(sleepTimeNs / 1_000_000, (int) + (sleepTimeNs % 1_000_000)); + } + } + + // Checking whether an output directory is created inside the bucket + private static void ensureOutputDirExists(FileSystem fs, Path outputDir) + throws IOException { + if (!fs.exists(outputDir)) { + LOG.error("No Such Output Directory exists : {}", outputDir); + System.exit(1); } } + @Override protected void taskLoopCompleted() { FileSystem fileSystem = threadLocalFileSystem.get(); @@ -195,5 +202,4 @@ protected void taskLoopCompleted() { throw new UncheckedIOException(e); } } -} - +} \ No newline at end of file From 677d2cbf308a9ce71b34f76b38447618fe4194d7 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 14 Mar 2022 10:20:42 +0530 Subject: [PATCH 03/19] Added the new class path to Freon.class --- .../src/main/java/org/apache/hadoop/ozone/freon/Freon.java | 3 ++- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/Freon.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/Freon.java index c5b9a3a882cd..31144021d3fe 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/Freon.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/Freon.java @@ -63,7 +63,8 @@ GeneratorDatanode.class, ClosedContainerReplicator.class, StreamingGenerator.class, - SCMThroughputBenchmark.class}, + SCMThroughputBenchmark.class, + WriteFileThroughputBenchmark.class}, versionProvider = HddsVersionProvider.class, mixinStandardHelpOptions = true) public class Freon extends GenericCli { diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index d747a1f08028..d030a14fdb70 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -94,6 +94,7 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator public Void call() throws Exception{ + init(); LOG.info("NumFiles=" + getTestNo()); LOG.info("Total FileSize=" + fileSize); LOG.info("BlockSize=" + blockSize); @@ -154,7 +155,7 @@ private void createFile(long counter) throws Exception { timer.time(() -> { try ( FSDataOutputStream outputStream = fileSystem.create(file, - false, bufferSize,replication,blockSize);) { + false, bufferSize,replication,blockSize)) { contentGenerator.write(outputStream); // Enforcing throttle delay From ad2e96227a0f77f268d0eb42ad3aa5748a377685 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 14 Mar 2022 10:32:12 +0530 Subject: [PATCH 04/19] HDDS-1726.Integrate FsPerfTest into Ozone freon performance test suite. --- .../apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index d030a14fdb70..0aec839ff091 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -135,6 +135,7 @@ else if(hFlush){ contentGenerator = new ContentGenerator(filesizeinBytes, bufferSize, hSync, hFlush); + // Initializing the time it should take to write a file expectedIoTimeNs = (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) : 0); From 245e17719690a6493b6e0d0aa177d88220b6c48b Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 14 Mar 2022 11:13:02 +0530 Subject: [PATCH 05/19] HDDS-1726.Integrate FsPerfTest into Ozone freon performance test suite. --- .../hadoop/ozone/freon/ContentGenerator.java | 26 +- .../freon/WriteFileThroughputBenchmark.java | 347 +++++++++--------- 2 files changed, 188 insertions(+), 185 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java index 10c959cda844..da6e692b8481 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java @@ -50,36 +50,40 @@ public class ContentGenerator { private final byte[] buffer; /** - * Issue Hsync after every write ( Cannot be used with Hflush ) + * Issue Hsync after every write ( Cannot be used with Hflush ). */ private final boolean hSync; /** - * Issue Hflush after every write ( Cannot be used with Hsync ) + * Issue Hflush after every write ( Cannot be used with Hsync ). */ private final boolean hFlush; ContentGenerator(long keySize, int bufferSize) { - this(keySize, bufferSize, bufferSize,false,false); + this(keySize, bufferSize, bufferSize, false, false); } - ContentGenerator(long keySize, int bufferSize, int copyBufferSize){ - this(keySize, bufferSize, copyBufferSize,false,false); + ContentGenerator(long keySize, int bufferSize, int copyBufferSize) { + this(keySize, bufferSize, copyBufferSize, false, false); } - ContentGenerator(long keySize, int bufferSize, boolean hsync, boolean hflush) { - this(keySize, bufferSize, bufferSize,hsync,hflush); + ContentGenerator(long keySize, int bufferSize, boolean hsync, + boolean hflush) { + this(keySize, bufferSize, bufferSize, hsync, hflush); } - ContentGenerator(long keySize, int bufferSize, int copyBufferSize, boolean hSync, boolean hFlush) { + ContentGenerator(long keySize, int bufferSize, int copyBufferSize, + boolean hSync, boolean hFlush) { this.keySize = keySize; this.bufferSize = bufferSize; this.copyBufferSize = copyBufferSize; this.hSync = hSync; this.hFlush = hFlush; - buffer = RandomStringUtils.randomAscii(bufferSize).getBytes(StandardCharsets.UTF_8); + buffer = RandomStringUtils.randomAscii(bufferSize) + .getBytes(StandardCharsets.UTF_8); } + /** * Write the required bytes to the output stream. */ @@ -105,9 +109,9 @@ public void write(OutputStream outputStream) throws IOException { private void flushOrSync(OutputStream outputStream) throws IOException { if (outputStream instanceof FSDataOutputStream) { if (hSync) { - ((FSDataOutputStream)outputStream).hsync(); + ((FSDataOutputStream) outputStream).hsync(); } else if (hFlush) { - ((FSDataOutputStream)outputStream).hflush(); + ((FSDataOutputStream) outputStream).hflush(); } } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 0aec839ff091..69c0016c03e3 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -18,190 +18,189 @@ @CommandLine.Command(name = "wtb", - aliases = "write-throughput-benchmark", - description = "Benchmark for creating a file", - versionProvider = HddsVersionProvider.class, - mixinStandardHelpOptions = true, - showDefaultValues = true) + aliases = "write-throughput-benchmark", + description = "Benchmark for creating a file", + versionProvider = HddsVersionProvider.class, + mixinStandardHelpOptions = true, + showDefaultValues = true) public class WriteFileThroughputBenchmark extends BaseFreonGenerator - implements Callable{ - - @Option(names = {"-o"}, - description = "Ozone filesystem path", - defaultValue = "o3fs://bucket1.vol1") - private String rootPath; - - @Option(names = {"-s", "--size"}, - description = "Size of each generated files (in GB)", - defaultValue = "1") - private long fileSize; - - @Option(names = {"-bl", "--block"}, - description = "Specify the Block Size in MB", - defaultValue = "128") - private long blockSize; - - @Option(names = {"-bu", "--buffer"}, - description = "Size of buffer used store the generated " + - "key content", - defaultValue = "10240") - private int bufferSize; - - @Option(names = {"-th", "--throttle"}, - description = "Specify the Delay in Input/Output", - defaultValue = "0") - private int throttle; - - @Option(names = {"-re", "--replication"}, - description = "Specify the Replication factor", - defaultValue = "1") - private short replication; - - @Option(names= {"--sync"}, - description = "Optionally Issue hsync after every write " + - "Cannot be used with hflush", - defaultValue = "false" - ) - private boolean hSync; - - @Option(names= {"--flush"}, - description = "Optionally Issue hsync after every write " + - "Cannot be used with hflush", - defaultValue = "false" - ) - private boolean hFlush; - - // For Generating the content of the files - private ContentGenerator contentGenerator; - // For Creating the required configurations for the file system - private OzoneConfiguration configuration; - - private URI uri; - - // variable to check if the user wants a delay - private boolean isThrottled; - - long expectedIoTimeNs; - - private Timer timer; - - private final ThreadLocal threadLocalFileSystem = - ThreadLocal.withInitial(this::createFS); - - public static final Logger LOG = - LoggerFactory.getLogger(WriteFileThroughputBenchmark.class); - - - public Void call() throws Exception{ - - init(); - LOG.info("NumFiles=" + getTestNo()); - LOG.info("Total FileSize=" + fileSize); - LOG.info("BlockSize=" + blockSize); - LOG.info("BufferSize=" + bufferSize); - LOG.info("Replication=" + replication); - LOG.info("Threads=" + getThreadNo()); - LOG.info("URI Scheme Used=" + uri.getScheme()); - if(hSync){ - LOG.info("Hsync after every write= True"); - } - else if(hFlush){ - LOG.info("Hflush after every write= True"); - } - - // Initialize the configuration variable with - // OzoneFS configuration - configuration = createOzoneConfiguration(); - - //Constructs a URI object by parsing the given string rootPath - uri = URI.create(rootPath); - - // Disabling the file system cache - String disableCacheName = String.format("fs.%s.impl.disable.cache", - uri.getScheme()); - print("Disabling FS cache: " + disableCacheName); - configuration.setBoolean(disableCacheName, true); - - Path file = new Path(rootPath + "/" + - generateObjectName(0)); - try (FileSystem fileSystem = threadLocalFileSystem.get()) { - fileSystem.mkdirs(file.getParent()); - } - // Checks whether output directory exists - ensureOutputDirExists(createFS(),file); - - // Initialize the size of the file to be written in Bytes - long filesizeinBytes = fileSize*1_000_000_000; - contentGenerator = new ContentGenerator(filesizeinBytes, - bufferSize, hSync, hFlush); - - // Initializing the time it should take to write a file - expectedIoTimeNs = - (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) - : 0); - - timer = getMetrics().timer("file-create"); - - runTests(this::createFile); - - return null; + implements Callable { + + @Option(names = {"-o"}, + description = "Ozone filesystem path", + defaultValue = "o3fs://bucket1.vol1") + private String rootPath; + + @Option(names = {"-s", "--size"}, + description = "Size of each generated files (in GB)", + defaultValue = "1") + private long fileSize; + + @Option(names = {"-bl", "--block"}, + description = "Specify the Block Size in MB", + defaultValue = "128") + private long blockSize; + + @Option(names = {"-bu", "--buffer"}, + description = "Size of buffer used store the generated " + + "key content", + defaultValue = "10240") + private int bufferSize; + + @Option(names = {"-th", "--throttle"}, + description = "Specify the Delay in Input/Output", + defaultValue = "0") + private int throttle; + + @Option(names = {"-re", "--replication"}, + description = "Specify the Replication factor", + defaultValue = "1") + private short replication; + + @Option(names = {"--sync"}, + description = "Optionally Issue hsync after every write " + + "Cannot be used with hflush", + defaultValue = "false" + ) + private boolean hSync; + + @Option(names = {"--flush"}, + description = "Optionally Issue hsync after every write " + + "Cannot be used with hflush", + defaultValue = "false" + ) + private boolean hFlush; + + // For Generating the content of the files + private ContentGenerator contentGenerator; + // For Creating the required configurations for the file system + private OzoneConfiguration configuration; + + private URI uri; + + // variable to check if the user wants a delay + private boolean isThrottled; + + private long expectedIoTimeNs; + + private Timer timer; + + private final ThreadLocal threadLocalFileSystem = + ThreadLocal.withInitial(this::createFS); + + public static final Logger LOG = + LoggerFactory.getLogger(WriteFileThroughputBenchmark.class); + + + public Void call() throws Exception { + + init(); + LOG.info("NumFiles=" + getTestNo()); + LOG.info("Total FileSize=" + fileSize); + LOG.info("BlockSize=" + blockSize); + LOG.info("BufferSize=" + bufferSize); + LOG.info("Replication=" + replication); + LOG.info("Threads=" + getThreadNo()); + LOG.info("URI Scheme Used=" + uri.getScheme()); + if (hSync) { + LOG.info("Hsync after every write= True"); + } else if (hFlush) { + LOG.info("Hflush after every write= True"); } + // Initialize the configuration variable with + // OzoneFS configuration + configuration = createOzoneConfiguration(); - private void createFile(long counter) throws Exception { - Path file = new Path(rootPath + "/" + generateObjectName(counter)); - FileSystem fileSystem = threadLocalFileSystem.get(); + //Constructs a URI object by parsing the given string rootPath + uri = URI.create(rootPath); - final long ioStartTimeNs = (isThrottled ? System.nanoTime() : 0); + // Disabling the file system cache + String disableCacheName = String.format("fs.%s.impl.disable.cache", + uri.getScheme()); + print("Disabling FS cache: " + disableCacheName); + configuration.setBoolean(disableCacheName, true); - timer.time(() -> { - try ( FSDataOutputStream outputStream = fileSystem.create(file, - false, bufferSize,replication,blockSize)) { - contentGenerator.write(outputStream); - - // Enforcing throttle delay - final long ioEndTimeNs = (isThrottled ? System.nanoTime() : 0); - enforceThrottle(ioEndTimeNs - ioStartTimeNs, expectedIoTimeNs); - } - return null; - }); + Path file = new Path(rootPath + "/" + + generateObjectName(0)); + try (FileSystem fileSystem = threadLocalFileSystem.get()) { + fileSystem.mkdirs(file.getParent()); } + // Checks whether output directory exists + ensureOutputDirExists(createFS(), file); - private FileSystem createFS() { - try { - return FileSystem.get(uri, configuration); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } + // Initialize the size of the file to be written in Bytes + long filesizeinBytes = fileSize * 1_000_000_000; + contentGenerator = new ContentGenerator(filesizeinBytes, + bufferSize, hSync, hFlush); - // Method to cause the delay of a certain amount - static void enforceThrottle(long ioTimeNs, long expectedIoTimeNs) throws - InterruptedException { - if (ioTimeNs < expectedIoTimeNs) { - // The IO completed too fast, so sleep for some time. - long sleepTimeNs = expectedIoTimeNs - ioTimeNs; - Thread.sleep(sleepTimeNs / 1_000_000, (int) - (sleepTimeNs % 1_000_000)); - } - } + // Initializing the time it should take to write a file + expectedIoTimeNs = + (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) + : 0); + + timer = getMetrics().timer("file-create"); + + runTests(this::createFile); + + return null; + } - // Checking whether an output directory is created inside the bucket - private static void ensureOutputDirExists(FileSystem fs, Path outputDir) - throws IOException { - if (!fs.exists(outputDir)) { - LOG.error("No Such Output Directory exists : {}", outputDir); - System.exit(1); - } - } - @Override - protected void taskLoopCompleted() { - FileSystem fileSystem = threadLocalFileSystem.get(); - try { - fileSystem.close(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + private void createFile(long counter) throws Exception { + Path file = new Path(rootPath + "/" + generateObjectName(counter)); + FileSystem fileSystem = threadLocalFileSystem.get(); + + final long ioStartTimeNs = (isThrottled ? System.nanoTime() : 0); + + timer.time(() -> { + try (FSDataOutputStream outputStream = fileSystem.create(file, + false, bufferSize, replication, blockSize)) { + contentGenerator.write(outputStream); + + // Enforcing throttle delay + final long ioEndTimeNs = (isThrottled ? System.nanoTime() : 0); + enforceThrottle(ioEndTimeNs - ioStartTimeNs, expectedIoTimeNs); + } + return null; + }); + } + + private FileSystem createFS() { + try { + return FileSystem.get(uri, configuration); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + // Method to cause the delay of a certain amount + static void enforceThrottle(long ioTimeNs, long expectedIoTimeNs) throws + InterruptedException { + if (ioTimeNs < expectedIoTimeNs) { + // The IO completed too fast, so sleep for some time. + long sleepTimeNs = expectedIoTimeNs - ioTimeNs; + Thread.sleep(sleepTimeNs / 1_000_000, (int) + (sleepTimeNs % 1_000_000)); + } + } + + // Checking whether an output directory is created inside the bucket + private static void ensureOutputDirExists(FileSystem fs, Path outputDir) + throws IOException { + if (!fs.exists(outputDir)) { + LOG.error("No Such Output Directory exists : {}", outputDir); + System.exit(1); + } + } + + @Override + protected void taskLoopCompleted() { + FileSystem fileSystem = threadLocalFileSystem.get(); + try { + fileSystem.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); } + } } \ No newline at end of file From 54efc3ed118a945db43f9b7002077cea1781aeba Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 14 Mar 2022 18:23:55 +0530 Subject: [PATCH 06/19] HDDS-1726. Integrate FsPerfTest into Ozone freon performance test suite. --- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 69c0016c03e3..c3cce9842b34 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -16,7 +16,9 @@ import java.net.URI; import java.util.concurrent.Callable; - +/** + * File Generator for populating the cluster with random files + */ @CommandLine.Command(name = "wtb", aliases = "write-throughput-benchmark", description = "Benchmark for creating a file", From 065bd2cb71939df065891c173dddb8cb820fd6ed Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 14 Mar 2022 20:31:17 +0530 Subject: [PATCH 07/19] Added a period to the first sentence --- .../apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index c3cce9842b34..63b8eb74bcab 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -17,7 +17,7 @@ import java.util.concurrent.Callable; /** - * File Generator for populating the cluster with random files + * File Generator for populating the cluster with random files. */ @CommandLine.Command(name = "wtb", aliases = "write-throughput-benchmark", From 54629df359f0c94f45603a96215ce908a5fa1a17 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Tue, 15 Mar 2022 10:57:26 +0530 Subject: [PATCH 08/19] Replaced print message with LOG message at line:123 --- .../apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 63b8eb74bcab..b5caa8d79709 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -120,7 +120,7 @@ public Void call() throws Exception { // Disabling the file system cache String disableCacheName = String.format("fs.%s.impl.disable.cache", uri.getScheme()); - print("Disabling FS cache: " + disableCacheName); + LOG.info("Disabling FS cache: "+disableCacheName); configuration.setBoolean(disableCacheName, true); Path file = new Path(rootPath + "/" + From a84380629de5dc78b64c9ca23e45abbf741c568e Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Tue, 15 Mar 2022 11:05:49 +0530 Subject: [PATCH 09/19] Removed the try block at :128 so as to reuse filesystem object --- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index b5caa8d79709..f3ccb1a7297d 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -125,9 +125,8 @@ public Void call() throws Exception { Path file = new Path(rootPath + "/" + generateObjectName(0)); - try (FileSystem fileSystem = threadLocalFileSystem.get()) { - fileSystem.mkdirs(file.getParent()); - } + FileSystem fileSystem = threadLocalFileSystem.get(); + fileSystem.mkdirs(file.getParent()); // Checks whether output directory exists ensureOutputDirExists(createFS(), file); From 33deba7a44f87dd9416d5aa9927db952484b9ff3 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Tue, 15 Mar 2022 18:41:16 +0530 Subject: [PATCH 10/19] Implemented the changes suggested in code review --- .../hadoop/ozone/freon/ContentGenerator.java | 4 ++-- .../freon/WriteFileThroughputBenchmark.java | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java index da6e692b8481..724ff56430d4 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/ContentGenerator.java @@ -32,13 +32,13 @@ public class ContentGenerator { /** * Size of the destination object (key or file). */ - private long keySize; + private final long keySize; /** * Buffer for the pre-allocated content (will be reused if less than the * keySize). */ - private int bufferSize; + private final int bufferSize; /** * Number of bytes to write in one call. diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index f3ccb1a7297d..ba6dee58d3e3 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -28,9 +28,9 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements Callable { - @Option(names = {"-o"}, - description = "Ozone filesystem path", - defaultValue = "o3fs://bucket1.vol1") + @Option(names = {"-p", "--path"}, + description = "Ozone filesystem path OFS scheme", + defaultValue = "ofs://ozone1/volume1/bucket1") private String rootPath; @Option(names = {"-s", "--size"}, @@ -97,6 +97,15 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator public Void call() throws Exception { init(); + + // We cannot have both Hsync and Hflush set to TRUE at the same time + if(hSync == true || hFlush == true){ + if(hSync == hFlush){ + LOG.info("Both Hsync and Hflush cannot be set to TRUE"); + System.exit(1); + } + } + LOG.info("NumFiles=" + getTestNo()); LOG.info("Total FileSize=" + fileSize); LOG.info("BlockSize=" + blockSize); @@ -125,7 +134,7 @@ public Void call() throws Exception { Path file = new Path(rootPath + "/" + generateObjectName(0)); - FileSystem fileSystem = threadLocalFileSystem.get(); + FileSystem fileSystem = FileSystem.get(configuration); fileSystem.mkdirs(file.getParent()); // Checks whether output directory exists ensureOutputDirExists(createFS(), file); From 3b57f6d71b20c08f1f5b785137a8bdb27d9b6ec2 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Wed, 16 Mar 2022 14:59:29 +0530 Subject: [PATCH 11/19] Added Apache License --- hadoop-ozone/tools/pom.xml | 4 ---- .../freon/WriteFileThroughputBenchmark.java | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hadoop-ozone/tools/pom.xml b/hadoop-ozone/tools/pom.xml index 67cc0b8789ea..47501795307b 100644 --- a/hadoop-ozone/tools/pom.xml +++ b/hadoop-ozone/tools/pom.xml @@ -124,10 +124,6 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd"> mockito-core test - - org.apache.hadoop - hadoop-common - diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index ba6dee58d3e3..b74a420e2997 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -1,3 +1,19 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ package org.apache.hadoop.ozone.freon; import com.codahale.metrics.Timer; From b11756dc196f90d911261bd5ecb1a3334461e83d Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Wed, 16 Mar 2022 19:46:00 +0530 Subject: [PATCH 12/19] Fixed the style checks --- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index b74a420e2997..1f50ba5c6f6a 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -115,8 +115,8 @@ public Void call() throws Exception { init(); // We cannot have both Hsync and Hflush set to TRUE at the same time - if(hSync == true || hFlush == true){ - if(hSync == hFlush){ + if (hSync && hFlush) { + if (hSync == hFlush) { LOG.info("Both Hsync and Hflush cannot be set to TRUE"); System.exit(1); } @@ -145,7 +145,7 @@ public Void call() throws Exception { // Disabling the file system cache String disableCacheName = String.format("fs.%s.impl.disable.cache", uri.getScheme()); - LOG.info("Disabling FS cache: "+disableCacheName); + LOG.info("Disabling FS cache: " + disableCacheName); configuration.setBoolean(disableCacheName, true); Path file = new Path(rootPath + "/" + From 2714f4d2f6d5f7edf7b78ef6245dbc1a5efdcb0c Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Thu, 17 Mar 2022 11:19:30 +0530 Subject: [PATCH 13/19] retrigger checks From f5908061e56c3f9994f659f39905fe481b745b8f Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 13:00:39 +0530 Subject: [PATCH 14/19] Removed two mutually exclusive flags with a single 3-way option. --- .../freon/WriteFileThroughputBenchmark.java | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 1f50ba5c6f6a..2798d4787cf6 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -75,19 +75,20 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator defaultValue = "1") private short replication; - @Option(names = {"--sync"}, - description = "Optionally Issue hsync after every write " + + @Option(names = {"--flags"}, + description = "Optionally issue hSync or hFlush after every write" + "Cannot be used with hflush", defaultValue = "false" ) - private boolean hSync; - - @Option(names = {"--flush"}, - description = "Optionally Issue hsync after every write " + - "Cannot be used with hflush", - defaultValue = "false" - ) - private boolean hFlush; + private String flag = ""; + + /** + * Type of flags. + */ + public enum Flags { + hSync, + hFlush, + } // For Generating the content of the files private ContentGenerator contentGenerator; @@ -114,14 +115,6 @@ public Void call() throws Exception { init(); - // We cannot have both Hsync and Hflush set to TRUE at the same time - if (hSync && hFlush) { - if (hSync == hFlush) { - LOG.info("Both Hsync and Hflush cannot be set to TRUE"); - System.exit(1); - } - } - LOG.info("NumFiles=" + getTestNo()); LOG.info("Total FileSize=" + fileSize); LOG.info("BlockSize=" + blockSize); @@ -129,10 +122,22 @@ public Void call() throws Exception { LOG.info("Replication=" + replication); LOG.info("Threads=" + getThreadNo()); LOG.info("URI Scheme Used=" + uri.getScheme()); - if (hSync) { - LOG.info("Hsync after every write= True"); - } else if (hFlush) { - LOG.info("Hflush after every write= True"); + LOG.info("Flag Chosen=" + flag); + + // Choosing which flag is to be set + boolean flush = false; + boolean sync = false; + Flags type = Flags.valueOf(flag); + switch (type) { + case hSync: + sync = true; + break; + case hFlush: + flush = true; + break; + default: + throw new IllegalArgumentException( + flag + " is not a valid benchmarkType."); } // Initialize the configuration variable with @@ -150,7 +155,7 @@ public Void call() throws Exception { Path file = new Path(rootPath + "/" + generateObjectName(0)); - FileSystem fileSystem = FileSystem.get(configuration); + FileSystem fileSystem = FileSystem.get(configuration); fileSystem.mkdirs(file.getParent()); // Checks whether output directory exists ensureOutputDirExists(createFS(), file); @@ -158,7 +163,7 @@ public Void call() throws Exception { // Initialize the size of the file to be written in Bytes long filesizeinBytes = fileSize * 1_000_000_000; contentGenerator = new ContentGenerator(filesizeinBytes, - bufferSize, hSync, hFlush); + bufferSize, sync, flush); // Initializing the time it should take to write a file expectedIoTimeNs = From 3001c9b79fff0a9318aebd83abd649f133f7126e Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 13:05:40 +0530 Subject: [PATCH 15/19] Improved the desciription of throttle option --- .../apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 2798d4787cf6..835beae09b16 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -66,7 +66,7 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator private int bufferSize; @Option(names = {"-th", "--throttle"}, - description = "Specify the Delay in Input/Output", + description = "Specify the Max Write throughput in bytes/second", defaultValue = "0") private int throttle; From 529cad7f02555d8df3bbec8f5d808193460a4207 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 13:08:12 +0530 Subject: [PATCH 16/19] Improved the desciription of throttle option --- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 835beae09b16..159ffb7fc9e9 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -66,7 +66,8 @@ public class WriteFileThroughputBenchmark extends BaseFreonGenerator private int bufferSize; @Option(names = {"-th", "--throttle"}, - description = "Specify the Max Write throughput in bytes/second", + description = "Specify the Max Write throughput in bytes/second - " + + "Should not be used while benchmarking", defaultValue = "0") private int throttle; From 6a3691672c9db0e38b364fd357aa9abdc1ac67e1 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 13:31:22 +0530 Subject: [PATCH 17/19] Made minor changes --- .../hadoop/ozone/freon/WriteFileThroughputBenchmark.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 159ffb7fc9e9..70823453d81c 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -41,7 +41,7 @@ versionProvider = HddsVersionProvider.class, mixinStandardHelpOptions = true, showDefaultValues = true) -public class WriteFileThroughputBenchmark extends BaseFreonGenerator +public class WriteFileThroughputBenchmark extends HadoopFsGenerator implements Callable { @Option(names = {"-p", "--path"}, @@ -99,7 +99,7 @@ public enum Flags { private URI uri; // variable to check if the user wants a delay - private boolean isThrottled; + private boolean isThrottled = false; private long expectedIoTimeNs; @@ -166,6 +166,10 @@ public Void call() throws Exception { contentGenerator = new ContentGenerator(filesizeinBytes, bufferSize, sync, flush); + if (throttle > 0) { + isThrottled = true; + } + // Initializing the time it should take to write a file expectedIoTimeNs = (isThrottled ? (((long) bufferSize * 1_000_000_000) / throttle) From 5f9f9ba940d2a1d851012d0e1ca2baf869ce1995 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 13:46:42 +0530 Subject: [PATCH 18/19] Changed the problem with the flags --- .../ozone/freon/WriteFileThroughputBenchmark.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index 70823453d81c..b29f5f23bbe9 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -44,7 +44,7 @@ public class WriteFileThroughputBenchmark extends HadoopFsGenerator implements Callable { - @Option(names = {"-p", "--path"}, + @Option(names = {"-P", "--path"}, description = "Ozone filesystem path OFS scheme", defaultValue = "ofs://ozone1/volume1/bucket1") private String rootPath; @@ -54,24 +54,24 @@ public class WriteFileThroughputBenchmark extends HadoopFsGenerator defaultValue = "1") private long fileSize; - @Option(names = {"-bl", "--block"}, + @Option(names = {"-b", "--block"}, description = "Specify the Block Size in MB", defaultValue = "128") private long blockSize; - @Option(names = {"-bu", "--buffer"}, + @Option(names = {"-B", "--buffer"}, description = "Size of buffer used store the generated " + "key content", defaultValue = "10240") private int bufferSize; - @Option(names = {"-th", "--throttle"}, + @Option(names = {"-T", "--throttle"}, description = "Specify the Max Write throughput in bytes/second - " + "Should not be used while benchmarking", defaultValue = "0") private int throttle; - @Option(names = {"-re", "--replication"}, + @Option(names = {"-r", "--replication"}, description = "Specify the Replication factor", defaultValue = "1") private short replication; From d37ff9d6f6910b8108e636b5db1c17f72a6ba480 Mon Sep 17 00:00:00 2001 From: Mohammad Arafat Khan Date: Mon, 21 Mar 2022 15:47:23 +0530 Subject: [PATCH 19/19] Made changes for Code Review --- .../ozone/freon/WriteFileThroughputBenchmark.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java index b29f5f23bbe9..ff712f2dcb0f 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/freon/WriteFileThroughputBenchmark.java @@ -41,7 +41,7 @@ versionProvider = HddsVersionProvider.class, mixinStandardHelpOptions = true, showDefaultValues = true) -public class WriteFileThroughputBenchmark extends HadoopFsGenerator +public class WriteFileThroughputBenchmark extends BaseFreonGenerator implements Callable { @Option(names = {"-P", "--path"}, @@ -66,7 +66,7 @@ public class WriteFileThroughputBenchmark extends HadoopFsGenerator private int bufferSize; @Option(names = {"-T", "--throttle"}, - description = "Specify the Max Write throughput in bytes/second - " + + description = "Specify the Max Write throughput in bytes/second " + "Should not be used while benchmarking", defaultValue = "0") private int throttle; @@ -79,9 +79,9 @@ public class WriteFileThroughputBenchmark extends HadoopFsGenerator @Option(names = {"--flags"}, description = "Optionally issue hSync or hFlush after every write" + "Cannot be used with hflush", - defaultValue = "false" + defaultValue = "None" ) - private String flag = ""; + private String flag; /** * Type of flags. @@ -89,6 +89,7 @@ public class WriteFileThroughputBenchmark extends HadoopFsGenerator public enum Flags { hSync, hFlush, + None, } // For Generating the content of the files @@ -136,6 +137,8 @@ public Void call() throws Exception { case hFlush: flush = true; break; + case None: + break; default: throw new IllegalArgumentException( flag + " is not a valid benchmarkType.");