HBASE-13187 Add ITBLL that exercises per CF flush
Signed-off-by: stack <stack@apache.org>
This commit is contained in:
parent
874aa9eb85
commit
f1b53d71b8
|
@ -20,8 +20,8 @@ package org.apache.hadoop.hbase.test;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -32,6 +32,7 @@ import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
@ -64,7 +65,6 @@ import org.apache.hadoop.hbase.client.BufferedMutatorParams;
|
||||||
import org.apache.hadoop.hbase.client.Connection;
|
import org.apache.hadoop.hbase.client.Connection;
|
||||||
import org.apache.hadoop.hbase.client.ConnectionFactory;
|
import org.apache.hadoop.hbase.client.ConnectionFactory;
|
||||||
import org.apache.hadoop.hbase.client.Get;
|
import org.apache.hadoop.hbase.client.Get;
|
||||||
import org.apache.hadoop.hbase.client.HBaseAdmin;
|
|
||||||
import org.apache.hadoop.hbase.client.Mutation;
|
import org.apache.hadoop.hbase.client.Mutation;
|
||||||
import org.apache.hadoop.hbase.client.Put;
|
import org.apache.hadoop.hbase.client.Put;
|
||||||
import org.apache.hadoop.hbase.client.RegionLocator;
|
import org.apache.hadoop.hbase.client.RegionLocator;
|
||||||
|
@ -79,6 +79,8 @@ import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
|
||||||
import org.apache.hadoop.hbase.mapreduce.TableMapper;
|
import org.apache.hadoop.hbase.mapreduce.TableMapper;
|
||||||
import org.apache.hadoop.hbase.mapreduce.TableRecordReaderImpl;
|
import org.apache.hadoop.hbase.mapreduce.TableRecordReaderImpl;
|
||||||
import org.apache.hadoop.hbase.mapreduce.WALPlayer;
|
import org.apache.hadoop.hbase.mapreduce.WALPlayer;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.FlushLargeStoresPolicy;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.FlushPolicyFactory;
|
||||||
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
|
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
|
||||||
import org.apache.hadoop.hbase.testclassification.IntegrationTests;
|
import org.apache.hadoop.hbase.testclassification.IntegrationTests;
|
||||||
import org.apache.hadoop.hbase.util.AbstractHBaseTool;
|
import org.apache.hadoop.hbase.util.AbstractHBaseTool;
|
||||||
|
@ -100,16 +102,16 @@ import org.apache.hadoop.mapreduce.RecordReader;
|
||||||
import org.apache.hadoop.mapreduce.Reducer;
|
import org.apache.hadoop.mapreduce.Reducer;
|
||||||
import org.apache.hadoop.mapreduce.TaskAttemptContext;
|
import org.apache.hadoop.mapreduce.TaskAttemptContext;
|
||||||
import org.apache.hadoop.mapreduce.TaskAttemptID;
|
import org.apache.hadoop.mapreduce.TaskAttemptID;
|
||||||
|
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
|
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
|
||||||
import org.apache.hadoop.mapreduce.lib.input.SequenceFileAsBinaryInputFormat;
|
import org.apache.hadoop.mapreduce.lib.input.SequenceFileAsBinaryInputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
|
|
||||||
import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
|
import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
|
||||||
import org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl;
|
|
||||||
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
|
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
|
import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.output.SequenceFileAsBinaryOutputFormat;
|
import org.apache.hadoop.mapreduce.lib.output.SequenceFileAsBinaryOutputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
|
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
|
||||||
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
|
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
|
||||||
|
import org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl;
|
||||||
import org.apache.hadoop.util.Tool;
|
import org.apache.hadoop.util.Tool;
|
||||||
import org.apache.hadoop.util.ToolRunner;
|
import org.apache.hadoop.util.ToolRunner;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -189,6 +191,8 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
protected static String DEFAULT_TABLE_NAME = "IntegrationTestBigLinkedList";
|
protected static String DEFAULT_TABLE_NAME = "IntegrationTestBigLinkedList";
|
||||||
|
|
||||||
protected static byte[] FAMILY_NAME = Bytes.toBytes("meta");
|
protected static byte[] FAMILY_NAME = Bytes.toBytes("meta");
|
||||||
|
private static byte[] BIG_FAMILY_NAME = Bytes.toBytes("big");
|
||||||
|
private static byte[] TINY_FAMILY_NAME = Bytes.toBytes("tiny");
|
||||||
|
|
||||||
//link to the id of the prev node in the linked list
|
//link to the id of the prev node in the linked list
|
||||||
protected static final byte[] COLUMN_PREV = Bytes.toBytes("prev");
|
protected static final byte[] COLUMN_PREV = Bytes.toBytes("prev");
|
||||||
|
@ -237,6 +241,20 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(Generator.class);
|
private static final Log LOG = LogFactory.getLog(Generator.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this configuration if you want to test single-column family flush works. If set, we will
|
||||||
|
* add a big column family and a small column family on either side of the usual ITBLL 'meta'
|
||||||
|
* column family. When we write out the ITBLL, we will also add to the big column family a value
|
||||||
|
* bigger than that for ITBLL and for small, something way smaller. The idea is that when
|
||||||
|
* flush-by-column family rather than by region is enabled, we can see if ITBLL is broke in any
|
||||||
|
* way. Here is how you would pass it:
|
||||||
|
* <p>
|
||||||
|
* $ ./bin/hbase org.apache.hadoop.hbase.test.IntegrationTestBigLinkedList
|
||||||
|
* -Dgenerator.multiple.columnfamilies=true generator 1 10 g
|
||||||
|
*/
|
||||||
|
public static final String MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY =
|
||||||
|
"generator.multiple.columnfamilies";
|
||||||
|
|
||||||
static class GeneratorInputFormat extends InputFormat<BytesWritable,NullWritable> {
|
static class GeneratorInputFormat extends InputFormat<BytesWritable,NullWritable> {
|
||||||
static class GeneratorInputSplit extends InputSplit implements Writable {
|
static class GeneratorInputSplit extends InputSplit implements Writable {
|
||||||
@Override
|
@Override
|
||||||
|
@ -327,8 +345,9 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some ASCII art time:
|
* Some ASCII art time:
|
||||||
|
* <p>
|
||||||
* [ . . . ] represents one batch of random longs of length WIDTH
|
* [ . . . ] represents one batch of random longs of length WIDTH
|
||||||
*
|
* <pre>
|
||||||
* _________________________
|
* _________________________
|
||||||
* | ______ |
|
* | ______ |
|
||||||
* | | ||
|
* | | ||
|
||||||
|
@ -348,6 +367,7 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^_____|||
|
* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^_____|||
|
||||||
* | |________||
|
* | |________||
|
||||||
* |___________________________|
|
* |___________________________|
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
static class GeneratorMapper
|
static class GeneratorMapper
|
||||||
extends Mapper<BytesWritable, NullWritable, NullWritable, NullWritable> {
|
extends Mapper<BytesWritable, NullWritable, NullWritable, NullWritable> {
|
||||||
|
@ -363,6 +383,9 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
long numNodes;
|
long numNodes;
|
||||||
long wrap;
|
long wrap;
|
||||||
int width;
|
int width;
|
||||||
|
boolean multipleUnevenColumnFamilies;
|
||||||
|
byte[] tinyValue = new byte[] { 't' };
|
||||||
|
byte[] bigValue = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setup(Context context) throws IOException, InterruptedException {
|
protected void setup(Context context) throws IOException, InterruptedException {
|
||||||
|
@ -378,6 +401,8 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
if (this.numNodes < this.wrap) {
|
if (this.numNodes < this.wrap) {
|
||||||
this.wrap = this.numNodes;
|
this.wrap = this.numNodes;
|
||||||
}
|
}
|
||||||
|
this.multipleUnevenColumnFamilies =
|
||||||
|
context.getConfiguration().getBoolean(MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void instantiateHTable() throws IOException {
|
protected void instantiateHTable() throws IOException {
|
||||||
|
@ -403,8 +428,9 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
persist(output, count, prev, current, id);
|
persist(output, count, prev, current, id);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (first == null)
|
if (first == null) {
|
||||||
first = current;
|
first = current;
|
||||||
|
}
|
||||||
prev = current;
|
prev = current;
|
||||||
current = new byte[this.width][];
|
current = new byte[this.width][];
|
||||||
|
|
||||||
|
@ -434,13 +460,25 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
for (int i = 0; i < current.length; i++) {
|
for (int i = 0; i < current.length; i++) {
|
||||||
Put put = new Put(current[i]);
|
Put put = new Put(current[i]);
|
||||||
put.add(FAMILY_NAME, COLUMN_PREV, prev == null ? NO_KEY : prev[i]);
|
put.addColumn(FAMILY_NAME, COLUMN_PREV, prev == null ? NO_KEY : prev[i]);
|
||||||
|
|
||||||
if (count >= 0) {
|
if (count >= 0) {
|
||||||
put.add(FAMILY_NAME, COLUMN_COUNT, Bytes.toBytes(count + i));
|
put.addColumn(FAMILY_NAME, COLUMN_COUNT, Bytes.toBytes(count + i));
|
||||||
}
|
}
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
put.add(FAMILY_NAME, COLUMN_CLIENT, id);
|
put.addColumn(FAMILY_NAME, COLUMN_CLIENT, id);
|
||||||
|
}
|
||||||
|
// See if we are to write multiple columns.
|
||||||
|
if (this.multipleUnevenColumnFamilies) {
|
||||||
|
// Use any column name.
|
||||||
|
put.addColumn(TINY_FAMILY_NAME, TINY_FAMILY_NAME, this.tinyValue);
|
||||||
|
// If we've not allocated bigValue, do it now. Reuse same value each time.
|
||||||
|
if (this.bigValue == null) {
|
||||||
|
this.bigValue = new byte[current[i].length * 10];
|
||||||
|
ThreadLocalRandom.current().nextBytes(this.bigValue);
|
||||||
|
}
|
||||||
|
// Use any column name.
|
||||||
|
put.addColumn(BIG_FAMILY_NAME, BIG_FAMILY_NAME, this.bigValue);
|
||||||
}
|
}
|
||||||
mutator.mutate(put);
|
mutator.mutate(put);
|
||||||
|
|
||||||
|
@ -474,12 +512,15 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
protected void createSchema() throws IOException {
|
protected void createSchema() throws IOException {
|
||||||
Configuration conf = getConf();
|
Configuration conf = getConf();
|
||||||
Admin admin = new HBaseAdmin(conf);
|
|
||||||
TableName tableName = getTableName(conf);
|
TableName tableName = getTableName(conf);
|
||||||
try {
|
try (Connection conn = ConnectionFactory.createConnection(conf);
|
||||||
|
Admin admin = conn.getAdmin()) {
|
||||||
if (!admin.tableExists(tableName)) {
|
if (!admin.tableExists(tableName)) {
|
||||||
HTableDescriptor htd = new HTableDescriptor(getTableName(getConf()));
|
HTableDescriptor htd = new HTableDescriptor(getTableName(getConf()));
|
||||||
htd.addFamily(new HColumnDescriptor(FAMILY_NAME));
|
htd.addFamily(new HColumnDescriptor(FAMILY_NAME));
|
||||||
|
// Always add these families. Just skip writing to them when we do not test per CF flush.
|
||||||
|
htd.addFamily(new HColumnDescriptor(BIG_FAMILY_NAME));
|
||||||
|
htd.addFamily(new HColumnDescriptor(TINY_FAMILY_NAME));
|
||||||
int numberOfServers = admin.getClusterStatus().getServers().size();
|
int numberOfServers = admin.getClusterStatus().getServers().size();
|
||||||
if (numberOfServers == 0) {
|
if (numberOfServers == 0) {
|
||||||
throw new IllegalStateException("No live regionservers");
|
throw new IllegalStateException("No live regionservers");
|
||||||
|
@ -498,8 +539,6 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
} catch (MasterNotRunningException e) {
|
} catch (MasterNotRunningException e) {
|
||||||
LOG.error("Master not running", e);
|
LOG.error("Master not running", e);
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
} finally {
|
|
||||||
admin.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +546,7 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
Integer width, Integer wrapMuplitplier) throws Exception {
|
Integer width, Integer wrapMuplitplier) throws Exception {
|
||||||
LOG.info("Running RandomInputGenerator with numMappers=" + numMappers
|
LOG.info("Running RandomInputGenerator with numMappers=" + numMappers
|
||||||
+ ", numNodes=" + numNodes);
|
+ ", numNodes=" + numNodes);
|
||||||
Job job = new Job(getConf());
|
Job job = Job.getInstance(getConf());
|
||||||
|
|
||||||
job.setJobName("Random Input Generator");
|
job.setJobName("Random Input Generator");
|
||||||
job.setNumReduceTasks(0);
|
job.setNumReduceTasks(0);
|
||||||
|
@ -533,7 +572,7 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
Integer width, Integer wrapMuplitplier) throws Exception {
|
Integer width, Integer wrapMuplitplier) throws Exception {
|
||||||
LOG.info("Running Generator with numMappers=" + numMappers +", numNodes=" + numNodes);
|
LOG.info("Running Generator with numMappers=" + numMappers +", numNodes=" + numNodes);
|
||||||
createSchema();
|
createSchema();
|
||||||
Job job = new Job(getConf());
|
Job job = Job.getInstance(getConf());
|
||||||
|
|
||||||
job.setJobName("Link Generator");
|
job.setJobName("Link Generator");
|
||||||
job.setNumReduceTasks(0);
|
job.setNumReduceTasks(0);
|
||||||
|
@ -551,6 +590,11 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
job.setOutputFormatClass(NullOutputFormat.class);
|
job.setOutputFormatClass(NullOutputFormat.class);
|
||||||
|
|
||||||
job.getConfiguration().setBoolean("mapreduce.map.speculative", false);
|
job.getConfiguration().setBoolean("mapreduce.map.speculative", false);
|
||||||
|
String multipleUnevenColumnFamiliesStr = System.getProperty(MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY);
|
||||||
|
if (multipleUnevenColumnFamiliesStr != null) {
|
||||||
|
job.getConfiguration().setBoolean(MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY,
|
||||||
|
Boolean.parseBoolean(multipleUnevenColumnFamiliesStr));
|
||||||
|
}
|
||||||
TableMapReduceUtil.addDependencyJars(job);
|
TableMapReduceUtil.addDependencyJars(job);
|
||||||
TableMapReduceUtil.addDependencyJars(job.getConfiguration(), AbstractHBaseTool.class);
|
TableMapReduceUtil.addDependencyJars(job.getConfiguration(), AbstractHBaseTool.class);
|
||||||
TableMapReduceUtil.initCredentials(job);
|
TableMapReduceUtil.initCredentials(job);
|
||||||
|
@ -704,9 +748,9 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SortedSet<byte []> readFileToSearch(final Configuration conf,
|
private static SortedSet<byte[]> readFileToSearch(final Configuration conf,
|
||||||
final FileSystem fs, final LocatedFileStatus keyFileStatus)
|
final FileSystem fs, final LocatedFileStatus keyFileStatus) throws IOException,
|
||||||
throws IOException, InterruptedException {
|
InterruptedException {
|
||||||
SortedSet<byte []> result = new TreeSet<byte []>(Bytes.BYTES_COMPARATOR);
|
SortedSet<byte []> result = new TreeSet<byte []>(Bytes.BYTES_COMPARATOR);
|
||||||
// Return entries that are flagged Counts.UNDEFINED in the value. Return the row. This is
|
// Return entries that are flagged Counts.UNDEFINED in the value. Return the row. This is
|
||||||
// what is missing.
|
// what is missing.
|
||||||
|
@ -719,13 +763,11 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
while (rr.nextKeyValue()) {
|
while (rr.nextKeyValue()) {
|
||||||
rr.getCurrentKey();
|
rr.getCurrentKey();
|
||||||
BytesWritable bw = rr.getCurrentValue();
|
BytesWritable bw = rr.getCurrentValue();
|
||||||
switch (Verify.VerifyReducer.whichType(bw.getBytes())) {
|
if (Verify.VerifyReducer.whichType(bw.getBytes()) == Verify.Counts.UNDEFINED) {
|
||||||
case UNDEFINED:
|
byte[] key = new byte[rr.getCurrentKey().getLength()];
|
||||||
byte [] key = new byte [rr.getCurrentKey().getLength()];
|
System.arraycopy(rr.getCurrentKey().getBytes(), 0, key, 0, rr.getCurrentKey()
|
||||||
System.arraycopy(rr.getCurrentKey().getBytes(), 0, key, 0,
|
.getLength());
|
||||||
rr.getCurrentKey().getLength());
|
|
||||||
result.add(key);
|
result.add(key);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +782,8 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
static class Verify extends Configured implements Tool {
|
static class Verify extends Configured implements Tool {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(Verify.class);
|
private static final Log LOG = LogFactory.getLog(Verify.class);
|
||||||
protected static final BytesWritable DEF = new BytesWritable(NO_KEY);
|
protected static final BytesWritable DEF = new BytesWritable(new byte[] { 0 });
|
||||||
|
protected static final BytesWritable DEF_LOST_FAMILIES = new BytesWritable(new byte[] { 1 });
|
||||||
|
|
||||||
protected Job job;
|
protected Job job;
|
||||||
|
|
||||||
|
@ -748,12 +791,29 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
private BytesWritable row = new BytesWritable();
|
private BytesWritable row = new BytesWritable();
|
||||||
private BytesWritable ref = new BytesWritable();
|
private BytesWritable ref = new BytesWritable();
|
||||||
|
|
||||||
|
private boolean multipleUnevenColumnFamilies;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setup(
|
||||||
|
Mapper<ImmutableBytesWritable, Result, BytesWritable, BytesWritable>.Context context)
|
||||||
|
throws IOException, InterruptedException {
|
||||||
|
this.multipleUnevenColumnFamilies =
|
||||||
|
context.getConfiguration().getBoolean(Generator.MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void map(ImmutableBytesWritable key, Result value, Context context)
|
protected void map(ImmutableBytesWritable key, Result value, Context context)
|
||||||
throws IOException ,InterruptedException {
|
throws IOException ,InterruptedException {
|
||||||
byte[] rowKey = key.get();
|
byte[] rowKey = key.get();
|
||||||
row.set(rowKey, 0, rowKey.length);
|
row.set(rowKey, 0, rowKey.length);
|
||||||
context.write(row, DEF);
|
if (multipleUnevenColumnFamilies
|
||||||
|
&& (!value.containsColumn(BIG_FAMILY_NAME, BIG_FAMILY_NAME) || !value.containsColumn(
|
||||||
|
TINY_FAMILY_NAME, TINY_FAMILY_NAME))) {
|
||||||
|
context.write(row, DEF_LOST_FAMILIES);
|
||||||
|
} else {
|
||||||
|
context.write(row, DEF);
|
||||||
|
}
|
||||||
byte[] prev = value.getValue(FAMILY_NAME, COLUMN_PREV);
|
byte[] prev = value.getValue(FAMILY_NAME, COLUMN_PREV);
|
||||||
if (prev != null && prev.length > 0) {
|
if (prev != null && prev.length > 0) {
|
||||||
ref.set(prev, 0, prev.length);
|
ref.set(prev, 0, prev.length);
|
||||||
|
@ -769,7 +829,8 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
* problems found from the reducer.
|
* problems found from the reducer.
|
||||||
*/
|
*/
|
||||||
public static enum Counts {
|
public static enum Counts {
|
||||||
UNREFERENCED, UNDEFINED, REFERENCED, CORRUPT, EXTRAREFERENCES, EXTRA_UNDEF_REFERENCES
|
UNREFERENCED, UNDEFINED, REFERENCED, CORRUPT, EXTRAREFERENCES, EXTRA_UNDEF_REFERENCES,
|
||||||
|
LOST_FAMILIES
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -777,11 +838,13 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
* subsequent investigative mapreduce jobs. Each emitted value is prefaced by a one byte flag
|
* subsequent investigative mapreduce jobs. Each emitted value is prefaced by a one byte flag
|
||||||
* saying what sort of emission it is. Flag is the Count enum ordinal as a short.
|
* saying what sort of emission it is. Flag is the Count enum ordinal as a short.
|
||||||
*/
|
*/
|
||||||
public static class VerifyReducer
|
public static class VerifyReducer extends
|
||||||
extends Reducer<BytesWritable,BytesWritable,BytesWritable,BytesWritable> {
|
Reducer<BytesWritable, BytesWritable, BytesWritable, BytesWritable> {
|
||||||
private ArrayList<byte[]> refs = new ArrayList<byte[]>();
|
private ArrayList<byte[]> refs = new ArrayList<byte[]>();
|
||||||
private final BytesWritable UNREF =
|
private final BytesWritable UNREF = new BytesWritable(addPrefixFlag(
|
||||||
new BytesWritable(addPrefixFlag(Counts.UNREFERENCED.ordinal(), new byte [] {}));
|
Counts.UNREFERENCED.ordinal(), new byte[] {}));
|
||||||
|
private final BytesWritable LOSTFAM = new BytesWritable(addPrefixFlag(
|
||||||
|
Counts.LOST_FAMILIES.ordinal(), new byte[] {}));
|
||||||
|
|
||||||
private AtomicInteger rows = new AtomicInteger(0);
|
private AtomicInteger rows = new AtomicInteger(0);
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
@ -794,9 +857,12 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cleanup(Reducer<BytesWritable, BytesWritable, BytesWritable, BytesWritable>.Context context)
|
protected void cleanup(
|
||||||
throws IOException, InterruptedException {
|
Reducer<BytesWritable, BytesWritable, BytesWritable, BytesWritable>.Context context)
|
||||||
if (this.connection != null) this.connection.close();
|
throws IOException, InterruptedException {
|
||||||
|
if (this.connection != null) {
|
||||||
|
this.connection.close();
|
||||||
|
}
|
||||||
super.cleanup(context);
|
super.cleanup(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,12 +872,12 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
* @return Return new byte array that has <code>ordinal</code> as prefix on front taking up
|
* @return Return new byte array that has <code>ordinal</code> as prefix on front taking up
|
||||||
* Bytes.SIZEOF_SHORT bytes followed by <code>r</code>
|
* Bytes.SIZEOF_SHORT bytes followed by <code>r</code>
|
||||||
*/
|
*/
|
||||||
public static byte [] addPrefixFlag(final int ordinal, final byte [] r) {
|
public static byte[] addPrefixFlag(final int ordinal, final byte [] r) {
|
||||||
byte [] prefix = Bytes.toBytes((short)ordinal);
|
byte[] prefix = Bytes.toBytes((short)ordinal);
|
||||||
if (prefix.length != Bytes.SIZEOF_SHORT) {
|
if (prefix.length != Bytes.SIZEOF_SHORT) {
|
||||||
throw new RuntimeException("Unexpected size: " + prefix.length);
|
throw new RuntimeException("Unexpected size: " + prefix.length);
|
||||||
}
|
}
|
||||||
byte [] result = new byte [prefix.length + r.length];
|
byte[] result = new byte[prefix.length + r.length];
|
||||||
System.arraycopy(prefix, 0, result, 0, prefix.length);
|
System.arraycopy(prefix, 0, result, 0, prefix.length);
|
||||||
System.arraycopy(r, 0, result, prefix.length, r.length);
|
System.arraycopy(r, 0, result, prefix.length, r.length);
|
||||||
return result;
|
return result;
|
||||||
|
@ -831,21 +897,24 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
* @param bw
|
* @param bw
|
||||||
* @return Row bytes minus the type flag.
|
* @return Row bytes minus the type flag.
|
||||||
*/
|
*/
|
||||||
public static byte [] getRowOnly(BytesWritable bw) {
|
public static byte[] getRowOnly(BytesWritable bw) {
|
||||||
byte [] bytes = new byte [bw.getLength() - Bytes.SIZEOF_SHORT];
|
byte[] bytes = new byte [bw.getLength() - Bytes.SIZEOF_SHORT];
|
||||||
System.arraycopy(bw.getBytes(), Bytes.SIZEOF_SHORT, bytes, 0, bytes.length);
|
System.arraycopy(bw.getBytes(), Bytes.SIZEOF_SHORT, bytes, 0, bytes.length);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reduce(BytesWritable key, Iterable<BytesWritable> values, Context context)
|
public void reduce(BytesWritable key, Iterable<BytesWritable> values, Context context)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
int defCount = 0;
|
int defCount = 0;
|
||||||
|
boolean lostFamilies = false;
|
||||||
refs.clear();
|
refs.clear();
|
||||||
for (BytesWritable type : values) {
|
for (BytesWritable type : values) {
|
||||||
if (type.getLength() == DEF.getLength()) {
|
if (type.getLength() == DEF.getLength()) {
|
||||||
defCount++;
|
defCount++;
|
||||||
|
if (type.getBytes()[0] == 1) {
|
||||||
|
lostFamilies = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] bytes = new byte[type.getLength()];
|
byte[] bytes = new byte[type.getLength()];
|
||||||
System.arraycopy(type.getBytes(), 0, bytes, 0, type.getLength());
|
System.arraycopy(type.getBytes(), 0, bytes, 0, type.getLength());
|
||||||
|
@ -861,13 +930,18 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
LOG.error("LinkedListError: key=" + keyString + ", reference(s)=" +
|
LOG.error("LinkedListError: key=" + keyString + ", reference(s)=" +
|
||||||
(refsSb != null? refsSb.toString(): ""));
|
(refsSb != null? refsSb.toString(): ""));
|
||||||
}
|
}
|
||||||
|
if (lostFamilies) {
|
||||||
|
LOG.error("LinkedListError: key=" + keyString + ", lost big or tiny families");
|
||||||
|
context.getCounter(Counts.LOST_FAMILIES).increment(1);
|
||||||
|
context.write(key, LOSTFAM);
|
||||||
|
}
|
||||||
|
|
||||||
if (defCount == 0 && refs.size() > 0) {
|
if (defCount == 0 && refs.size() > 0) {
|
||||||
// This is bad, found a node that is referenced but not defined. It must have been
|
// This is bad, found a node that is referenced but not defined. It must have been
|
||||||
// lost, emit some info about this node for debugging purposes.
|
// lost, emit some info about this node for debugging purposes.
|
||||||
// Write out a line per reference. If more than one, flag it.;
|
// Write out a line per reference. If more than one, flag it.;
|
||||||
for (int i = 0; i < refs.size(); i++) {
|
for (int i = 0; i < refs.size(); i++) {
|
||||||
byte [] bs = refs.get(i);
|
byte[] bs = refs.get(i);
|
||||||
int ordinal;
|
int ordinal;
|
||||||
if (i <= 0) {
|
if (i <= 0) {
|
||||||
ordinal = Counts.UNDEFINED.ordinal();
|
ordinal = Counts.UNDEFINED.ordinal();
|
||||||
|
@ -963,16 +1037,16 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int run(String[] args) throws Exception {
|
public int run(String[] args) throws Exception {
|
||||||
|
|
||||||
if (args.length != 2) {
|
if (args.length != 2) {
|
||||||
System.out.println("Usage : " + Verify.class.getSimpleName() + " <output dir> <num reducers>");
|
System.out.println("Usage : " + Verify.class.getSimpleName()
|
||||||
|
+ " <output dir> <num reducers>");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String outputDir = args[0];
|
String outputDir = args[0];
|
||||||
int numReducers = Integer.parseInt(args[1]);
|
int numReducers = Integer.parseInt(args[1]);
|
||||||
|
|
||||||
return run(outputDir, numReducers);
|
return run(outputDir, numReducers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int run(String outputDir, int numReducers) throws Exception {
|
public int run(String outputDir, int numReducers) throws Exception {
|
||||||
|
@ -982,7 +1056,7 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
public int run(Path outputDir, int numReducers) throws Exception {
|
public int run(Path outputDir, int numReducers) throws Exception {
|
||||||
LOG.info("Running Verify with outputDir=" + outputDir +", numReducers=" + numReducers);
|
LOG.info("Running Verify with outputDir=" + outputDir +", numReducers=" + numReducers);
|
||||||
|
|
||||||
job = new Job(getConf());
|
job = Job.getInstance(getConf());
|
||||||
|
|
||||||
job.setJobName("Link Verifier");
|
job.setJobName("Link Verifier");
|
||||||
job.setNumReduceTasks(numReducers);
|
job.setNumReduceTasks(numReducers);
|
||||||
|
@ -994,6 +1068,11 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
scan.addColumn(FAMILY_NAME, COLUMN_PREV);
|
scan.addColumn(FAMILY_NAME, COLUMN_PREV);
|
||||||
scan.setCaching(10000);
|
scan.setCaching(10000);
|
||||||
scan.setCacheBlocks(false);
|
scan.setCacheBlocks(false);
|
||||||
|
if (isMultiUnevenColumnFamilies()) {
|
||||||
|
scan.addColumn(BIG_FAMILY_NAME, BIG_FAMILY_NAME);
|
||||||
|
scan.addColumn(TINY_FAMILY_NAME, TINY_FAMILY_NAME);
|
||||||
|
job.getConfiguration().setBoolean(Generator.MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY, true);
|
||||||
|
}
|
||||||
|
|
||||||
TableMapReduceUtil.initTableMapperJob(getTableName(getConf()).getName(), scan,
|
TableMapReduceUtil.initTableMapperJob(getTableName(getConf()).getName(), scan,
|
||||||
VerifyMapper.class, BytesWritable.class, BytesWritable.class, job);
|
VerifyMapper.class, BytesWritable.class, BytesWritable.class, job);
|
||||||
|
@ -1012,7 +1091,6 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
return success ? 0 : 1;
|
return success ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public boolean verify(long expectedReferenced) throws Exception {
|
public boolean verify(long expectedReferenced) throws Exception {
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
throw new IllegalStateException("You should call run() first");
|
throw new IllegalStateException("You should call run() first");
|
||||||
|
@ -1024,6 +1102,7 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
Counter unreferenced = counters.findCounter(Counts.UNREFERENCED);
|
Counter unreferenced = counters.findCounter(Counts.UNREFERENCED);
|
||||||
Counter undefined = counters.findCounter(Counts.UNDEFINED);
|
Counter undefined = counters.findCounter(Counts.UNDEFINED);
|
||||||
Counter multiref = counters.findCounter(Counts.EXTRAREFERENCES);
|
Counter multiref = counters.findCounter(Counts.EXTRAREFERENCES);
|
||||||
|
Counter lostfamilies = counters.findCounter(Counts.LOST_FAMILIES);
|
||||||
|
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
//assert
|
//assert
|
||||||
|
@ -1045,6 +1124,11 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lostfamilies.getValue() > 0) {
|
||||||
|
LOG.error("Found nodes which lost big or tiny families, count=" + lostfamilies.getValue());
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
handleFailure(counters);
|
handleFailure(counters);
|
||||||
}
|
}
|
||||||
|
@ -1358,17 +1442,17 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
Path p = new Path(args[0]);
|
Path p = new Path(args[0]);
|
||||||
Configuration conf = getConf();
|
Configuration conf = getConf();
|
||||||
TableName tableName = getTableName(conf);
|
TableName tableName = getTableName(conf);
|
||||||
|
try (FileSystem fs = HFileSystem.get(conf);
|
||||||
|
Connection conn = ConnectionFactory.createConnection(conf);
|
||||||
|
Admin admin = conn.getAdmin()) {
|
||||||
|
if (admin.tableExists(tableName)) {
|
||||||
|
admin.disableTable(tableName);
|
||||||
|
admin.deleteTable(tableName);
|
||||||
|
}
|
||||||
|
|
||||||
FileSystem fs = HFileSystem.get(conf);
|
if (fs.exists(p)) {
|
||||||
Admin admin = new HBaseAdmin(conf);
|
fs.delete(p, true);
|
||||||
|
}
|
||||||
if (admin.tableExists(tableName)) {
|
|
||||||
admin.disableTable(tableName);
|
|
||||||
admin.deleteTable(tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.exists(p)) {
|
|
||||||
fs.delete(p, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1420,12 +1504,22 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isMultiUnevenColumnFamilies() {
|
||||||
|
return Boolean.TRUE.toString().equalsIgnoreCase(
|
||||||
|
System.getProperty(Generator.MULTIPLE_UNEVEN_COLUMNFAMILIES_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContinuousIngest() throws IOException, Exception {
|
public void testContinuousIngest() throws IOException, Exception {
|
||||||
//Loop <num iterations> <num mappers> <num nodes per mapper> <output dir> <num reducers>
|
//Loop <num iterations> <num mappers> <num nodes per mapper> <output dir> <num reducers>
|
||||||
int ret = ToolRunner.run(getTestingUtil(getConf()).getConfiguration(), new Loop(),
|
Configuration conf = getTestingUtil(getConf()).getConfiguration();
|
||||||
new String[] {"1", "1", "2000000",
|
if (isMultiUnevenColumnFamilies()) {
|
||||||
util.getDataTestDirOnTestFS("IntegrationTestBigLinkedList").toString(), "1"});
|
// make sure per CF flush is on
|
||||||
|
conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushLargeStoresPolicy.class.getName());
|
||||||
|
}
|
||||||
|
int ret =
|
||||||
|
ToolRunner.run(conf, new Loop(), new String[] { "1", "1", "2000000",
|
||||||
|
util.getDataTestDirOnTestFS("IntegrationTestBigLinkedList").toString(), "1" });
|
||||||
org.junit.Assert.assertEquals(0, ret);
|
org.junit.Assert.assertEquals(0, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,7 +1562,6 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int runTestFromCommandLine() throws Exception {
|
public int runTestFromCommandLine() throws Exception {
|
||||||
|
|
||||||
Tool tool = null;
|
Tool tool = null;
|
||||||
if (toRun.equalsIgnoreCase("Generator")) {
|
if (toRun.equalsIgnoreCase("Generator")) {
|
||||||
tool = new Generator();
|
tool = new Generator();
|
||||||
|
@ -1504,7 +1597,12 @@ public class IntegrationTestBigLinkedList extends IntegrationTestBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<String> getColumnFamilies() {
|
protected Set<String> getColumnFamilies() {
|
||||||
return Sets.newHashSet(Bytes.toString(FAMILY_NAME));
|
if (isMultiUnevenColumnFamilies()) {
|
||||||
|
return Sets.newHashSet(Bytes.toString(FAMILY_NAME), Bytes.toString(BIG_FAMILY_NAME),
|
||||||
|
Bytes.toString(TINY_FAMILY_NAME));
|
||||||
|
} else {
|
||||||
|
return Sets.newHashSet(Bytes.toString(FAMILY_NAME));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setJobConf(Job job, int numMappers, long numNodes,
|
private static void setJobConf(Job job, int numMappers, long numNodes,
|
||||||
|
|
Loading…
Reference in New Issue