diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java index 1da9e34..926f7d6 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/Mutation.java @@ -66,7 +66,6 @@ public abstract class Mutation extends OperationWithAttributes implements Row, C protected byte [] row = null; protected long ts = HConstants.LATEST_TIMESTAMP; protected Durability durability = Durability.USE_DEFAULT; - protected boolean writeToWAL = true; // make current mutation as a distributed log replay change protected boolean isReplay = false; diff --git hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSource.java hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSource.java index 7ad6e4f..d40f2fc 100644 --- hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSource.java +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSource.java @@ -60,6 +60,8 @@ public interface MetricsMasterSource extends BaseSource { static final String SNAPSHOT_TIME_NAME = "snapshotTime"; static final String SNAPSHOT_RESTORE_TIME_NAME = "snapshotRestoreTime"; static final String SNAPSHOT_CLONE_TIME_NAME = "snapshotCloneTime"; + static final String META_SPLIT_TIME_NAME = "metaHlogSplitTime"; + static final String META_SPLIT_SIZE_NAME = "metaHlogSplitSize"; static final String CLUSTER_REQUESTS_NAME = "clusterRequests"; static final String RIT_COUNT_NAME = "ritCount"; static final String RIT_COUNT_OVER_THRESHOLD_NAME = "ritCountOverThreshold"; @@ -78,7 +80,8 @@ public interface MetricsMasterSource extends BaseSource { static final String SNAPSHOT_TIME_DESC = "Time it takes to finish snapshot()"; static final String SNAPSHOT_RESTORE_TIME_DESC = "Time it takes to finish restoreSnapshot()"; static final String SNAPSHOT_CLONE_TIME_DESC = "Time it takes to finish cloneSnapshot()"; - + static final String META_SPLIT_TIME_DESC = "Time it takes to finish splitMetaLog()"; + static final String META_SPLIT_SIZE_DESC = "Size of META HLog files being split"; /** * Increment the number of requests the cluster has seen. @@ -117,4 +120,9 @@ public interface MetricsMasterSource extends BaseSource { void updateSnapshotCloneTime(long time); void updateSnapshotRestoreTime(long time); + + void updateMetaSplitTime(long time); + + void updateMetaSplitSize(long size); + } diff --git hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySource.java hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySource.java new file mode 100644 index 0000000..dc42ac5 --- /dev/null +++ hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySource.java @@ -0,0 +1,72 @@ +/** + * 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.hbase.regionserver.wal; + +import org.apache.hadoop.hbase.metrics.BaseSource; + +/** + * Interface of the source that will export metrics about log replay statistics when recovering a + * region server in distributedLogReplay mode + */ +public interface MetricsEditsReplaySource extends BaseSource { + + /** + * The name of the metrics + */ + static final String METRICS_NAME = "replay"; + + /** + * The name of the metrics context that metrics will be under. + */ + static final String METRICS_CONTEXT = "regionserver"; + + /** + * Description + */ + static final String METRICS_DESCRIPTION = "Metrics about HBase RegionServer HLog Edits Replay"; + + /** + * The name of the metrics context that metrics will be under in jmx + */ + static final String METRICS_JMX_CONTEXT = "RegionServer,sub=" + METRICS_NAME; + + + static final String REPLAY_TIME_NAME = "replayTime"; + static final String REPLAY_TIME_DESC = "Time an replay operation took."; + static final String REPLAY_BATCH_SIZE_NAME = "replayBatchSize"; + static final String REPLAY_BATCH_SIZE_DESC = "Number of changes of each replay batch."; + static final String REPLAY_DATA_SIZE_NAME = "replayDataSize"; + static final String REPLAY_DATA_SIZE_DESC = "Size (in bytes) of the data of each replay."; + + /** + * Add the time a replay command took + */ + void updateReplayTime(long time); + + /** + * Add the batch size of each replay + */ + void updateReplayBatchSize(long size); + + /** + * Add the payload data size of each replay + */ + void updateReplayDataSize(long size); + +} diff --git hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java index 2d7c9fb..228f931 100644 --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java @@ -48,6 +48,8 @@ public class MetricsMasterSourceImpl private MetricMutableStat snapshotTimeHisto; private MetricMutableStat snapshotCloneTimeHisto; private MetricMutableStat snapshotRestoreTimeHisto; + private MetricMutableHistogram metaSplitTimeHisto; + private MetricMutableHistogram metaSplitSizeHisto; public MetricsMasterSourceImpl(MetricsMasterWrapper masterWrapper) { this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT, masterWrapper); @@ -77,6 +79,8 @@ public class MetricsMasterSourceImpl SNAPSHOT_CLONE_TIME_NAME, SNAPSHOT_CLONE_TIME_DESC, "Ops", "Time", true); snapshotRestoreTimeHisto = metricsRegistry.newStat( SNAPSHOT_RESTORE_TIME_NAME, SNAPSHOT_RESTORE_TIME_DESC, "Ops", "Time", true); + metaSplitTimeHisto = metricsRegistry.newHistogram(META_SPLIT_TIME_NAME, META_SPLIT_TIME_DESC); + metaSplitSizeHisto = metricsRegistry.newHistogram(META_SPLIT_SIZE_NAME, META_SPLIT_SIZE_DESC); } public void incRequests(final int inc) { @@ -120,6 +124,16 @@ public class MetricsMasterSourceImpl snapshotRestoreTimeHisto.add(time); } + @Override + public void updateMetaSplitTime(long time) { + metaSplitTimeHisto.add(time); + } + + @Override + public void updateMetaSplitSize(long size) { + metaSplitSizeHisto.add(size); + } + /** * Method to export all the metrics. * diff --git hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java new file mode 100644 index 0000000..dfb94f2 --- /dev/null +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java @@ -0,0 +1,75 @@ +/** + * 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.hbase.regionserver.wal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.metrics.BaseSourceImpl; +import org.apache.hadoop.metrics2.lib.MetricMutableHistogram; + +/** + * Hadoop1 implementation of MetricsMasterSource. + * + * Implements BaseSource through BaseSourceImpl, following the pattern + */ +public class MetricsEditsReplaySourceImpl + extends BaseSourceImpl implements MetricsEditsReplaySource { + + private static final Log LOG = LogFactory.getLog(MetricsEditsReplaySourceImpl.class.getName()); + + private MetricMutableHistogram replayTimeHisto; + private MetricMutableHistogram replayBatchSizeHisto; + private MetricMutableHistogram replayDataSizeHisto; + + public MetricsEditsReplaySourceImpl() { + this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT); + } + + public MetricsEditsReplaySourceImpl(String metricsName, + String metricsDescription, + String metricsContext, + String metricsJmxContext) { + super(metricsName, metricsDescription, metricsContext, metricsJmxContext); + } + + @Override + public void init() { + super.init(); + replayTimeHisto = metricsRegistry.newHistogram(REPLAY_TIME_NAME, REPLAY_TIME_DESC); + replayBatchSizeHisto = + metricsRegistry.newHistogram(REPLAY_BATCH_SIZE_NAME, REPLAY_BATCH_SIZE_DESC); + replayDataSizeHisto = + metricsRegistry.newHistogram(REPLAY_DATA_SIZE_NAME, REPLAY_DATA_SIZE_DESC); + } + + @Override + public void updateReplayTime(long time) { + replayTimeHisto.add(time); + } + + @Override + public void updateReplayBatchSize(long size) { + replayBatchSizeHisto.add(size); + } + + @Override + public void updateReplayDataSize(long size) { + replayDataSizeHisto.add(size); + } +} diff --git hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource new file mode 100644 index 0000000..ed95795 --- /dev/null +++ hbase-hadoop1-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySourceImpl diff --git hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java index 6f9f143..6751d0c 100644 --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/master/MetricsMasterSourceImpl.java @@ -45,6 +45,8 @@ public class MetricsMasterSourceImpl private MutableStat snapshotTimeHisto; private MutableStat snapshotCloneTimeHisto; private MutableStat snapshotRestoreTimeHisto; + private MutableHistogram metaSplitTimeHisto; + private MutableHistogram metaSplitSizeHisto; public MetricsMasterSourceImpl(MetricsMasterWrapper masterWrapper) { this(METRICS_NAME, @@ -79,6 +81,8 @@ public class MetricsMasterSourceImpl SNAPSHOT_CLONE_TIME_NAME, SNAPSHOT_CLONE_TIME_DESC, "Ops", "Time", true); snapshotRestoreTimeHisto = metricsRegistry.newStat( SNAPSHOT_RESTORE_TIME_NAME, SNAPSHOT_RESTORE_TIME_DESC, "Ops", "Time", true); + metaSplitTimeHisto = metricsRegistry.newHistogram(META_SPLIT_TIME_NAME, META_SPLIT_TIME_DESC); + metaSplitSizeHisto = metricsRegistry.newHistogram(META_SPLIT_SIZE_NAME, META_SPLIT_SIZE_DESC); } public void incRequests(final int inc) { @@ -123,6 +127,16 @@ public class MetricsMasterSourceImpl } @Override + public void updateMetaSplitTime(long time) { + metaSplitTimeHisto.add(time); + } + + @Override + public void updateMetaSplitSize(long size) { + metaSplitSizeHisto.add(size); + } + + @Override public void getMetrics(MetricsCollector metricsCollector, boolean all) { MetricsRecordBuilder metricsRecordBuilder = metricsCollector.addRecord(metricsName) diff --git hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java new file mode 100644 index 0000000..6420f40 --- /dev/null +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsEditsReplaySourceImpl.java @@ -0,0 +1,74 @@ +/** + * 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.hbase.regionserver.wal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.metrics.BaseSourceImpl; +import org.apache.hadoop.metrics2.MetricHistogram; + +/** + * Hadoop1 implementation of MetricsMasterSource. Implements BaseSource through BaseSourceImpl, + * following the pattern + */ +public class MetricsEditsReplaySourceImpl extends BaseSourceImpl implements + MetricsEditsReplaySource { + + private static final Log LOG = LogFactory.getLog(MetricsEditsReplaySourceImpl.class.getName()); + + private MetricHistogram replayTimeHisto; + private MetricHistogram replayBatchSizeHisto; + private MetricHistogram replayDataSizeHisto; + + public MetricsEditsReplaySourceImpl() { + this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT); + } + + public MetricsEditsReplaySourceImpl(String metricsName, + String metricsDescription, + String metricsContext, + String metricsJmxContext) { + super(metricsName, metricsDescription, metricsContext, metricsJmxContext); + } + + @Override + public void init() { + super.init(); + replayTimeHisto = metricsRegistry.newHistogram(REPLAY_TIME_NAME, REPLAY_TIME_DESC); + replayBatchSizeHisto = metricsRegistry.newHistogram(REPLAY_BATCH_SIZE_NAME, + REPLAY_BATCH_SIZE_DESC); + replayDataSizeHisto = metricsRegistry + .newHistogram(REPLAY_DATA_SIZE_NAME, REPLAY_DATA_SIZE_DESC); + } + + @Override + public void updateReplayTime(long time) { + replayTimeHisto.add(time); + } + + @Override + public void updateReplayBatchSize(long size) { + replayBatchSizeHisto.add(size); + } + + @Override + public void updateReplayDataSize(long size) { + replayDataSizeHisto.add(size); + } +} diff --git hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource new file mode 100644 index 0000000..ed95795 --- /dev/null +++ hbase-hadoop2-compat/src/main/resources/META-INF/services/org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySource @@ -0,0 +1 @@ +org.apache.hadoop.hbase.regionserver.wal.MetricsEditsReplaySourceImpl diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java index 4451183..72c4f48 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java @@ -306,7 +306,7 @@ public class MasterFileSystem { splitLogSize = splitLogManager.splitLogDistributed(serverNames, logDirs, META_FILTER); splitTime = EnvironmentEdgeManager.currentTimeMillis() - splitTime; if (this.metricsMaster != null) { - this.metricsMaster.addSplit(splitTime, splitLogSize); + this.metricsMaster.addMetaSplit(splitTime, splitLogSize); } } @@ -432,7 +432,11 @@ public class MasterFileSystem { } if (this.metricsMaster != null) { - this.metricsMaster.addSplit(splitTime, splitLogSize); + if (filter == this.META_FILTER) { + this.metricsMaster.addMetaSplit(splitTime, splitLogSize); + } else { + this.metricsMaster.addSplit(splitTime, splitLogSize); + } } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsMaster.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsMaster.java index 2a42c44..d6f281f 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsMaster.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetricsMaster.java @@ -59,6 +59,16 @@ public class MetricsMaster { } /** + * Record a single instance of a split + * @param time time that the split took + * @param size length of original HLogs that were split + */ + public synchronized void addMetaSplit(long time, long size) { + masterSource.updateMetaSplitTime(time); + masterSource.updateMetaSplitSize(size); + } + + /** * @param inc How much to add to requests. */ public void incrementRequests(final int inc) { diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsWALEditsReplay.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsWALEditsReplay.java index 4fdb4ae..d87ab5d 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsWALEditsReplay.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/MetricsWALEditsReplay.java @@ -25,33 +25,36 @@ import org.apache.hadoop.hbase.CompatibilitySingletonFactory; import org.apache.hadoop.util.StringUtils; /** - * Class used to push numbers about the WAL into the metrics subsystem. This will take a single - * function call and turn it into multiple manipulations of the hadoop metrics system. + * Class used to push numbers about WAL edits replay into the metrics subsystem. This will take a + * single function call and turn it into multiple manipulations of the hadoop metrics system. */ @InterfaceAudience.Private public class MetricsWALEditsReplay { static final Log LOG = LogFactory.getLog(MetricsWALEditsReplay.class); - private final MetricsWALSource source; + private final MetricsEditsReplaySource source; public MetricsWALEditsReplay() { - source = CompatibilitySingletonFactory.getInstance(MetricsWALSource.class); + source = CompatibilitySingletonFactory.getInstance(MetricsEditsReplaySource.class); } - public void finishSync(long time) { - source.incrementSyncTime(time); + /** + * Add the time a replay command took + */ + void updateReplayTime(long time) { + source.updateReplayTime(time); } - public void finishAppend(long time, long size) { - - source.incrementAppendCount(); - source.incrementAppendTime(time); - source.incrementAppendSize(size); + /** + * Add the batch size of each replay + */ + void updateReplayBatchSize(long size) { + source.updateReplayDataSize(size); + } - if (time > 1000) { - source.incrementSlowAppendCount(); - LOG.warn(String.format("%s took %d ms appending an edit to hlog; len~=%s", Thread - .currentThread().getName(), time, StringUtils.humanReadableInt(size))); - } + /** + * Add the payload data size of each replay + */ + void updateReplayDataSize(long size) { } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALEditsReplaySink.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALEditsReplaySink.java index 7bebb72..ae82f57 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALEditsReplaySink.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALEditsReplaySink.java @@ -80,14 +80,16 @@ public class WALEditsReplaySink { if (actions.size() == 0) { return; } - + + int batchSize = actions.size(); + int dataSize = 0; Map>> actionsByRegion = new HashMap>>(); HRegionLocation loc = null; Row row = null; List> regionActions = null; // Build the action list. - for (int i = 0; i < actions.size(); i++) { + for (int i = 0; i < batchSize; i++) { loc = actions.get(i).getFirst(); row = actions.get(i).getSecond(); if (actionsByRegion.containsKey(loc.getRegionInfo())) { @@ -98,6 +100,7 @@ public class WALEditsReplaySink { } Action action = new Action(row, i); regionActions.add(action); + dataSize += row.getRow().length; } try { @@ -111,10 +114,12 @@ public class WALEditsReplaySink { long endTime = EnvironmentEdgeManager.currentTimeMillis() - startTime; LOG.debug("number of rows:" + actions.size() + " are sent by batch! spent " + endTime + "(ms)!"); - /** - * TODO: Add more metricis. - */ - this.totalReplayedEdits.addAndGet(actions.size()); + + metrics.updateReplayTime(endTime); + metrics.updateReplayBatchSize(batchSize); + metrics.updateReplayDataSize(dataSize); + + this.totalReplayedEdits.addAndGet(batchSize); } catch (RuntimeException rx) { throw new IOException(rx); }