Hbase中的二级索引
一、什么是索引
索引是一种数据结构,为了加速查询!
- HBase中的一级索引指,数据在写入region时,会根据rowkey进行排序后写入,之后regionserver在加载region时,会自动为当前region的rowkey创建一个LSM树的索引!方便对当前region,rowkey的查询!
HBase 里面只有 rowkey 作为一级索引, 如果要对库里的非 rowkey 字段进行数据检索和查询, 往往要通过 MapReduce/Spark 等分布式计算框架进行,硬件资源消耗和时间延迟都会比较高。为了 HBase 的数据查询更高效、适应更多的场景, 诸如使用非 rowkey 字段检索也能做到秒级响应,或者支持各个字段进行模糊查询和多字段组合查询等, 因此需要在 HBase 上面构建二级索引, 以满足现实中更复杂多样的业务需求。
- 二级索引:如果要固定查询一个hbase表中的某些列,可以针对这些列的数据,创建索引,可以在查询指定的数据时,快速定位到列的位置!
二、配置 HBase 支持 Phoenix 创建二级索引
2.1 配置
添加如下配置到HBase的HRegionserver节点的hbase-site.xml
<!-- phoenix regionserver 配置参数 -->
<property>
<name>hbase.regionserver.wal.codec</name>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
<property>
<name>hbase.region.server.rpc.scheduler.factory.class</name>
<value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
<description>Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates</description>
</property>
<property>
<name>hbase.rpc.controllerfactory.class</name>
<value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
<description>Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates</description>
</property>
2.2 创建索引
1)准备数据:
create table user_1(id varchar primary key, name varchar, addr varchar)
upsert into user_1 values ('1', 'zs', 'beijing');
upsert into user_1 values ('2', 'lisi', 'shanghai');
upsert into user_1 values ('3', 'ww', 'sz');
2) 创建索引
create [local] index 索引名 on 表名( 列1,...列2 )
--查看索引
!tables
drop index 索引名 on 表名
给 name 字段添加索引:
create index idx_user_1 on user_1(name)
注意: 这种索引, 对 name 创建的索引, 则查询的时候也必须只查询 name 字段.
3) 如何得知索引是否使用了
在mysql中,可以使用 explain + sql ,如果 出现的结果中, Type = All ,说明执行了全表的扫描查询,没有使用上索引!
在phoenix中,使用explain + sql ,如果出现了 FULL SCAN ,说明没有使用索引,执行了全部扫描!
如果出现了RANGE SCAN ,说明使用了二级索引!
切记,为除了主键的列,创建索引! 索引一般都需要集合where过滤条件查询! select * from 表,用不上索引!
三、全局索引和本地索引
Phoenix 索引分全局索引和局部索引。
3.1 全局索引
全局索引:global index 是默认的索引格式。
适用于多读少写的业务场景。写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。
在读数据的时候 Phoenix 会选择索引表来降低查询消耗的时间。
如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。
创建全局索引的方法: CREATE INDEX my_index ON my_table (my_col)
.
3.2 本地索引
local index 适用于写操作频繁的场景。索引数据和数据表的数据是存放在相同的服务器中的,避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。
查询的字段不是索引字段索引表也会被使用,这会带来查询速度的提升。
创建局部索引的方法(相比全局索引多了一个关键字 local): CREATE LOCAL INDEX my_index ON my_table (my_index)
.
3.3 本地索引和全局索引的区别
Local index 由于是数据与索引在同一服务器上,所以要查询的数据在哪台服务器的哪个region是无法定位的,只能先找到region然后再利用索引。
Global index 是一种分布式索引,可以直接利用索引定位服务器和region,速度更快,但是由于分布式的原因,数据一旦出现新增变化,分布式的索引要进行跨服务的同步操作,带来大量的通信消耗。所以在写操作频繁的字段上不适合建立Global index。