bigtable: Add ability to create table with initial splits
Note that creating initial splits is not normally necessary.
If, however, a large amount of data must be imported into the
table right after creation then creating ~100's of splits
across the expected key space can be beneficial for performance
until Bigtable figures out how to split the load naturally.
Change-Id: I531f194dab87056b77e2b950e5bd0a174264fbb5
Reviewed-on: https://code-review.googlesource.com/11290
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/bigtable/admin.go b/bigtable/admin.go
index f136e67..f65054e 100644
--- a/bigtable/admin.go
+++ b/bigtable/admin.go
@@ -104,6 +104,27 @@
return err
}
+// CreatePresplitTable creates a new table in the instance.
+// The list of row keys will be used to initially split the table into multiple tablets.
+// Given two split keys, "s1" and "s2", three tablets will be created,
+// spanning the key ranges: [, s1), [s1, s2), [s2, ).
+// This method may return before the table's creation is complete.
+func (ac *AdminClient) CreatePresplitTable(ctx context.Context, table string, split_keys []string) error {
+ var req_splits []*btapb.CreateTableRequest_Split
+ for _, split := range split_keys {
+ req_splits = append(req_splits, &btapb.CreateTableRequest_Split{[]byte(split)})
+ }
+ ctx = mergeMetadata(ctx, ac.md)
+ prefix := ac.instancePrefix()
+ req := &btapb.CreateTableRequest{
+ Parent: prefix,
+ TableId: table,
+ InitialSplits: req_splits,
+ }
+ _, err := ac.tClient.CreateTable(ctx, req)
+ return err
+}
+
// CreateColumnFamily creates a new column family in a table.
func (ac *AdminClient) CreateColumnFamily(ctx context.Context, table, family string) error {
// TODO(dsymonds): Permit specifying gcexpr and any other family settings.
diff --git a/bigtable/cmd/cbt/cbt.go b/bigtable/cmd/cbt/cbt.go
index 85e3db4..4afd1e8 100644
--- a/bigtable/cmd/cbt/cbt.go
+++ b/bigtable/cmd/cbt/cbt.go
@@ -205,7 +205,9 @@
Name: "createtable",
Desc: "Create a table",
do: doCreateTable,
- Usage: "cbt createtable <table>",
+ Usage: "cbt createtable <table> [initial_splits...]\n" +
+ " initial_splits=row A row key to be used to initially split the table " +
+ "into multiple tablets. Can be repeated to create multiple splits.",
Required: cbtconfig.ProjectAndInstanceRequired,
},
{
@@ -335,10 +337,16 @@
}
func doCreateTable(ctx context.Context, args ...string) {
- if len(args) != 1 {
- log.Fatal("usage: cbt createtable <table>")
+ if len(args) < 1 {
+ log.Fatal("usage: cbt createtable <table> [initial_splits...]")
}
- err := getAdminClient().CreateTable(ctx, args[0])
+ var err error
+ if len(args) > 1 {
+ splits := args[1:]
+ err = getAdminClient().CreatePresplitTable(ctx, args[0], splits)
+ } else {
+ err = getAdminClient().CreateTable(ctx, args[0])
+ }
if err != nil {
log.Fatalf("Creating table: %v", err)
}