zoukankan      html  css  js  c++  java
  • Hive和并行数据仓库的比较

    最近分析和比较了Hive和并行数据仓库的架构,本文记下一些体会。
    Hive是架构在Hadoop MapReduce Framework之上的开源数据分析系统。 Hive具有如下特点:

    1. 数据以HDFS文件的形式存储,从而可以很方便的使用外部文件
    2. 元数据存储独立于数据存储之外,从而解耦合元数据和数据,同样的数据,不同的用户可以有不同的元数据
    3. 查询计划被分解为多个MapReduce Job,并按照依赖关系依次执行,复用了MapReduce的执行架构
    4. 灵活的存储格式,通过ObjectInspector将对数据列的访问与数据的具体存储格式解耦合,同一行数据在同一个数据处理流中可以以不同的格式出现
    5. 基于规则的查询优化器,依次使用规则转换逻辑计划

    下面,我们就把Hive跟传统的并行数据仓库进行一下深入的比较:

    1. 存储引擎。 并行数据仓库需要先把数据装载到数据库中,按特定的格式存储成特定的页文件,然后才能查询;而Hive则不用装载数据,也不用格式转换,Hive内置了多种文件格式的支持,并且可以使用用户定制的格式实现(inputformat),这样大大节省了数据导入的开销。传统数据仓库是把数据导入系统中,而Hive则是动态的将对数据处理的逻辑(代码)导入系统中。

    2. 执行引擎。Hive架构于MapReduce Framework之上,执行计划的灵活性较差,优化器可做的选择很少,例如:Join算法只有Grace Hash Join一种选择,性能更加优秀且稳定的Hybrid Hash Join则无法实现; Map端的Group-by算法只有Hash Group-by一种选择, Reduce端的Group-by只有sort group-by一种选择(不然MapReduce提供的sort就浪费了); limit无法和sort融合起来,很多情况下,用堆排序来融合limit与sort会更加高效。 Join, Group-by, Limit在OLAP,日志分析等任务中非常常用的Operator,而Hive在这3个Operator的实现上都依赖于MapReduce Frameowork提供的partition和sort,好处是实现比较简单,缺点是效率往往不是最优的。 然而,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现。 相反,并行数据仓库实现了各种算法,它的查询优化器可以更加灵活的选择这3个Operator的不同实现。

    3. 查询优化器。大多数商用数据仓库使用基于代价的优化器,在生成查询计划时,利用元数据中的统计信息估算每个operator要处理的数据量,选取代价较低的执行计划。不过,这些商用数据仓库的都起步于基于规则的查询优化器,而Hive正处于这样一个类似的起步阶段。因而Hive查询优化器能做的优化并不多,仅限于10几条转换规则。

    4. 索引和缓冲管理。 对于查询来说,索引的作用至关重要,尽管Hive中的partition起到和索引类似的作用,但还比较初级,与并行数据仓库较为完善的索引(primary,secondary, clustered, unclustered)还有很大差距。 当然,Hive也没有缓冲区管理机制,只能依赖于文件系统的缓冲机制;并行数据仓库往往禁用操作系统的缓冲机制,针对不同的查询的特点设计了多种缓冲机制,从而优化了性能。

    5. 并行扩展性。MapReduce将MR job的中间结果保存到Map Task的本地硬盘,从而MR Job的容错性非常好,Hive自然的利用了这一点;Hive执行计划中,每一个MapReduce job又把处理结果写到HDFS,从而又利用了HDFS的容错性。 这样,在一个Hive查询的执行中,如果某个节点出现故障了,只需要重新调度执行该节点的任务即可,不需要重新提交查询。 因此,Hive有非常好的intra-query fault-tolerance,所以可扩展性非常强,例如一个查询可以在4000个节点上同时跑;缺点是大大减少了pipeline parallelism的机会。 并行数据仓库往往采用的是pipeline架构,上游的Operator每产生一条数据就会送去下游的Operator。这样的好处是最大化了pipeline parallelism并避免了中间结果的磁盘读写,但是,当一个查询运行于并行数据库上时,一旦一个节点出现故障,并行数据仓库就必须重新执行该查询。所以,当一个集群中的单点故障发生率较高时,并行数据仓库的性能就会下降了。假设每个节点故障发生率是0.01%,那么1000个节点的集群中,单点故障发生率则为10%;假设每个节点故障发生率是0.0001%,那么5000个节点的集群中,单点故障发生率为0.5%!

    6. 内存拷贝开销。 千万别小看这一点,内存拷贝会很大程度上拖累系统性能。 我们可以注意到,Hive中所有的哈希,比较,数值运算操作,都需要操作在Writable Object上,而每次重置(reset)这些Writable Object,都需要将数据从byte array拷贝到这些对象的byte[]成员中。 在更精巧的实现中,很多内存拷贝其实是可以避免的,并行数据仓库往往做了很多优化(甚至包含操作系统内核的优化,比如Teradata的PDE)去节省不必要的内存拷贝,从而又带来了性能提升。

    在实际应用中,到底该选用Hive还是并行数据仓库,取决于这些:
    1. 钱,Hive是开源的,并行数据仓库(db2, teradata, netezza, vertica)是非常昂贵的
    2. 还是钱,Hive只需要普通机器集群,并且集群节点的操作系统和硬件都可以是异构的,单点故障发生率高也无所谓;并行数据仓库往往希望使用性能较高的服务器作为集群节点,从而单点故障发生率可以控制在一个非常低的范围。
    3. 数据规模,如果是Google, Facebook, Baidu这种规模的应用,需要几千甚至上万节点的集群,目前的商业并行数据仓库产品就很难支撑了;如果是沃尔玛,eBay这些应用,并行数据仓库还是完全可以胜任的,并且性能会远优于Hive。

    此文旨在抛砖引玉,欢迎大家进行更多的比较:-)

    =============================================================

    另补充我的一些观点:

    Hive本意是在Hadoop的MapReduce编程模型上进行包装,使其支持声明式的SQL查询,其各种opr都是使用MapReduce模型模拟实现。这样的好处就是与Hadoop无缝融合,但是,MapReduce模型最适用的场景是聚集类的操作,即数据库中的Group By,其模型并不是为Join量身打造,即使能够通过设计实现Join操作,但是效率以及可选择性上也大大折扣,有点削足适履的感觉。

    我觉得如果不拘束在MapReduce模型上,而是对于各种操作寻求最合适的模型而不是拘束在MapReduce模型上,但是充分吸收其Fault Tolerance的特性,可能会较好。

    但是,Fault Tolerance的满足需要对中间结果进行物化,这与Pipeline又会矛盾。两者需要寻找一个平衡点。我觉得部分物化、部分Pipeline的方式也许是一种选择,类似于checkpoint。这样Fault Tolerance的粒度不是MapReduce模式下的单个操作,也不是Pipeline模式下的整个查询,而是居中,即查询中的子操作块。

    总的感觉,Hive的工作更倾向于工程,而不是模式的创新。但是作为初级产品,还是很有意义的。

  • 相关阅读:
    《DSP using MATLAB》Problem 6.17
    一些老物件
    《DSP using MATLAB》Problem 6.16
    《DSP using MATLAB》Problem 6.15
    《DSP using MATLAB》Problem 6.14
    《DSP using MATLAB》Problem 6.13
    《DSP using MATLAB》Problem 6.12
    《DSP using MATLAB》Problem 6.11
    P1414 又是毕业季II
    Trie树
  • 原文地址:https://www.cnblogs.com/qqflying/p/9246081.html
Copyright © 2011-2022 走看看