Hive 3.1 确定 Reduce 数量的算法

不使用 tez 引擎,或者使用 tez 引擎不设置自动并行度

在 hive-.xml 里有两个配置可以确定 reduce task 的数量。

  1. hive.exec.reducers.bytes.per.reducer 是每个 reduce 多少字节。是 Map Task 处理的数据量除以这个数,得到 reduce 的数量。
  2. hive.exec.reducers.max 是最大的 reduce 数量。如果上一步计算的结果没有超过此值,则用上一步计算的结果。如果超过,则用此参数的值作为最终的 reduce 的数量。

以下是这两个参数在 hive-default.xml 的定义和默认值。

<property>
    <name>hive.exec.reducers.bytes.per.reducer</name>
    <value>256000000</value>
    <description>size per reducer.The default is 256Mb, i.e if the input size is 1G, it will use 4 reducers.</description>
  </property>
  <property>
    <name>hive.exec.reducers.max</name>
    <value>1009</value>
    <description>
      max number of reducers will be used. If the one specified in the configuration parameter mapred.reduce.tasks is
      negative, Hive will use this one as the max number of reducers when automatically determine number of reducers.
    </description>
  </property>

调大 hive.exec.reducers.max

如果处理的数据量大,而 reduce 的个数仅有 1099,特别是 reduce 任务出现 OOM 时,则需要在任务中设置参数 hive.exec.reducers.max
set hive.exec.reducers.max=4999;,则说明最大的 reduce 数量调整到 4999。

数据量的计算

第 1 步中的数据量怎么计算? 通过代码得知,不是 Map 处理的存储在 HDFS 上的文件的大小相加。

我们做一个测试。

  • t3_parquet_snappy 的格式是 parquet,压缩方式是 snappy。

t3_parquet_snappy

hive> select length(c1),count(1) from hdfs.t3_parquet_snappy group by length(c1);
----------------------------------------------------------------------------------------------
        VERTICES      MODE        STATUS  TOTAL  COMPLETED  RUNNING  PENDING  FAILED  KILLED  
----------------------------------------------------------------------------------------------
Map 1 .......... container     SUCCEEDED      5          5        0        0       0       0  
Reducer 2 ...... container     SUCCEEDED      7          7        0        0       0       0  

可以看到,用了 5 个 Map 任务,但是 7 个 reducer 任务。

看下文件的数据量,只有 172.9M。

hive> dfs -du -s -h hdfs://localhost:9000/user/hive/warehouse/hdfs.db/t3_parquet_snappy;
172.9 M  172.9 M  hdfs://localhost:9000/user/hive/warehouse/hdfs.db/t3_parquet_snappy

表的信息

hive> desc extended hdfs.t3_parquet_snappy;
OK
c1                  	string              	                    
	 	 
Detailed Table Information	Table(tableName:t3_parquet_snappy, dbName:hdfs, owner:houzhizhen, createTime:1637661315, lastAccessTime:0, retention:0, sd:StorageDescriptor(cols:[FieldSchema(name:c1, type:string, comment:null)], location:hdfs://localhost:9000/user/hive/warehouse/hdfs.db/t3_parquet_snappy, inputFormat:org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe, parameters:{serialization.format=1}), bucketCols:[], sortCols:[], parameters:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[], parameters:{totalSize=181313115, numRows=8313906, rawDataSize=1577233803, COLUMN_STATS_ACCURATE={\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"c1\":\"true\"}}, numFiles=30, transient_lastDdlTime=1637666614, bucketing_version=2, parquet.compression=SNAPPY}, viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE, rewriteEnabled:false, catName:hive, ownerType:USER)	
Time taken: 0.069 seconds, Fetched: 3 row(s)

可以看到,表有属性 rawDataSize=1577233803。 1577233803/256000000= 6.16,向上取整,得到 7。

totalSize

如果表的信息里没有rawDataSize,但是有 totalSize,代表现在的存储的文件大小之和。Hive 使用压缩比参数 hive.stats.deserialization.factor, 默认是10.0。得到原始数据量,再除以 256000000,得到 reduce 的数量。

如果表里既没有 rawDataSize,也没有 totalSize。则通过文件系统的接口,得到表的文件的大小,即 totalSize,剩下的计算和 totalSize 一样。

分区的表的计算方法和表一样,每个分区看是否有 rawDataSize 或者 totalSize,如果没有,则通过文件系统接口计算。

使用 tez 引擎自动并行度

set hive.tez.auto.reducer.parallelism=true;
set hive.tez.max.partition.factor=2;
set hive.tez.min.partition.factor=0.25;
set hive.exec.reducers.bytes.per.reducer=256000000;

在编译阶段,根据估计的订单的数据量除以hive.exec.reducers.bytes.per.reducer ,得到顶点的并行度 parallel。在运行时,根据本顶点需要处理的数据量动态调整,最多是 parallel * 2,最少是 parallel * 0.25。

没有设置动态调整的3个SQL (tpcds-3000 的 query1,query2,query3)的执行时间。

INFO  : Run DAG                                98.95s
INFO  : Run DAG                               349.92s
INFO  : Run DAG                               100.52s

动态 partition 调整的参数。

set hive.tez.auto.reducer.parallelism=true;
set hive.tez.max.partition.factor=1;
set hive.tez.min.partition.factor=0.01;

动态 partition 调整的执行时间。

INFO  : Run DAG                                92.65s
INFO  : Run DAG                               312.95s
INFO  : Run DAG                                83.23s
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值