Hive基本架构和原理

2023-11-08

概述

Hive是建立在 Hadoop 上的数据仓库基础构架。

它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。

Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。

可以将SQL 查询转换为MapReduce 的job 在Hadoop集群上执行。

官方文档:https://cwiki.apache.org/confluence/display/Hive/Home

Hive架构

Meta store(元数据存储):通常是存储在关系数据库如mysql/derby中。hive将元数据存储在数据库中,hive中的元数据包括表的名字,表的列和分区,表的属性(内部表、外部表)。

Client(用户接口):包括CLI、JDBC/ODBC、WebGUI。CLI是shell命令行;JDBC/ODBC是hive的java实现;WebGUI通过浏览器访问hive。

解析器、编译器、优化器、执行器:完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,最后由MapReduce调用执行。

从架构图上可以很清楚地看出Hive和Hadoop(MapReduce,HDFS)的关系。

  1. Hive是最上层,即客户端层或者作业提交层。
  2. MapReduce/Yarn是中间层,也就是计算层。
  3. HDFS是底层,也就是存储层。

facebook的一张架构图

从Facebook的图上可以看出,Hive主要有QL,MetaStore和Serde三大核心组件构成。QL就是编译器,也是Hive中最核心的部分。Serde就是Serializer和Deserializer的缩写,用于序列化和反序列化数据,即读写数据。MetaStore对外暴露Thrift API,用于元数据的修改。比如表的增删改查,分区的增删改查,表的属性的修改,分区的属性的修改等。

Hive数据模型

Hive元数据信息存储在Hive MetaStore中,如文件路径、文件格式、列、数据类型、分隔符,Hive默认的分格符有三种,分别是A(Ctrl+A)、B和^C,即ASCii码的1、2和3,分别用于分隔列,分隔列中的数组元素,和元素Key-Value对中的Key和Value。

Hive 中所有的数据都存储在 HDFS 中,Hive 中包含以下数据模型:Table,External Table,Partition,Bucket。

(1)表table:一个表就是hdfs中的一个目录

(2)区Partition:表内的一个区就是表的目录下的一个子目录

(3)桶Bucket:如果有分区,那么桶就是区下的一个单位,如果表内没有区,那么桶直接就是表下的单位,桶一般是文件的形式。

Hive SQL的编译

一条SQL,进入的Hive。经过上述的过程,其实也是一个比较典型的编译过程变成了一个作业。

Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:

(1)Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree

(2)遍历AST Tree,抽象出查询的基本组成单元QueryBlock

(3)遍历QueryBlock,翻译为执行操作树OperatorTree

(4)逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量

(5)遍历OperatorTree,翻译为MapReduce任务

(6)物理层优化器进行MapReduce任务的变换,生成最终的执行计划

Hive执行计划

可以通过查看Explain查看一个一个SQL如何变成MapReduce作业的过程的过程,例如在hive cli中执行:explain sql语句就能看到

官网LanguageManual Explain:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain#LanguageManualExplain-TheASTClause

下面是执行的一个例子:

Hive Sql的MapReduce实现原理

hive把复杂sql分解成多个MapReduce chain执行,各MR的中间结果存在为hdfs的临时文件,然后链式跑完即可获得最终结果。因此,只需明白其核心即可见微知著,下面介绍join、group by和distinct原理(直接摘抄美团技术团队的总结,so 感谢):

Join的实现原理

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

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

Group By的实现原理

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

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

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文件压缩和文件存储

hive对文件的压缩是对内容的压缩,也就是说对文件的压缩不是先生成文件,再对文件压缩,而是在生成文件时,对其中的内容字段进行压缩,最终压缩后,对外仍体现为某种具体的压缩文件。

常用的压缩编解码器如下表:

常用的文件格式:

(1) Textfile

文本格式,Hive的默认格式,数据不压缩,磁盘开销大、数据解析开销大。可结合Gzip、Bzip2使用,但使用Gzip这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。行式存储

对应的hive API为:org.apache.hadoop.mapred.TextInputFormat和org.apache.hive.ql.io.HiveIgnoreKeyTextOutputFormat

(2)SequenceFile

Hadoop提供的一种二进制文件格式是Hadoop支持的标准文件格式(其他生态系统并不适用),可以直接将对序列化到文件中,所以sequencefile文件不能直接查看,可以通过Hadoop fs -text查看。具有使用方便,可分割,可压缩,可进行切片。压缩支持NONE, RECORD, BLOCK(优先)等格式,可进行切片。行式存储

对应hive API为:org.apache.hadoop.mapred.SequenceFileInputFormat和org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

(3)RCFile

是一种行列存储相结合的存储方式,先将数据按行进行分块再按列式存储,保证同一条记录在一个块上,避免读取多个块,有利于数据压缩和快速进行列存储。列式存储

对应的hive API为:org.apache.hadoop.hive.ql.io.RCFileInputFormat和org.apache.hadoop.hive.ql.io.RCFileOutputFormat

(4)ORCFile

orcfile是对rcfile的优化,可以提高hive的读写、数据处理性能,提供更高的压缩效率(目前主流选择之一)。列式存储

(5)Parquet

一种列格式, 可提供对其他 hadoop 工具的可移植性, 包括Hive, Drill, Impala, Crunch, and Pig

对应的hive API为:org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat和org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat

(6)Avro

Avro是一个数据序列化系统,设计用于支持大批量数据交换的应用。它的主要特点有:支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro提供的机制使动态语言可以方便地处理Avro数据。

对应的hive API为:org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat和org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat

几种文件存储格式的性能测试结果:

存储格式

ORC

Sequencefile

Parquet

RCfile

Avro

数据压缩后大小

1.8G

67.0G

11G

63.8G

66.7G

存储耗费时间

535.7s

625.8s

537.3s

543.48

544.3

SQL查询响应速度

19.63s

184.07s

24.22s

88.5s

281.65s

实践中常用的压缩+存储可以选择(部分)

Textfile+Gzip

SequenceFile+Snappy

ORC+Snappy

Hive建表指定文件格式

[STORED AS file_format]

file_format:

  : SEQUENCEFILE

  | TEXTFILE -- (Default, depending on hive.default.fileformat configuration)

  | RCFILE -- (Note: Available in Hive 0.6.0 and later)

  | ORC -- (Note: Available in Hive 0.11.0 and later)

  | PARQUET -- (Note: Available in Hive 0.13.0 and later)

  | AVRO -- (Note: Available in Hive 0.14.0 and later)

  | JSONFILE -- (Note: Available in Hive 4.0.0 and later)

  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

注:

Hive wiki CreateTable:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable

Hive建表指定压缩

CREATE EXTERNAL TABLE IF NOT EXISTS tb_test(
     id bigint COMMENT 'id',
     name string COMMENT 'name'     
 )
COMMENT 'test table'
PARTITIONED BY (dt string)
STORED AS ORC
tblproperties ('orc.compress'='SNAPPY');

Hive动态设置压缩

压缩格式       Hadoop压缩编码/解码器

Deflate   org.apache.hadoop.io.compress.DeflateCodec

gzip org.apache.hadoop.io.compress.GzipCodec

bzip2      org.apache.hadoop.io.compress.BZip2Codec

LZO com.hadoop.compression.lzo.LzopCodec

Lz4  org.apache.hadoop.io.compress.Lz4Codec

Snappy   org.apache.hadoop.io.compress.SnappyCodec

Hive中间数据压缩

hive.exec.compress.intermediate:默认该值为false,设置为true为激活中间数据压缩功能。就是在MapReduce的shuffle阶段对mapper产生的中间结果数据压缩。在这个阶段,优先选择一个低CPU开销的算法。

set hive.exec.compress.intermediate=true;
set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;

Hive最终数据压缩

hive.exec.compress.output:用户可以对最终生成的Hive表的数据通常也需要压缩。该参数控制这一功能的激活与禁用,设置为true来声明将结果文件进行压缩。

set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;

参考:

Hive支持的文件格式与压缩算法:https://my.oschina.net/hulubo/blog/915072?tdsourcetag=s_pctim_aiomsg(推荐)

File Formats:https://cwiki.apache.org/confluence/display/Hive/FileFormats

Hive文件存储格式:https://www.jianshu.com/p/694f044d1c34

Hive压缩格式:https://www.cnblogs.com/skyl/p/4740301.html

如何在MapReduce中使用SequenceFile数据格式?http://blog.itpub.net/31077337/viewspace-2214505

如何在MapReduce中使用Avro数据格式?http://blog.itpub.net/31077337/viewspace-2214709

Hive Map和Reduce数量计算

Map数量

num_Map_tasks = max[${Mapred.min.split.size},min(${dfs.block.size}, ${Mapred.max.split.size})]

Mapred.min.split.size指的是数据的最小分割单元大小。

Mapred.max.split.size指的是数据的最大分割单元大小。

dfs.block.size指的是HDFS设置的数据块大小。

一般来说dfs.block.size这个值是一个已经指定好的值,而且这个参数Hive是识别不到的,所以实际上只有Mapred.min.split.size和Mapred.max.split.size这两个参数(本节内容后面就以min和max指代这两个参数)来决定Map数量。在Hive中min的默认值是1B,max的默认值是256MB。所以如果不做修改的话,就是1个map task处理256MB数据,我们就以调整max为主。通过调整max可以起到调整Map数的作用,减小max可以增加Map数,增大max可以减少Map数 。需要提醒的是,直接调整Mapred.Map.tasks这个参数是没有效果的。

Reduce数量

这里说的Reduce阶段,是指前面流程图中的Reduce phase(实际的Reduce计算)而非图中整个Reduce task。Reduce阶段优化的主要工作也是选择合适的Reducetask数量,跟上面的Map优化类似。

与Map优化不同的是,Reduce优化时,可以直接设置Mapred。Reduce。tasks参数从而直接指定Reduce的个数。当然直接指定Reduce个数虽然比较方便,但是不利于自动扩展。Reduce数的设置虽然相较Map更灵活,但是也可以像Map一样设定一个自动生成规则,这样运行定时Job的时候就不用担心原来设置的固定Reduce数会由于数据量的变化而不合适。

Hive估算Reduce数量的时候,使用的是下面的公式:

num_Reduce_tasks = min[${Hive.exec.Reducers.max},(${input.size} / ${ Hive.exec.Reducers.bytes.per.Reducer})]

也就是说,根据输入的数据量大小来决定Reduce的个数,默认Hive.exec.Reducers.bytes.per.Reducer为1G,而且Reduce个数不能超过一个上限参数值,这个参数的默认取值为999。所以我们可以调整Hive.exec.Reducers.bytes.per.Reducer来设置Reduce个数。

数据倾斜

定义: 由于数据分布不均匀,造成数据热点。

现象: 一个或几个key的记录数与平均记录数差异过大,最长时长远大于平均时长。任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。

数据倾斜优化:一般分为join引起和group by引起分别解决。

  1. Group by :      分组key集中 处理某key值的reduce非常耗时
  2. Join :关联key集中(例如关联字段空值过多) 处理某key值的reduce非常耗时

Group by引起的数据倾斜

分两方面优化:

第一个:

set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval=100000;
set hive.map.aggr.hash.min.reduction=0.5;

hive.map.aggr=true(默认)参数控制在group by的时候是否map局部聚合,但也不是都会局部聚合,如果聚合前后差别不是很大,聚合也就没什么意义了。

后两个设置是判断是否需要做map局部聚合,即:预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合。

第二个:

set Hive.groupby.skewindata=true;

控制启动两个MR Job完成,第一个Job先不按GroupBy字段分发,而是随机分发做一次聚合,然后启动第二个Job,拿前面聚合过的数据按GroupBy字段分发计算出最终结果。但是否生效还存在限制,详情见 Hive-hive.groupby.skewindata配置相关问题调研

Join引起的数据倾斜

优化主要分两个方向:skew join和重写业务逻辑

Skew join

set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;

记录超过hive.skewjoin.key(默认100000)阈值的key值先写入hdfs,然后再进行一个map join的job任务,最终和其他key值的结果合并为最终结果。其过程如下图:

重写业务逻辑

这个需要结合具体的场景重写,例如:在日志表与用户表关联时候(通过user_id关联),直接关联可能导致user_id为null的发生数据倾斜,此时可以把日志表中user_id为null的单独处理,如下:

SELECT a.xx, b.yy FROM log a JOIN users b
            ON a.user_id IS NOT NULL
                AND a.user_id = b.user_id
UNION ALL
SELECT a.xx, NULL AS yy FROM log a WHERE a.user_id IS NULL;

参考:

HiveQL中如何排查数据倾斜问题:https://blog.csdn.net/u012151684/article/details/77074356

Hive性能优化

见另一篇博文 Hive常用优化参数

常见问题

请说明hive中 Sort By,Order By,Cluster By,Distrbute By各代表什么意思

order by:会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。

sort by:对分区内的数据进行排序,不是全局排序,其在数据进入reducer前完成排序。

distribute by:对map输出进行分区,按照指定的字段对数据进行划分输出到不同的reduce中。常和sort by一起使用,例如:select mid, money, name from store distribute by mid sort by mid asc, money asc

cluster by:当 distribute by 和 sorts by 字段相同时,可使用 cluster by 方式替代,cluster by 具有 distribute by 和 sort by 的组合功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC

NULL在hive的一般处理

NULL默认的存储都是\N,可以在建表时通过serialization.null.format的设置。

NULL 值的过滤,一般是is null 和 is not null。

multi-group新特性的好处?

multi group by 可以将查询中的多个group by操作组装到一个MapReduce任务中,起到优化作用。例如:

from area
    insert overwrite table temp1
        select Provice,city,county,count(rainfall) from area where data="2018-09-02" group by provice,city,count
    insert overwrite table temp2
        select Provice,count(rainfall) from area where data="2018-09-02" group by provice

参考

官方文档:https://cwiki.apache.org/confluence/display/Hive/Home

HiveSQL的编译过程(美团):https://tech.meituan.com/2014/02/12/hive-sql-to-mapreduce.html

HiveSQL编译过程: https://www.slideshare.net/recruitcojp/internal-hive

Hive的核心原理以及查询优化:http://www.pianshen.com/article/4247149029

深入浅出数据仓库中SQL性能优化之Hive篇:http://www.codeceo.com/article/sql-hive.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hive基本架构和原理 的相关文章

随机推荐

  • ADC0832的AD模数转换原理及编程

    作者简介 嵌入式领域优质创作者 博客专家 个人主页 咸鱼弟 系列专栏 单片机设计专栏 目录 一 描述 二 模数转换原理 三 模数转换的过程 四 八位串行A D转换器ADC0832简介 五 ADC0832特点 六 芯片接口说明 七 ADC08
  • TongWeb及应用系统安全加固

    前言 本文档主要面向运维人员说明常见的TongWeb6 TongWeb7安全加固的配置方法 TongWeb配置 一 首先建议TongWeb升级到最新版本 早期版本存在一些代码级安全漏洞 无法通过配置解决 截止2021年4月15日TongWe
  • codeblocks安装后出现问题的可能解决办法

    昨天在写cf的时候遇到了一个问题 因为办公室这台电脑我是刚用 没有装过codeblocks之前 在用到花括号构造的时候报错 如图 不能直接用花括号了 这我能忍 按照以往的经验来说 是compiler出现了问题 于是设置了一下 看起来好像对了
  • msvcr120.dll丢失的解决方法,win10系统dll报错解决方法

    今天 我将和大家分享一个在win10系统中经常遇到的问题 msvcr120 dll丢失 相信很多朋友在使用电脑的过程中都会遇到这个问题 那么如何解决呢 接下来 就让我为大家详细讲解一下解决方法 首先 我们来了解一下msvcr120 dll文
  • Kazantzis-Kravaris-Luenberger ( KKL )非线性观测器

    The formulation of the observer design problem is realized via a system of singular first order linear PDEs and a rather
  • 【Python搞搞轻量Blog】第二发 Flask入门(2)

    上一篇文章 Flask入门 中创建了一个非常简单的Web应用 但从最简单中又稍微深入的说了一下Flask 基于Werkzeug 使用模板 利用HTML 如何快速利用写好的HTML呢 第一步 在和主应用的同级目录下 创建一个名为 templa
  • [算法]PRML学习笔记1.2.6贝叶斯曲线拟合(Bayesian curve fitting)

    参考文献 Pattern Recognition and Machine Learning Published by Springer January 2006 https www microsoft com en us research
  • 【Vue 学习】修改页面默认的标题

    修改页面默认的标题 一般是在 public index html 里面进行设置网页标题 如下 Vue 的脚手架使用了读取配置文件的方式来设置网页标题 如下 配置文件的内容如下 总结 直接修改 public index html 文件 修改配
  • FPN(特征金字塔)图解

    FPN 看了mask RCNN的源代码 其中用到fpn 根据源代码画了个图 当然FPN重要的是它的思想 有一些超参数可以根据自己的框架进行调整
  • [HFSS]Floquet port激励及主从边界设置(实例)

    Floquet port激励及主从边界设置 1 Floquet port简介 2 基本模型建立 3 主从边界设置 4 wave port 设置 5 floquet port 设置 6 Analysis setup 7 验证 仿真 8 结果演
  • Python标准库、模块、包的区别

    文章目录 模块 包 标准库 第三方库 自定义模块 模块 模块可定义为一个包含python定义和语句的 py文件 模块中包含python代码以及python函数 类或python变量 一个模块可以被其他 py文件导入使用 也可以单独作为脚本文
  • 3.3 Git 分支 - 分支管理

    3 3 Git 分支 分支管理 版本说明 版本 作者 日期 备注 0 1 loon 2019 3 23 初稿 目录 文章目录 3 3 Git 分支 分支管理 版本说明 目录 分支管理 分支管理 现在已经创建 合并 删除了一些分支 让我们看看
  • 51单片机的几种中断的用法

    1 外部中断0 外部中断0实验 实现现象 下载程序后按下K3按键可以对D1小灯状态取反 注意事项 无 include reg52 h 此文件中定义了单片机的一些特殊功能寄存器 typed
  • gitlab可以访问,但git clone连接超时不能下载

    因此 我们可以把 http wozhendetainanle map 地址后面加上 git后缀 更改为 http wozhendetainanle map git 此时使用就可以下载了
  • 关于C#监视剪贴板信息

    1 常规方法 在C 中 有一个常规检测剪贴板的方法 用的是 System Windows Forms Clipboard 使用起来很简单 代码如下
  • 微信小程序中的App、Page、Component的生命周期函数

    有点混乱的官方文档 一 什么是生命周期和生命周期函数 字面意义上说 生命周期就是指一个对象自身的生老病死 在程序运行上也可以这么理解 程序也是对象 也有 生老病死 程序自身从创建到销毁的过程中 运行到特定的阶段 会触发特定的函数 这些函数
  • Distributed Database System —— 什么是嵌入式数据库?

    文章目录 什么是嵌入式数据库 Embedded Database 数据库服务器的架构 嵌入式数据库架构 区别 像Oracle Sybase MySQL和SQL Server这些大家熟知的数据库都属于数据库服务器 当然不排除某些也提供嵌入式版
  • “新”科学家Stephen Wolfram

    2011年10月的iPhone 4S发布会上 苹果副总裁Scott Forstall长按Home键 对着那个泛着紫色光晕的话筒问道 Stephen Wolfram 离圣诞节还有几天 让我查查 稍等 Scott得到了他想要的答案 82 天 也
  • 单片机设计_室内环境智能监测系统(STM32 OLED ESP8266 DHT11 MQ-2 加湿器)

    想要更多项目私wo 一 电路设计 室内环境智能监测系统 主要功能 1 检测空气温湿度 2 检测光照强度 3 检测烟雾浓度 4 数据显示在手机端和设备OLED屏幕上 5 当空气温度高于设定的阈值时 风扇开启 6 当空气湿度低于设定的阈值时 加
  • Hive基本架构和原理

    概述 Hive是建立在 Hadoop 上的数据仓库基础构架 它提供了一系列的工具 可以用来进行数据提取转化加载 ETL 这是一种可以存储 查询和分析存储在 Hadoop 中的大规模数据的机制 Hive 定义了简单的类 SQL 查询语言 称为