Phoenix 使用说明
Phoenix是什么
Phoenix查询引擎支持使用SQL进行HBase数据的查询,会将SQL查询转换为一个或多个HBase API,协同处理器与自定义过滤器的实现,并编排执行。使用Phoenix进行简单查询,其性能量级是毫秒。
更多的信息可以参考官网:http://phoenix.apache.org/
使用说明
-
准备工作
准备一个内网的ECS,需要和HBase处在同一个网络内。
例如HBase是在经典网络的,那么就准备一个经典网络的ECS,如果HBase是在VPC的,那么就在需要在同一个VPC内的ECS
-
按照下载地址下载 Phoenix 客户端
在这台ECS上下载HBase对应版本的Phoenix客户端,这里以4.12.0-AliHBase-1.1-0.6版本举例
wget http://hbase-opt.oss-cn-hangzhou.aliyuncs.com/ali-phoenix-4.12.0-AliHBase-1.1-0.6.tar.gz
- 解压缩压缩包
tar zxvf ali-phoenix-4.12.0-AliHBase-1.1-0.6.tar.gz
-
在HBase的网络白名单中开启访问节点的IP白名单
查看这台ECS的内网IP
hostname -i
然后把他加到HBase的网络白名单中。加入的方法请参考HBase白名单控制。
-
启动sqlline
在HBase产品的集群详情页面查看ZooKeeper的连接地址,然后使用如下的方式启动。启动命令sqlline.py在bin目录下
./sqlline.py hb-bp19142ir9xxxxxx-001.hbase.rds.aliyuncs.com,hb-bp19142ir9ruxxxxx-002.hbase.rds.aliyuncs.com,hb-bp19142ir9ruxxxxx-004.hbase.rds.aliyuncs.com
界面如果显示出类似
jdbc:xxxx>
这样的一个提示的时候,就表示启动成功了。 -
验证
我们在这个命令行中输入
!tables
如果看到一个表的列表,那么就说明我们配置成功了。可以开始更加深入的使用了。
-
退出
使用quit命令退出Phoenix
!quit
[Phoenix] 六、MR在Ali-Phoenix上的使用
[Phoenix] 七、如何使用自增ID[Phoenix] 八、动态列
Phoenix 中如何使用Spark
Spark相信大家不会陌生,翻开有关大数据的报刊杂志,大家都在讨论Spark.也会有不少公司依靠Spark构建数据仓库。
但我今天介绍的是另一款软件Apache Phoenix.那么它是用来解决什么问题的呢。为什么说它和Spark是绝配的搭档。
作为一个数据仓库,繁琐的数据处理只是其中的一环,这也正是Spark擅长的,但是还有一环大家似乎都不怎么关注,就是数据处理的结果以及数据详单的查询。
现在业内普遍的做法就是将数据处理的结果回吐至传统型关系型数据,以及各种Nosql数据库。而Phoenix属于后者。
回退至传统型关系数据库的数据往往是数据聚合的结果,数量级通常较小,开发人员容易理解并上手,但是缺点就是无法支撑大量的详单数据。
譬如说我们的系统可能支持每天统计用户的PV数量,系统无法提供每个用户浏览行为的清单。不是数据仓库不想做这种功能,而是数量级过于庞大,传统关系型数据库力不能逮。
遇到这种时候人们往往会将目光转向Nosql数据库,比较耳熟能详的就是Apache Hbase ,这种数据库能够支持海量数据的即时查询,即使是PB级别的是数据能够提供非常出色查询效率。
但是Hbase拥有自己的语法与存储结构,普通开发人员往往很难上手。
而我们今天介绍Phoenix则介于关系型数据与Hbase两者之间,它对外提供类似标准SQL的语法,并将Sql语句转为Hbase原生查询语句。
举个列子
CREATE TABLE stats.prod_metrics ( host char(50) not null, created_date date not null,
txn_count bigint CONSTRAINT pk PRIMARY KEY (host, created_date) )
上述SQL建立了一张表,拥有三个字段host,created_date,txn_count.
PRIMARY KEY 由host,created_date两个字段构成,这就相当于Hbase中的主键RowKey.
查询sql:
select * from stats.prod_metrics where host=? and created_date =。
这便相当于Hbase的get操作。
查询sql:
select * from stats.prod_metrics where host=?
如果只查询host那么就相当于RangeScan操作
相信大家都Hbase的GET操作查询效率不会产生质疑,那么Phoenix也是如此。
Phoenix具有如下优点
1.查询效率优秀
由于Phoenix基于Hbase,即使是PB级的数据量,只要建表语句合理,也能在毫秒级别返回结果。笔者曾经在4台regionserver的Hbase集群上进行10亿数据的基于主键的即时查询,效率惊人,0.017s就能够完成即时查询。
2.安装简便
Phoenix只需要将两个JAR包放到各个RegionServer的lib目录下即可,实在方便的不得了。
3.运维轻松
Spark往往搭配HDFS使用,Hbase同样也是基于HDFS,Phoenix更是基于Hbase,针对文件存储层运维人员只要关注HDFS的健康即可。而且HBASE自带的监控页面足以解决90%的问题。
4.与Spark之间无缝对接
Phoenix提供Apache Spark Plugin
该插件可以保证Spark程序可以轻松读取或写入Phoenix数据。
如:
读数据
val df = sqlContext.load(
“org.apache.phoenix.spark”,
Map(“table” -> “TABLE1”, “zkUrl” -> “phoenix-server:2181”)
)
写数据
df.save(“org.apache.phoenix.spark”, SaveMode.Overwrite, Map(“table” -> “OUTPUT_TABLE”,
“zkUrl” -> hbaseConnectionString))
5.支持二级索引
Hbase如果想保证查询效率,那么优秀的主键设计是必不可少的,但是如果某个查询条件所涉及的字段没有集成到主键上就会非常麻烦。
Phoenix的二级索引就可以完美解决这个问题,它会新建一张表用来维护一个二级索引,你可以先去索引表根据字段查询主键,再依靠主键从主表查询数据。
而且插入主表的过程中,会自动添加索引。相对于繁琐的HBASE不知道方便多少。
6.提供标准的JDBC接口
你完全可以使用诸如Mybatis等ORM层工具查询Phoenix.
Spark+Phoenix的配合我想应当是最适合小型BI仓库团队的方案了。
这种方案运维成本不高,只需关注HDFS即可。
学习成本也很低,开发人员其实更加接受这种类SQL查询。
有人可能会提及Greenplum等数据库,其实我不太喜欢这种数据库,过于依赖合理的表结构设计。
可能它既支持数据处理,又支持即时查询,但是数据处理不如Spark灵活方便,即时查询不如Phoenix优秀。而后面两者则是在各自擅长的场景做到了极致。
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索hadoop ,以便于您获取更多的相关知识。
scala-version:2.11.8
spark-version:2.2.0
hbase-version:1.3.1
phoenix-version:4.14.0
1. 添加Maven依赖
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-spark</artifactId>
<version>4.14.0-HBase-1.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
2. Spark 操作 Phoenix
import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}
object Phoenix2Spark {
def main(args: Array[String]): Unit = {
val jdbcPhoenixUrl = "jdbc:phoenix:172.18.18.100:2181"
val tableName = "test"
val conf = new SparkConf().setAppName("phoenix-spark").setMaster("local")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
val df = sqlContext.load("org.apache.phoenix.spark", Map("table"->tableName, "zkUrl"->jdbcPhoenixUrl))
df.save(“org.apache.phoenix.spark”, SaveMode.Overwrite, Map(“table” -> “OUTPUT_TABLE”,
“zkUrl” -> hbaseConnectionString))
df.show()
sc.stop()
}
}