如何在GeminiDB HBase兼容版实例中创表时设置预分区键
本章节主要介绍如何在GeminiDB HBase兼容版实例中创表时设置预分区键的相关操作。
什么是预分区
在GeminiDB HBase兼容版实例中,数据存储在不同数据分区中,每条数据通过rowkey前缀来决定其所归属的数据分区。 一个好的数据预分区,可以让请求压力更加均匀的分散在各个节点上,提升集群整体性能。
例如,创表时设置2个预分区键为[1111, 2222] , 则数据一共被分为3个区间, 数据会通过rowkey和分区键的字典序大小来决定其所归属的数据分区。rowkey < '1111'的数据会归属第一分区,'1111' <= rowkey < '2222' 则会归属第二分区, rowkey >='2222'则会归属第三分区。理想情况下,3个数据分区会各自归属于一个节点;实际使用中,当数据分区键设置不合理时,多个数据分区可能归属于同一个集群节点。
如何设计预分区键
最理想的设计方式是根据客户应用数据的前缀来合理打散整体数据,使各个数据分区的数据量尽可能平均。 在GeminiDB HBase兼容版实例中,一个分区的理想数据量是100GB左右,单分区没有最高数据量限制。当一个分区的数据量超过100GB时,会触发分区自动分裂功能,如有特殊需要,您可以在管理控制台右上角,选择“工单 > 新建工单”,联系客服关闭自动分裂功能。
- 样例1:
如果数据rowkey第一位平均分布在0-9中, 则可以设置10个分区键,分别为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],相应数字开头的数据都会归属对应分区。
- 样例2:
如果数据rowkey前两位平均分布在十六进制数字00–FF中,且每个分区预估数据量都在100GB左右,则推荐创建256个分区键,分别为[00, 01, 02, …..., FD, FE, FF]。
如何在创表时指定预分区
在GeminiDB HBase兼容版实例中,主要有Hbase Shell和Java Code两种方法在创表时指定预分区。
- 通过HBase Shell在创表时指定预分区:
create 'tb','cf1','cf2', 'cf3', SPLITS => ['1111', '2222', '3333']
其中'1111','2222', '3333'可替换为其他自定义分区键,多个分区键以英文逗号分隔。
- 通过Java Code在创表时指定预分区:
import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.client.TableDescriptorBuilder; public class ExampleCreateTable { public static void main(String[] args) throws Throwable { // Create HBase configuration Configuration hbaseConfig = HBaseConfiguration.create(); hbaseConfig.set("hbase.zookeeper.quorum", AllTestsSuite.instance.addr); hbaseConfig.set("hbase.zookeeper.property.clientPort", AllTestsSuite.instance.zk_port); TableName tableName = TableName.valueOf("default", "tb1"); try (Connection connection = ConnectionFactory.createConnection(hbaseConfig)) { // provide your split key here byte[][] splitkey = new byte[][]{ "rowkey1".getBytes(), "rowkey2".getBytes()}; // 5 column families List<ColumnFamilyDescriptor> cfs = new ArrayList<>(); cfs.add(ColumnFamilyDescriptorBuilder.newBuilder("cf1".getBytes()).build()); cfs.add(ColumnFamilyDescriptorBuilder.newBuilder("cf2".getBytes()).build()); cfs.add(ColumnFamilyDescriptorBuilder.newBuilder("cf3".getBytes()).build()); cfs.add(ColumnFamilyDescriptorBuilder.newBuilder("cf4".getBytes()).build()); cfs.add(ColumnFamilyDescriptorBuilder.newBuilder("cf5".getBytes()).build()); TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TestBase.tableName).setColumnFamilies(cfs).build(); // create table TestBase.createTable(tableDescriptor, splitkey); } } }