使用JDBC操作数据,而不是HBase client API
在RegionServer端通过coprocessor过滤where条件,执行aggregation函数。比较Hive on HBase,Impala on HBase和Phoenix这三者的架构是相似的,不同点就是Hive on HBase和Impala on HBase都没有把coprocessor利用好,都是通过HBase client API把数据读到他们自己进程的内存之后才进行的filter, aggregation等操作。
从查询的角度来看HBase的column主要分为两类:primary key(row key column)和other columns。主要的不同是row key column能够利用Region Server的index, filter, sort等特性,而other columns没有这些特性,只能通过二级索引辅助做一些优化。Phoenix能够在HBase上创建二级索引用于优化条件查询(目前只支持在 static table上建二级索引,一个更通用的HBase二级索引实现方法参考 https://github.com/Huawei-Hadoop/hindex)。
如果是row key column上的IN/OR/LIKE条件,可以通过Region Server的skip scan filter优化。
Dynamic columns支持。
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的实现里 好多条件比较,是不利于全表扫描的。
还有个问题就是coprocessor的问题了,由于coprocessor和HBase Region Server是在一个JVM里面,所以当coprocessor计算逻辑非常复杂,中间结果数据量很大的时候会占用大量内存。同时coprocessor 不是流式地读取数据,某些节点数据积累过多也会造成内存不够用的问题。
RoadMap:
JOIN支持,虽然有点不符合设计初衷,但是大家都支持,就我不支持,太过时了吧。
Transaction支持,通过参考 https://github.com/yahoo/omid的方法。
Online Schema Evolution,动态改变column的类型,rename等。
Hadapt/HadoopDB
架构和Hive相似,底层存储引擎有两种:HDFS和RDBMS(PostgreSQL),一个DataNode节点上有一个RDBMS节点。
提供两种接口:SQL和MR,SQL也是解析成MR job来执行的,所以总的来说执行引擎都是MR。
把多个MR任务,转换成单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),然后使用MR来做JOIN/Group By。而且如果在数据被load到分布式PG节点上时分布情况正好符合group by/order by的条件,那么还省得通过MR的shuffle来做了。
Hadapt的本质还是把SQL解析成MR任务来做,所以Hive的有些缺点(启动时间长,JOIN效率较低)它也是具有的。还有如果想要join/group by/order by能够在RDBMS数据源之间高效执行,还得考虑数据预分布的问题。