Phoenix V1.1 分析与测试

1. 文档说明

1.1 编写目的

了解Phoenix的基本功能,应用范围和基本性能。为后续项目应用Phoenix提供参考。

1.2 适用范围

本系统测试报告的预期读者是:HBase&Hive应用、设计、开发、测试人员

1.3 参考资料

Phoenixgithub上的说明及资料:

https://github.com/forcedotcom/phoenix/wiki

http://forcedotcom.github.com/phoenix/index.html

 

1.4 测试目的

主要测试:

Ø Phoenix的环境部署依赖;

Ø Phoenix的可用性及应用范围;

Ø Phoenix&HBaseHive&HBase整合的性能对比;

2. 测试说明

2.1 测试类型

测试类型

测 试 内 容

测 试 目 的

测试方法

功能测试

Phoenix基于JDBC接口

协议的增删改查

核实PhoenixJDBC的实现情况

手工编码测试

性能测试

(粗略)

测试基于主键范围、列值模糊查询及简单MaxMin函数查询性能。

掌握Phoenix的优势与劣势,在合适的环境下充分利用Phoenix优势

手工编码测试

2.2 硬件环境

2.3 软件环境

JAVA版本

1.6.0_33-b04

Hadoop版本

Hadoop 2.0.0-cdh4.1.1

HBase版本

HBase 0.94.2-cdh4.2.0

Hive版本

hive-0.9.0-cdh4.1.1

Phoenix版本

1.0

注:Phoenix必须依赖于JDK1.6 or higher,HBase-0.94.2 or higher

2.4 部署环境

基于以上的软件版本,部署Phoenix非常简单,将phoenix-[version].jar分别拷贝至HBasemaster节点和regionserver节点的lib目录下,重启hbase即可生效。

phoenix-[version]-client.jar拷贝至客户端类路径下即可。

3. 测试结果及分析

3.1测试类型

建表说明:若需采用PhoenixJDBC查询,务必采用Phoenix客户端的建表语句,而HBase自身的建表语句生成的表,在Phoenix里不识别,但是通过Phoenix创建的表,在HBase客户端却可以识别。因此Hive建外部表也必须依赖于Phoenix所建的表。

另外,数据类型也存在差异,HBase自身仅支持字符串,而Phoenix通过额外的编码,可支持比较复杂的数据类。【关于Phoenix,详见本文第5章】

 

建表语句

Phoenix

CREATE TABLE PHOENIXTABLE_TEST 

 id VARCHAR(25)  not null primary key, 

name VARCHAR(255) ,

addr VARCHAR(500),

date TIMESTAMP not null

)  VERSIONS=10

HBase

{NAME => 'PHOENIXTABLE_TEST', coprocessor$4 => 'phoenix.jar|com.salesforce.phoenix.join.HashJoiningRegionObserver|1|', coprocessor$3 => 'phoenix.jar|com.salesforce.phoenix.coprocessor.GroupedAggregateRegionObserver|1|', coprocessor$2 => 'phoenix.jar|com.salesforce.phoenix.coprocessor.UngroupedAggregateRegionObserver|1|', coprocessor$1 => 'phoenix.jar|com.salesforce.phoenix.coprocessor.ScanRegionObserver|1|', FAMILIES => [{NAME => '_0', DATA_BLOCK_ENCODING => 'FAST_DIFF', VERSIONS => '10', KEEP_DELETED_CELLS => 'true'}]}

Hive

CREATE EXTERNAL TABLE PHOENIXTABLE_TEST 

( id  string, 

name  string, 

addr  string ,

date  TIMESTAMP

)  STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'  

WITH SERDEPROPERTIES 

("hbase.columns.mapping"=":key,_0:NAME,_0:ADDR, _0:DATE ")  

TBLPROPERTIES ("hbase.table.name" = "PHOENIXTABLE_TEST");

 

本文主要集中测试写入和查询两个方面做对比。删除操作本次未做详细测试(因为在NoSQL的环境下很少做常规性删除)。

 

3.2 Phoenix VS HBase 写入

写入说明:

a.Phoenix采用PreparedStatement一次写入30w条数据(每条数据90字节左右)

b.HBase采用自身客户端API一次写入30w条数据(与Phoenix基本一致)

 

由图可知,Phoenix的写入性能与HBase自身客户端相比,略低。

3.3 Phoenix VS HBase VS Hive 基于主键查询

查询说明:三者同时基于主键范围查询。为保持属性设置一致,fetchSize统一为50(因为Hive源码固化了此参数)

a.PhoenixHive采用PreparedStatement,查询语句【select *  from  PHOENIXTABLE_TEST where ID >="10500000" and  ID <="10600000"

b.HBase采用Scan s = new Scan(Bytes.toBytes("10500000"),Bytes.toBytes("10600000"));

由图可以看出,基于纯主键的查询,HBaseScan性能是最高的,得益于其天生的一级索引(基于RowKey)属性。而PhoenixHBase很接近,但是Hive差距很大。

3.4 Phoenix VS Hive 基于列模糊查询

查询说明:由于HBase局限于自身简单的查询机制,在对列值模糊查询时,HBase显得十分笨重(要么全局扫描,要么限制主键范围,但这取决于业务背景和主键设计),因此在基于列值模糊查询时,与PhoenixHive没有可比性。

PhoenixHive同时基于列值进行模糊查询,采用PreparedStatement,语句为(fetchSize=50)select *  from  PHOENIXTABLE_TEST where ADDR like  %59_9%

 

由于Phoenix查询是整合HBase自身的API,在性能上具有天生的优势,并且做到实时返回数据;而Hive采用的是离线批量处理的重框架MapReduce,其启动和执行需要更多的资源和时间,并且只能在MR执行完成以后,数据才能返回。因此,在一定数据和环境约束下,性能反而比较低。

3.5 Phoenix VS Hive基于列模糊带函数查询

PhoenixHive同时基于列值进行模糊查询,采用PreparedStatement,语句为(fetchSize=50)select MIN(ID) ,MAX(ID)  from  PHOENIXTABLE_TEST  where ADDR like  '%59_9%' GROUP BY ID

 

分析同上。

4. 结论

4.1 Phoenix优势

Phoenix对单表操作具备很高性能优势,通过标准的SQL和JDBC,简单易用。

4.2 Phoenix劣势

仅对单表和部分SQL特征支持。 

4.3 应用建议

根据Phoenix的优势和劣势可以得出,在HBase自身客户端API可用的环境下,Phoenix一样实用,且性能并没有损耗太多。因此,Phoenix不失是一种值得逐步推广应用的插件。

由于它自身开源,其服务端代码量不多,客户端代码量相对较多。因此,可视项目应用需要对Phoenix进行自定制的改进!

5. Phoenix简单介绍

以下部分由我个人整理,仅供参考,部分内容会随着我对Phoenix源码的深入陆续改进。

5.1 Phoenix简述

PhoenixSalesforce.com开源的基于JAVA开发SQL中间层,实现JDBC协议接口,可在HBase上执行SQL(当前仅支持对单表的增删改查以及部分函数)语句,几乎达到实时响应和交互。其查询做到实时响应的基本原理是:将一个相对于HBase客户端比较复杂的查询转换成一些列Scan,结合建表时植入的corprocessor和定制的filter进行查询,并经过有序地汇集各scan结果再输出给调用程序的ResultSet,从而快速完成查询。内部核心是整合HBase自身的API,而没有采用笨重的MapReduce

Phoenix致力于打造成访问HBase数据的行业标准的API

5.2当前支持的SQL

Phoenix目前仅支持对单表的SELECTUPSERT VALUESUPSERT SELECTDELETECREATEDROPALTER TABLEEXPLAIN。以及一些有HBase表、列族特色的一些SQL选项。

目前还不支持JoinDerived tables()Relational operators(Union, Intersect, Minus) 等。

5.3当前支持的函数

Phoenix目前支持AVGCOUNTMAXMINSUMSUBSTRTRIMLTRIMTRIMLENGTHREGEXP_SUBSTRREGEXP_REPLACEROUNDTRUNCATETO_CHARTO_DATECURRENT_DATECURRENT_TIME等。

5.4当前支持的数据类型

Phoenix目前支持INTEGERUNSIGNED_INTBIGINTUNSIGNED_LONGDECIMALBOOLEANTIMEDATETIMESTAMPVARCHARCHARBINARY

5.5当前支持的Scheme

Phoenix目前支持TableView,但是基于View查询性能远低于TablePhoenix的所有scheme都是多版本支持的。

另外,HBase中的表若需Phoenix提供SQL的查询支持,务必通过PhoenixCreate语句创建,否则PhoenixSQL会报表不存在的异常。其实这个不难理解,其一,HBase的表中列族下的列是完全动态的,每一行都可能不一样,因此,由HBase表无法准确反向关联至标准的SQL;其二,为了充分利用HBase corprocessor,需在建表时写入元数据。其三,Phoenix提供scheme多版本支持,需要一个元数据表,即Phoenix自身的SYSTEM.TABLE,其作为一个HBase的表存在于HBase中。

通过Phoenix创建的表,其主键为HBase表的row key,其他列为默认列族_0下的列。因此,在Phoenix中创建的表,通过HBase客户端亦可正常访问。不过要特别注意:HBase自身默认存储的数据类型都是字符串,但Phoenix支持更多的数据类型(大部分也支持Hive),这在通过HBase自身客户端查询Phoenix创建的表时,假如不是字符串型,会存在一定的转换乱码问题。

5.6事务支持

Phoenix支持UPSERT VALUESUPSERT SELECT and DELETE的事务。

5.7后续发展路线

Phoenix将陆续对以下数据库特征的支持:

 Secondary Indexes. Allow users to create indexes through a new CREATE INDEX DDL command, and then, behind the scenes, build multiple projections of the table (i.e. a copy of the table using re-ordered or different row key columns). Phoenix will take care of maintaining the indexes when DML commands are issued and will choose the best table to use at query time.

 TopN Queries. Support a query that returns the top N rows, through support for derived tables and implementation of a server-side coprocessor that keeps the top N rows.

 IN Optimizations. When an IN (or the equivalent OR) appears in a query using the leading row key columns, compile it into a batched get to more efficiently retrieve the query results.

 COUNT DISTINCT. Although COUNT is currently supported, supporting COUNT DISTINCT will require returning more state to the client for the final merge operation.

 CREATE SEQUENCE. Surface the HBase put-and-increment functionality through the standard SQL sequence support.

 Dynamic Columns. For some use cases, it's difficult to model a schema up front. You may have columns that you'd like to specify only at query time. This is possible in HBase, in that every row (and column family) contains a map of values with keys that can be specified at run time. So, we'd like to support that.

 Nested Children. Unlike with standard relational databases, HBase allows you the flexibility of dynamically creating as many key values in a row as you'd like. Phoenix could leverage this by providing a way to model child rows inside of a parent row. The child row would be comprised of the set of key values whose column qualifier is prefixed with a known name and appended with the primary key of the child row. Phoenix could hide all this complexity, and allow querying over the nested children through joining to the parent row.

 Joins. Support hash joins first, where one side of the join is small enough to fit into memory.

 Schema evolution. Phoenix supports adding and removing columns through the ALTER TABLE DDL command, but changing the data type of, or renaming, an existing column is not yet supported.

 TABLESAMPLE. Implement a filter that uses a skip next hint based on the region boundaries of the table to only return n rows per region.

 OLAP extensions. Support the WINDOW, PARTITION OVER, RANK, etc. functionality.

 

 

 

<!--EndFragment-->

你可能感兴趣的:(sql,hive,hbase,hbase,hbase,Phoenix,corprocessor)