Phoenix创建Hbase二级索引

官方文档

1. 配置Hbase支持Phoenix创建二级索引

  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.  添加如下配置到Hbase中Hmaster节点的hbase-site.xml中

<!-- phoenix master 配置参数 -->
<property>
<name>hbase.master.loadbalancer.class</name>
<value>org.apache.phoenix.hbase.index.balancer.IndexLoadBalancer</value>
</property> <property>
<name>hbase.coprocessor.master.classes</name>
<value>org.apache.phoenix.hbase.index.master.IndexMasterObserver</value>
</property>

可以在hbase-site.xml里配置以下调优参数 

index.builder.threads.max
o 为主表更新操作建立索引的最大线程数
o Default: index.builder.threads.keepalivetime
o 上面线程的超时时间
o Default: index.writer.threads.max
o 将索引写到索引表的最大线程数
o Default: index.writer.threads.keepalivetime
o 上面线程的超时时间
o Default: hbase.htable.threads.max
o 同时最多有这么多线程往索引表写入数据
o Default: ,,, hbase.htable.threads.keepalivetime
o 上面线程的超时时间
o Default: index.tablefactory.cache.size
o 缓存10个往索引表写数据的线程
o Default:

3. 常见问题汇总:

  1)注意:网上配置文档里有这一条,但在实际测试中(测试环境hbase-1.3.1,网上0.98.6),加入该条的regionserver会在hbase启动时失败,对应节点上没有HregionServer进程,去掉该配置后正常启动,且能正常创建local index。

<property>
<name>hbase.coprocessor.regionserver.classes</name>
<value>org.apache.hadoop.hbase.regionserver.LocalIndexMerger</value>
</property>

  2hbase-site.xml的zookeeeper的配置信息不能加2181,否则在创建local index的时候会报以下异常:

正常配置:

<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop101,hadoop102,hadoop103</value>
</property>

2. 创建索引

  phoenix的索引分类

1)全局索引 global index是默认的索引格式。

适用于多读少写的业务场景。写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。

在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。

全局索引必须是查询语句中所有列都包含在全局索引中,它才会生效。
CREATE INDEX MY_INDEX ON STUDENT("info"."dt");

查询语句:

select "dt" from STUDENT where "dt" >= '2018-08-08'; #可以使用到索引表MY_INDEX
select "name","age","dt" from STUDENT where "dt" >= '2018-08-08'; #这样子就不会用到索引表MY_INDEX,因为name和age不在索引表中;

  所以使用全局索引,必须要所有的列都包含在索引中。那么怎样才能使用上索引呢?有三种方法:

①. 创建索引的时候使用覆盖索引。 

CREATE INDEX MY_INDEX ON STUDENT("info"."dt") INCLUDE("info"."name", "info"."age"); //INCLUED之前的索引,只能建立一个才会走range scan索引,不然就是full scan

这种索引会把name加到索引表里面,同时name也会随着原数据表中的变化而变化。这种方式很明显的缺点是索引表的大小较大,然后就是全局索引不适合写特别多的情况。

Covered Index覆盖索引的二级索引。这种索引在获取数据的过程中,内部不需要再去HBase上获取任何数据,你查询需要返回的列的数据都会被存储在索引中。要想达到这种效果,你的select 的列,where 的列都需要在索引中出现。

注意关键字INCLUDE(注意跟异步索引的区别),就是包含需要返回数据结果的列。这种索引方式的最大好处就是速度快,而我们也知道,索引就是空间换时间,所以缺点也很明显,存储空间耗费较多。Phoenix的索引其实就是建了一张HBase的表。你可以通过HBase Shell的list命令看到。

 ②. 使用类似于Oracle的Hint,强制索引。

select /*+ INDEX(STUDENT MY_INDEX)*/ "name","age" from STUDENT where "dt" >= '2018-08-08';

查询引擎会使用MY_INDEX这个索引,由于它会发现索引表中没有name,age数据,所以每一行它都会去原数据表中获取name,age的值。这个强制索引只有在你认为索引有比较好的选择性的时候才是好的选择,也就是说dt大于2018-08-08的行数不多。不然的话,使用Phoenix默认的全表扫描的性能也许会更好。

 ③. 创建本地索引

CREATE LOCAL INDEX MY_INDEX ON STUDENT("info"."dt");

本地索引和全局索引不同的是,查询语句中,即使所有的列都不在索引定义中,它也会使用索引,这是本地索引的默认行为。Phoenix知道原数据和索引数据在同一个RegionServer上,能保证索引查找是本地的。

global index的设计方式,会单独写一张索引表,列族为include字段,rowkey的设计方位是:
二级索引字段1+"\x00"+二级索引字段2(复合索引)…+"\x00"+原表rowkey
2.查询的时候,会直接定位到索引表,通过rowkey查到位置,然后从索引表中带出数据
3.因为建立索引的时候还要多写一份include字段,读的时候直接从索引表定位并读出信息。所以这种表的应用场景定位是写的慢,读得快

2)本地索引 Local index适用于写操作频繁的场景。

本地索引适合那些写多读少,或者存储空间有限的场景。和全局索引一样,Phoenix也会在查询的时候自动选择是否使用本地索引。本地索引之所以是本地,只要是因为

索引数据和真实数据存储在同一台机器上,这样做主要是为了避免网络数据传输的开销。如果你的查询条件没有完全覆盖索引列,本地索引还是可以生效。因为无法提前确定数据在哪个Region上,所以在读数据的时候,还需要检查每个Region上的数据而带来一些性能损耗。

如下示例,创建了本地索引

CREATE LOCAL INDEX my_index ON my_table (my_index)

local index的设计方式,索引数据直接写在原表rowkey中,列族不写任何实际信息,local index的rowkey的设计方位是:
原数据region的start key+"\x00"+二级索引字段1+"\x00"+二级索引字段2(复合索引)…+"\x00"+原rowkey
第一条信息"原数据region的start key",这样做的目的是保证索引数据和原数据在一个region上,定位到二级索引后根据原rowkey就可以很快在本region上获取到其它信息,减少网络开销和检索成本。
2.查询的时候,会在不同的region里面分别对二级索引字段定位,查到原rowkey后在本region上获取到其它信息
3.因为这种索引设计方式只写索引数据,省了不少空间的占用,根据索引信息拿到原rowkey后再根据rowkey到原数据里面获取其它信息。所以这种表的应用场景定位是写的快,读得慢

local index和global index比较

1.索引数据

global index单独把索引数据存到一张表里,保证了原始数据的安全,侵入性小
local index把数据写到原始数据里面,侵入性强,原表的数据量=原始数据+索引数据,使原始数据更大
2.性能方面

global index要多写出来一份数据,写的压力就大一点,但读的速度就非常快
local index只用写一份索引数据,节省不少空间,但多了一步通过rowkey查找数据,写的速度非常快,读的速度就没有直接取自己的列族数据快。

3)异步创建索引

一般我们可以使用CREATE INDEX来创建一个索引,这是一种同步的方法。但是有时候我们创建索引的表非常大,我们需要等很长时间。Phoenix 4.5以后有一个异步创建索引的方式,使用关键字ASYNC来创建索引:

create index MY_INDEX on FRUITS("info"."name") include ("info"."color") async;

这时候创建的索引表中不会有数据。你还必须要单独的使用命令行工具来执行数据的创建。当语句给执行的时候,后端会启动一个map reduce任务,只有等到这个任务结束,数据都被生成在索引表中后,这个索引才能被使用。启动工具的方法:

${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool \
> --data-table FRUITS --index-table MY_INDEX \
> --output-path ASYNC_IDX_HFILES
注:  --schema MY_SCHEMA,不加这个就是默认的schema
注: 上边尽量不要用小写,即使""双引号里边写的是小写它也不识别;
2019-10-10 15:04:01,579 INFO  [main] index.IndexTool: Loading HFiles from ASYNC_IDX_HFILES/MY_INDEX
2019-10-10 15:04:01,723 WARN [main] mapreduce.LoadIncrementalHFiles: Skipping non-directory hdfs://hadoop101:9000/user/kris/ASYNC_IDXEX/_SUCCESS
2019-10-10 15:04:01,909 INFO [LoadIncrementalHFiles-0] hfile.CacheConfig: Created cacheConfig: CacheConfig:disabled
2019-10-10 15:04:01,985 INFO [LoadIncrementalHFiles-0] mapreduce.LoadIncrementalHFiles: Trying to load hfile=hdfs://hadoop101:9000/usIDX_HFILES/MY_INDEX/info/6b69a7babd4e4c629b6bee988cf15c5d first=water\x001005 last=watermelon\x001006
2019-10-10 15:04:02,136 INFO [main] index.IndexToolUtil: Updated the status of the index MY_INDEX to ACTIVE

这个任务不会因为客户端给关闭而结束,是在后台运行。你可以在指定的文件ASYNC_IDX_HFILES中找到最终实行的结果。

在Hbase中查看:

   测试:

综上三种提升效率查询方式:

1) CREATE INDEX my_index ON my_table (v1) INCLUDE (v2)
2) SELECT /*+ INDEX(my_table my_index) */ v2 FROM my_table WHERE v1 = 'foo'
3) CREATE LOCAL INDEX my_index ON my_table (v1)

如何删除索引

use "test"再删索引 drop index "my_index" on "student"不行,必须前边加schema,默认的不需要加

DROP INDEX "my_index" ON "test"."student"
用phoenix只是用hbase自身实现了hbase自己的二级索引,用hbase自己rowkey查询的特点来设计索引数据的rowkey,性能方面完全要靠一次检索索引数据的数据量大小了。

Phoenix基本优化方法

索引性能调优

phoenix中添加二级索引的更多相关文章

  1. Phoenix系列:二级索引(1)

    Phoenix使用HBase作为后端存储,对于HBase来说,我们通常使用字典序的RowKey来快速访问数据,除此之外,也可以使用自定义的Filter来搜索数据,但是它是基于全表扫描的.而Phoeni ...

  2. [Phoenix] 五、二级索引

    摘要: 目前HBASE只有基于字典序的主键索引,对于非主键过滤条件的查询都会变成扫全表操作,为了解决这个问题Phoenix引入了二级索引功能.然而此二级索引又有别于传统关系型数据库的二级索引,本文将详 ...

  3. Phoenix系列:二级索引(2)

    上一篇介绍了Phoenix基于HBase的二级索引的基本知识,这一篇介绍一下和索引相关的一致性和优化相关内容. 一致性的保证 Phoenix客户端在成功提交一个操作并且得到成功响应后,就代表你所做的操 ...

  4. 通过phoenix在hbase上创建二级索引,Secondary Indexing

    环境描述: 操作系统版本:CentOS release 6.5 (Final) 内核版本:2.6.32-431.el6.x86_64 phoenix版本:phoenix-4.10.0 hbase版本: ...

  5. Phoenix二级索引(Secondary Indexing)的使用

    摘要 HBase只提供了一个基于字典排序的主键索引,在查询中你只能通过行键查询或扫描全表来获取数据,使用Phoenix提供的二级索引,可以避免在查询数据时全表扫描,提高查过性能,提升查询效率   测试 ...

  6. 利用Phoenix为HBase创建二级索引

    为什么需要Secondary Index 对于Hbase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询.如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄. ...

  7. Phoenix综述(史上最全Phoenix中文文档)

    个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...

  8. HBase 二级索引与Join

    二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...

  9. HBase二级索引与Join

    转自:http://www.oschina.net/question/12_32573 二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也 ...

随机推荐

  1. 利用 OpenCC 工具进行文字的简繁转换

    前言 近日在公司遇到一个需求,因为准备要推出海外版产品,所以需要将所有的简体文字转换为繁体文字.一开始是改了表面的文字,但是后面发现很多提示语也需要去改,所以找了一个工具去对所有 .m 文件进行批量文 ...

  2. Andriod安卓下开发UHF读写器

    随着在Andriod设备上使用UHF读写器变得越来越广泛,友我科技独立研发了UHF读写器的android开发包,使用此开发包,工程师只需在工程中导入jar包,使用java语言就可以轻松的开发出Andr ...

  3. centos7设置静态ip-修改配置文件方式

    修改IP地址为静态地址需要修改配置文件,首先打开配置文件,在控制台输入cd /etc/sysconfig/network-scripts 输入ifconfig,这样就可以看到你的ip地址等信息了. v ...

  4. V4 Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup (Doc ID 2471245.1)

    V4 Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup (Doc ID 2471245. ...

  5. 微信 PC HOOK

    一.概述 Web端有开源代码,但新用户登录不了 PC端也有开源代码,新老用户都能登录 市场上已有的产品:发卡机器人.多群转发机器人.营销管理机器人 基本的功能:收发消息,加人加群,收账抢红包 二.原理 ...

  6. mybatis入门视频总结

    1.基础知识 2. 原生态jdbc问题总结 3.mybatis是什么 4.工程结构 5.SqlMapConfig.xml文件 6.sqlmap 包下新建user.xml文件(namespace,par ...

  7. [译]Vulkan教程(29)组合的Image采样器

    [译]Vulkan教程(29)组合的Image采样器 Combined image sampler 组合的image采样器 Introduction 入门 We looked at descripto ...

  8. oracle相邻表记录交换(单双两两交换)

    在博客园的博问中看到了一个这样的提问:一个表中有id和name两个字段,id是连续非空不重复的,想要交换相邻表记录的name值(单双两两交换). 另外,如果最后的单独行没有对应的下一行匹配记录的话,就 ...

  9. 如何关闭jdk自动更新提示

    缘由 国庆将电脑重装了一下,jdk自然也就重装了,一开机总是提示我更新,索性就将他关掉. 解决办法 右键这个图标,点击属性. 将自动更新取消勾选.

  10. (四十四)c#Winform自定义控件-水波-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...