
# HBase全局二级索引介绍
#### 场景介绍
使用HBase二级索引可以加速带Filter的条件查询，支持HIndex（本地索引，即Local Secondary Index，简称为LSI）和全局二级索引（Global Secondary Index，简称为GSI）。全局二级索引相较于本地索引（HIndex），查询性能更好，适合读时延要求高的场景。
HBase全局二级索引，使用独立的索引表存储索引数据。当给定的查询条件可以命中索引时，可以将对数据表的全表查询转换为对索引表的精确范围查询，提升查询速度。开启全局二级索引特性后，应用侧代码无需特殊修改，简单易用。
HBase全局二级索引支持以下重点特性：
- **复合索引**
  支持指定多个列作为索引列（支持跨列族）。
  

- **覆盖索引**
  支持指定多个列/列族作为覆盖列/列族冗余存储到索引表中，用于索引查询中对非索引列的快速查询。
  

- **索引TTL**
  支持索引表TTL。用于支持数据表开启TTL的场景，为了保障与数据表的一致性，索引表TTL将自动继承数据表索引列和覆盖列的TTL，不支持手动指定。
  

- **索引在线变更**
  支持索引在线创建、删除和修改状态，不影响数据表读写。
  
- **索引在线修复**
  当查询命中的索引数据无效时，可以触发索引修复，保障最终查询结果正确。
  
- **索引工具**
  支持索引一致性检查、索引修复、索引创建/删除/修改状态、索引数据重建等功能。
  
 
#### HBase全局二级索引限制与约束
- MRS 3.3.0及之后版本的集群默认启用HBase全局二级索引功能，如果需要修改全局二级索引相关参数，需登录FusionInsight Manager，选择"集群 \> 服务 \> HBase \> 配置 \> 全部配置"，在"RegionServer（角色） \> 二级索引"和"HMaster（角色） \> 二级索引"中修改。
- 使用场景限制
  - GSI不支持与HIndex同时使用，即不支持在同一个数据表上同时创建本地索引与全局索引。
  
  - 索引表不支持容灾。
  
  - 索引数据不支持滚动升级。
  
  - 不支持直接对索引表执行DISABLE、DROP、MODIFY和TRUNCATE操作。
  
  - 索引DDL操作支持修改索引状态、删除索引、创建索引；不支持修改索引定义，如需修改，请先删除后重新创建。
   
- 索引创建约束
  - 索引名需要符合正则要求，不支持其他字符，正则要求支持的字符为：**\[a-zA-Z_0-9-.\]:**。
  
  - 数据表必须存在，要创建的索引不能已存在。
  
  - 索引表不支持多版本 不支持在多版本（VERSION\>1）的数据表上创建索引，且索引表的版本VERSION=1。
    
  
  - 单个数据表的索引个数不能超过5个 不建议为单个数据表创建过多索引，索引数量过多会造成存储成本较高，写入耗时大。如果需创建超过5个索引，请在HMaster的自定义配置"hbase.hmaster.config.expandor"中新增参数"hbase.gsi.max.index.count.per.table"，设置值大于5，并重启HMaster使配置生效。
    
  
  
  
  - 索引名长度不能超过18个字符 不建议使用过长的索引名。如果需创建较长的索引名，请在HMaster的自定义配置"hbase.hmaster.config.expandor"中新增参数"hbase.gsi.max.index.name.length"，设置值大于18，并重启HMaster使配置生效。
    
  
  - 不支持为索引表创建索引 不支持嵌套创建多个索引，索引表仅用于加速查询，不承担数据表功能。
    
  
  - 不支持创建可以被已有索引覆盖的索引 新建索引时，如果之前已存在的索引能够完全覆盖新建的索引（即创建的索引是已有索引的子集），则无法创建此索引，重复功能的索引会造成存储浪费。例如，以下操作将无法创建索引2：
    创建数据表：**create 't1','cf1'**
    创建索引1：**hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='t1' -Dindexspecs.to.add='idx1=\>cf1:\[q1\],\[q2\]'**
    创建索引2：**hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='t1' -Dindexspecs.to.add='idx2=\>cf1:\[q1\]'**
    
  
  - 不支持在同一张数据表上创建同名索引，支持在不同数据表上创建同名索引。
  
  - 索引表列族TTL继承原表，索引列族TTL必须一致 索引表所有列族TTL相同，继承自数据表，要求数据表中相关列族TTL必须一致，否则无法创建相关索引。
    
  
  - 不支持为表创建索引时自定义索引的其他属性，例如，压缩方式、BLOCKSIZE、列编码等。
   
- 索引写入约束
  - 索引数据生成仅支持Put/Delete接口，使用其他方式（Increment、Append、Bulkload等）写入数据表时不会生成对应索引。
  
  - 索引列数据定义为String类型时，要避免写入**\\x00** 和**\\x01**两个特殊字符（特殊不可见字符）。
  
  - 避免指定时间戳的方式写入索引列。
   
- 索引查询约束
  - 索引查询时索引的状态必须为**ACTIVE**。
  
  - 索引查询不支持**指定时间戳范围查询**。如果需要通过索引查询时间范围内的数据，请添加时间列存储该条数据时间戳，否则会使用数据表进行查询。
  
  - 索引查询不支持指定StartRow和StopRow进行区间查询。如果指定了其中任意一个，查询操作将不走索引查询，变为主表的Range Scan+Filter过滤。
  
  
  
  - 索引查询仅支持**SingleColumnValueFilter**，使用其他Filter或无Filter条件时无法触发索引加速。
   
 
