Hive_HIVE优化指南_场景六_通过让MAP 端, 多去承担任务, 去减少 Reducer 的计算成本 和 数据传输成本

 

参考文章 :

https://www.cnblogs.com/skyEva/p/5632374.html

 

 

Hive 优化大纲

大纲地址 : https://blog.csdn.net/u010003835/article/details/105334641

 

场景六.通过让MAP 端, 多去承担任务, 去减少 Reducer 的计算成本 和 数据传输成本。

1)MAP JOIN 的方式

2)  MAP AGGR , 在 Map 端进行预聚合

 

 

构建测试数据

use data_warehouse_test;
 
 
CREATE TABLE IF NOT EXISTS datacube_salary_org (
 company_name STRING COMMENT '公司名称'
 ,dep_name STRING COMMENT '部门名称'
 ,user_id BIGINT COMMENT '用户id'
 ,user_name STRING COMMENT '用户姓名'
 ,salary DECIMAL(10,2) COMMENT '薪水'
 ,create_time DATE COMMENT '创建时间'
 ,update_time DATE COMMENT '修改时间'
) 
PARTITIONED BY(
 pt STRING COMMENT '数据分区'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
;
 
 
CREATE TABLE IF NOT EXISTS datacube_salary_basic_aggr(
 company_name STRING COMMENT '公司名称'
 ,dep_name STRING COMMENT '部门名称'
 ,user_id BIGINT COMMENT '用户id'
 ,salary DECIMAL(10,2) COMMENT '薪水'
)
STORED AS ORC
;
 
 
CREATE TABLE IF NOT EXISTS datacube_salary_dep_aggr(
 company_name STRING COMMENT '公司名称'
 ,dep_name STRING COMMENT '部门名称'
 ,total_salary DECIMAL(10,2) COMMENT '薪水'
)
STORED AS ORC
;
 
 
CREATE TABLE IF NOT EXISTS datacube_salary_company_aggr(
 company_name STRING COMMENT '公司名称'
 ,total_salary DECIMAL(10,2) COMMENT '薪水'
)
STORED AS ORC
;
 
 
CREATE TABLE IF NOT EXISTS datacube_salary_total_aggr(
 total_salary DECIMAL(10,2) COMMENT '薪水'
)
STORED AS ORC
;

 

看下每张表的数据

datacube_salary_org 表的数据

+-----------------------------------+-------------------------------+------------------------------+--------------------------------+-----------------------------+----------------------------------+----------------------------------+-------------------------+
| datacube_salary_org.company_name  | datacube_salary_org.dep_name  | datacube_salary_org.user_id  | datacube_salary_org.user_name  | datacube_salary_org.salary  | datacube_salary_org.create_time  | datacube_salary_org.update_time  | datacube_salary_org.pt  |
+-----------------------------------+-------------------------------+------------------------------+--------------------------------+-----------------------------+----------------------------------+----------------------------------+-------------------------+
| s.zh                              | engineer                      | 1                            | szh                            | 28000.00                    | 2020-04-07                       | 2020-04-07                       | 20200405                |
| s.zh                              | engineer                      | 2                            | zyq                            | 26000.00                    | 2020-04-03                       | 2020-04-03                       | 20200405                |
| s.zh                              | tester                        | 3                            | gkm                            | 20000.00                    | 2020-04-07                       | 2020-04-07                       | 20200405                |
| x.qx                              | finance                       | 4                            | pip                            | 13400.00                    | 2020-04-07                       | 2020-04-07                       | 20200405                |
| x.qx                              | finance                       | 5                            | kip                            | 24500.00                    | 2020-04-07                       | 2020-04-07                       | 20200405                |
| x.qx                              | finance                       | 6                            | zxxc                           | 13000.00                    | 2020-04-07                       | 2020-04-07                       | 20200405                |
| x.qx                              | kiccp                         | 7                            | xsz                            | 8600.00                     | 2020-04-07                       | 2020-04-07                       | 20200405                |
| s.zh                              | engineer                      | 1                            | szh                            | 28000.00                    | 2020-04-07                       | 2020-04-07                       | 20200406                |
| s.zh                              | engineer                      | 2                            | zyq                            | 26000.00                    | 2020-04-03                       | 2020-04-03                       | 20200406                |
| s.zh                              | tester                        | 3                            | gkm                            | 20000.00                    | 2020-04-07                       | 2020-04-07                       | 20200406                |
| x.qx                              | finance                       | 4                            | pip                            | 13400.00                    | 2020-04-07                       | 2020-04-07                       | 20200406                |
| x.qx                              | finance                       | 5                            | kip                            | 24500.00                    | 2020-04-07                       | 2020-04-07                       | 20200406                |
| x.qx                              | finance                       | 6                            | zxxc                           | 13000.00                    | 2020-04-07                       | 2020-04-07                       | 20200406                |
| x.qx                              | kiccp                         | 7                            | xsz                            | 8600.00                     | 2020-04-07                       | 2020-04-07                       | 20200406                |
| s.zh                              | enginer                       | 1                            | szh                            | 28000.00                    | 2020-04-07                       | 2020-04-07                       | 20200407                |
| s.zh                              | enginer                       | 2                            | zyq                            | 26000.00                    | 2020-04-03                       | 2020-04-03                       | 20200407                |
| s.zh                              | tester                        | 3                            | gkm                            | 20000.00                    | 2020-04-07                       | 2020-04-07                       | 20200407                |
| x.qx                              | finance                       | 4                            | pip                            | 13400.00                    | 2020-04-07                       | 2020-04-07                       | 20200407                |
| x.qx                              | finance                       | 5                            | kip                            | 24500.00                    | 2020-04-07                       | 2020-04-07                       | 20200407                |
| x.qx                              | finance                       | 6                            | zxxc                           | 13000.00                    | 2020-04-07                       | 2020-04-07                       | 20200407                |
| x.qx                              | kiccp                         | 7                            | xsz                            | 8600.00                     | 2020-04-07                       | 2020-04-07                       | 20200407                |
+-----------------------------------+-------------------------------+------------------------------+--------------------------------+-----------------------------+----------------------------------+----------------------------------+-------------------------+
21 rows selected (0.153 seconds)

 

datacube_salary_dep_aggr 表的数据

+----------------------------------------+------------------------------------+----------------------------------------+
| datacube_salary_dep_aggr.company_name  | datacube_salary_dep_aggr.dep_name  | datacube_salary_dep_aggr.total_salary  |
+----------------------------------------+------------------------------------+----------------------------------------+
| s.zh                                   | enginer                            | 54000.00                               |
| s.zh                                   | tester                             | 20000.00                               |
| x.qx                                   | finance                            | 50900.00                               |
| x.qx                                   | kiccp                              | 8600.00                                |
+----------------------------------------+------------------------------------+----------------------------------------+
4 rows selected (0.262 seconds)

 

 

 

 

 

场景六.通过让MAP 端, 多去承担任务, 去减少 Reducer 的计算成本 和 数据传输成本。

 

1)MAP JOIN 的方式

当两张数据表进行JOIN的时候,如果一张表的数据比较小. 比如维度表 这种,我们完全可以使用 MAP JOIN 的方式。

这个时候,我们需要把 小表 写在 JOIN 条件的左边。

 

Map JOIN 的使用场景 :

  • 关联操作中有一张表非常小
  • 不等值的链接操作

SQL demo

select   /*+ mapjoin(c)*/    -- hint
   c.tag
   ,b.yemaozi_pre
from
(
 select
    row_number() over(partition by 1 order by yemaozi_pre)  yemaozi_rank
	,yemaozi_pre
 from  customer_purchase_time_pre
) b       -- 大表                             
join
(select
    count(buyer_nick) total_buyer
	,'yemaozi' as tag
 from customer_purchase_time_pre
) c        -- 小表,只有一行
where b.yemaozi_rank = round(c.total_buyer*0.9);

 /*+mapjoin( c ) */  这个语法里面的c  是join的小表的名字!

 

 

================================================

原理 

  MAP JOIN会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce,运行的效率也会高很多。

  使用mapjoin时,会先执行一个本地任务(mapreduce local task)将小表转成hashtable并序列化为文件再压缩,随后这些 hashtable文件会被上传到hadoop缓存,提供给各个mapjoin 使用。

 

================================================

分析

  • 例子中的小表参与join,没使用map join时,会导致数据倾斜严重。某个reduce上落太多数据,reduce时内存会严重占用,甚至不足。
  • 不等连接时,reduce会进行笛卡儿积,效率很低。
  • 使用map join后  join操作会在map阶段完成。

 

=================================================

相关参数设置 :

hive.auto.convert.join : 是否自动转换为mapjoin


hive.mapjoin.smalltable.filesize : 小表的最大文件大小,默认为25000000,即25M

 

hive.auto.convert.join.noconditionaltask : 是否将多个mapjoin合并为一个

 

hive.auto.convert.join.noconditionaltask.size : 多个mapjoin转换为1个时,所有小表的文件大小总和的最大值。

注意 :不过,这个值只是限制输入的表文件的大小,并不代表实际mapjoin时,hashtable 的大小。 

 

还有一些关于内存的参数设置

hive.mapjoin.localtask.max.memory.usage : 将小表转成hashtable的本地任务的最大内存使用率,默认0.9


hive.mapjoin.followby.gby.localtask.max.memory.usage : 如果mapjoin后面紧跟着一个group by任务,这种情况下 本地任务的最大内存使用率,默认是0.55

 

hive.mapjoin.check.memory.rows : localtask每处理完多少行,就执行内存检查。默认为100000

 

如果我们的localtask的内存使用超过阀值,任务会直接失败。

 

示例 :

--是否自动转换为mapjoin
set hive.auto.convert.join = true;
--小表的最大文件大小,默认为25000000,即25M
set hive.mapjoin.smalltable.filesize = 25000000;
--是否将多个mapjoin合并为一个
set hive.auto.convert.join.noconditionaltask = true;
--多个mapjoin转换为1个时,所有小表的文件大小总和的最大值。
set hive.auto.convert.join.noconditionaltask.size = 10000000;

 

其他的注意事项:

    此外,使用mapjoin时还要注意,用作join的关联字段的字段类型最好要一致。 

     我就碰到一个诡异的问题,执行mapjoin 的local task时一直卡住,40万行的小表处理了好几个小时,正常情况下应该几秒钟就完成了。查了好久原因,结果原来是做join的关联字段的类型不一致,一边是int, 一边是string,hive解释计划里显示它们都会被转成double再来join。我把字段类型改为一致的,瞬间就快了。照理说就算转成double也不该这么慢,不知道是不是hive的bug。

 

 

下面,我们根据最开始构造的测试数据,演示一下 MAP JOIN 

EXPLAIN
SELECT 
 a.*
FROM datacube_salary_org AS a
JOIN datacube_salary_dep_aggr AS b
 ON a.company_name = b.company_name
;

 

由于我们没有用 hint 标志,我们需要显示开启下 自动转化为 map join ( 这个参数是默认开启的,这里只是手动设置下

set hive.auto.convert.join = true;

 

INFO  : Starting task [Stage-5:EXPLAIN] in serial mode
INFO  : Completed executing command(queryId=hive_20200415024514_56f33fa3-a2e7-45e7-b649-f92ed288eb2d); Time taken: 0.023 seconds
INFO  : OK
+----------------------------------------------------+
|                      Explain                       |
+----------------------------------------------------+
| STAGE DEPENDENCIES:                                |
|   Stage-4 is a root stage                          |
|   Stage-3 depends on stages: Stage-4               |
|   Stage-0 depends on stages: Stage-3               |
|                                                    |
| STAGE PLANS:                                       |
|   Stage: Stage-4                                   |
|     Map Reduce Local Work                          |
|       Alias -> Map Local Tables:                   |
|         b                                          |
|           Fetch Operator                           |
|             limit: -1                              |
|       Alias -> Map Local Operator Tree:            |
|         b                                          |
|           TableScan                                |
|             alias: b                               |
|             filterExpr: company_name is not null (type: boolean) |
|             Statistics: Num rows: 4 Data size: 1160 Basic stats: COMPLETE Column stats: NONE |
|             Filter Operator                        |
|               predicate: company_name is not null (type: boolean) |
|               Statistics: Num rows: 4 Data size: 1160 Basic stats: COMPLETE Column stats: NONE |
|               HashTable Sink Operator              |
|                 keys:                              |
|                   0 company_name (type: string)    |
|                   1 company_name (type: string)    |
|                                                    |
|   Stage: Stage-3                                   |
|     Map Reduce                                     |
|       Map Operator Tree:                           |
|           TableScan                                |
|             alias: a                               |
|             filterExpr: company_name is not null (type: boolean) |
|             Statistics: Num rows: 7 Data size: 1628 Basic stats: COMPLETE Column stats: PARTIAL |
|             Filter Operator                        |
|               predicate: company_name is not null (type: boolean) |
|               Statistics: Num rows: 7 Data size: 1288 Basic stats: COMPLETE Column stats: PARTIAL |
|               Map Join Operator                    |
|                 condition map:                     |
|                      Inner Join 0 to 1             |
|                 keys:                              |
|                   0 company_name (type: string)    |
|                   1 company_name (type: string)    |
|                 outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7 |
|                 Statistics: Num rows: 7 Data size: 1416 Basic stats: COMPLETE Column stats: NONE |
|                 File Output Operator               |
|                   compressed: false                |
|                   Statistics: Num rows: 7 Data size: 1416 Basic stats: COMPLETE Column stats: NONE |
|                   table:                           |
|                       input format: org.apache.hadoop.mapred.SequenceFileInputFormat |
|                       output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat |
|                       serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe |
|       Local Work:                                  |
|         Map Reduce Local Work                      |
|                                                    |
|   Stage: Stage-0                                   |
|     Fetch Operator                                 |
|       limit: -1                                    |
|       Processor Tree:                              |
|         ListSink                                   |
|                                                    |
+----------------------------------------------------+
60 rows selected (0.209 seconds)

 

 

2)  MAP AGGR , 在 Map 端进行预聚合

我们在做 GROUP BY ,  DISTINCT 这些都是可以在 Map 端进行预聚合的,

Map端聚合设置的参数

set hive.map.aggr=true;

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值