您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 资本运营 > Hive—一种基于MapReduce框架的仓储策略(译文)
Hive—一种基于MapReduce框架的仓储策略AshishThusoo,JoydeepSenSarma,NamitJain,ZhengShao,PrasadChakka,SureshAnthony,HaoLiu,PeteWyckoffandRaghothamMurthyFacebook数据架构团队1.引言由于商务智能行业收集和分析的数据集大小正在迅速增长,使得了传统的仓储策略代价变得尤其的高昂。Hadoop[3]是一种很受欢迎的开源map-reduce实现,它正在被用于基于通用计算机作为超大数据集存储和处理的替代品。然而,map-reduce程序设计模型是一种非常低端的,并且需要开发者去编写一些难以维护和重用性的定制程序。在本论文中,我们将提出Hive,一种开源并以Hadoop为基础的仓储策略。Hive支持类SQL说明性语言的查询表达-HiveQL,一种能在Hadoop上编译成map-reduce作业的查询语言。另外,HiveQL支持能嵌入查询的通用map-reduce脚本。这种语言包含了一个此类系统,该系统支持包含原始类型数据表,数组集合和映射集合,以及相同层分的嵌套。底层的IO库可以扩展到自定义格式下的数据查询。Hive还包括一个系统的目录和包含了模式和统计的Hive-Metastore,这在数据的索引和优化上是很有用的。在Facebook,Hive仓库包含了几千张表,这些表中有超过700TB用于报告和分析超过100个用户的的数据。文章接下来将说明如下内容。第二部分描述Hive的数据模型和结合一个例子的HiveQl语言应用。第三部分讲解Hive的系统结构和概述它的查询生命周期。第四部分则是提供一个示范的全过程。最后将在第五部分做一个总结和未来的计划。2.HIVE数据库2.1数据模型数据在Hive中是这样组成的:内部表——这些表和关系数据库中的表的概念是类似的。每个表在Hive中都有一个相应的HDFS目录。表中的数据被序列化并存储在该目录的文件当中。用户可以将表和序列化格式的底层数据关联起来。Hive提供利用压缩和懒惰反序列化的内置序列化格式。用户还可以添加SerDe方法(该方法用Java编写,称为自定义序列化和反序列化方法)所支持的新数据格式。每张表的序列化格式被存储在系统的目录下,并且自动被Hive用于查询的编译和执行。Hive也支持外部表存储在HDFS,NFS和本地路径中。分区——每张表可以有一个或更多的分区,这些分区决定了表目录下子目录中的数据分布。假设数据表T在目录/wh/T下。如果T是划分了ds和ctry列,那么特定值分别是ds=20090101和ctry=US的数据,将存储在目录为/wh/T/ds=20091010/ctry=US的文件里。Buckt——在每个分区的数据可能顺序分成以表中hash列为基础的Buckt。每个Buckt将以文件形式存储在分区目录中。Hive支持基本的列类型(整数、浮点、字符串、日期和布尔型)和嵌套集合类型——数组和映射。用户也可以编程方式来定义自己的类型。2.2查询语言Hive提供了一种类似SQL的查询语言——HiveQL,它支持在from子句中嵌套select,project,join,aggregate,unionall和子查询。HiveQL支持数据定义(DDL)语句来创建特定序列化格式的内部表和分区,以及Buckt类型的列。用户可以从外部源加载数据,将查询结果通过数据操作(DML)语句分别加载和插入到Hive表中。HiveQL目前还不支持更新和删除现有表中的行。HiveQL支持多表插入操作,用户可以通过使用一个HiveQL语句来执行在一个相同输入数据中的多个查询。Hive通过共享该输入数据的扫描来优化这些查询。HiveQL也是有很好扩展性的。它支持Java实现的用户定义的列变换(UDF)和聚合(UDAF)函数。此外,用户可以使用一个简单的基于行的流的接口嵌入用任何语言写的map-reduce自定义脚本,也就是从标准输入中读取行,以及在标准输出写出行。这也就灵活的实现了字符串和行的转换。由于缺少空间我们省略了很多的细节。如有需要对HiveQL的完整描述请查看语言指南[5]。2.3运行实例:StatusMeme我们现在展示一个高度简化的应用程序——StatusMeme——灵感源于Facebook的词典[6]。当Facebook用户更新自己的状态时,该更新将记录到每天循环更新的网络文件系统(NFS)目录/logs/statusupdates下。我们每天加载这个数据到Hive的一个表中statusupdates(useridint,statusstring,dsstring)使用加载声明如下:LOADDATALOCALINPATH`/logs/status_updates'INTOTABLEstatus_updatesPARTITION(ds='2009-03-20')当状态更新发生时,每个状态更新记录包含了用户标识(userid),实际状态的字符串(Status),以及日期(ds)。该表分区在ds列。在配置文件(useridint,schoolstring,genderint)的表中可见详细的用户配置文件信息,如用户的性别和用户就读的学校。我们首先要每日计算基于用户性别和就读学校的统计状态的更新频率。以下多表插入语句由学校(归入schoolsummary(schoolstring,cntint,dsstring))和性别(归入gendersummary(genderint,cntint,dsstring))使用状态更新和配置文件表的结合的单一扫描生成每日状态更新。既然输出表也在ds列分区,HiveQL允许用户将查询结果插入到一个输出表的特定分区中。FROM(SELECTa.status,b.school,b.genderFROMstatus_updatesaJOINprofilesbON(a.userid=b.useridanda.ds='2009-03-20'))subq1INSERTOVERWRITETABLEgender_summaryPARTITION(ds='2009-03-20')SELECTsubq1.gender,COUNT(1)GROUPBYsubq1.genderINSERTOVERWRITETABLEschool_summaryPARTITION(ds='2009-03-20')SELECTsubq1.school,COUNT(1)GROUPBYsubq1.school接下来,我们想要展示每个学校用户状态更新所决定的十个最流行的模因。我们现在说明该计算是如何通过HiveQl的map-reduce结构做到的。我们通过插入一个自定义Pythonmapper脚本memes-extractor.py文件来分析状态更新和概要表之间连接的结果,该文件使用复杂的自然语言处理技术来从状态字符串中提取模因。Hive由于还不支持该等级排列集合函数,但每个学校的前十模因能够通过一个简单的自定义Pythonreduce脚本top10.py文件来计算。REDUCEsubq2.school,subq2.meme,subq2.cntUSING`top10.py'AS(school,meme,cnt)FROM(SELECTsubq1.school,subq1.meme,COUNT(1)AScntFROM(MAPb.school,a.statusUSING`meme-extractor.py'AS(school,meme)FROMstatus_updatesaJOINprofilesbON(a.userid=b.userid))subq1GROUPBYsubq1.school,subq1.memeDISTRIBUTEBYschool,memeSORTBYschool,meme,cntdesc)subq2;图1:Hive的体系结构3.HIVE的体系结构图1显示的是Hive主要组件以及它和Hadoop的相互作用。Hive的主要组件:外部接口——Hive同时提供了用户界面的命令行(CLI)和WebUI,以及应用程序编程接口(API),如JDBC和ODBC。HiveThrift服务器公开了一个简单的客户端API来执行HiveQL语句。Thrift[8]是一个用于跨语言服务的框架,框架内用一种语言(如Java)编写,服务器也可以支持其他的语言的客户端。ThriftHive客户端用不同语言生成用于构建常用的驱动程序,如JDBC(java),ODBC(c++),以及用php,perl,python等编写的脚本驱动程序。元数据存储(metastore)是系统目录。所有其他的Hive组件都和metastore有交互。更多的细节详见3.1节。驱动程序控制着一个HiveQL语句在编译、优化和执行的生命周期。在收到HiveQL语句后,它从Thrift服务器或者其他的接口创建一个用于后来跟踪比如执行时间、输出行数量等统计的会话句柄。编译器在驱动程序接收到一个HiveQL语句时被调用。编译器将该语句编译成mapreduce作业主动管理中的一个计划。更多细节详见3.2节。该驱动程序从主动管理器提交单独的map-reduce作业到一个拓扑秩序中的驱动引擎。Hive目前使用Hadoop作为它的驱动引擎。我们接下来详细描诉metastore和编译器。3.1MetastoreMetastore是系统目录,包含存储在Hive中表的元数据。这个元数据在表每次在HiveQL引用时被创建和重用期间是规定的。Metastore使得Hive作为一个传统的仓储策略(alaOracle或者DB2)和构建在map-reduce架构上类似数据处理系统的Pig[7]和Scope[2]相比较显得尤为突出。Metastore包含以下对象:数据库——一个作为表的命名空间。数据库中“default”是用于表示该表在数据库中没有用户指定值。表——表中元数据含有列的列表和它们的类型、所属单位、存储以及SerDe信息。它也可以包含任何用户提供的key-value的数据;该工具在未来可以用来存储表统计信息。存储信息包括了文件系统、数据格式和桶信息底层表数据的位置。SerDe元数据包括了并串行转换器和串并转换器方法的实现类,以及任何支持实现所需信息。所有这些都可以在表的创建期间提供信息。分区——每个分区可以有它自己的列和SerDe以及存储信息。这个可以用于在将来支持Hive存储仓库模式演变。作为Metastore的存储系统应该在联机事务处理的随机存取和更新上被充分利用。文件系统如HDFS是不适合的,因为它在顺序扫描上而不是随机存取上有优化。所以,Metastore要么使用传统的关系数据库(比如MySQL,Oracle),要么是文件系统(如本地存储,NFS,AFS),但不是HDFS。因此,只访问元数据对象的HiveQL语句在低的延迟时可以有效的执行。但是,Hive必须明确地维护元数据和数据之间的一致性。3.2编译器驱动程序调用编译器和DDL,DML或者查询语句中之一的HiveQL字符串。该编译器将字符串转换成一个执行策略。该策略仅包含元数据和HDFS操作,元数据操作只有DDL语句,HDFS操作只有LOAD语句。对于insert语句和查询来说,该方案由map-reduce作业中的有向非循环图(DAG,directedacyclicgraph)组成。解析器将查询字符串转换成一个解析树。语义分析器将解析树转换成一个基于内部的查询表示。它从Metastore中检索输入表的模式信息。它用这些信息验证列名称,扩展select*和对包括隐式类型转换的类型检查。逻辑计划发生器将内部查询表示转换为一个包含一个逻辑运算符树的逻辑计划。优化程序从几个方面执行多次经过和重写逻辑计划:结合多个共享join嵌入到一个单一的多路join的joins,因此只有一个map-reduce作业。给join,group-by和自定义map-reduce操作
本文标题:Hive—一种基于MapReduce框架的仓储策略(译文)
链接地址:https://www.777doc.com/doc-2876051 .html