• 一文弄懂Hive基本架构和原理——Hive元数据信息存储在Hive MetaStore中,Hive 中所有的数据都存储在 HDFS 中,Hive 中数据模型:Table,External Table,Partition,Bucket;最后将一个SQL变成hadoop MapReduce作业


    一文弄懂Hive基本架构和原理
    from:https://blog.csdn.net/oTengYue/article/details/91129850

    文章目录

        概述
        Hive架构
        Hive数据模型
        Hive SQL的编译
        Hive执行计划
        Hive Sql的MapReduce实现原理
            Join的实现原理
            Group By的实现原理
            Distinct的实现原理
        Hive文件压缩和文件存储
            Hive建表指定文件格式
            Hive建表指定压缩
            Hive动态设置压缩
                Hive中间数据压缩
                Hive最终数据压缩
        Hive Map和Reduce数量计算
            Map数量
            Reduce数量
        数据倾斜
            Group by引起的数据倾斜
            Join引起的数据倾斜
                Skew join
                重写业务逻辑
        Hive性能优化
        常见问题
            请说明hive中 Sort By,Order By,Cluster By,Distrbute By各代表什么意思
            NULL在hive的一般处理
            multi-group新特性的好处?
        参考

    概述

    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架构

    在这里插入图片描述
    从架构图上可以很清楚地看出Hive和Hadoop(MapReduce,HDFS)的关系。

        Hive是最上层,即客户端层或者作业提交层。
        MapReduce/Yarn是中间层,也就是计算层。
        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
    在这里插入图片描述
    下面是执行的一个例子:
    Xnip2019-06-06_14-08-13
    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

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10

    注:
    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');

        1
        2
        3
        4
        5
        6
        7
        8

    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;

        1
        2

    Hive最终数据压缩

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

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

        1
        2

    参考:
    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})]

        1
        2
        3

        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})]

        1
        2

    也就是说,根据输入的数据量大小来决定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引起分别解决。
    操作     原因     现象
    Group by     分组key集中     处理某key值的reduce非常耗时
    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;

        1
        2
        3
        4
        5

    参考:
    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
    ————————————————
    版权声明:本文为CSDN博主「HaiwiSong」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/oTengYue/article/details/91129850

  • 相关阅读:
    HBase导入数据同时与Phoenix实现同步映射
    Hive导入数据到HBase,再与Phoenix映射同步
    CDH5.16.1离线集成Phoenix
    设计原则学习笔记
    Maven安装配置
    SpringBoot之Mybatis操作中使用Redis做缓存
    Linux服务器防火墙白名单设置
    Linux查看端口占用情况,并强制释放占用的端口
    shell脚本切割tomcat日志文件
    mysql读写分离
  • 原文地址:https://www.cnblogs.com/bonelee/p/12441622.html
Copyright © 2020-2023  润新知