TDW(Tencent Data Warehouse)之hive简介



1.     基本概念


  Hive是由Facebook在2007年8月开始开发,并于2008年8月开源(https://issues.apache.org/jira/browse/HADOOP-3601)。它是建立在Hadoop上的数据仓库工具,它可以对存储在HDFS、HBase、PG等存储系统中的文件进行结构化分析等操作。


  Hive提供了以下功能:


  1)       提供类SQL语言(HQL),可以很方便的做ETL操作


  2)       数据可以存储在多个不同的存储系统,可以使用多种存储类型


  3)       查询执行是通过MapReduce实现


  4)       提供丰富的函数,普通函数(split等)、分析函数(sum等)、表级函数(row_number等)


 

2.     产生背景


  在Hadoop出现以前,是关系型数据库的天下,SQL语言成为很多人的必备技能。但是,随着数据量的日益增长,单机存储计算已然满足不了海量数据的分析需求。并行计算框架MapReduce随之产生,并得到了迅猛的发展,它可以对数据并行分析处理,使得海量数据的快速分析成为可能。但是,编写MR程序却不是一件很容易的事情,Hive随之而来,它可以将SQL语言自动转换成MR程序去执行,可以让使用者只关注自己的业务逻辑,如此方便的神器自然得到了很多人的青睐,尤其是原来习惯编写SQL的人,hive得到的迅猛发展。


 


3.     TDW之Hive历史


  了解我们公司的Hive,不得不说TDW(Tencent distributed Data Warehouse)的历史。我们是在2009年7月,成立TDW项目组,并启动技术架构预言。同年12月,确定TDW技术架构方案,并开始投入开发。2010年6月TDW 0.1版本发布,具备数据仓库基础功能。随后,不断完善功能、调优。2011年7月,TDW IDE发布,提高了TDW的易用性的同时,大大促进了TDW在公司的普及。


  TDW是公司级数据平台,基于share-nothing架构,具有高可用性和高可伸缩性。业务涉及公司各个BG,目前拥有8800台集群规模,主要包括查询引擎,计算引擎和存储引擎。这其中的查询引擎就是指的Hive(这里指离线计算,实时计算使用的EasyCount系统),Hive在TDW中所处的位置如下图所示。


(老架构)



  我们的Hive是在社区版本的基础上,做了大量的优化,根据业务特点做了大量的个性化定制,如元数据库的重新设计、各类函数的实现、List/Range分区的优化设计等,使得平台的稳定性、性能和易用性都有显著提高。


 


4.     执行流程


下面将说下hive的工作原理。


 


工作流程:


  Hive提供3种用户接口:CLI(命令行模式),Client(交互模式),WebUI(网页访问)。TDW的使用方式是后台启动hiveserver,然后,使用PLC去连接HiveServer,执行相应的SQL,并返回结果。PLC是TDW自己用python实现的连接hiveServer的脚本。




  如图所示,IDE/Lhotse通过PLC连接到HiveServer(通过Thrift实现),HiveServer会去解析sql,通过MR计算相应结果,然后返回。下面将详细介绍Hive是怎样解析SQL语句,并执行任务的。


 详细流程:


  HQL语句主要分为四种:DDL(数据定义语言)、DCL(数据控制语言)、DML(数据操作语言)、DQL(数据查询语言)。


  DDL:创建/删除表,创建/删除分区,显示函数等操作。


  DCL:创建/删除用户,授予/撤销权限等操作。


  DML:insert/update等操作。


  DQL:select操作。


  DDL和DCL语句执行流程很简单,无须执行MR作业,只需要对元数据(metaDB)、HDFS、tPG库进行相应的操作即可完成。DML和DQL是一般都需要执行MR作业,除非一些特殊的语句进行优化后,无须执行MR(如select * from limit语句等)。


  DML和DQL都比较复杂,它会将HQL语句转换成一个或者多个MR作业执行,得到最终结果。


  HQL语句的执行过程总的概括为:HQL->AST->OpT->TaskT->执行->返回结果。下面我们以“SELECT a, sum(b), count(distinct c) FROM test::a_roncen1 GROUP BY a”为例,对Hive执行流程进行说明。(表a_roncen1的定义为CREATE TABLE a_roncen1(a BIGINT,bBIGINT,c STRING))


(1)     HQL->AST


  AST是指抽象语法树,Hive使用开源的语法分析器Antlr对HQL进行解析。可以在Hive.g文件中定义新的语法。上述语句,则会转为以下AST树。




(2)     AST->OpT


  OpT是指算子树,这个过程比较负责,也是hive的核心内容之一。大概分为3步:


  ①   对AST树进行深度优先遍历,遇到相应的标签,将其存储到相应的数据结构,供后续操作。


  ②   根据第一步所得的数据结构,查找元数据和操作HDFS,得到对应的相关信息,并存储。


  ③   根据上两部所得的信息,生成最后的OpT。


   如上图,


  ①   进行深度优先遍历:


      遇到TOK_FROM:将其子树作为HQL的数据源;


      遇到TOK_DESTINATION:将其作为结果文件的存放位置;


      遇到TOK_SELECT:保存选择列的信息;


      遇到TOK_GROUPBY:保存group by列的信息。


  ②   读取元数据信息:


      将数据源信息(表a_roncen1信息),结果文件信息(存放HDFS临时目录)等存放到相应的数据结构。


  ③   根据上述信息生成对应的OpT:


      数据源表(TOK_FROM)会生成“表扫描算子(TableScanOperator)”;


      选择列会生成“选择算子(SelectOperator)”;


      Group by列比较复杂,会用到reduce功能,生成“选择算子”、“输出算子(ReduceSinkOperator)”和“分组算子(GroupByOperator)”三个算子。





(3)     OpT->TaskT


  TaskT是指任务树,每个任务是hive执行的逻辑单元,任务树在这里可以简单理解为一个MR的job。


  Hive会根据算子树,生成对应的任务树,上述例子比较简单,将此算子树生成对应的MRjob。


  举个复杂的例子:SELECT a,sum(b) FROM (SELECT a, sum(b) AS b, count(distinct c) AS c FROM test::a_roncen1 GROUP BY a) sub WHERE sub.a=0 GROUP BY a ;



  这条HQL生成的TaskT如下所示,是两个MRjob,两个作业之间使用HDFS作为中间数据存储。




(4)     TaskT执行


  生成完TaskT后,就开始执行任务了。有依赖关系的job,必须要等其所有的父job执行完后,当前job才会开始执行。


  Hive会将当前job的OpT序列化到HDFS上,然后,将job提交到MR,当执行Map和Reduce时,会将序列化的OpT反序列化,对每一行数据,依次执行每个算子。数据就像流水一样,沿着算子树往下流。





(5)     返回结果


  如果是DQL语句,则会将结果存放在HDFS的临时目录下,然后,Hiveserver会去读取临时目录下的文件,并返回给客户端。


5.     总结


  TDW的Hive经历很多年的打磨,已经日趋成熟稳定。但是,随着时间的推移,我们的Hive也暴露出很多问题,如与社区的Hive相差太大,社区的很多好的功能(向量查询引擎、基于代价查询优化等)都没有引进;Hive的多个job之间使用HDFS作为中间结果存储媒介,严重影响效率等问题。


  针对第一个问题,我们在评估将社区Hive的适用我们公司业务的功能整合到TDW的Hive上。


  针对第二个问题,我们基于社区的SparkSQL上,做了很多的性能优化和个性化定制,和Hive的HQL语句已经实现了很好的兼容,可以显著提高SQL执行效率和系统稳定性。


  TDW平台会不断对平台进行优化和革新,一心致力于为用户提供稳定、优质、可靠的数据服务。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章