HBASE-16091 Canary takes lot more time when there are delete markers in the table (Vishal Khandelwal)

This commit is contained in:
Andrew Purtell 2016-07-05 10:11:08 -07:00
parent 29c46c4834
commit 318751cfd6
3 changed files with 72 additions and 15 deletions

View File

@ -1244,6 +1244,8 @@ public final class HConstants {
public static final String HBASE_CANARY_WRITE_TABLE_CHECK_PERIOD_KEY = public static final String HBASE_CANARY_WRITE_TABLE_CHECK_PERIOD_KEY =
"hbase.canary.write.table.check.period"; "hbase.canary.write.table.check.period";
public static final String HBASE_CANARY_READ_RAW_SCAN_KEY = "hbase.canary.read.raw.enabled";
/** /**
* Configuration keys for programmatic JAAS configuration for secured ZK interaction * Configuration keys for programmatic JAAS configuration for secured ZK interaction

View File

@ -264,12 +264,15 @@ public final class Canary implements Tool {
private HRegionInfo region; private HRegionInfo region;
private Sink sink; private Sink sink;
private TaskType taskType; private TaskType taskType;
private boolean rawScanEnabled;
RegionTask(Connection connection, HRegionInfo region, Sink sink, TaskType taskType) { RegionTask(Connection connection, HRegionInfo region, Sink sink, TaskType taskType,
boolean rawScanEnabled) {
this.connection = connection; this.connection = connection;
this.region = region; this.region = region;
this.sink = sink; this.sink = sink;
this.taskType = taskType; this.taskType = taskType;
this.rawScanEnabled = rawScanEnabled;
} }
@Override @Override
@ -323,7 +326,11 @@ public final class Canary implements Tool {
get.addFamily(column.getName()); get.addFamily(column.getName());
} else { } else {
scan = new Scan(); scan = new Scan();
scan.setRaw(true); if (LOG.isDebugEnabled()) {
LOG.debug(String.format("rawScan : %s for table: %s", rawScanEnabled,
tableDesc.getTableName()));
}
scan.setRaw(rawScanEnabled);
scan.setCaching(1); scan.setCaching(1);
scan.setCacheBlocks(false); scan.setCacheBlocks(false);
scan.setFilter(new FirstKeyOnlyFilter()); scan.setFilter(new FirstKeyOnlyFilter());
@ -749,6 +756,8 @@ public final class Canary implements Tool {
System.err.println(" -treatFailureAsError treats read / write failure as error"); System.err.println(" -treatFailureAsError treats read / write failure as error");
System.err.println(" -writeTable The table used for write sniffing." System.err.println(" -writeTable The table used for write sniffing."
+ " Default is hbase:canary"); + " Default is hbase:canary");
System.err.println(" -Dhbase.canary.read.raw.enabled=<true/false> Use this flag to enable or disable raw scan during read canary test"
+ " Default is false and raw is not enabled during scan");
System.err System.err
.println(" -D<configProperty>=<value> assigning or override the configuration params"); .println(" -D<configProperty>=<value> assigning or override the configuration params");
System.exit(USAGE_EXIT_CODE); System.exit(USAGE_EXIT_CODE);
@ -873,6 +882,7 @@ public final class Canary implements Tool {
private float regionsLowerLimit; private float regionsLowerLimit;
private float regionsUpperLimit; private float regionsUpperLimit;
private int checkPeriod; private int checkPeriod;
private boolean rawScanEnabled;
public RegionMonitor(Connection connection, String[] monitorTargets, boolean useRegExp, public RegionMonitor(Connection connection, String[] monitorTargets, boolean useRegExp,
Sink sink, ExecutorService executor, boolean writeSniffing, TableName writeTableName, Sink sink, ExecutorService executor, boolean writeSniffing, TableName writeTableName,
@ -890,6 +900,7 @@ public final class Canary implements Tool {
this.checkPeriod = this.checkPeriod =
conf.getInt(HConstants.HBASE_CANARY_WRITE_TABLE_CHECK_PERIOD_KEY, conf.getInt(HConstants.HBASE_CANARY_WRITE_TABLE_CHECK_PERIOD_KEY,
DEFAULT_WRITE_TABLE_CHECK_PERIOD); DEFAULT_WRITE_TABLE_CHECK_PERIOD);
this.rawScanEnabled = conf.getBoolean(HConstants.HBASE_CANARY_READ_RAW_SCAN_KEY, false);
} }
@Override @Override
@ -901,7 +912,8 @@ public final class Canary implements Tool {
String[] tables = generateMonitorTables(this.targets); String[] tables = generateMonitorTables(this.targets);
this.initialized = true; this.initialized = true;
for (String table : tables) { for (String table : tables) {
taskFutures.addAll(Canary.sniff(admin, sink, table, executor, TaskType.READ)); taskFutures.addAll(Canary.sniff(admin, sink, table, executor, TaskType.READ,
this.rawScanEnabled));
} }
} else { } else {
taskFutures.addAll(sniff(TaskType.READ)); taskFutures.addAll(sniff(TaskType.READ));
@ -917,8 +929,8 @@ public final class Canary implements Tool {
lastCheckTime = EnvironmentEdgeManager.currentTime(); lastCheckTime = EnvironmentEdgeManager.currentTime();
} }
// sniff canary table with write operation // sniff canary table with write operation
taskFutures.addAll(Canary.sniff(admin, sink, taskFutures.addAll(Canary.sniff(admin, sink, admin.getTableDescriptor(writeTableName),
admin.getTableDescriptor(writeTableName), executor, TaskType.WRITE)); executor, TaskType.WRITE, this.rawScanEnabled));
} }
for (Future<Void> future : taskFutures) { for (Future<Void> future : taskFutures) {
@ -990,7 +1002,7 @@ public final class Canary implements Tool {
for (HTableDescriptor table : admin.listTables()) { for (HTableDescriptor table : admin.listTables()) {
if (admin.isTableEnabled(table.getTableName()) if (admin.isTableEnabled(table.getTableName())
&& (!table.getTableName().equals(writeTableName))) { && (!table.getTableName().equals(writeTableName))) {
taskFutures.addAll(Canary.sniff(admin, sink, table, executor, taskType)); taskFutures.addAll(Canary.sniff(admin, sink, table, executor, taskType, this.rawScanEnabled));
} }
} }
return taskFutures; return taskFutures;
@ -1056,38 +1068,58 @@ public final class Canary implements Tool {
* Canary entry point for specified table. * Canary entry point for specified table.
* @throws Exception * @throws Exception
*/ */
public static void sniff(final Admin admin, TableName tableName, boolean rawScanEnabled)
throws Exception {
sniff(admin, tableName, TaskType.READ, rawScanEnabled);
}
/**
* Canary entry point for specified table.
* Keeping this method backward compatibility
* @throws Exception
*/
public static void sniff(final Admin admin, TableName tableName) public static void sniff(final Admin admin, TableName tableName)
throws Exception { throws Exception {
sniff(admin, tableName, TaskType.READ); sniff(admin, tableName, TaskType.READ, false);
} }
/** /**
* Canary entry point for specified table with task type(read/write) * Canary entry point for specified table with task type(read/write)
* @throws Exception * @throws Exception
*/ */
public static void sniff(final Admin admin, TableName tableName, TaskType taskType) public static void sniff(final Admin admin, TableName tableName, TaskType taskType,
throws Exception { boolean rawScanEnabled) throws Exception {
List<Future<Void>> taskFutures = List<Future<Void>> taskFutures =
Canary.sniff(admin, new StdOutSink(), tableName.getNameAsString(), Canary.sniff(admin, new StdOutSink(), tableName.getNameAsString(),
new ScheduledThreadPoolExecutor(1), taskType); new ScheduledThreadPoolExecutor(1), taskType, rawScanEnabled);
for (Future<Void> future : taskFutures) { for (Future<Void> future : taskFutures) {
future.get(); future.get();
} }
} }
/**
* Canary entry point for specified table with task type(read/write)
* Keeping this method backward compatible
* @throws Exception
*/
public static void sniff(final Admin admin, TableName tableName, TaskType taskType)
throws Exception {
Canary.sniff(admin, tableName, taskType, false);
}
/** /**
* Canary entry point for specified table. * Canary entry point for specified table.
* @throws Exception * @throws Exception
*/ */
private static List<Future<Void>> sniff(final Admin admin, final Sink sink, String tableName, private static List<Future<Void>> sniff(final Admin admin, final Sink sink, String tableName,
ExecutorService executor, TaskType taskType) throws Exception { ExecutorService executor, TaskType taskType, boolean rawScanEnabled) throws Exception {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug(String.format("checking table is enabled and getting table descriptor for table %s", LOG.debug(String.format("checking table is enabled and getting table descriptor for table %s",
tableName)); tableName));
} }
if (admin.isTableEnabled(TableName.valueOf(tableName))) { if (admin.isTableEnabled(TableName.valueOf(tableName))) {
return Canary.sniff(admin, sink, admin.getTableDescriptor(TableName.valueOf(tableName)), return Canary.sniff(admin, sink, admin.getTableDescriptor(TableName.valueOf(tableName)),
executor, taskType); executor, taskType, rawScanEnabled);
} else { } else {
LOG.warn(String.format("Table %s is not enabled", tableName)); LOG.warn(String.format("Table %s is not enabled", tableName));
} }
@ -1098,7 +1130,8 @@ public final class Canary implements Tool {
* Loops over regions that owns this table, and output some information abouts the state. * Loops over regions that owns this table, and output some information abouts the state.
*/ */
private static List<Future<Void>> sniff(final Admin admin, final Sink sink, private static List<Future<Void>> sniff(final Admin admin, final Sink sink,
HTableDescriptor tableDesc, ExecutorService executor, TaskType taskType) throws Exception { HTableDescriptor tableDesc, ExecutorService executor, TaskType taskType,
boolean rawScanEnabled) throws Exception {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug(String.format("reading list of regions for table %s", tableDesc.getTableName())); LOG.debug(String.format("reading list of regions for table %s", tableDesc.getTableName()));
@ -1112,8 +1145,8 @@ public final class Canary implements Tool {
} }
List<RegionTask> tasks = new ArrayList<RegionTask>(); List<RegionTask> tasks = new ArrayList<RegionTask>();
try { try {
for (HRegionInfo region : admin.getTableRegions(tableDesc.getTableName())) { for (HRegionInfo region : admin.getTableRegions(tableDesc.getTableName())) {
tasks.add(new RegionTask(admin.getConnection(), region, sink, taskType)); tasks.add(new RegionTask(admin.getConnection(), region, sink, taskType, rawScanEnabled));
} }
} finally { } finally {
table.close(); table.close();

View File

@ -142,6 +142,28 @@ public class TestCanaryTool {
})); }));
} }
@Test
public void testRawScanConfig() throws Exception {
TableName tableName = TableName.valueOf("testTableRawScan");
Table table = testingUtility.createTable(tableName, new byte[][] { FAMILY });
// insert some test rows
for (int i=0; i<1000; i++) {
byte[] iBytes = Bytes.toBytes(i);
Put p = new Put(iBytes);
p.addColumn(FAMILY, COLUMN, iBytes);
table.put(p);
}
ExecutorService executor = new ScheduledThreadPoolExecutor(1);
Canary.RegionServerStdOutSink sink = spy(new Canary.RegionServerStdOutSink());
Canary canary = new Canary(executor, sink);
String[] args = { "-t", "10000", "testTableRawScan" };
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration(testingUtility.getConfiguration());
conf.setBoolean(HConstants.HBASE_CANARY_READ_RAW_SCAN_KEY, true);
ToolRunner.run(conf, canary, args);
verify(sink, atLeastOnce())
.publishReadTiming(isA(HRegionInfo.class), isA(HColumnDescriptor.class), anyLong());
}
private void runRegionserverCanary() throws Exception { private void runRegionserverCanary() throws Exception {
ExecutorService executor = new ScheduledThreadPoolExecutor(1); ExecutorService executor = new ScheduledThreadPoolExecutor(1);
Canary canary = new Canary(executor, new Canary.RegionServerStdOutSink()); Canary canary = new Canary(executor, new Canary.RegionServerStdOutSink());