Hive 进化最终方向:列数据库

来源:互联网 发布:服务器性能监测软件 编辑:程序博客网 时间:2024/05/21 20:28
 

Facebook 在2010年4月发表了一篇在Hadoop 里面实现列储存的论文: RCFile: A Fast and Space efficient Data Placement Structure in MapReduce based Warehouse Systems.

CSDN 上面有这篇文章的一部分翻译, 它当时提出这个设想其实就是想做一个列数据库,而实现列数据库的第一步就是实现列储存,本文主要介绍当时Hive 的RCFile 的实现环境与限制,下一代Hadoop的架构对新的RCFile 产生的影响以及将来可能出现的Hadoop 列数据库计算模型的一些相关问题.

 

RCFile 在实现的时候主要需要满足facebook 在以下4个方面的需求:

  • Fast data loading、
  • Fast query processing、
  • Highly efficient storage space utilization
  • Strong adaptivity to highly dynamic workload patterns

    facebook 团队在参考设计的时候使用的是实验性质的C-store 数据库,而不是像另外一篇非常有名的Hadoop 与DBMS 争论的论文: A Comparison of Approaches to Large-Scale Data Analysis 中使用的是列数据库中非常好的Vertica 数据库做参考. 所以其在上面4点中并没有得到最好的设计,尤其是当时的Hadoop 架构上的限制非常的大,RCFile 的推出算是一种可以接受的能够实现的设计, 毕竟一个不算完美的设计可以慢慢修改,而一个设计非常优秀但是不能实现的设计等于空话.

  •  

    RCFile 的IO 设计

    RCFile 在实现上实行先水平切分,然后垂直切分的原则,示意图如下:

    RCFile

    RCFile 将一列的数据放在一起,然后紧接着放另外一列的数据,这种设计跟大多数现在商业数据库的设计都不同,即不像Oracle 那种PAX 设计,也不是其他分析型数据库的混合设计. 这主要是由于以下几点因素的限制:

  • Block Size 太大
  • NameNode 内存限制

    Hadoop 的Java 文件API 无法提供细粒度的随机IO 控制

    HDFS 由于设计之初就是为了大规模读取设计,默认的Block Size 为64M,一般的情况下甚至都是128M往上走,这个跟列分析数据库的默认64K 的block size 大了整整1000倍,即使Facebook测量了各种block size 发现4M 以上压缩率没有明显提升之后,block size 默认就设计成了4M,这可是在2010年早期,根据HDFS scalability: the limits to growth ,yahoo 的256M 的blocksize 只能管理不到14PB ,100M文件个数计算 ,4M 的blocksize 在单NameNode 内存的限制下只能管理大概不到1PB 的数据.可见当时的RCFile 设计的确是不能像传统的列数据那样,将block size 设置的同时适合储存和IO .

    为什么block size 的大小会影响性能呢? 因为列数据库主要是依靠数据的排序将所有数据的可能值储存在block 头部来过滤数据的,它需要将每一列分开储存,以便减少不必要的IO 读取,而在那些可能涉及到大量过滤条件的列在block头部储存所有值又可以过滤掉绝大多数不必要的block. 从而只解压缩少量可能的block 数据.

    RCFile 因为Hadoop 整体的限制, 其设计算是一个折中的方案. 它并没有大量减少文件读的IO , 但是在读取需要列的数据的时候,其读入内存的数据的确是完完整整的列数据, 而不是像行储存一样耗费不必要的内存和磁盘IO

     

    数据过滤

    RCFile 在实现上也提到了列数据库的late decompression , 这个可能有多个不同的术语,比如延迟物化(later materialization) , 延迟解压 或者内存压缩( in-memory compression) , 但是都是表示的同一个意思: 如何在没有索引的情况下实现最大程度的数据过滤与减少不必要的IO和内存消耗. RCFile 由于没有排序. 所以在实现的时候并没有遵守列数据库先按选择性对列进行排序,然后每列按照频率进行排序的原则, 而是纠结在如何选择row group 的大小上了. 让我们讨论以下论文里面的出现的一个例子

    select a,b,c,d from TBL where e=1

    RCFile 里面是这样论述的:

    选择合适的row group 是需要考虑多方面的因素的,一般来说大的row group 有助与提高压缩率,但是当row group 到一定程度的时候压缩率会趋于一致. 另一方面,大的row group 不利于读的性能,也会增加当解压缩的时候所消耗的内存.首先RCFile 会检查e 这一列, 查到只有一条记录符合条件,这个时候需要解压缩abcd四列. 如果它将abcd 放一起, e放一组,那么对于这种SQL 就是比较有利的,无论有没有e这一列的记录,abcd都能快速的解压缩. 但是当sql 改变的时候. 这种row group 就无法即快速的做出判断需不需要解压缩,又同时可以避免在需要解压缩的时候能够快速解压缩需要的列而不去处理不需要解压缩的列. (如果你要问为什么不每一列都分开储存?前面已经说了,更大的group 有更好的压缩率,虽然这个前提假设在真正的商业列数据库中是不成立的 )

    这个结论其实是因为他们研究的是Yahoo 为pig 实现的列储存Zebra 和一个实验性质的C-store 数据库为参考对象,(还有一个被淘汰的Cheetah设计,先水平切分后垂直切分,所以解压缩更早,跟Oracle有些类似) . 实际上成熟的商业列数据库都不是这么设计的. 比如同样一个SQL,列数据库应该是这种:

    在数据装载的时候就判断abcde这5列的特性,按照数据的选择性高低进行排序,比如c 列是性别只有两个值:男和女, d 列是年龄,从18-50共有33个唯一值,那么c 列作为选择性最高的列就排在前面,d 列的选择性比c 小但是比其他列大的时候就排在c后面. 对于每一列的数据按照频率的大小进行排序以便最大化的压缩.

    另外由于RCFile 的提前解压,所以在做join ,partition , combine,reduce copy,reduce sort 的时候,并不像列数据库那样能大幅减少计算,内存和网络传输,基本上跟行数据库差不多的模式.

     

    下一代Hadoop对RCFile的影响

    下一代hadoop的架构变更一直讨论了一整年了,主要涉及3个大的模块

    • HDFS Federation
    • YARN
    • HCatalog

    HDFS Federation 就是为了解决单NameNode 的限制问题. 将用多个NameSpace来管理整个集群, 解决了可用性和网络拥堵的问题. 这使得1M 的blocksize 变的可能. 这样RCFile 大可不必像现在这样将所有列放在一起,每一列真真正正的分开储存, 这样对IO 和并行性也是一大提升. Google 在今年发表的Tenzing : A SQL Implementation On The MapReduce Framework就是按照默认的1M 大小进行列储存的,不过Google 的BigTable 可以容纳混合储存(纯行或者纯列).既然Google 已经实现了分析PB 级的数据能在秒级别的延迟,相信未来的Hadoop 至少也可以做到10秒级别的延迟.

    YARN 则是改变了现在的jobtracker 和tasktracker 在分配资源和可用性通信的机制. 它将jt 和tt 分解为

    ResourceManager , AppMaster , NodeManager , Resouce Manager 只负责总体资源的分配和负载,AppMaster 用来处理实际的每个任务的资源和任务进度, NodeManager 用来管理每台服务器的磁盘,内存和子任务的执行.

    (YARN 结构图)

    YARN 跟Google 的Tenzing 大体架构上没有太大区别 .YARN 在官方资料的介绍中说是为了解决现在的可用性,扩展性,并行性和任务资源分配的粒度问题,对于为了实现列数据库,YARN 实际上为解决动态负载,静态执行计划和资源共享提供了必要的前提,参考对应数据库的功能来解释也许更加容易.

     

    • 动态负载

      Hadoop 目前的资源分配机制都是以task slot 为粒度的,每一个task slot 管理自己的资源 , 目前task slot 的分配机制主要是以cpu core 为准,但是现在的4核cpu 和3年前的4核cpu显然具有不同的计算能力,对于不同的服务器有不同的CPU计算能力,内存大小,磁盘IO能力,Hadoop 无法为每个节点控制自己的资源分配情况,而新的YARN 的每个服务器的NodeManager 就是为了解决资源分配,统计信息等情况的,从而对于细粒度的任务管理变成可能. 另外一个负载的问题参考MPP DBMS的设计,是要实现在什么时候分配给什么人什么粒度的资源,Hadoop 现在的两个调度器在目前的版本下根本无法实现这点. 尤其是时间点的控制,这需要一种在job 已经运行的时候动态的增加资源或减少资源的分配机制. 另外Hadoop 对于小任务和大批量任务也缺乏控制,常见DBMS数据仓库中的晚上1点开始批量装载数据的时候是可以使用系统全部资源的,而在正常的上班时间是静止任何进程独立的占用全部资源,像这种数据仓库讨论的比较多的也比较成熟的负载控制问题,Hadoop 目前还没有机制去解决. 但是一旦Hadoop 解决了目前的问题,就能够解决动态负载问题,而这又能够提高系统整体吞吐能力和健全的调度机制

      • 静态执行计划

        hadoop 目前的执行计划是完全动态的,哪个节点有空闲的task slot就给哪个节点运行,这样hadoop 在分配小任务和执行“将计算靠近数据” 任务的时候非常不适合. 它没办法预测如果一台服务器上有数据,但是服务器没有空闲task slot 的时候该怎么办,也许有些任务不需要大量CPU,这时它可以零时分配多一个task slot 给它,以免分配其他的节点增加不必要的数据传输. Hadoop 2代已经开始慢慢做关于资源消耗,历史执行信息,统计信息(这部分是Hive做), 一旦基础的做完,总有一天Hadoop 可以做出静态的执行计划的.

       

      • 资源共享

        下一代 Hadoop 一个比较大的变革就是集群资源分配方面,可以让一部分的服务只运行在一部分的节点上,而所有的不同服务之间可以互相访问,比如HBase 以后就是这样,这就为列式数据库的缓存提供了可能性,注意只是列数据库. 行数据库在每个节点上放缓存没有意思,因为你面对的是12T/24T 的磁盘和48G/64G 的内存,每小时所有的缓存都会全换一遍,即使是索引,你也没办法保证索引会被访问多少次. 但是列数据库不同,列数据库的纬度信息的压缩率往往都是200:1 到1000:1 的数量级,如果只讨论头部信息的话,数据更少,再加上一旦压缩后可以不用修改,将多个节点的信息放在公用的节点的缓存内,比如Hbase或者其他形式的分布式缓存. 这样可以极大的提高数据过滤和减少磁盘不必要的IO,再加上统计信息,为静态执行计划又提供了一定的可能性.

       

      如果说Google 的Tenzing 能够实现分析PB 级的数据以秒的延迟完成,绝对有理由相信未来的Hadoop 至少可以实现10秒-20秒级别分析PB 级别的数据.(当然别变成了中国国足,韩国国足,日本国足去见上帝的笑话了)

       

       

      参考资料:

      原版的rcfile 论文

      http://www.cse.ohio-state.edu/hpcs/WWW/HTML/publications/papers/TR-11-4.pdf

       

      csdn 上翻译的rcfile 论文: 作者没有翻译论证的过程,其实这部分才是一个论文最重要的部分

      http://cloud.csdn.net/a/20110429/296900.html

       

      Hadoop 的资源统计

      https://issues.apache.org/jira/browse/MAPREDUCE-220

    •  

      关注我的微博:http://t.qq.com/EnnisCai

      我的微博