创建二级索引


功能简介

一般都通过调用org.apache.hadoop.hbase.index.client.IndexAdmin中方法进行HBase二级索引的管理,该类中提供了创建索引的方法。

说明:

二级索引不支持修改,如果需要修改,请先删除旧的然后重新创建。

在表上增加二级索引后,不支持对原始表的truncate操作。

代码样例

public void createIndex() {
    LOG.info("Entering createIndex.");

    String indexName = "index_name";
    // Create index instance
    IndexSpecification iSpec = new IndexSpecification(indexName);
    iSpec.addIndexColumn(new HColumnDescriptor("info"), "name", ValueType.String);//注[1]

    IndexAdmin iAdmin = null;
    Admin admin = null;
    try {
      // Instantiate IndexAdmin Object
      iAdmin = new IndexAdmin(conf);
      // Create Secondary Index
      iAdmin.addIndex(tableName, iSpec);

      admin = conn.getAdmin();

      //Specify the encryption type of indexed column 
      HTableDescriptor htd = admin.getTableDescriptor(tableName);
      admin.disableTable(tableName);
      htd = admin.getTableDescriptor(tableName);
      //Instantiate index column description.
      HColumnDescriptor indexColDesc = new HColumnDescriptor(
          IndexMasterObserver.DEFAULT_INDEX_COL_DESC);

      //Set the description of index as the HTable description.
      htd.setValue(Constants.INDEX_COL_DESC_BYTES,
          indexColDesc.toByteArray());
      admin.modifyTable(tableName, htd);
      admin.enableTable(tableName);

      LOG.info("Create index successfully.");
    } catch (IOException e) {
      LOG.error("Create index failed " ,e);
    } finally {
      if (admin != null) {
          try {
            admin.close();
        } catch (IOException e) {
            LOG.error("Close admin failed " ,e);
        }
      }
      if (iAdmin != null) {
        try {
          // Close IndexAdmin Object
          iAdmin.close();
        } catch (IOException e) {
          LOG.error("Close admin failed " ,e);
        }
      }
    }
    LOG.info("Exiting createIndex.");
  }
样例:如果用户表在创建时对列或列族设置了加密,那么在创建对应的索引表时,需添加对应的加密参数。请参考“管理员指南 > 安全管理 > 安全加固 > 加密HFile和WAL内容”进行安全加固。
//Specify the encryption type of indexed column  
       HTableDescriptor htd = admin.getTableDescriptor(Bytes.toBytes("user")); 
       admin.disableTable(tableName); 
       htd = admin.getTableDescriptor(Bytes.toBytes("user")); 

       //Instantiate index column description. 
       HColumnDescriptor indexColDesc = new HColumnDescriptor(IndexMasterObserver.DEFAULT_INDEX_COL_DESC); 
       indexColDesc.setEncryptionType("AES"); 

       //Set the description of index as the HTable description. 
       htd.setValue(Constants.INDEX_COL_DESC_BYTES, indexColDesc.toByteArray()); 
       admin.modifyTable("user", htd); 
       admin.enableTable(tableName);

注意事项

注[1]:创建联合索引

HBase支持在多个字段上创建二级索引,例如在列name和age上。但需要注意的是创建联合索引时需要指定每个列的长度。

 IndexSpecification iSpecUnite = new IndexSpecification(indexName); 
 iSpecUnite.addIndexColumn(new HColumnDescriptor("info"), "name", ValueType.String, 10); 
 iSpecUnite.addIndexColumn(new HColumnDescriptor("info"), "age", ValueType.String, 3);

相关操作

使用命令创建索引表。

您还可以通过TableIndexer工具在已有用户表中创建索引。

说明:

    <table\_name>用户表必须存在。
hbase org.apache.hadoop.hbase.index.mapreduce.TableIndexer -Dtablename.to.index=<table_name> -Dtable.columns.index='IDX1=>cf1:[q1->datatype&length];cf2:[q1->datatype&length],[q2->datatype&length],[q3->datatype& lenght]#IDX2=>cf1:[q5->datatype&length]'

“#”用于区分不同的索引,“;”用于区分不同的列族,“,”用于区分不同的列。

tablename.to.index:创建索引的用户表表名。

table.columns.index:创建索引对应的用户表列。

其中命令中各参数的含义如下:

  • IDX1:索引名称
  • cf1:列族名称。
  • q1:列名。
  • datatype:数据类型。数据类型仅支持Int、String、Double、Float类型。
  • length:值的最大长度。

获取索引创建时间

当在用户表中添加新的索引时,新索引的创建时间会作为HBase的表格属性被保存在用户表中。这个表格属性包含属性关键字,比如带“_idx”后缀的索引名,创建时间的单位为毫秒。

例如:

如果一个名为“IndexName”的索引被添加进用户表“UserTable”,这个“UserTable”表格将会有下列的属性被添加进这个表格,描述如下。

hbase(main):084:0> desc 'UserTable'

UserTable, {TABLE_ATTRIBUTES => {METADATA => {'IndexName_idx' => '1461303606018', 'INDEX_SPEC' => '\x00\x00\x00\x01\x02I1\x00\x00\x00\x01\x02f1\x02c1\x06Strin
g\x00\x00\x00\x14\x00\x04NONE\x00\x00\x00\x01\x00\x00\x00\x00\x7F\xFF\xFF\xFF'}}
COLUMN FAMILIES DESCRIPTION
{NAME => 'f1', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '1', COMPRESSION => 'NONE', VERSIONS => '1', TTL => 'FO
REVER', MIN_VERSIONS => '0', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.5780 seconds

其中,“IndexName_idx”即为属性关键字,包含了带后缀“_idx”的新增索引“IndexName”。

索引创建时间也可以通过使用HBase标准API接口获取。获取目录创建时间对其他工具开发者来说是非常有用的,例如基于时间范围的备份和存储。

results matching ""

    No results matching ""