package transactions;
import java.io.IOException;
import java.util.List;
import com.google.protobuf.ServiceException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.protobuf.generated.MultiRowMutationProtos.*;
import org.apache.hadoop.hbase.regionserver.KeyPrefixRegionSplitPolicy;
import org.apache.hadoop.hbase.util.Bytes;
import util.HBaseHelper;
// cc MultiRowMutationExample Use the coprocessor based multi-row mutation call
public class MultiRowMutationExample {
public static void main(String[] args) throws IOException,
InterruptedException, ServiceException {
Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
HBaseHelper helper = HBaseHelper.getHelper(conf);
helper.dropTable("testtable");
TableName tableName = TableName.valueOf("testtable");
// vv MultiRowMutationExample
HTableDescriptor htd = new HTableDescriptor(tableName)
.addFamily(new HColumnDescriptor("colfam1"))
.addCoprocessor(MultiRowMutationEndpoint.class.getCanonicalName(), // co MultiRowMutationExample-01-SetCopro Set the coprocessor explicitly for the table.
null, Coprocessor.PRIORITY_SYSTEM, null)
.setValue(HTableDescriptor.SPLIT_POLICY,
KeyPrefixRegionSplitPolicy.class.getName()) // co MultiRowMutationExample-02-SetSplitPolicy Set the supplied split policy.
.setValue(KeyPrefixRegionSplitPolicy.PREFIX_LENGTH_KEY,
String.valueOf(2)); // co MultiRowMutationExample-03-SetPrefixLen Set the length of the prefix keeping entities together to two.
// ^^ MultiRowMutationExample
System.out.println("Creating table...");
// vv MultiRowMutationExample
Admin admin = connection.getAdmin();
admin.createTable(htd);
Table table = connection.getTable(tableName);
// ^^ MultiRowMutationExample
System.out.println("Filling table with test data...");
// vv MultiRowMutationExample
for (int i = 0; i < 10; i++) { // co MultiRowMutationExample-04-FillOne Fill first entity prefixed with two zeros, adding 10 rows.
Put put = new Put(Bytes.toBytes("00-row" + i));
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"),
Bytes.toBytes("val1"));
table.put(put);
}
for (int i = 0; i < 10000; i++) { // co MultiRowMutationExample-05-FillTwo Fill second entity prefixed with two nines, adding 10k rows.
Put put = new Put(Bytes.toBytes("99-row" + i));
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"),
Bytes.toBytes("val1"));
table.put(put);
}
// ^^ MultiRowMutationExample
System.out.println("Flushing table...");
// vv MultiRowMutationExample
admin.flush(tableName); // co MultiRowMutationExample-06-Flush Force a flush of the created data.
Thread.sleep(3 * 1000L);
List<HRegionInfo> regions = admin.getTableRegions(tableName);
int numRegions = regions.size();
// ^^ MultiRowMutationExample
System.out.println("Number of regions: " + numRegions);
System.out.println("Splitting table...");
// vv MultiRowMutationExample
admin.split(tableName); // co MultiRowMutationExample-07-Split Subsequently split the table to test the split policy.
do {
regions = admin.getTableRegions(tableName);
Thread.sleep(1 * 1000L);
System.out.print(".");
} while (regions.size() <= numRegions);
numRegions = regions.size();
System.out.println("Number of regions: " + numRegions);
System.out.println("Regions: ");
for (HRegionInfo info : regions) { // co MultiRowMutationExample-08-CheckBoundaries The region was split exactly between the two entities, despite the difference in size.
System.out.print(" Start Key: " + Bytes.toString(info.getStartKey()));
System.out.println(", End Key: " + Bytes.toString(info.getEndKey()));
}
MutateRowsRequest.Builder builder = MutateRowsRequest.newBuilder();
Put put = new Put(Bytes.toBytes("00-row1"));
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"),
Bytes.toBytes("val99999"));
builder.addMutationRequest(ProtobufUtil.toMutation(
ClientProtos.MutationProto.MutationType.PUT, put)); // co MultiRowMutationExample-09-AddPuts Add puts that address separate rows within the same entity (prefixed with two zeros).
put = new Put(Bytes.toBytes("00-row5"));
put.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"),
Bytes.toBytes("val99999"));
builder.addMutationRequest(ProtobufUtil.toMutation(
ClientProtos.MutationProto.MutationType.PUT, put));
// ^^ MultiRowMutationExample
System.out.println("Calling mutation service...");
// vv MultiRowMutationExample
CoprocessorRpcChannel channel = table.coprocessorService(
Bytes.toBytes("00")); // co MultiRowMutationExample-10-Endpoint Get the endpoint to the region that holds the proper entity (same prefix).
MultiRowMutationService.BlockingInterface service =
MultiRowMutationService.newBlockingStub(channel);
MutateRowsRequest request = builder.build();
service.mutateRows(null, request); // co MultiRowMutationExample-11-Mutate Call the mutate method that updates the entity across multiple rows atomically.
// ^^ MultiRowMutationExample
System.out.println("Scanning first entity...");
Scan scan = new Scan()
.setStartRow(Bytes.toBytes("00"))
.setStopRow(Bytes.toBytes("01"));
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
System.out.print("Result: " + result);
byte[] val = result.getValue(Bytes.toBytes("colfam1"),
Bytes.toBytes("qual1"));
System.out.println(", Value: " + Bytes.toString(val));
}
System.out.println(admin.getTableDescriptor(tableName));
table.close();
admin.close();
connection.close();
}
}