HBase之八--(2):HBase二级索引之Phoenix
1. 介绍
Phoenix 是 Salesforce.com 开源的一个 Java 中间件,可以让开发者在Apache HBase 上执行 SQL 查询。Phoenix完全使用Java编写,代码位于 GitHub 上,并且提供了一个客户端可嵌入的 JDBC 驱动。
根据项目所述,Phoenix 被 Salesforce.com 内部使用,对于简单的低延迟查询,其量级为毫秒;对于百万级别的行数来说,其量级为秒。Phoenix 并不是像 HBase 那样用于 map-reduce job 的,而是通过标准化的语言来访问 HBase 数据的。
Phoenix 为 HBase 提供 SQL 的查询接口,它在客户端解析SQL语句,然后转换为 HBase native 的客户端语言,并行执行查询然后生成标准的JDBC结果集。
Phoenix 最值得关注的一些特性 有:
- 嵌入式的JDBC驱动,实现了大部分的java.sql接口,包括元数据API
- 可以通过多部行键或是键/值单元对列进行建模
- 完善的查询支持,可以使用多个谓词以及优化的扫描键
- DDL支持:通过CREATE TABLE、DROP TABLE及ALTER TABLE来添加/删除列
- 版本化的模式仓库:当写入数据时,快照查询会使用恰当的模式
- DML支持:用于逐行插入的UPSERT VALUES、用于相同或不同表之间大量数据传输的UPSERT SELECT、用于删除行的DELETE
- 通过客户端的批处理实现的有限的事务支持
- 表连接 和二级索引
- 紧跟ANSI SQL标准
SQL Support 可以参考 language reference,Phoenix 当前不支持:
- 完全的事物支持
- 嵌套查询
- 关联操作: Union、Intersect、Minus
- 各种各样的内建函数。可以参考这篇文章添加自定义函数。
2. 安装
HBase 兼容性:
- Phoenix 2.x - HBase 0.94.x
- Phoenix 3.x - HBase 0.94.x
- Phoenix 4.x - HBase 0.98.1+
安装已经编译好的 phoenix :
- 下载对应你 hbase 版本的 phoenix-[version]-incubating.tar 并解压,下载地址:http://www.apache.org/dyn/closer.cgi/incubator/phoenix/。
- 添加 phoenix-core-[version]-incubating.jar 到 HBase region server 的 classpath 中,或者直接将其加载到 hbase 的 lib 目录
- 重启 HBase region server
- 添加 phoenix-[version]-incubating-client.jar 到 hadoop 客户端的 lib 目录。
3. 使用
3.1 JDBC
Java 客户端连接 jdbc 代码如下:
Connection conn = DriverManager.getConnection("jdbc:phoenix:server1,server2:2181");
jdbc 的 url 类似为 jdbc:phoenix [ :<zookeeper quorum> [ :<port number> ] [ :<root node> ] ]
,需要引用三个参数:hbase.zookeeper.quorum
、hbase.zookeeper.property.clientPort
、and zookeeper.znode.parent
,这些参数可以缺省不填而在 hbase-site.xml 中定义。
3.2 sqlline 命令行
进入解压后的 bin 目录,执行下面命令可以进入一个命令行模式:
$ sqlline.py localhost
进入之后,可以查看表和列:
sqlline version 1.1.2
0: jdbc:phoenix:localhost> !tables
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+--------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION | INDEX_ |
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+--------+
| null | SYSTEM | CATALOG | SYSTEM TABLE | null | null | null | null | null |
| null | SYSTEM | SEQUENCE | SYSTEM TABLE | null | null | null | null | null |
+------------+-------------+------------+------------+------------+------------+---------------------------+----------------+--------+
0: jdbc:phoenix:localhost> !columns sequence
+------------+-------------+------------+-------------+------------+------------+-------------+---------------+----------------+-----+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | DATA_TYPE | TYPE_NAME | COLUMN_SIZE | BUFFER_LENGTH | DECIMAL_DIGITS | NUM |
+------------+-------------+------------+-------------+------------+------------+-------------+---------------+----------------+-----+
| null | SYSTEM | SEQUENCE | TENANT_ID | 12 | VARCHAR | null | null | null | nul |
+------------+-------------+------------+-------------+------------+------------+-------------+---------------+----------------+-----+
0: jdbc:phoenix:localhost>
从上面可以看出来,phoenix 中存在两个系统表:
- SYSTEM.CATALOG
- SYSTEM.SEQUENCE
通过 HBase Master 的 web 页面,可以看到上面两个表的建表语句,例如:
'SYSTEM.CATALOG', {METHOD => 'table_att', coprocessor$1 => '|org.apache.phoenix.coprocessor.ScanRegionObserver|1|', coprocessor$2 => '|org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver|1|', coprocessor$3 => '|org.apache.phoenix.coprocessor.GroupedAggregateRegionObserver|1|', coprocessor$4 => '|org.apache.phoenix.coprocessor.ServerCachingEndpointImpl|1|', coprocessor$5 => '|org.apache.phoenix.coprocessor.MetaDataEndpointImpl|1|', coprocessor$6 => '|org.apache.phoenix.coprocessor.MetaDataRegionObserver|2|', CONFIG => {'SPLIT_POLICY' => 'org.apache.phoenix.schema.MetaDataSplitPolicy', 'UpgradeTo30' => 'true'}}, {NAME => '0', DATA_BLOCK_ENCODING => 'FAST_DIFF', VERSIONS => '1000', KEEP_DELETED_CELLS => 'true'}
可以用下面脚本执行一个 sql 语句:
$ ./sqlline.py localhost ../examples/STOCK_SYMBOL.sql
执行结果如下:
1/4 /*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-- creates stock table with single row
CREATE TABLE IF NOT EXISTS STOCK_SYMBOL (SYMBOL VARCHAR NOT NULL PRIMARY KEY, COMPANY VARCHAR);
No rows affected (1.714 seconds)
2/4 UPSERT INTO STOCK_SYMBOL VALUES ('CRM','SalesForce.com');
1 row affected (0.035 seconds)
3/4 SELECT * FROM STOCK_SYMBOL;
+------------+------------+
| SYMBOL | COMPANY |
+------------+------------+
| CRM | SalesForce.com |
+------------+------------+
1 row selected (0.117 seconds)
4/4
Closing: org.apache.phoenix.jdbc.PhoenixConnection
sqlline version 1.1.2
../examples/STOCK_SYMBOL.sql 文件主要包括三个 sql 语句:
CREATE TABLE IF NOT EXISTS STOCK_SYMBOL (SYMBOL VARCHAR NOT NULL PRIMARY KEY, COMPANY VARCHAR);
UPSERT INTO STOCK_SYMBOL VALUES ('CRM','SalesForce.com');
SELECT * FROM STOCK_SYMBOL;
- 第一个语句创建表
- 第二个语句插入一条记录
- 第三个语句查询数据
在 hbase shell 中查看存在的表:
hbase(main):001:0> list
TABLE
STOCK_SYMBOL
SYSTEM.CATALOG
SYSTEM.SEQUENCE
查看 STOCK_SYMBOL
表中数据:
hbase(main):004:0> scan 'STOCK_SYMBOL'
ROW COLUMN+CELL
CRM column=0:COMPANY, timestamp=1406535419510, value=SalesForce.com
CRM column=0:_0, timestamp=1406535419510, value=
1 row(s) in 0.0210 seconds
可以看到插入了一行记录,rowkey 为 CRM,而列族名称为 0 ,存在两列,一列为指定的COMPANY,另一列为 phoenix 插入的 _0
然后,也可以通过 sqlline.py 来查看数据:
0: jdbc:phoenix:localhost> select * from STOCK_SYMBOL;
+------------+------------+
| SYMBOL | COMPANY |
+------------+------------+
| CRM | SalesForce.com |
+------------+------------+
1 row selected (0.144 seconds)
注意到:从上面查询看到的就只有两列,没有看到 _0
这一列。
从上可以知道,Phoenix 是构建在 HBase 之上的 SQL 中间层,向 HBase 发送标准 sql 语句,对 HBase 进行操作。
3.3 加载数据
你可以使用 bin/psql.py 来加载 CSV 数据 或者执行 SQL 脚本,例如:
$ ./psql.py localhost ../examples/WEB_STAT.sql ../examples/WEB_STAT.csv ../examples/WEB_STAT_QUERIES.sql
其输出结果为:
no rows upserted
Time: 1.528 sec(s)
csv columns from database.
CSV Upsert complete. 39 rows upserted
Time: 0.122 sec(s)
DOMAIN AVERAGE_CPU_USAGE AVERAGE_DB_USAGE
---------- ----------------- ----------------
Salesforce.com 260.727 257.636
Google.com 212.875 213.75
Apple.com 114.111 119.556
Time: 0.062 sec(s)
DAY TOTAL_CPU_USAGE MIN_CPU_USAGE MAX_CPU_USAGE
------------------- --------------- ------------- -------------
2013-01-01 00:00:00 35 35 35
2013-01-02 00:00:00 150 25 125
2013-01-03 00:00:00 88 88 88
2013-01-04 00:00:00 26 3 23
2013-01-05 00:00:00 550 75 475
2013-01-06 00:00:00 12 12 12
2013-01-08 00:00:00 345 345 345
2013-01-09 00:00:00 390 35 355
2013-01-10 00:00:00 345 345 345
2013-01-11 00:00:00 335 335 335
2013-01-12 00:00:00 5 5 5
2013-01-13 00:00:00 355 355 355
2013-01-14 00:00:00 5 5 5
2013-01-15 00:00:00 720 65 655
2013-01-16 00:00:00 785 785 785
2013-01-17 00:00:00 1590 355 1235
Time: 0.045 sec(s)
HOST TOTAL_ACTIVE_VISITORS
---- ---------------------
EU 150
NA 1
Time: 0.058 sec(s)
WEB_STAT.sql 中 sql 语句为:
CREATE TABLE IF NOT EXISTS WEB_STAT (
HOST CHAR(2) NOT NULL,
DOMAIN VARCHAR NOT NULL,
FEATURE VARCHAR NOT NULL,
DATE DATE NOT NULL,
USAGE.CORE BIGINT, -- 指定了列族: USAGE
USAGE.DB BIGINT, -- 指定了列族: USAGE
STATS.ACTIVE_VISITOR INTEGER , --指定了列族: STATS
CONSTRAINT PK PRIMARY KEY (HOST, DOMAIN, FEATURE, DATE)
);
从 sql 语句上可以看出来,HOST、DOMAIN、FEATURE、DATE 这四列前面并没有指定列族,并且通过约束设置这四列组成 hbase 的 rowkey,其他三列都指定了列族。
通过 sqlline.py 查询第一条记录:
0: jdbc:phoenix:localhost> select * from WEB_STAT limit 1;
+------+------------+------------+---------------------+------------+------------+----------------+
| HOST | DOMAIN | FEATURE | DATE | CORE | DB | ACTIVE_VISITOR |
+------+------------+------------+---------------------+------------+------------+----------------+
| EU | Apple.com | Mac | 2013-01-01 | 35 | 22 | 34 |
+------+------------+------------+---------------------+------------+------------+----------------+
而通过 hbase shell 查询 WEB_STAT
表第一条记录:
EUApple.com\x00Mac\x00\x80\x00\x0 column=STATS:ACTIVE_VISITOR, timestamp=1406535785946, value=\x80\x00\x00"
1;\xF3\xA04\xC8
EUApple.com\x00Mac\x00\x80\x00\x0 column=USAGE:CORE, timestamp=1406535785946, value=\x80\x00\x00\x00\x00\x00\x00#
1;\xF3\xA04\xC8
EUApple.com\x00Mac\x00\x80\x00\x0 column=USAGE:DB, timestamp=1406535785946, value=\x80\x00\x00\x00\x00\x00\x00\x16
1;\xF3\xA04\xC8
EUApple.com\x00Mac\x00\x80\x00\x0 column=USAGE:_0, timestamp=1406535785946, value=
1;\xF3\xA04\xC8
通过上面对比知道:
- phoenix 对用户屏蔽了 rowkey 的设计细节
- USAGE 列族中存在一列为
_0
,而 STATS 列族中却没有,这是为什么? - Phoenix 把 rowkey 内化为 table 的 PRIMARY KEY 处理,由 HOST、DOMAIN、FEATURE、DATE 这四列拼接在一起,组成了 rowkey
其他可选的加载数据的方法:
- 使用 map-reduce based CSV loader 加载更大的数据
- 映射一个存在的 HBase 表到 Phoenix 表 以及使用 UPSERT SELECT 来创建一个新表
- 使用 UPSERT VALUES 插入记录
3.4 映射到存在的 HBase 表
创建一张hbase表:
create 't1', 'f'
put 't1', "row1", 'f:q', 1
put 't1', "row2", 'f:q', 2
put 't1', "row3", 'f:q', 3
put 't1', "row4", 'f:q', 4
put 't1', "row5", 'f:q', 5
在phoenix建一张同样的表:
./sqlline.py localhost
CREATE TABLE IF NOT EXISTS "t1" (
row VARCHAR NOT NULL,
"f"."q" VARCHAR
CONSTRAINT PK PRIMARY KEY (row)
);
t1、f、q 需要用双引号括起来,原因主要是大小写的问题,参考 phoenix 的 wiki。
注意:
在这里, phoenix 会修改 table 的 Descriptor,然后添加 coprocessor,所以会先 disable,在 modify,最后 enable 表。
接下来就可以查询了:
0: jdbc:phoenix:localhost> select * from "t1";
+------------+------------+
| ROW | q |
+------------+------------+
| row1 | 1 |
| row2 | 2 |
| row3 | 3 |
| row4 | 4 |
| row5 | 5 |
+------------+------------+
5 rows selected (0.101 seconds)
0: jdbc:phoenix:localhost> select count(1) from "t1";
+------------+
| COUNT(1) |
+------------+
| 5 |
+------------+
1 row selected (0.068 seconds)
4. 总结
这篇文章主要是介绍了什么是 Phoenix 、如何安装以及他的一些特性,然后介绍了他的使用方法,主要包括命令行使用、加载数据以及如何映射存在的 HBase 表,通过该篇文章对 Phoenix 有了一个初步的认识。
HBase之八--(2):HBase二级索引之Phoenix的更多相关文章
- phoenix连接hbase数据库,创建二级索引报错:Error: org.apache.phoenix.exception.PhoenixIOException: Failed after attempts=36, exceptions: Tue Mar 06 10:32:02 CST 2018, null, java.net.SocketTimeoutException: callTimeou
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- hbase基于solr配置二级索引
一.概述 Hbase适用于大表的存储,通过单一的RowKey查询虽然能快速查询,但是对于复杂查询,尤其分页.查询总数等,实现方案浪费计算资源,所以可以针对hbase数据创建二级索引(Hbase Sec ...
- HBase二级索引、读写流程
HBase二级索引.读写流程 一.HBse二级索引方案 1.1 基于Coprocessor方案 1.2 Phoenix二级索引特点 1.3 Phoenix 二级索引方案 二.HBase读写流程 2.1 ...
- hbase构建二级索引解决方案
关注公众号:大数据技术派,回复"资料",领取1024G资料. 1 为什么需要二级索引 HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索.假设我们相对Hbas ...
- [转]HBASE 二级索引
1.二级索引的核心思想是什么?2.二级索引由谁来管理?3.在主表中插入某条数据后,hbase如何将索引列写到索引表中去?4.scan查询的时候,coprocessor钩子的作用是什么?5.在split ...
- Hbase 学习(九) 华为二级索引(原理)
这个是华为的二级索引方案,已经开放源代码了,下面是网上的一篇讲解原理的帖子,发出来和大家共享一下. 经过本人认真阅读了一下代码,发现这个源码仅供参考,想要集成到原有的集群当中是有点儿难度的,它对hba ...
- HBase 二级索引与Coprocessor协处理器
Coprocessor简介 (1)实现目的 HBase无法轻易建立“二级索引”: 执行求和.计数.排序等操作比较困难,必须通过MapReduce/Spark实现,对于简单的统计或聚合计算时,可能会因为 ...
- Lily HBase Indexer同步HBase二级索引到Solr丢失数据的问题分析
一.问题描述二.分析步骤2.1 查看日志2.2 修改Solr的硬提交2.3 寻求StackOverFlow帮助2.4 修改了read-row="never"后,丢失部分字段2.5 ...
- HBase的二级索引
使用HBase存储中国好声音数据的案例,业务描述如下: 为了能高效的查询到我们需要的数据,我们在RowKey的设计上下了不少功夫,因为过滤RowKey或者根据RowKey查询数据的效率是最高的,我们的 ...
随机推荐
- 【linux】VirtualBox-“please use a kernel appropriate for your cpu”
This kernel requires the following features not present on the CPU:paeUnable to boot – please use a ...
- C++设计模式之-模板模式
模板方法模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对模板方法模式是这样说的:定义一个操作中的算法骨架,而将一些步骤延迟到子类中.TemplateMethod使得子类可以不 ...
- Shell学习笔记——算数运算与条件测试
算数运算 1. 使用let命令 #!/sbin/bash var1=2 var2=3 let sum=var1+var2 echo $sum 使用let命令式,变量前不需要加$号 只用于整数运算,不适 ...
- c# DataTable 数据集处理DataTableHandler
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- charles抓包unknow
如果能抓到包,可是解析不出请求,那一定是证书问题,注意以下几点: 1.设备安装证书,注意要抓包的每一个设备都要安装证书,每一个设备! 2.pc端也要安装证书 如果以上两点都做到一定可以解析https请 ...
- React之前端路由
通过之前的博客介绍,对于react,我们已经可以写单个组件.复合组件/单个页面了,接下来就是实现页面的跳转了,这个时候,我们就需要前端路由了. 一.react-router-dom 安装这个依赖,th ...
- Ubuntu 16.04安装QQ国际版
QQ国际版wine-qqintl的下载链接:http://pan.baidu.com/s/1jIwKdXs sudo apt install libgtk2.0-0:i386 sudo apt in ...
- java运行jar命令提示没有主清单属性和找不到主类
推荐一个java运行jar命令提示没有主清单属性的百度经验的链接:https://jingyan.baidu.com/article/db55b60990f6084ba30a2fb8.html jav ...
- BZOJ2946 Poi2000 公共串 【后缀自动机】
Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输出结果 Input 文件的第一行是整数 n,1<=n& ...
- 《DSP using MATLAB》示例Example 8.7
%% ------------------------------------------------------------------------ %% Output Info about thi ...