From 89153a9c684bbafd9a1309ca2a20347251c577e8 Mon Sep 17 00:00:00 2001 From: Todd Lipcon Date: Wed, 15 Aug 2012 18:53:13 +0000 Subject: [PATCH] HDFS-3796. Speed up edit log tests by avoiding fsync(). Contributed by Todd Lipcon. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1373567 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 2 ++ .../namenode/EditLogFileOutputStream.java | 17 ++++++++++++++++- .../hdfs/server/namenode/TestEditLog.java | 5 +++++ .../namenode/TestEditLogFileOutputStream.java | 6 ++++++ .../server/namenode/TestFileJournalManager.java | 6 ++++++ .../server/namenode/TestNameNodeRecovery.java | 1 + .../namenode/TestSecurityTokenEditLog.java | 6 ++++++ .../namenode/ha/TestEditLogsDuringFailover.java | 7 +++++++ 8 files changed, 49 insertions(+), 1 deletion(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 1d8c25975cb..ce3643fb34e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -397,6 +397,8 @@ Branch-2 ( Unreleased changes ) HDFS-3802. StartupOption.name in HdfsServerConstants should be final. (Jing Zhao via szetszwo) + HDFS-3796. Speed up edit log tests by avoiding fsync() (todd) + OPTIMIZATIONS HDFS-2982. Startup performance suffers when there are many edit log diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EditLogFileOutputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EditLogFileOutputStream.java index bb181d743b6..f7a8b337a6d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EditLogFileOutputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EditLogFileOutputStream.java @@ -49,6 +49,8 @@ public class EditLogFileOutputStream extends EditLogOutputStream { private EditsDoubleBuffer doubleBuf; static ByteBuffer fill = ByteBuffer.allocateDirect(MIN_PREALLOCATION_LENGTH); + private static boolean shouldSkipFsyncForTests = false; + static { fill.position(0); for (int i = 0; i < fill.capacity(); i++) { @@ -184,7 +186,9 @@ public void flushAndSync() throws IOException { } preallocate(); // preallocate file if necessay doubleBuf.flushTo(fp); - fc.force(false); // metadata updates not needed + if (!shouldSkipFsyncForTests) { + fc.force(false); // metadata updates not needed + } } /** @@ -247,4 +251,15 @@ public void setFileChannelForTesting(FileChannel fc) { public FileChannel getFileChannelForTesting() { return fc; } + + /** + * For the purposes of unit tests, we don't need to actually + * write durably to disk. So, we can skip the fsync() calls + * for a speed improvement. + * @param skip true if fsync should not be called + */ + @VisibleForTesting + public static void setShouldSkipFsyncForTesting(boolean skip) { + shouldSkipFsyncForTests = skip; + } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLog.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLog.java index e7abc1132d0..d9ac54ed0ef 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLog.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLog.java @@ -119,6 +119,11 @@ public class TestEditLog { "a4ff 0000 0000 0000 0000 0000 0000 0000" ).replace(" ","")); + static { + // No need to fsync for the purposes of tests. This makes + // the tests run much faster. + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); + } static final byte TRAILER_BYTE = FSEditLogOpCodes.OP_INVALID.getOpCode(); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLogFileOutputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLogFileOutputStream.java index ead94968eeb..22ab02d2a9d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLogFileOutputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestEditLogFileOutputStream.java @@ -40,6 +40,12 @@ public class TestEditLogFileOutputStream { final static int MIN_PREALLOCATION_LENGTH = EditLogFileOutputStream.MIN_PREALLOCATION_LENGTH; + static { + // No need to fsync for the purposes of tests. This makes + // the tests run much faster. + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); + } + @Before @After public void deleteEditsFile() { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileJournalManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileJournalManager.java index 1a968c7d1d1..722e4e24bf3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileJournalManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFileJournalManager.java @@ -51,6 +51,12 @@ public class TestFileJournalManager { static final Log LOG = LogFactory.getLog(TestFileJournalManager.class); + static { + // No need to fsync for the purposes of tests. This makes + // the tests run much faster. + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); + } + /** * Find out how many transactions we can read from a * FileJournalManager, starting at a given transaction ID. diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeRecovery.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeRecovery.java index 1717bb04125..23fd3b51a71 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeRecovery.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeRecovery.java @@ -57,6 +57,7 @@ public class TestNameNodeRecovery { static { recoverStartOpt.setForce(MetaRecoveryContext.FORCE_ALL); + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); } static void runEditLogTest(EditLogTestSetup elts) throws IOException { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSecurityTokenEditLog.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSecurityTokenEditLog.java index e3056e9b0bf..dd679d1a9af 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSecurityTokenEditLog.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSecurityTokenEditLog.java @@ -49,6 +49,12 @@ public class TestSecurityTokenEditLog { static final int NUM_THREADS = 100; static final int opsPerTrans = 3; + static { + // No need to fsync for the purposes of tests. This makes + // the tests run much faster. + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); + } + // // an object that does a bunch of transactions // diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/ha/TestEditLogsDuringFailover.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/ha/TestEditLogsDuringFailover.java index dd5c1bab75c..5e18381e7a5 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/ha/TestEditLogsDuringFailover.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/ha/TestEditLogsDuringFailover.java @@ -34,6 +34,7 @@ import org.apache.hadoop.hdfs.HAUtil; import org.apache.hadoop.hdfs.MiniDFSCluster; import org.apache.hadoop.hdfs.MiniDFSNNTopology; +import org.apache.hadoop.hdfs.server.namenode.EditLogFileOutputStream; import org.apache.hadoop.hdfs.server.namenode.FSImageTestUtil; import org.apache.hadoop.hdfs.server.namenode.NNStorage; import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter; @@ -52,6 +53,12 @@ public class TestEditLogsDuringFailover { private static final Log LOG = LogFactory.getLog(TestEditLogsDuringFailover.class); private static final int NUM_DIRS_IN_LOG = 5; + + static { + // No need to fsync for the purposes of tests. This makes + // the tests run much faster. + EditLogFileOutputStream.setShouldSkipFsyncForTesting(true); + } @Test public void testStartup() throws Exception {