|
一、HIVE组件介绍
1、客户端组件
Hive-cli
JDBC/ODBC
Toad or SQuirreL
2、HCatalog元数据管理组件,
Provides a common schema environment for multiple tools
Allows for connectors to tools to read data from and write data to Hive’s warehouse
Lets users share data across tools
Creates a relational structure to Hadoop data
Abstracts away the how and where of data storage
Hides schema and storage changes from users
3、hiveServer2接口服务组件
Execution-Engine
4、MR执行引擎组件
5、Tez执行引擎组件,省略shuffle过程
Tez avoids disk IO by avoiding expensive shuffle and shorts while leveraging more efficient map side joins. Tez also utilizes a costbased optimizer, which helps produce faster execution plans. Combine this with the ORC file format geared
toward SQL performance and you have a query engine performing up to 100x faster than native MapReduce
6、Hive-on-Spark
7、Storage: Hadoop基于hdfs文件存储
二、Hive执行流程图
HSQL执行步骤如下:
1、Antlr 定义 HSQL 的语法规则,完成 SQL 词法,语法解析,并将 SQL 转化为抽象语法树 AST Tree。
2、遍历 AST Tree,抽象出查询的基本组成单元 QueryBlock。
3、遍历 QueryBlock,翻译为执行操作树 OperatorTree。
4、逻辑层优化器进行 OperatorTree 变换,合并不必要的 ReduceSinkOperator,减少 shuffle数据量。
5、遍历 OperatorTree,翻译为 MapReduce 任务。
6、物理层优化器进行 MapReduce 任务的变换,生成最终的执行计划。
三、HIVE优化本质
1、数据倾斜
数据倾斜是指在并行进行数据处理的时候,由于单个partition的数据显著多余其他部分,分布不均匀,导致大量数据集中分布到一台或者某几台计算节点上,使得该部分的处理速度远低于平均计算速度,成为整个数据集处理的瓶颈,从而影响整体计算性能。
数据倾斜产生原因主要有以下几点:
(1)数据key值分布不均,机器配置和数据量比例不合理,业务数据本身特性导致。
(2)机器配置不合理
当机器配置与所需的数据量不相匹配的时候,总会出现部分需要处理的key值数量超出机器处理能力的情况,由此造成Reduce进程卡顿。
(3)业务数据自身特性
除了技术上的原因,业务本身的特性也会导致数据分布不均匀的情况。
2、jobs 数比较多的作业运行效率相对比较低
3、sum,count,max,min 等 UDAF,不怕数据倾斜问题
4、count(distinct ),在数据量大的情况下,效率较低,如果是多 count(distinct )效率更低因为 count(distinct)是按 group by 字段分组,按 distinct 字段排序,一般这种分布方式是很倾斜的。
四、优化原则
HiveQL 本质是 M/R 程序,所以要从 M/R 的运行角度来考虑性能优化,从更底层思考如何优化运算性能,而不仅仅局限于逻辑代码的替换层面。RDBMS 下得 sql 就像一辆机动灵活的小货车,响应快;但 Hadoop 就像吞吐量巨大的轮船,启动开销大,如果每次只做小数量的输入输出,利用率将会很低。所以用好 Hadoop 的首要任务是增大每次任务所搭载的数据量。
1、好的模型设计事半功倍
2、解决数据倾斜问题
3、合理控制 map reduce 数量
4、减少 job 数,合并,大的分拆
5、设置合理的 map reduce 的 task 数,能有效提升性能比如,10w+级别的计算,用 160 个 reduce,那是相当的浪费,1 个足够
6、了解数据分布,自己动手解决数据倾斜问题是个不错的选择set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化有时不能适应特定业务背景,开发人员了解业务,了解数据,可以通过业务逻辑精确有效的解决数据倾斜问题。
7、数据量较大的情况下,慎用 count(distinct),count(distinct)容易产生倾斜问题。
8、对小文件进行合并,是行至有效的提高调度效率的方法,假如所有的作业设置合理的文件数,对云梯的整体调度效率也会产生积极的正向影响。
9、优化时把握整体,单个作业最优不如整体最优。
10、从表连接的角度优化尽量使用内连接,因为内连接是两表都满足的行的组合,而外连接是以其中一个表的全部为基准
11、从索引的角度优化对那些常用的查询字段简历索引,这样查询时值进行索引扫描,不读取数据块
12、行列裁剪可以在查询的过程中减少不必要的分区,字段
13、首要任务是增大每次任务所搭载的数据量Hadoop 就像吞吐量巨大的轮船,启动开销大,如果每次只做小数量的输入输出,利用率将会很低
14、Hadoop 的核心能力是 parition 和 sort,这是优化的根本
15、避实就虚用 job 数的增加,输入量的增加,占用更多存储空间,充分利用空闲 CPU 等各种方法,分解数据倾斜造成的负担
五、优化方案
1、减小 job 数量
2、分区
3、分桶
4、batchinsert
5、临时表
6、全局索引
7、全文索引
8、holodesk
六、优化目的
1、减少数据访问(减少磁盘访问)
2、减少中间结果量(减少网络传输或磁盘访问)
3、减少交互次数(减少网络传输、减少调度开销)
4、改进算法,减少服务器 CPU 以及内存开销
七、参数优化
控制 Map 个数,可以减轻调度开销,合理设置 Reduce 个数,避免单个 task 数据量处过大或过少,通过启用中间数据压缩,用 CPU 换磁盘和网络,尽量减少磁盘 IO,磁盘操作是最慢的。
八、语句优化
1、in,exists 子查询用 LEFT SEMI 替代。
2、多表插入使用语句,采用 from 在上,多个 insert select 在下的写法,减少表的扫描次数。
3、动态分区使用语句
1.动态分区,只能为分区的最后一个列,只能是最后一个子分区,不能是这样(dt,country=‘US’) ,动态分区需要在select指定分区列,静态分区不需要。如果被插入的分区已经存在,数据被重写,否则不被重写。如果分区列的值为null戒‘’,数据会被插入到默认分区__HIVE_DEFAULT_PARTITION__,此数据被认为是坏数据。2.每一个节点(mapper or reducer)创建的分区数不能超过100个,通过DML创建的总的分区数不能超过1000个,文件数不能超过10w个,都可以通过参数配置而改变。hive默认不允许所有的分区都是动态的,可以通过改变hive.exec.dynamic.partition.mode=nonstrict来改变这种状态。
4、合理调整reduce个数
Hadoop MapReduce 程序中,reducer 个数的设定极大影响执行效率,这使得 Hive 怎样决定 reducer 个数成为一个关键问题。遗憾的是 Hive 的估计机制很弱,不指定 reducer 个数的情况下,Hive 会猜测确定一个 reducer 个数,基于以下两个设定:参数 1、hive.exec.reducers.bytes.per.reducer(默认为 1000^3)参数 2、hive.exec.reducers.max(默认为 999)计算 reducer 数的公式很简单:N=min(参数 2,总输入数据量/参数 1)通常情况下,有必要手动指定 reducer 个数。考虑到 map 阶段的输出数据量通常会比输入有大幅减少,因此即使不设定 reducer 个数,重设参数 2 还是必要的。依据 Hadoop 的经验,可以将参数 2 设定为 0.95*(集群中 TaskTracker 个数)
5、合并MapReduce操作
Multi-group by 是 Hive 的一个非常好的特性,它使得 Hive 中利用中间结果变得非常方便
6、合理设计表
Bucket 是指将数据以指定列的值为 key 进行 hash,hash 到指定数目的桶中
7、mapjion 使用
Join操作在Map阶段完成,不再需要Reduce,前提条件是需要的数据在Map的过程中可以访问到
8、合并小文件
文件数目过多,会给 HDFS 带来压力,并且会影响处理效率,可以通过合并 Map 和Reduce 的结果文件来消除这样的影响:hive.merge.mapfiles = true 是否合并 Map 输出文件,默认为 Truehive.merge.mapredfiles =false 是否合并 Reduce 输出文件,默认为 Falsehive.merge.size.per.task = 25610001000 合并文件的大小
9、Map端部分聚合
并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce 端得出最终结果。基于 Hash 参数包括:hive.map.aggr = true 是否在 Map 端进行聚合,默认为 Truehive.groupby.mapaggr.checkinterval = 100000 在 Map 端进行聚合操作的条目数目有数据倾斜的时候进行负载均衡hive.groupby.skewindata = false当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
10、防止内存溢出
Hive中进行表的关联查询时,尽可能将较大的表放在Join之后。Hive在处理表的关联查询时,会默认对最后一张表执行streaming操作,也就是将其它的表缓存起来,将最后一张表与其它的表进行关联,这个操作只会读一遍这张最大的表,反之,该表会读取多次,特别是包含多张表时。另外,由于Join之前的表会默认缓存,如果大表放在前面的位置,也会造成内存的消耗
11、使用开窗函数
没有主键,且数据量巨大(超过 1000 万),建议对方增加主键,然后开并行。如果有主键,直接开并行,并行数目的判断:
12、排序方式使用
Order by 、Sort by 、Distribute By 区别:
这四个语句都和排序相关,但底层的执行细节不同。
Order By:会将所有的数据在一个 reducer 上执行,得到的结果是整体有序的。但是由于不能并发执行,所以效率比较低。
Sort By:排序操作在多个 reducer 上执行,得到的结果是局部有序(一个 reducer 内)的,但是整体数据不一定是严格有序的。另外,这个语句还可能造成数据的重叠和丢失。 由于MapReduce 是采用 Hash 的方式来组织数据的,所以当使用 Sort By 时,一个 reducer 的输出会覆盖另一个 reducer 的数据。
Distribute By:为 Sort By 而生!它可以修正 Sort By 带来的负面作用,避免数据的覆盖和丢失。Distribute By 将保证具有相同的指定关键字的记录进入到同一个 reducer 进行处理,这样就可以避免 reducer 在输出数据时将不同 reducer 的记录放到同一个位置,从而造成数据的覆盖。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|