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优秀。而后面两者则是在各自擅长的场景做到了极致。