上篇主要讨论了hive, stinger/tez, impala, shark这些sql on hadoop产品,这篇接着讨论phoenix, hadapt, hawq。 phoenix salesforce开源的基于hbase的sql查询系统,建立在hbase client api, coprocessors, custom filter的基础之上。 基本原理是将一个对于hb
上篇主要讨论了hive, stinger/tez, impala, shark这些sql on hadoop产品,这篇接着讨论phoenix, hadapt, hawq。
phoenixsalesforce开源的基于hbase的sql查询系统,建立在hbase client api, coprocessors, custom filter的基础之上。基本原理是将一个对于hbase client来说比较复杂的查询转换成一系列region scan,结合create table时hook的coprocessor和custom ?filter在多台region server上进行并行查询, 汇总各个scan结果输出给调用程序的resultset。说白了就是看大家用hbase client api开发程序太麻烦了,就弄了个jdbc包装,这样对于software engineer来说降低了开发成本,同时对于简单单表查询性能损失不大。种种迹象表明,phoenix应该不是个优化的olap系统,更像是一个用于简单单表查询,过滤,排序,检索的oltp系统。优点:
hbase默认存储的数据类型都是字符串,但phoenix支持更多的数据类型(int, float, char, varchar, time, date)使用jdbc操作数据,而不是hbase client api在regionserver端通过coprocessor过滤where条件,执行aggregation函数。hive on hbase把sql转化成mapreduce去查询hbase;impala on hbase把sql转化成planfragment执行计划去查询hbase;?phoenix把sql转化成对hbase client api和coprocessor的调用,这三者的架构是相似的。不同点就是hive on hbase和impala on hbase都没有把coprocessor利用好,都是通过hbase client api把数据读到他们自己进程的内存之后才进行的filter, aggregation等操作。所以理论上讲前两种架构设计的产品性能不可能超过直接调用hbase client的方式。从查询的角度来看hbase的column主要分为两类:primary key(row key column)和other columns。主要的不同是row key column能够利用hbase region server的index, filter, sort等特性,而other columns没有这些特性,只能通过二级索引辅助做一些优化。phoenix能够在hbase上创建二级索引用于优化non row key columns的条件查询(目前只支持在static table上建二级索引,一个更通用的hbase二级索引实现方法可以参考华为开源的这个实现https://github.com/huawei-hadoop/hindex)。salting of row keys to evenly distribute write load如果是row key column上的in/or/like条件,可以通过region server的skip scan filter优化。dynamic columns支持(跟rdbms的dynamic schema change类似),也就是用户不需要在create table的时候指定所有的column,后面什么时候需要随时添加。这个功能主要依赖于hbase的动态添加column的功能。autocommit=false时(默认是false)把所有操作先缓存在客户端,只有你显示commit时才一次批量提交到hbase,sql解析优化全是在客户端做,这个有点事务的意思。缺点:
不支持join,考虑到hbase的设计初衷是尽量用冗余数据减少复杂的join操作,实际上可以把相关数据都放在同一个表里,而不需要为了减少数据冗余,拆分到多个表中,所以很大程度也可以认为这不是一个缺点。从架构上看也仅是把sql转成hbase client的api和coprocessor的调用,而且coprocessor还不适合大规模数据的传输,所以如果中间结果的数据量还是比较大的话性能问题还是很明显的。这个缺点是所有的基于hbase的sql系统都有的(包括hive on hbase和impala on hbase)。不管什么请求到hbase region server这边都得通过regionscanner,这个接口不是面向olap型应用优化的存储文件读取接口。例如regionscanner的实现里好多条件比较,是不利于全表扫描的。所以全表扫描的应用不如一个一个地读hfile,当然前提是得离线把memstore的数据都dump到hfile。目前coprocessor也是走的regionscanner。这部分要想改得改region server代码了,那就是apache hbase社区的事了。还有个问题就是coprocessor的问题了,由于coprocessor和hbase region server是在一个jvm里面,所以当coprocessor计算逻辑非常复杂,中间结果数据量很大的时候会占用大量内存。同时coprocessor不是流式地读取数据,某些节点数据积累过多也会造成内存不够用的问题。roadmap:
join支持,虽然有点不符合设计初衷,但是大家都支持,就我不支持,太out of fashion了吧。transaction支持,通过参考https://github.com/yahoo/omid的方法。online schema evolution,动态改变column的类型,rename等。https://github.com/forcedotcom/phoenix/wikihadapt/hadoopdbhttp://hadapt.com/product/
http://db.cs.yale.edu/hadoopdb/hadoopdb.pdf
架构和hive相似,底层存储引擎有两种:hdfs和rdbms(postgresql),一个datanode节点上有一个rdbms节点。提供两种接口:sql和mapreduce,sql也是解析成mapreduce job来执行的,所以总的来说执行引擎都是mr。把多个mapreduce任务,转换成单node上的sql+一个mr(data shuffle),这个跟水平压缩,垂直压缩类似,尽量减少sql解析出的mr task个数,减少任务之间写hdfs的io数据量。把一个sql拆解成两部分:适合sql做的用单机sql,不适合的用mr(data shuffle)和hive的不同点在于hive只能操控hdfs上的数据,而hadapt可以操控hdfs和rdbms两种数据来源。对于rdbms这个数据源来说,数据被预先load到分布式的rdbms节点中,有统一的catalog管理所有rdbms中的数据。例如map中的有些执行逻辑直接通过一个在rdbms上执行的sql来获得(修改inputformat),然后使用mapreduce来做join/group by。而且如果在数据被load到分布式postgresql节点上时分布情况正好符合group by/order by的条件,那么还省得通过mapreduce的shuffle来做了。hadapt的本质还是把sql解析成mr任务来做,不是mpp的思想,所以hive具备的有些缺点(启动时间长,join效率较低)它也是具有的。还有如果想要join/group by/order by能够在rdbms数据源之间高效执行,还得考虑数据预分布的问题。需要统一的元数据和数据一致性服务用于管理hdfs上的数据导入分布式postgresql以及分区。在执行多个query的时候,后面的query能够利用前面query的查询结果(已经把前面query的查询结果可以写到rdbms中,有点类似于数据仓库中的物化视图的概念),从而可以提高查询的性能。combine structured and unstructured data in single query。现在很多公司为了统一计算平台,把放到rdbms中的数据也放到hdfs上存一份,要不没法和hdfs中的非结构化数据做join。在hadapt这里用户通过一个query可以操控两种数据,不用分两个步骤走了。现在企业级应用大多使用的方案(ebay使用的是hadoop+teradata)是hadoop+mpp/open source+commercial software的方式,即通过hadoop批处理unstructured data(进行etl操作)然后通过connector导入mpp进行structure data的query操作。但是这只是临时的替代方案,hadapt说invisible loading(http://hadapt.com/blog/2012/09/05/invisible-loading-a-new-paradigm-for-loading-from-unstructured-to-structured-storage/?)才是最合理的,这样企业就有了一个unified analytic platform。但是用户把数据load到rdbms之后就失去了在hdfs上存储的robust和scalable的特征,需要这个系统提供维护数据一致性相关的功能。hawqa relational database that runs atop of hdfs
原来greenplum database中的存储是本地磁盘,现在改成hdfs,原来greenplum database的单节点的rdbms只充当execution engine的功能,不再充当storage功能。query执行通过greenplum database的parallel?execution engine(不再使用mr),每次查询开始把数据从hdfs中导入到greenplum database,执行过程中通过内存交换数据而非mapreduce那样每次任务结束都写磁盘。hawq提供一个universal catalog service管理分布在各个rdbms节点的数据。gp特有的cost-based parallel query optimizer and planner是它的一大优势,也是目前其他大多数的产品中没有的。它能够帮用户选出该sql最高效的执行顺序。使用greenplum database充当执行引擎的好处:标准sql兼容(correlated sub query, window functions, rollups, cube, scalar and aggregate function);支持acid事务;jdbc/odbc支持;join顺序优化和索引支持(查询优化器);支持row/column两种存储格式。gpxf (greenplum extension framework) 使得hawq能够读取存储在hdfs上的任何格式的数据(delimited text, sequence files, protobuf and avro)以及存储在cassandra, mongodb,?isilon, atom, mapr, lustre, gpfs中的数据,无非就是多开发个读取接口。emc是存储出身,肯定是希望这个analytic stack能够接入更多的存储产品,特别是他们卖的东西。底层的hdfs需要支持trancate语义(https://issues.apache.org/jira/browse/hdfs-3107)和native c interface(不是jni的,jni的不适合大规模并行查询,所以应该hawq自己实现了一个基于c的rpc通信接口,与namenode和datanode直接通信)。所以说hawq底层的hdfs跟apache版本的到底有多大区别,我也不知道。支持in-database analytics (?http://madlib.net/?)可以在hawq内执行除了query以外的分析任务,例如analytic functions(standard deviation, variance等)和off-the-shelf analytic package支持数据挖掘算法:principal components analysis (pca), enhanced support vector machines (svm), linear models性能相关:
scott yara(greenplum老大)?公开承认hawq比pure greenplum database要慢。这么做的目的无非就是更好的利用hdfs的可扩展性,统一存储管理。和其他sql on hadoop产品的性能对比方面,hawq在group by和join操作上与其他方案相比优势明显,前提是数据量不是特别大。(是不是因为数据导入的时候partition做的好呢,是不是拿load的时间换group by/join的时间呢?)http://www.dataintoresults.com/2013/09/big-data-benchmark-impala-vs-hawq-vs-hive/
不过hawq和hadapt都说明了一个问题:就是unified analytic platform的重要性。
从商业产品来看,大数据分析产品主要有:
teradata/aster dataemc/greenplum/hawqhp/vertica 列存数据仓库sap/hana 内存分析google/bigquery 典型的analysis as a serviceamazon/redshif 和aws结合比较紧密而传统软件厂商ibm, oracle, microsoft也都有产品,不过从技术的角度对后面这些公司的产品了解不多。
说完数据仓库相关产品,我们也顺便看看机器学习相关产品。机器学习不像sql那么普遍,但是非常重要。我所知道的目前互联网公司做机器学习的系统是这样的:
(1) twitter基于pig做machine learning
http://www.umiacs.umd.edu/~jimmylin/publications/lin_kolcz_sigmod2012.pdf
在hadoop/mapreduce基础上,通过pig扩展,使该平台具有机器学习处理能力特征抽取通过udf实现单个学习单元的内部循环封装在pig storage function中预测是根据学习训练的模型,结合udf实现(2) 不过目前互联网公司大多使用hadoop做feature selection,然后对于不同的问题采用两种思路:
采样数据,然后跑单机模型。因为很多机器学习算法是非常不容易并行化的,所以在全量数据的子集上面跑单机模型。基于mpi开发大规模并行的机器学习算法。(3) spark是个非常适合迭代型机器学习算法的计算模型和框架,而且ecosystem非常完备(shark,blinkdb,mlbase)。特别是基于spark的机器学习算法库mlbase(http://www.cs.berkeley.edu/~ameet/mlbase.pdf)更是给机器学习算法大规模应用提供了帮助。
由于mahout是mr上的machine learning库,但是底层的mr天然不适合密集迭代计算的机器学习算法,导致mahout的应用并不是很广泛。但是spark却是非常适合迭代机器学习算法,那么mlbase的重要性就非常明显了。
目前berkeley的教授们已经搞了一个公司叫databricks来做spark/shark的商业化,我是非常看好spark的前途的。
原文地址:sql on hadoop系统的最新进展(2), 感谢原作者分享。
