HBASE-12655 WALPerformanceEvaluation should only add stat gathering listener once per WAL.
This commit is contained in:
parent
2372739e46
commit
d2d6945e89
|
@ -41,6 +41,9 @@ import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
|
||||||
/**
|
/**
|
||||||
* A Write Ahead Log (WAL) provides service for reading, writing waledits. This interface provides
|
* A Write Ahead Log (WAL) provides service for reading, writing waledits. This interface provides
|
||||||
* APIs for WAL users (such as RegionServer) to use the WAL (do append, sync, etc).
|
* APIs for WAL users (such as RegionServer) to use the WAL (do append, sync, etc).
|
||||||
|
*
|
||||||
|
* Note that some internals, such as log rolling and performance evaluation tools, will use
|
||||||
|
* WAL.equals to determine if they have already seen a given WAL.
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
@InterfaceStability.Evolving
|
@InterfaceStability.Evolving
|
||||||
|
|
|
@ -19,9 +19,14 @@
|
||||||
package org.apache.hadoop.hbase.wal;
|
package org.apache.hadoop.hbase.wal;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -329,4 +334,26 @@ public class TestDefaultWALProvider {
|
||||||
new String [] {"-threads", "3", "-verify", "-noclosefs", "-iterations", "3000"});
|
new String [] {"-threads", "3", "-verify", "-noclosefs", "-iterations", "3000"});
|
||||||
assertEquals(0, errCode);
|
assertEquals(0, errCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that we can use Set.add to deduplicate WALs
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void setMembershipDedups() throws IOException {
|
||||||
|
final Configuration localConf = new Configuration(conf);
|
||||||
|
localConf.set(WALFactory.WAL_PROVIDER, DefaultWALProvider.class.getName());
|
||||||
|
final WALFactory wals = new WALFactory(localConf, null, currentTest.getMethodName());
|
||||||
|
try {
|
||||||
|
final Set<WAL> seen = new HashSet<WAL>(1);
|
||||||
|
final Random random = new Random();
|
||||||
|
assertTrue("first attempt to add WAL from default provider should work.",
|
||||||
|
seen.add(wals.getWAL(Bytes.toBytes(random.nextInt()))));
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
assertFalse("default wal provider is only supposed to return a single wal, which should " +
|
||||||
|
"compare as .equals itself.", seen.add(wals.getWAL(Bytes.toBytes(random.nextInt()))));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
wals.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ package org.apache.hadoop.hbase.wal;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -460,43 +462,48 @@ public final class WALPerformanceEvaluation extends Configured implements Tool {
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Set<WAL> walsListenedTo = new HashSet<WAL>();
|
||||||
|
|
||||||
private HRegion openRegion(final FileSystem fs, final Path dir, final HTableDescriptor htd,
|
private HRegion openRegion(final FileSystem fs, final Path dir, final HTableDescriptor htd,
|
||||||
final WALFactory wals, final long whenToRoll) throws IOException {
|
final WALFactory wals, final long whenToRoll) throws IOException {
|
||||||
// Initialize HRegion
|
// Initialize HRegion
|
||||||
HRegionInfo regionInfo = new HRegionInfo(htd.getTableName());
|
HRegionInfo regionInfo = new HRegionInfo(htd.getTableName());
|
||||||
// Initialize WAL
|
// Initialize WAL
|
||||||
final WAL wal = wals.getWAL(regionInfo.getEncodedNameAsBytes());
|
final WAL wal = wals.getWAL(regionInfo.getEncodedNameAsBytes());
|
||||||
wal.registerWALActionsListener(new WALActionsListener.Base() {
|
// If we haven't already, attach a listener to this wal to handle rolls and metrics.
|
||||||
private int appends = 0;
|
if (walsListenedTo.add(wal)) {
|
||||||
|
wal.registerWALActionsListener(new WALActionsListener.Base() {
|
||||||
|
private int appends = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLogEntryBeforeWrite(HTableDescriptor htd, WALKey logKey,
|
public void visitLogEntryBeforeWrite(HTableDescriptor htd, WALKey logKey,
|
||||||
WALEdit logEdit) {
|
WALEdit logEdit) {
|
||||||
this.appends++;
|
this.appends++;
|
||||||
if (this.appends % whenToRoll == 0) {
|
if (this.appends % whenToRoll == 0) {
|
||||||
LOG.info("Rolling after " + appends + " edits");
|
LOG.info("Rolling after " + appends + " edits");
|
||||||
// We used to do explicit call to rollWriter but changed it to a request
|
// We used to do explicit call to rollWriter but changed it to a request
|
||||||
// to avoid dead lock (there are less threads going on in this class than
|
// to avoid dead lock (there are less threads going on in this class than
|
||||||
// in the regionserver -- regionserver does not have the issue).
|
// in the regionserver -- regionserver does not have the issue).
|
||||||
// TODO I think this means no rolling actually happens; the request relies on there
|
// TODO I think this means no rolling actually happens; the request relies on there
|
||||||
// being a LogRoller.
|
// being a LogRoller.
|
||||||
DefaultWALProvider.requestLogRoll(wal);
|
DefaultWALProvider.requestLogRoll(wal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postSync(final long timeInNanos, final int handlerSyncs) {
|
public void postSync(final long timeInNanos, final int handlerSyncs) {
|
||||||
syncMeter.mark();
|
syncMeter.mark();
|
||||||
syncHistogram.update(timeInNanos);
|
syncHistogram.update(timeInNanos);
|
||||||
syncCountHistogram.update(handlerSyncs);
|
syncCountHistogram.update(handlerSyncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postAppend(final long size, final long elapsedTime) {
|
public void postAppend(final long size, final long elapsedTime) {
|
||||||
appendMeter.mark(size);
|
appendMeter.mark(size);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
wal.rollWriter();
|
wal.rollWriter();
|
||||||
|
}
|
||||||
|
|
||||||
return HRegion.createHRegion(regionInfo, dir, getConf(), htd, wal);
|
return HRegion.createHRegion(regionInfo, dir, getConf(), htd, wal);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue