diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml index 174efac..b8cd787 100644 --- a/hbase-common/src/main/resources/hbase-default.xml +++ b/hbase-common/src/main/resources/hbase-default.xml @@ -273,6 +273,16 @@ possible configurations would overwhelm and obscure the important. The HLog file writer implementation. + hbase.wal.hsync + false + Set to true if hbase should call hsync rather than hflush + whenever it syncs edits in its WAL log. See the Hadoop Syncable + Interface, + http://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/Syncable.html, + for an explanation of the difference. Since HBase 1.0. + + + hbase.master.distributed.log.replay true Enable 'distributed log replay' as default engine splitting diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java index eb3692e..b152a22 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java @@ -110,6 +110,10 @@ public interface HLog { * WAL Writer Intrface. */ interface Writer { + // Key to use fetching whether to call hsync whenever {@link #sync} is called. + public static final String HBASE_WAL_HSYNC_KEY = "hbase.wal.hsync"; + public static final boolean HBASE_WAL_HSYNC_DEFAULT = false; + void init(FileSystem fs, Path path, Configuration c, boolean overwritable) throws IOException; void close() throws IOException; diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java index 14ffa45..de58d23 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java @@ -50,6 +50,12 @@ public class ProtobufLogWriter extends WriterBase { // than this size, it is written/read respectively, with a WARN message in the log. private int trailerWarnSize; + /** + * Whether to call hsync or hflush on our stream. See HDFS Syncable Interface for + * the difference (hsync fsyncs, hflush just flushes to the memory of the datanodes). + */ + private volatile boolean doHSync = false; + public ProtobufLogWriter() { super(); } @@ -76,6 +82,9 @@ public class ProtobufLogWriter extends WriterBase { throws IOException { super.init(fs, path, conf, overwritable); assert this.output == null; + // Whether to call hflush or hsync when {@link #sync()} is called. See Syncable.java from + // Hadoop FS for detail. + this.doHSync = conf.getBoolean(HBASE_WAL_HSYNC_KEY, HBASE_WAL_HSYNC_DEFAULT); boolean doCompress = initializeCompressionContext(conf, path); this.trailerWarnSize = conf.getInt(HLog.WAL_TRAILER_WARN_SIZE, HLog.DEFAULT_WAL_TRAILER_WARN_SIZE); @@ -163,8 +172,11 @@ public class ProtobufLogWriter extends WriterBase { @Override public void sync() throws IOException { try { - this.output.hflush(); - this.output.hsync(); + // This looks to be a noop but its what we have always done. Leaving for now. + this.output.flush(); + // See the Syncable Interface from HDFS as to difference between hsync and hflush. + if (this.doHSync) this.output.hsync(); + else this.output.hflush(); } catch (NullPointerException npe) { // Concurrent close... throw new IOException(npe);