创建HBase全局二级索引
在HBase数据查询场景中,当数据表存在大量数据时,基于非RowKey列的查询需要全表扫描,查询效率低下。如何在已有数据表上快速创建索引以加速条件查询?HBase全局二级索引功能允许用户在指定列上创建索引,将全表扫描转换为索引表的精确范围查询,大幅提升查询性能。本文介绍如何创建和删除HBase全局二级索引。
- 全局二级索引(Global Secondary Index,GSI):HBase提供的索引功能,使用独立的索引表存储索引数据。当查询条件命中索引时,可将全表扫描转换为索引表的精确范围查询,提升查询速度。
- 索引状态:索引的生命周期状态,包括ACTIVE(可用)、INACTIVE(不可用)、BUILDING(构建中)等。空表创建的索引状态为ACTIVE,非空表创建的索引初始状态为INACTIVE,需要生成索引数据后才能变为ACTIVE。
- 覆盖列(Covered Column):索引表中冗余存储的数据表列。查询时如果所需数据都在覆盖列中,可直接从索引表返回结果,无需回查数据表,进一步提升查询性能。
- 预分区(Split Key):索引表创建时预先划分的Region分片点。合理设置预分区可以避免索引表Region成为热点,提升写入和查询性能。
- GlobalTableIndexer工具:HBase提供的命令行工具,用于创建、删除和管理全局二级索引。
在数据表上创建索引时,系统会创建一个独立的索引表,索引表以索引列为RowKey,存储索引列值与数据表RowKey的映射关系。当执行基于索引列的查询时,HBase先查询索引表获取匹配的RowKey列表,再根据RowKey从数据表读取完整数据。由于索引表数据量远小于数据表且按索引列有序存储,查询效率显著提升。对于非空表,创建的索引初始状态为INACTIVE,需要通过索引数据生成工具填充索引数据后,索引状态变为ACTIVE才能正常使用。
场景介绍
- 在用户的表中预先存在大量数据的情况下,可以在某个列上添加索引,加速基于该列的条件查询。
- 对于未建立索引的用户表,该工具允许用户同时添加索引并构建索引数据。
前提条件
- 已安装HBase客户端。了解如何安装客户端,请参考安装客户端(3.x及之后版本)。
- 当前用户已具有创建HBase索引的权限。
创建HBase全局二级索引
在HBase客户端执行以下命令即可添加或创建索引,执行命令后,指定的索引将被添加到表中:
hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='table' -Dindexspecs.to.add='idx1=>cf1:[c1->string],[c2]#idx2=>cf2:[c1->string],[c2]#idx3=>cf1:[c1];cf2:[c1]' -Dindexspecs.covered.family.to.add='idx2=>cf1' -Dindexspecs.covered.to.add='idx1=>cf1:[c3],[c4]' -Dindexspecs.coveredallcolumn.to.add='idx3=>true' -Dindexspecs.splitkeys.to.set='idx1=>[\x010,\x011,\x012]#idx2=>[\x01a,\x01b,\x01c]#idx3=>[\x01d,\x01e,\x01f]'
参数说明如下:
- tablename.to.index:表示创建索引的数据表的名称。
当使用tablename.to.index创建索引时,如果数据表为空表,创建的索引状态为ACTIVE,否则索引状态为INACTIVE。
- indexspecs.to.addandbuild(可选):表示创建时同时生成索引数据,数据表数据量较大时不建议使用,建议使用索引数据生成工具生成索引数据。
indexspecs.to.addandbuild和tablename.to.index不能同时使用,当使用indexspecs.to.addandbuild时,索引状态为BUILDING,当索引数据完整生成后,索引状态会修改为ACTIVE。
- indexspecs.to.add:表示索引名与对应数据表的列的映射(索引列定义)。
- indexspecs.covered.to.add(可选):表示索引中冗余存储的数据表的列(覆盖列定义)。
- indexspecs.covered.family.to.add(可选):表示索引表冗余存储的数据表的列族(覆盖列族定义)。
- indexspecs.coveredallcolumn.to.add(可选):表示索引表冗余存储数据表中的所有数据(覆盖所有列)。
- indexspecs.splitkeys.to.set(可选):表示索引表预分区切分点,建议指定,避免索引表Region成为热点。预分区指定格式为:
- '#'用于分隔索引。
- splitkey包含在'[]'中。
- ','用于分隔splitkey。
预分区每个splitkey必须由\x01开头。
- idx1、idx2、idx3:表示索引名称。
- cf1、cf2:表示列族名称。
- c1、c2、c3、c4:表示列名称。
- string:表示数据类型。支持STRING、INTEGER、FLOAT、LONG、DOUBLE、SHORT、BYTE和CHAR。
- '#'用于分隔索引,';' 用于分隔列族,','用于分隔列限定符。
- 列名及其数据类型应包含在'[]'中。
- 列名及其数据类型通过'->'分隔。
- 如果未指定具体列的数据类型,则使用默认数据类型(string)。
验证操作:
索引创建完成后,可通过查询索引信息命令验证索引是否创建成功。了解如何查询HBase全局二级索引信息,请参考查询HBase全局二级索引信息。
删除HBase全局二级索引
在HBase客户端执行以下命令可删除某个索引:
hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='table' -Dindexnames.to.drop='idx1#idx2'
相关参数介绍如下:
- tablename.to.index:表示需删除的索引所在的表名称。
- indexnames.to.drop:表示需要删除的索引名称,可以同时指定多个,用“#”号分隔。
验证操作:
索引删除完成后,可通过查询索引信息命令验证索引是否删除成功。
常见问题
- 创建索引后索引状态为INACTIVE
当数据表非空时,使用tablename.to.index创建的索引初始状态为INACTIVE,表示索引表已创建但索引数据尚未生成。这是正常现象,需要通过索引数据生成工具填充索引数据后,索引状态才会变为ACTIVE。
了解如何批量构建HBase全局二级索引数据,请参考批量构建HBase全局二级索引数据。也可以使用indexspecs.to.addandbuild参数在创建索引时同时生成索引数据(数据量较大时不建议使用)。
- 如何查询已创建的索引信息
创建索引后,用户可能需要查看索引的定义、状态、覆盖列等信息,以确认索引是否正确创建。
了解如何查询HBase全局二级索引的定义及状态,请参考查询HBase全局二级索引信息。
- 如何修改索引状态
索引创建后可能需要根据业务需求调整索引状态,如将INACTIVE状态的索引启用或禁用。
了解如何修改HBase全局二级索引状态,请参考修改HBase全局二级索引状态。
- 如何检查索引数据一致性
当查询命中的索引数据无效时,可能需要检查索引数据与数据表数据的一致性。
了解如何检查HBase全局二级索引数据一致性,请参考检查HBase全局二级索引数据一致性。
- 索引创建失败
索引创建失败的常见原因包括:数据表不存在、索引名已存在、索引名不符合正则要求、用户没有创建索引的权限等。
请确认数据表存在且索引名唯一。索引名需符合正则要求。确认当前用户具有创建索引的权限。
- 如何使用全局二级索引查询数据
创建索引后,用户需要通过索引查询数据以验证索引是否生效。
了解如何基于全局二级索引查询HBase表数据,请参考基于全局二级索引查询HBase表数据。
相关文档
- 了解HBase全局二级索引的工作原理和特性,请参考HBase全局二级索引介绍。
- 了解如何检查HBase全局二级索引数据一致性,请参考检查HBase全局二级索引数据一致性。
- 了解如何基于全局二级索引查询HBase表数据,请参考基于全局二级索引查询HBase表数据。
- 了解HBase常见问题,请参考HBase常见问题。