利用phoenix建立二级索引查询hbase

phoenix的简单介绍

 phoenix,中文译为“凤凰”,很美的名字。Phoenix是由saleforce.com开源的一个项目,后又捐给了Apache基金会。它相当于一个Java中间件,提供jdbc连接,操作hbase数据表。Phoenix是一个HBase的开源SQL引擎。你可以使用标准的JDBC API代替HBase客户端API来创建表,插入数据,查询你的HBase数据。Phoenix的团队用了一句话概括Phoenix:"We put the SQL back in NoSQL" 意思是:我们把SQL又放回NoSQL去了!这边说的NoSQL专指HBase,意思是可以用SQL语句来查询Hbase,你可能会说:“Hive和Impala也可以啊!”。但是Hive和Impala还可以查询文本文件,Phoenix的特点就是,它只能查Hbase,别的类型都不支持!但是也因为这种专一的态度,让Phoenix在Hbase上查询的性能超过了Hive和Impala!Phoenix是构建在HBase之上的SQL引擎。你也许会存在“Phoenix是否会降低HBase的效率?”或者“Phoenix效率是否很低?”这样的疑虑,事实上并不会,Phoenix通过以下方式实现了比你自己手写的方式相同或者可能是更好的性能(更不用说可以少写了很多代码):
编译你的SQL查询为原生HBase的scan语句。检测scan语句最佳的开始和结束的key。精心编排你的scan语句让他们并行执行。推送你的WHERE子句的谓词到服务端过滤器处理。执行聚合查询通过服务端钩子(称为协同处理器)。 除此之外,Phoenix还做了一些有趣的增强功能来更多地优化性能:
实现了二级索引来提升非主键字段查询的性能。统计相关数据来提高并行化水平,并帮助选择最佳优化方案。跳过扫描过滤器来优化IN,LIKE,OR查询。优化主键的来均匀分布写压力。
我相信,二级索引这个特性应该是大部分用户引入Phoenix主要考虑的因素之一。HBase因其历史原因只支持rowkey索引,当使用rowkey来查询数据时可以很快定位到数据位置。现实中,业务查询需求条件往往比较复杂,带有多个查询字段组合,如果用HBase查的话,只能全表扫描进行过滤,效率很低。而Phoenix支持除rowkey外的其它字段的索引创建,即二级索引,查询效率可大幅提升。

多的不说了:开搞,我是在测试环境搞的。
1、首先找到自己服务器上phoenix的安装目录,由于不是我装的,我只能locate一下:

locate phoenix

然后出来一堆目录找到跟我这个目录相似的:
/mnt/cdh/cloudera/parcels/CLABS_PHOENIX-4.7.0-1.clabs_phoenix1.3.0.p0.000/lib/phoenix

2、启动phoenix

/mnt/cdh/cloudera/parcels/CLABS_PHOENIX-4.7.0-1.clabs_phoenix1.3.0.p0.000/lib/phoenix/
bin/sqlline.py 10.1.47.14:2181

3、启动hbase

hbase shell

4、在hbase里面创建一个表

create 'RCM_TEST2','cf1'

5、在phoenix中创建RCM_TEST2的映射表

create table if not exists "RCM_TEST2"
(
"cf1"."dateid" VARCHAR(100),
"riskid" VARCHAR(100),
"saledeptid" VARCHAR(100),
"cf1"."salechnlcode" VARCHAR(100),
"cf1"."payintvcode" VARCHAR(100),
"cf1"."paytermcode" VARCHAR(100),
"cf1"."mainriskflag" VARCHAR(100),
"cf1"."mainriskid" VARCHAR(100),
"cf1"."mainpayintvcode" VARCHAR(100),
"cf1"."mainpaytermcode" VARCHAR(100),
"cf1"."employyear" VARCHAR(100),
"cf1"."agentgradeid" VARCHAR(100),
"cf1"."agentcode" VARCHAR(100),
"cf1"."agentcomid" VARCHAR(100),
"cf1"."contplancode" VARCHAR(100),
"cf1"."inputtype" VARCHAR(100),
"cf1"."year_cardprem" VARCHAR(100),
"cf1"."year_yaddition_prem" VARCHAR(100),
"cf1"."year_resurrder_prem" VARCHAR(100),
"cf1"."year_yaddition_prem_auto" VARCHAR(100),
"cf1"."year_laddition_prem" VARCHAR(100),
"cf1"."year_addition_prem" VARCHAR(100),
"cf1"."year_health_prem" VARCHAR(100),
"cf1"."year_intiv_prem_three" VARCHAR(100),
"cf1"."year_intiv_prem_3_5" VARCHAR(100),
"cf1"."year_intiv_prem_5_9" VARCHAR(100),
"cf1"."year_intiv_prem_ten" VARCHAR(100),
"cf1"."year_intiv_prem_main" VARCHAR(100),
"cf1"."year_intiv_prem" VARCHAR(100),
"cf1"."year_valueprem" VARCHAR(100),
"cf1"."year_valueprem_resur" VARCHAR(100),
"cf1"."year_renewpol_prem" VARCHAR(100),
"cf1"."year_premium_sum" VARCHAR(100),
"cf1"."year_addition_prem_resur" VARCHAR(100),
"cf1"."year_intiv_prem_ten_resur" VARCHAR(100),
"cf1"."year_health_prem_resur" VARCHAR(100),
"cf1"."year_fi_health_prem" VARCHAR(100),
"cf1"."year_yaddition_prem_resur" VARCHAR(100),
"cf1"."year_laddition_prem_resur" VARCHAR(100),
"cf1"."year_fi_health_prem_resur" VARCHAR(100),
"cf1"."year_laddition_aseprem" VARCHAR(100),
"cf1"."year_cardrenew_prem_auto" VARCHAR(100),
"cf1"."year_cardprem_value" VARCHAR(100),
"cf1"."year_intiv_valueprem_main" VARCHAR(100),
"cf1"."year_laddition_valueprem" VARCHAR(100),
"cf1"."year_yaddition_value" VARCHAR(100),
"cf1"."year_policy_value" VARCHAR(100),
"cf1"."year_yaddition_prem_aut_value" VARCHAR(100),
"cf1"."feeopertypefalg" VARCHAR(100),
"cf1"."loaddate" VARCHAR(100)
CONSTRAINT PK PRIMARY KEY ("riskid","saledeptid"));

这里我设置了复合主键riskid,saledeptid,注意作为主键的字段建表的时候不要写列族名字。

6、为了查询更快,我们对两个主键建立二级索引。

create index "RCM_TEST2_INDEX2" on "RCM_TEST2"("riskid","saledeptid");

7、加载数据到hbase
利用phoenix的PSQL加载数据文件到表中,由于建立了二级索引,这种加载方式非常慢,建议编写MR程序。

/mnt/cdh/cloudera/parcels/CLABS_PHOENIX-4.7.0-1.clabs_phoenix1.3.0.p0.000/lib/phoenix/bin/psql.py -t RCM_TEST2 -d'^' 10.1.47.14:2181  /home/sma_admin/rcm2.csv

这里-d后面是自定义的分隔符,由于我的数据文件rcm2.csv里面字段的分隔符是^,
所以这里采用^符号分隔。-t后面是表名字,phoenix对大小写比较敏感,采用大写没有问题,如果必须小写,要加特殊符号。

8、数据条数查看168168条,16万多条。

9、简单测试

不走索引的查询,执行如下sql,耗时4.832秒:

select "saledeptid","paytermcode" from "RCM_TEST2" WHERE "mainriskid"='584';


我们来查看一下这个sql的执行过程,应为where后面字段没有建立二级索引,所以查询较慢,是全表sacn的。

explain select "saledeptid","paytermcode" from "RCM_TEST2" WHERE "mainriskid"='584';


走索引的查询,执行如下sql,耗时0.148秒:

select "saledeptid","paytermcode" from "RCM_TEST2" WHERE "riskid"='584';


我们来查看一下这个sql的执行过程,应为where后面字段建立二级索引,所以查询块,是通过索引进行区间scan的。

explain select "saledeptid","paytermcode" from "RCM_TEST2" WHERE "riskid"='584';


10、由于我么建立了两个字段,按照资料上说hbase中RCM_TEST2这个表中的rowkey应该是两个主键拼接起来,我查看了一下,没太看懂,主键如下所示。

 108\x001024                column=cf1:_0, timestamp=1577258805546, value=x108\x001024               column=cf1:agentcode, timestamp=1577258805546, value=23240220108\x001024               column=cf1:agentcomid, timestamp=1577258805546, value=0108\x001024               column=cf1:agentgradeid, timestamp=1577258805546, value=8108\x001024               column=cf1:dateid, timestamp=1577258805546, value=20190331108\x001024               column=cf1:employyear, timestamp=1577258805546, value=17108\x001024               column=cf1:feeopertypefalg, timestamp=1577258805546, value=7108\x001024               column=cf1:loaddate, timestamp=1577258805546, value=06/12/2019 01:01:02108\x001024               column=cf1:mainpayintvcode, timestamp=1577258805546, value=12108\x001024               column=cf1:mainpaytermcode, timestamp=1577258805546, value=20108\x001024               column=cf1:mainriskflag, timestamp=1577258805546, value=1108\x001024               column=cf1:mainriskid, timestamp=1577258805546, value=244108\x001024               column=cf1:payintvcode, timestamp=1577258805546, value=0108\x001024               column=cf1:paytermcode, timestamp=1577258805546, value=0108\x001024               column=cf1:salechnlcode, timestamp=1577258805546, value=1108\x001024               column=cf1:year_addition_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_addition_prem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_cardprem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_cardprem_value, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_fi_health_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_fi_health_prem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_health_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_health_prem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_3_5, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_5_9, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_main, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_ten, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_ten_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_prem_three, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_intiv_valueprem_main, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_laddition_aseprem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_laddition_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_laddition_prem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_laddition_valueprem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_policy_value, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_premium_sum, timestamp=1577258805546, value=260.00108\x001024               column=cf1:year_renewpol_prem, timestamp=1577258805546, value=260.00108\x001024               column=cf1:year_resurrder_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_valueprem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_valueprem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_yaddition_prem, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_yaddition_prem_aut_value, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_yaddition_prem_auto, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_yaddition_prem_resur, timestamp=1577258805546, value=0.00108\x001024               column=cf1:year_yaddition_value, timestamp=1577258805546, value=0.00

如上是一条完整数据,rowke是108\x001024 ,这个是什么意思?看懂的人评论一下。

利用phoenix建立二级索引查询hbase,大神请无视相关推荐

  1. HBase 集成 Phoenix 构建二级索引实践

    Phoenix 在 HBase 生态系统中占据了非常重要的地位,本文主要包括以下几方面内容: Phoenix 介绍 CDH HBase 集成 Phoenix 使用 Phoenix 创建 HBase 二 ...

  2. 服务器主机GHOST装系统,大神请绕道!科普电脑装系统最基本的两种方式,萌新千万不要错过...

    原标题:大神请绕道!科普电脑装系统最基本的两种方式,萌新千万不要错过 Hello大家好,我是兼容机之家的小牛! 电脑装系统用GHOST好,还是原装版本好?这是很多小伙伴疑惑的问题,那么让我们来具体分析 ...

  3. Phoenix创建二级索引

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

  4. 怀旧服服务器在线人数查询,民间大神用土方法估算出魔兽怀旧服在线人数 震动了官方...

    随着<魔兽怀旧服>的正式发布,许多老玩家都在第一时间聚集到当初所怀念的"世界"当中.即便官方在开服前紧急新增了几组服务器,也难以抵挡住玩家所带来的热情,排队是正常的事情 ...

  5. java大神请出来_求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因。...

    求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因.classPlate{publicPlate(){System.out.println("inPlateconstru ...

  6. Phoenix: 验证二级索引和主表数据是否一致

    Phoenix 4.12之后才有这个工具, 就是跑一个MapReduce对比主表和数据表是否一致. 找到的不一致的行写入到文件或者 PHOENIX_INDEX_SCRUTINY 表中. 命令如下: h ...

  7. 【Solr - HBase二级索引 —— Lily HBase Indexer】

    开门见山,直接上图,这图瞧着熟悉吧~哈哈哈 Reference https://blog.csdn.net/cafebar123/article/details/79405029

  8. 大楼通信综合布线系统_某办公大楼综合布线系统设计实例,小白可以借鉴一下,大神请绕路...

    xxx办公大楼综合布线系统是一个包括内部数据语音通信.外线电话线路接入管理系统.办公用强电电气配电系统.电缆电视系统等内部的复合布线系统,在会议室还有一个小型的供音响系统设备使用的专用布线系统. 各子 ...

  9. linux首次安装mysql密码是多少,Linux小白,初次安装MySQL,大神请绕路

    在Linux上安装MySQL肯定不止一种方法,但是作为一名Linux小白,至少要知道一种安装方法,这里就记录一下小白的安装记录. 本系统的版本信息如图所示 第一,给你一台Linux服务器,要做的第一件 ...

最新文章

  1. python起步输入-Python 起飞系列————起步(一)
  2. oracle中sql命令分为几类,常用的SQL命令和ORACLE命令对比
  3. tableau三轴合并_《Tableau数据可视化实战》——1.12节合并不同数据源-阿里云开发者社区...
  4. oracle数据库安装提示M,Python第13课:oracle数据库的安装
  5. eff java_牛津大学为国家图书馆周开幕,EFF组织大学活动家,等等
  6. java aqs原理_Java并发之AQS详解
  7. Flutter TextField设置默认值默认值和光标位置
  8. 常见脱壳与反编译工具
  9. android大智慧安装目录,大智慧数据文件目录解读
  10. 阿里巴巴Java开发手册(原文地址)
  11. JAVA之父----詹姆斯.高斯林
  12. 【OSS】使用Element实现图片上传到OSS
  13. Jmeter实战:零基础也能看懂的性能测试
  14. Swagger怎么没有你要的model?一个注解帮你解决
  15. UE4使用OpenCV插件调用电脑摄像头
  16. 写一个强化学习训练的gym环境
  17. 神经网络仿真逻辑回归,神经网络仿真实验matlab
  18. Firefly AIO-3399ProC ARM开发板环境配置过程
  19. 计算机应用基础 周凌,计算机基础毕业论文范文
  20. 策略模式代替if-else

热门文章

  1. Java元数据和元编程的胡诌诌
  2. Tp5框架中的where条件的使用
  3. 【计量经济学导论】13. 虚拟变量与双重差分
  4. XMind 8 Pro 专业版激活 XMind ZEN 思维导图
  5. 淄博职业学院计算机应用技术专业,淄博职业学院计算机应用技术专业2016年在山东文科高考录取最低分数线...
  6. Python的xlrd的get_sheet方法读取Excel文件报错:XLRDError: Can‘t load sheets after releasing resources.
  7. CMakeLists入门
  8. 多屏幕电脑内置屏幕无法调节亮度的解决方法
  9. 核电站安全距离--如果大亚湾核电站泄漏,惠州深圳也会遭受污染?
  10. 使用excel结合线性规划求解Holt-Winters参数