hadoop mapreduce 过程解析及hive参数优化

 

一、hadoop mapreduce 过程理解

(1)分片(split)操作

该部分不属于map和reduce的主要过程,但是是整个计算框架比较消耗时间的一部分,为map做数据准备。

split只是将源文件的内容分片形成一系列的 InputSplit,每个 InputSpilt 中存储着对应分片的数据信息(例如,文件块信息、起始位置、数据长度、所在节点列表…),每个InputSplit 都由一个 mapper 进行后续处理。

每个分片大小参数是很重要的,splitSize 是分片规则很重要的一个参数,该参数由三个值来确定:

set mapred.max.split.size=256000000;  #每个Map最大输入大小,超过此阈值则被分片,不足则单独放着
set mapred.min.split.size.per.node=100000000; #一个节点上split的最小输入大小 
set mapred.min.split.size.per.rack=100000000; #一个交换机下split的最小输入大小


set hive.input.format=org.apache.Hadoop.hive.ql.io.CombineHiveInputFormat;  #执行Map前进行小文件合并在开启了org.apache.hadoop.hive.ql.io.CombineHiveInputFormat后,一个data node节点上多个小文件会进行合并,合并文件数由mapred.max.split.size限制的大小决定。
mapred.min.split.size.per.node决定了多个data node上的文件是否需要合并~
mapred.min.split.size.per.rack决定了多个交换机上的文件是否需要合并~

数据格式化(Format)操作:

将划分好的 InputSplit 格式化成键值对形式的数据。其中 key 为偏移量,value 是每一行的内容。值得注意的是,在map任务执行过程中,会不停的执行数据格式化操作,每生成一个键值对就会将其传入 map,进行处理。所以map和数据格式化操作并不存在前后时间差,而是同时进行的。(此处不理解)

(2)map过程

根据用户指定的map过程,MapReduce 尝试在数据所在机器上执行该 map 程序。在 HDFS中,文件数据是被复制多份的,所以计算将会选择拥有此数据的最空闲的节点。

在上图中,把Mapper任务的运行过程分为六个阶段

  • 第一阶段是把输入文件按照一定的标准分片 (InputSplit),每个输入片的大小是固定的。默认情况下,输入片(InputSplit)的大小与数据块(Block)的大小是相同的。如果数据块(Block)的大小是默认值64MB,输入文件有两个,一个是32MB,一个是72MB。那么小的文件是一个输入片,大文件会分为两个数据块,那么是两个输入片,一共产生三个输入片。每一个输入片由一个Mapper进程处理,这里的三个输入片,会有三个Mapper进程处理。
  • 第二阶段是对输入片中的记录按照一定的规则解析成键值对,有个默认规则是把每一行文本内容解析成键值对,这里的“键”是每一行的起始位置(单位是字节),“值”是本行的文本内容。

  • 第三阶段是调用Mapper类中的map方法,在第二阶段中解析出来的每一个键值对,调用一次map方法,如果有1000个键值对,就会调用1000次map方法,每一次调用map方法会输出零个或者多个键值对。

  • 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区,分区是基于键进行的,比如我们的键表示省份(如北京、上海、山东等),那么就可以按照不同省份进行分区,同一个省份的键值对划分到一个区中。默认情况下只有一个区,分区的数量就是Reducer任务运行的数量,因此默认只有一个Reducer任务。

  • 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键相同的键值对,按照值进行排序。比如三个键值 对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果 是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到本地的linux 文件中。

  • 第六阶段是对数据进行归约处理,也就是reduce处理,通常情况下的Comber过程,键相等的键值对会调用一次reduce方法,经过这一阶段,数据量会减少,归约后的数据输出到本地的linxu文件中。本阶段默认是没有的,需要用户自己增加这一阶段的代码。

(3)reducer 过程

包括以下几个步骤:

  • 第一阶段是Reducer任务会主动从Mapper任务复制其输出的键值对,Mapper任务可能会有很多,因此Reducer会复制多个Mapper的输出。
  • 第二阶段是把复制到Reducer本地数据,全部进行合并,即把分散的数据合并成一个大的数据,再对合并后的数据排序。
  • 第三阶段是对排序后的键值对调用reduce方法,键相等的键值对调用一次reduce方法,每次调用会产生零个或者多个键值对,最后把这些输出的键值对写入到HDFS文件中。

(4)Shuffle 派发:

Shuffle 过程是指Mapper 产生的直接输出结果,经过一系列的处理,成为最终的 Reducer 直接输入数据为止的整个过程。这是mapreduce的核心过程。

该过程可以分为两个阶段:

  • Mapper 端的Shuffle:由 Mapper 产生的结果并不会直接写入到磁盘中,而是先存储在内存中,当内存中的数据量达到设定的阀值时,一次性写入到本地磁盘中。并同时进行 sort(排序)、combine(合并)、partition(分片)等操作。其中,sort 是把 Mapper 产 生的结果按照 key 值进行排序;combine 是把key值相同的记录进行合并;partition 是把 数据均衡的分配给 Reducer。
  • Reducer 端的 Shuffle:由于Mapper和Reducer往往不在同一个节点上运行,所以 Reducer 需要从多个节点上下载Mapper的结果数据,并对这些数据进行处理,然后才能被 Reducer处理。

 

 

 

 

 

 

参考文章:

https://www.cnblogs.com/sunfie/p/4651609.html

https://www.linuxidc.com/Linux/2017-10/147428.htm

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用pyspark中的算子对给定单词进行计数的代码: ```python # 导入pyspark库 from pyspark import SparkContext # 创建SparkContext对象 sc = SparkContext("local", "Word Count") # 定义要计数的单词列表 words = ['hadoop', 'spark', 'spark', 'mapreduce', 'spark', 'hive', 'hive', 'spark', 'hadoop', 'mapreduce', 'spark'] # 将单词列表转换为RDD word_rdd = sc.parallelize(words) # 使用map算子将每个单词映射为(单词, 1)的键值对 word_count_rdd = word_rdd.map(lambda word: (word, 1)) # 使用reduceByKey算子将相同单词的计数相加 word_count_rdd = word_count_rdd.reduceByKey(lambda x, y: x + y) # 输出计数结果 for word, count in word_count_rdd.collect(): print("{}: {}".format(word, count)) ``` 输出结果为: ``` hadoop: 2 spark: 5 mapreduce: 2 hive: 2 ``` 特殊字符的统计可以使用正则表达式进行匹配,然后使用过滤算子将特殊字符过滤掉,最后再进行计数。具体代码如下: ```python import re # 定义要计数的字符串 text = 'hadoop spark spark mapreduce spark spark hive hive spark hadoop mapreduce spark %' # 使用正则表达式匹配单词和特殊字符 words = re.findall(r'\w+|\W+', text) # 将单词列表转换为RDD word_rdd = sc.parallelize(words) # 使用filter算子过滤掉特殊字符 word_rdd = word_rdd.filter(lambda word: re.match(r'\w+', word)) # 使用map算子将每个单词映射为(单词, 1)的键值对 word_count_rdd = word_rdd.map(lambda word: (word, 1)) # 使用reduceByKey算子将相同单词的计数相加 word_count_rdd = word_count_rdd.reduceByKey(lambda x, y: x + y) # 输出计数结果 for word, count in word_count_rdd.collect(): print("{}: {}".format(word, count)) ``` 输出结果为: ``` hadoop: 2 spark: 5 mapreduce: 2 hive: 2 %: 1 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值