热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【HIVE】sql语句转换成mapreduce

1.hive是什么?2.MapReduce框架实现SQL基本操作的原理是什么?3.Hive怎样实现SQL的词法和语法解析?连接:http:www.aboutyun.comthrea

1.hive是什么?

2.MapReduce框架实现SQL基本操作的原理是什么? 3.Hive怎样实现SQL的词法和语法解析?

连接:http://www.aboutyun.com/thread-20461-1-1.html

            美团大众点评上:http://tech.meituan.com/hive-sql-to-mapreduce.html

 

hive是什么?

Hive是基于Hadoop的一个数据仓库系统,在各大公司都有广泛的应用。美团数据仓库也是基于Hive搭建,每天执行近万次的Hive ETL计算流程,负责每天数百GB的数据存储和分析。Hive的稳定性和性能对我们的数据分析非常关键。

在几次升级Hive的过程中,我们遇到了一些大大小小的问题。通过向社区的 咨询和自己的努力,在解决这些问题的同时我们对Hive将SQL编译为MapReduce的过程有了比较深入的理解。对这一过程的理解不仅帮助我们解决了 一些Hive的bug,也有利于我们优化Hive SQL,提升我们对Hive的掌控力,同时有能力去定制一些需要的功能。

MapReduce实现基本SQL操作的原理

详细讲解SQL编译为MapReduce之前,我们先来看看MapReduce框架实现SQL基本操作的原理

Join的实现原理

 

select u.name, o.orderid from order o join user u on o.uid = u.uid;

在map的输出value中为不同表的数据打上tag标记,在reduce阶段根据tag判断数据来源。MapReduce的过程如下(这里只是说明最基本的Join的实现,还有其他的实现方式)

《【HIVE】sql语句转换成mapreduce》 

Group By的实现原理

 

select rank, isonline, count(*) from city group by rank, isonline;

将GroupBy的字段组合为map的输出key值,利用MapReduce的排序,在reduce阶段保存LastKey区分不同的key。MapReduce的过程如下(当然这里只是说明Reduce端的非Hash聚合过程)

《【HIVE】sql语句转换成mapreduce》 

Distinct的实现原理

 

select dealid, count(distinct uid) num from order group by dealid;

当只有一个distinct字段时,如果不考虑Map阶段的Hash GroupBy,只需要将GroupBy字段和Distinct字段组合为map输出key,利用mapreduce的排序,同时将GroupBy字段作 为reduce的key,在reduce阶段保存LastKey即可完成去重

《【HIVE】sql语句转换成mapreduce》 

如果有多个distinct字段呢,如下面的SQL

select dealid, count(distinct uid), count(distinct date) from order group by dealid;

实现方式有两种:

(1)如果仍然按照上面一个distinct字段的方法,即下图这种实现方式,无法跟据uid和date分别排序,也就无法通过LastKey去重,仍然需要在reduce阶段在内存中通过Hash去重

《【HIVE】sql语句转换成mapreduce》

(2)第二种实现方式,可以对所有的distinct字段编号,每行数据生成n行数据,那么相同字段就会分别排序,这时只需要在reduce阶段记录LastKey即可去重。

这种实现方式很好的利用了MapReduce的排序,节省了reduce阶段去重的内存消耗,但是缺点是增加了shuffle的数据量。

需要注意的是,在生成reduce value时,除第一个distinct字段所在行需要保留value值,其余distinct数据行value字段均可为空。

《【HIVE】sql语句转换成mapreduce》

SQL转化为MapReduce的过程

了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:

  • Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
  • 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
  • 遍历QueryBlock,翻译为执行操作树OperatorTree
  • 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
  • 遍历OperatorTree,翻译为MapReduce任务
  • 物理层优化器进行MapReduce任务的变换,生成最终的执行计划

下面分别对这六个阶段进行介绍

Phase1 SQL词法,语法解析

 

Antlr

Hive使用Antlr实现SQL的词法和语法解析。Antlr是一种语言识别的工具,可以用来构造领域语言。

这里不详细介绍Antlr,只需要了解使用Antlr构造特定的语言只需要编写一个语法文件,定义词法和语法替换规则即可,Antlr完成了词法分析、语法分析、语义分析、中间代码生成的过程。

Hive中语法规则的定义文件在0.10版本以前是Hive.g一个文件,随着语法规则越来越复杂,由语法规则生成的Java解析类可能超过Java类文 件的最大上限,0.11版本将Hive.g拆成了5个文件,词法规则HiveLexer.g和语法规则的4个文件 SelectClauseParser.g,FromClauseParser.g,IdentifiersParser.g,HiveParser.g。

抽象语法树AST Tree

经过词法和语法解析后,如果需要对表达式做进一步的处理,使用 Antlr 的抽象语法树语法Abstract Syntax Tree,在语法分析的同时将输入语句转换成抽象语法树,后续在遍历语法树时完成进一步的处理。

下面的一段语法是Hive SQL中SelectStatement的语法规则,从中可以看出,SelectStatement包含select, from, where, groupby, having, orderby等子句。
(在下面的语法规则中,箭头表示对于原语句的改写,改写后会加入一些特殊词标示特定语法,比如TOK_QUERY标示一个查询块)

 

[SQL] 
纯文本查看 
?

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 selectStatement     :     selectClause     fromClause     whereClause?     groupByClause?     havingClause?     orderByClause?     clusterByClause?     distributeByClause?     sortByClause?     limitClause? -> ^(TOK_QUERY fromClause ^(TOK_INSERT ^(TOK_DESTINATION ^(TOK_DIR TOK_TMP_FILE))                       selectClause whereClause? groupByClause? havingClause? orderByClause? clusterByClause?                       distributeByClause? sortByClause? limitClause?))     ;

 

样例SQL

为了详细说明SQL翻译为MapReduce的过程,这里以一条简单的SQL为例,SQL中包含一个子查询,最终将数据写入到一张表中

 

[SQL] 
纯文本查看 
?

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 FROM (    SELECT      p.datekey datekey,      p.userid userid,      c.clienttype    FROM      detail.usersequence_client c      JOIN fact.orderpayment p ON p.orderid = c.orderid      JOIN default . user du ON du.userid = p.userid    WHERE p.datekey = 20131118 ) base INSERT OVERWRITE TABLE `test`.`customer_kpi` SELECT    base.datekey,    base.clienttype,    count ( distinct base.userid) buyer_count GROUP BY base.datekey, base.clienttype

 

SQL生成AST Tree

Antlr对Hive SQL解析的代码如下,HiveLexerX,HiveParser分别是Antlr对语法文件Hive.g编译后自动生成的词法解析和语法解析类,在这两个类中进行复杂的解析。

 

[SQL] 
纯文本查看 
?

01 02 03 04 05 06 07 08 09 10 11 12 13 14 HiveLexerX lexer = new HiveLexerX(new ANTLRNoCaseStringStream(command));    //词法解析,忽略关键词的大小写 TokenRewriteStream tokens = new TokenRewriteStream(lexer); if (ctx != null ) {    ctx.setTokenRewriteStream(tokens); } HiveParser parser = new HiveParser(tokens);                                 //语法解析 parser.setTreeAdaptor(adaptor); HiveParser.statement_return r = null ; try {    r = parser.statement();                                                   //转化为AST Tree } catch (RecognitionException e) {    e.printStackTrace();    throw new ParseException(parser.errors); }

 

最终生成的AST Tree如下图右侧(使用Antlr Works生成,Antlr Works是Antlr提供的编写语法文件的编辑器),图中只是展开了骨架的几个节点,没有完全展开。

子查询1/2,分别对应右侧第1/2两个部分。

《【HIVE】sql语句转换成mapreduce》 

这里注意一下内层子查询也会生成一个TOK_DESTINATION节点。请看上面SelectStatement的语法规则,这个节点是在语法改写中特 意增加了的一个节点。原因是Hive中所有查询的数据均会保存在HDFS临时的文件中,无论是中间的子查询还是查询最终的结果,Insert语句最终会将 数据写入表所在的HDFS目录下。

详细来看,将内存子查询的from子句展开后,得到如下AST Tree,每个表生成一个TOK_TABREF节点,Join条件生成一个“=”节点。其他SQL部分类似,不一一详述。

《【HIVE】sql语句转换成mapreduce》 

Phase2 SQL基本组成单元QueryBlock

AST Tree仍然非常复杂,不够结构化,不方便直接翻译为MapReduce程序,AST Tree转化为QueryBlock就是将SQL进一部抽象和结构化。

QueryBlock

QueryBlock是一条SQL最基本的组成单元,包括三个部分:输入源,计算过程,输出。简单来讲一个QueryBlock就是一个子查询。

下图为Hive中QueryBlock相关对象的类图,解释图中几个重要的属性

  • QB#aliasToSubq(表示QB类的aliasToSubq属性)保存子查询的QB对象,aliasToSubq key值是子查询的别名
  • QB#qbp 即QBParseInfo保存一个基本SQL单元中的给个操作部分的AST Tree结构,QBParseInfo#nameToDest这个HashMap保存查询单元的输出,key的形式是inclause-i(由于Hive 支持Multi Insert语句,所以可能有多个输出),value是对应的ASTNode节点,即TOK_DESTINATION节点。类QBParseInfo其余 HashMap属性分别保存输出和各个操作的ASTNode节点的对应关系。
  • QBParseInfo#JoinExpr保存TOK_JOIN节点。QB#QBJoinTree是对Join语法树的结构化。
  • QB#qbm保存每个输入表的元信息,比如表在HDFS上的路径,保存表数据的文件格式等。
  • QBExpr这个对象是为了表示Union操作。

《【HIVE】sql语句转换成mapreduce》

AST Tree生成QueryBlock

AST Tree生成QueryBlock的过程是一个递归的过程,先序遍历AST Tree,遇到不同的Token节点,保存到相应的属性中,主要包含以下几个过程

  • TOK_QUERY => 创建QB对象,循环递归子节点
  • TOK_FROM => 将表名语法部分保存到QB对象的TOK_INSERT => 循环递归子节点
  • TOK_DESTINATION => 将输出目标的语法部分保存在QBParseInfo对象的nameToDest属性中
  • TOK_SELECT => 分别将查询表达式的语法部分保存在destToAggregationExprs、TOK_WHERE => 将Where部分的语法保存在QBParseInfo对象的destToWhereExpr属性中

最终样例SQL生成两个QB对象,QB对象的关系如下,QB1是外层查询,QB2是子查询

QB1 \ QB2

 

Phase3 逻辑操作符Operator

 

Operator

Hive最终生成的MapReduce任务,Map阶段和Reduce阶段均由OperatorTree组成。逻辑操作符,就是在Map阶段或者Reduce阶段完成单一特定的操作。

基本的操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator

从名字就能猜出各个操作符完成的功能,TableScanOperator从MapReduce框架的Map接口原始输入表的数据,控制扫描表的数据行数,标记是从原表中取数据。JoinOperator完成Join操作。FilterOperator完成过滤操作

ReduceSinkOperator将Map端的字段组合序列化为Reduce Key/value, Partition Key,只可能出现在Map阶段,同时也标志着Hive生成的MapReduce程序中Map阶段的结束。

Operator在Map Reduce阶段之间的数据传递都是一个流式的过程。每一个Operator对一行数据完成操作后之后将数据传递给childOperator计算。

Operator类的主要属性和方法如下

  • RowSchema表示Operator的输出字段
  • InputObjInspector outputObjInspector解析输入和输出字段
  • processOp接收父Operator传递的数据,forward将处理好的数据传递给子Operator处理
  • Hive每一行数据经过一个Operator处理之后,会对字段重新编号,colExprMap记录每个表达式经过当前Operator处理前后的名称对应关系,在下一个阶段逻辑优化阶段用来回溯字段名
  • 由 于Hive的MapReduce程序是一个动态的程序,即不确定一个MapReduce Job会进行什么运算,可能是Join,也可能是GroupBy,所以Operator将所有运行时需要的参数保存在OperatorDesc 中,OperatorDesc在提交任务前序列化到HDFS上,在MapReduce任务执行前从HDFS读取并反序列化。Map阶段 OperatorTree在HDFS上的位置在Job.getConf(“hive.exec.plan”)
    + “/map.xml”

《【HIVE】sql语句转换成mapreduce》 
QueryBlock生成Operator Tree

QueryBlock生成Operator Tree就是遍历上一个过程中生成的QB和QBParseInfo对象的保存语法的属性,包含如下几个步骤:

 

  • QB#aliasToSubq => 有子查询,递归调用
  • QB#aliasToTabs => TableScanOperator
  • QBParseInfo#joinExpr => QBJoinTree => ReduceSinkOperator + JoinOperator
  • QBParseInfo#destToWhereExpr => FilterOperator
  • QBParseInfo#destToGroupby => ReduceSinkOperator + GroupByOperator
  • QBParseInfo#destToOrderby => ReduceSinkOperator + ExtractOperator

 

由于Join/GroupBy/OrderBy均需要在Reduce阶段完成,所以在生成相应操作的Operator之前都会先生成一个ReduceSinkOperator,将字段组合并序列化为Reduce Key/value, Partition Key

 

接下来详细分析样例SQL生成OperatorTree的过程

 

先序遍历上一个阶段生成的QB对象

首先根据子QueryBlock 

[Plain Text] 
纯文本查看 
?

1 TableScanOperator(“dim.user”) TS[0] TableScanOperator(“detail.usersequence_client”) TS[1] TableScanOperator(“fact.orderpayment”) TS[2]

先序遍历QBJoinTree,类QBJoinTree保存左右表的ASTNode和这个查询的别名,最终生成的查询树如下    base    /  \   p    du  /      \ c        p
前序遍历detail.usersequence_client和《【HIVE】sql语句转换成mapreduce》 

图中 TS=TableScanOperator RS=ReduceSinkOperator JOIN=JoinOperator

生成中间表与dim.user的Join操作树

《【HIVE】sql语句转换成mapreduce》 

根据QB2 FilterOperator。此时QB2遍历完成。

下图中SelectOperator在某些场景下会根据一些条件判断是否需要解析字段。

 

《【HIVE】sql语句转换成mapreduce》

 

 

图中 FIL= FilterOperator SEL= SelectOperator

根据QB1的QBParseInfo#destToGroupby生成ReduceSinkOperator + GroupByOperator

《【HIVE】sql语句转换成mapreduce》 

图中 GBY= GroupByOperator

GBY[12]是HASH聚合,即在内存中通过Hash进行聚合运算

最终都解析完后,会生成一个FileSinkOperator,将数据写入HDFS

《【HIVE】sql语句转换成mapreduce》 

图中FS=FileSinkOperator

Phase4 逻辑层优化器

大部分逻辑层优化器通过变换OperatorTree,合并操作符,达到减少MapReduce Job,减少shuffle数据量的目的。

 

② MapJoinProcessor ② GroupByOptimizer ① PredicatePushDown ColumnPruner

 

名称 作用
② SimpleFetchOptimizer 优化没有GroupBy表达式的聚合查询
MapJoin,需要SQL中提供hint,0.11版本已不用
② BucketMapJoinOptimizer BucketMapJoin
Map端聚合
① ReduceSinkDeDuplication 合并线性的OperatorTree中partition/sort key相同的reduce
谓词前置
① CorrelationOptimizer 利用查询中的相关性,合并有相关性的Job,HIVE-2206
字段剪枝

 

表格中①的优化器均是一个Job干尽可能多的事情/合并。②的都是减少shuffle数据量,甚至不做Reduce。

 

CorrelationOptimizer优化器非常复杂,都能利用查询中的相关性,合并有相关性的Job,参考 Hive Correlation Optimizer

 

对于样例SQL,有两个优化器对其进行优化。下面分别介绍这两个优化器的作用,并补充一个优化器ReduceSinkDeDuplication的作用

PredicatePushDown优化器

断言判断提前优化器将OperatorTree中的FilterOperator提前到TableScanOperator之后

 

《【HIVE】sql语句转换成mapreduce》

 

NonBlockingOpDeDupProc优化器

《【HIVE】sql语句转换成mapreduce》 
ReduceSinkDeDuplication优化器

ReduceSinkDeDuplication可以合并线性相连的两个RS。实际上CorrelationOptimizer是 ReduceSinkDeDuplication的超集,能合并线性和非线性的操作RS,但是Hive先实现的 ReduceSinkDeDuplication

 

譬如下面这条SQL语句

 

 

[Python] 
纯文本查看 
?

1 from (select key, value from src group by key, value) s select s.key group by s.key;

 

 

经过前面几个阶段之后,会生成如下的OperatorTree,两个Tree是相连的,这里没有画到一起

 

《【HIVE】sql语句转换成mapreduce》

 

 

这时候遍历OperatorTree后能发现前前后两个RS输出的Key值和PartitionKey如下

 

parentRS

 

Key PartitionKey
childRS key key
key,value key,value

 

ReduceSinkDeDuplication优化器检测到:1. pRS Key完全包含cRS Key,且排序顺序一致;2. pRS PartitionKey完全包含cRS PartitionKey。符合优化条件,会对执行计划进行优化。

 

ReduceSinkDeDuplication将childRS和parentheRS与childRS之间的Operator删掉,保留的RS的Key为key,value字段,PartitionKey为key字段。合并后的OperatorTree如下:

 

《【HIVE】sql语句转换成mapreduce》

 

Phase5 OperatorTree生成MapReduce Job的过程

OperatorTree转化为MapReduce Job的过程分为下面几个阶段

 

  • 对输出表生成MoveTask
  • 从OperatorTree的其中一个根节点向下深度优先遍历
  • ReduceSinkOperator标示Map/Reduce的界限,多个Job间的界限
  • 遍历其他根节点,遇过碰到JoinOperator合并MapReduceTask
  • 生成StatTask更新元数据
  • 剪断Map与Reduce间的Operator的关系

对输出表生成MoveTask

由上一步OperatorTree只生成了一个FileSinkOperator,直接生成一个MoveTask,完成将最终生成的HDFS临时文件移动到目标表目录下

MoveTask[Stage-0] Move Operator

开始遍历

将OperatorTree中的所有根节点保存在一个toWalk的数组中,循环取出数组中的元素(省略QB1,未画出)

 

《【HIVE】sql语句转换成mapreduce》

 

 

取出最后一个元素TS[p]放入栈 opStack{TS[p]}中

Rule #1 TS% 生成MapReduceTask对象,确定MapWork

发现栈中的元素符合下面规则R1(这里用python代码简单表示)

 

 

[Python] 
纯文本查看 
?

1 " ".join([t + " % " for t in opStack]) == " TS % "

 

 

生成一个MapReduceTask[Stage-1]对象的MapReduceTask[Stage-1]包含了以

 

《【HIVE】sql语句转换成mapreduce》

 

Rule #2 TS%.*RS% 确定ReduceWork

继续遍历TS[p]的子Operator,将子Operator存入栈opStack中

当第一个RS进栈后,即栈opStack = {TS[p], FIL[18], RS[4]}时,就会满足下面的规则R2

 

 

[Python] 
纯文本查看 
?

1 " ".join([t + " % " for t in opStack]) == " TS % . * RS % "

 

 

这时候在ReduceWork属性保存

《【HIVE】sql语句转换成mapreduce》 

Rule #3 RS%.*RS% 生成新MapReduceTask对象,切分MapReduceTask

继续遍历JOIN[5]的子Operator,将子Operator存入栈opStack中

 

当第二个RS放入栈时,即当栈

 

 

[Python] 
纯文本查看 
?

1 " ".join([t + " % " for t in opStack]) = = “RS % . * RS % / / 循环遍历opStack的每一个后缀数组

 

 

这时候创建一个新的JOIN[5]和JOIN[5]生成一个子OperatorRS[6]生成一个MapReduceTask[Stage-2]对象的TS[20]的引用。

新生成的

《【HIVE】sql语句转换成mapreduce》 

继续遍历RS[6]的子Operator,将子Operator存入栈opStack中

 

 

《【HIVE】sql语句转换成mapreduce》

 

 

同理生成

R4 FS% 连接MapReduceTask与MoveTask

最终将所有子Operator存入栈中之后,

 

[Python] 
纯文本查看 
?

1 " ".join([t + " % " for t in opStack]) = = “FS %

这时候将MapReduceTask[Stage-3]连接起来,并生成一个《【HIVE】sql语句转换成mapreduce》 

合并Stage

此时并没有结束,还有两个根节点没有遍历。

 

将opStack栈清空,将toWalk的第二个元素加入栈。会发现MapReduceTask[Stage-5]

 

《【HIVE】sql语句转换成mapreduce》

 

 

继续从opStack={TS[du],

RS[7]}时,满足规则R2 TS%.*RS%

 

此时将MapReduceTask[Stage-5]的Map

MapReduceWork>对象中发现,MapReduceTask[Stage-2]和

 

《【HIVE】sql语句转换成mapreduce》

 

 

同理从最后一个根节点

 

《【HIVE】sql语句转换成mapreduce》

 

切分Map Reduce阶段

最后一个阶段,将MapWork和ReduceWork中的OperatorTree以RS为界限剪开

 

《【HIVE】sql语句转换成mapreduce》

 

OperatorTree生成MapReduceTask全貌

最终共生成3个MapReduceTask,如下图

 

《【HIVE】sql语句转换成mapreduce》

 

Phase6 物理层优化器

这里不详细介绍每个优化器的原理,单独介绍一下MapJoin的优化器

 

SortMergeJoinResolver

 

CommonJoinResolver + MapJoinResolver

 

名称 作用
Vectorizer HIVE-4160,将在0.13中发布
与bucket配合,类似于归并排序
SamplingOptimizer 并行order by优化器,在0.12中发布
MapJoin优化器

MapJoin原理

《【HIVE】sql语句转换成mapreduce》 

MapJoin简单说就是在Map阶段将小表读入内存,顺序扫描大表完成Join。

 

上图是Hive MapJoin的原理图,出自Facebook工程师Liyin Tang的一篇介绍Join优化的slice,从图中可以看出MapJoin分为两个阶段:

 

  • 通过MapReduce Local Task,将小表读入内存,生成HashTableFiles上传至Distributed Cache中,这里会对HashTableFiles进行压缩。
  • MapReduce Job在Map阶段,每个Mapper从Distributed Cache读取HashTableFiles到内存中,顺序扫描大表,在Map阶段直接进行Join,将数据传递给下一个MapReduce任务。

《【HIVE】sql语句转换成mapreduce》 

如果Join的两张表一张表是临时表,就会生成一个ConditionalTask,在运行期间判断是否使用MapJoin

CommonJoinResolver优化器

CommonJoinResolver优化器就是将CommonJoin转化为MapJoin,转化过程如下

 

  • 深度优先遍历Task Tree
  • 找到JoinOperator,判断左右表数据量大小
  • 对与小表 + 大表 => MapJoinTask,对于小/大表 + 中间表 => ConditionalTask

 

遍历上一个阶段生成的MapReduce任务,发现JOIN[8]中有一张表为临时表,先对Stage-2进行深度拷贝(由于需要保留原始执行计划为Backup
Plan,所以这里将执行计划拷贝了一份),生成一个MapJoinOperator替代JoinOperator,然后生成一个MapReduceLocalWork读取小表生成HashTableFiles上传至DistributedCache中。

 

《【HIVE】sql语句转换成mapreduce》

 

 

MapReduceTask经过变换后的执行计划如下图所示

 

《【HIVE】sql语句转换成mapreduce》

 

MapJoinResolver优化器

MapJoinResolver优化器遍历Task Tree,将所有有local work的MapReduceTask拆成两个Task

 

《【HIVE】sql语句转换成mapreduce》

 

 

最终MapJoinResolver处理完之后,执行计划如下图所示

 

《【HIVE】sql语句转换成mapreduce》

 

Hive SQL编译过程的设计

从上述整个SQL编译的过程,可以看出编译过程的设计有几个优点值得学习和借鉴

 

  • 使用Antlr开源软件定义语法规则,大大简化了词法和语法的编译解析过程,仅仅需要维护一份语法文件即可。
  • 整体思路很清晰,分阶段的设计使整个编译过程代码容易维护,使得后续各种优化器方便的以可插拔的方式开关,譬如Hive 0.13最新的特性Vectorization和对Tez引擎的支持都是可插拔的。
  • 每个Operator只完成单一的功能,简化了整个MapReduce程序。

社区发展方向

Hive依然在迅速的发展中,为了提升Hive的性能,hortonworks公司主导的Stinger计划提出了一系列对Hive的改进,比较重要的改进有:

 

  • Vectorization – 使Hive从单行单行处理数据改为批量处理方式,大大提升了指令流水线和缓存的利用率
  • Hive on Tez – 将Hive底层的MapReduce计算框架替换为Tez计算框架。Tez不仅可以支持多Reduce阶段的任务MRR,还可以一次性提交执行计划,因而能更好的分配资源。
  • Cost Based Optimizer – 使Hive能够自动选择最优的Join顺序,提高查询速度
  • Implement insert, update, and delete in Hive with full ACID support – 支持表按主键的增量更新

 

我们也将跟进社区的发展,结合自身的业务需要,提升Hive型ETL流程的性能


推荐阅读
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • 触发器的稳态数量分析及其应用价值
    本文对数据库中的SQL触发器进行了稳态数量的详细分析,探讨了其在实际应用中的重要价值。通过研究触发器在不同场景下的表现,揭示了其在数据完整性和业务逻辑自动化方面的关键作用。此外,还介绍了如何在Ubuntu 22.04环境下配置和使用触发器,以及在Tomcat和SQLite等平台上的具体实现方法。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • 在Java分层设计模式中,典型的三层架构(3-tier application)将业务应用细分为表现层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。这种分层结构不仅有助于提高代码的可维护性和可扩展性,还能有效分离关注点,使各层职责更加明确。通过合理的设计和实现,三层架构能够显著提升系统的整体性能和稳定性。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • Linux基础知识:Vi与Vim编辑器详解
    Linux基础知识:Vi与Vim编辑器详解 ... [详细]
  • Swoole加密机制的安全性分析与破解可能性探讨
    本文深入分析了Swoole框架的加密机制,探讨了其在实际应用中的安全性,并评估了潜在的破解可能性。研究结果表明,尽管Swoole的加密算法在大多数情况下能够提供有效的安全保护,但在特定场景下仍存在被攻击的风险。文章还提出了一些改进措施,以增强系统的整体安全性。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 如何有效防御网站中的SQL注入攻击
    本期文章将深入探讨网站如何有效防御SQL注入攻击。我们将从技术层面详细解析防范措施,并结合实际案例进行阐述,旨在帮助读者全面了解并掌握有效的防护策略。希望本文能为您的网络安全提供有益参考。 ... [详细]
  • 在将Excel数据导入MySQL数据库的过程中,如何确保不会生成重复记录?本文介绍了一种方法,通过PHP脚本检查数据库中是否存在相同的“Code”字段值,从而避免重复记录的产生。该方法不仅提高了数据导入的准确性,还增强了系统的健壮性。 ... [详细]
  • 数据库多表联合查询:内连接与外连接详解
    在数据库的多表查询中,内连接和外连接是两种常用的技术手段。内连接用于检索多个表中相互匹配的记录,即只有当两个表中的记录满足特定的连接条件时,这些记录才会被包含在查询结果中。相比之下,外连接则不仅返回匹配的记录,还可以选择性地返回不匹配的记录,具体取决于左外连接、右外连接或全外连接的选择。本文将详细解析这两种连接方式的使用场景及其语法结构,帮助读者更好地理解和应用多表查询技术。 ... [详细]
  • Vue应用预渲染技术详解与实践 ... [详细]
author-avatar
陶磊2922_502
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有