[Hadoop]MapReduce中的Partitioner与Combiner

简介: Partitioners负责划分Maper输出的中间键值对的key,分配中间键值对到不同的Reducer。Maper输出的中间结果交给指定的Partitioner,确保中间结果分发到指定的Reduce任务。

Partitioners负责划分Maper输出的中间键值对的key,分配中间键值对到不同的Reducer。Maper输出的中间结果交给指定的Partitioner,确保中间结果分发到指定的Reduce任务。在每个Reducer中,键按排序顺序处理(Within each reducer, keys are processed in sorted order)。Combiners是MapReduce中的一个优化,允许在shuffle和排序阶段之前在本地进行聚合。Combiners的首要目标是通过最小化键值对的数量来节省尽可能多的带宽,键值对将通过网络在mappers和reducers之间进行shuffle操作(The primary goal of combiners is to save as much bandwidth as possible by minimizing the number of key/value pairs that will be shuffled across the network between mappers and reducers)。我们可以把Combiners理解为发生在shuffle和sort阶段之前,对Mapper输出进行操作的"mini-reducers"。每个Combiner单独操作于一个Mapper,因此不能访问其他Mapper输出的中间结果。

1. Partitioner

第一次使用MapReduce程序的一个常见误解就是认为程序只使用一个reducer。毕竟,单个reducer在处理之前对所有数据进行排序,并将输出数据存储在单独一个输出文件中---谁不喜欢排序数据?(After all, a single reducer sorts all of your data before processing and would have stored output data in one single output file— and who doesn't like sorted data?)我们很容易理解这样的约束是毫无意义的,在大部分时间使用多个reducer是必需的,否则map / reduce理念将不在有用(It is easy to understand that such a constraint is a nonsense and that using more than one reducer is most of the time necessary, else the map/reduce concept would not be very useful)。

在使用多个Reducer的情况下,我们需要一些方法来决定Mapper输出的键值对发送到正确的Reducer中。默认情况是对key使用hash函数,来确定Reducer。分区(partition)阶段发生在Map阶段之后,Reduce阶段之前。分区的数量等于Reducer的个数(The number of partitions is equal to the number of reducers)。根据分区函数,数据都会得到正确的分区,传递到Reducer中。这种方法提供了整体性能,允许mapper能够独立完成操作(allows mappers to operate completely independently)。对于所有输出的键值对,由每个mapper决定哪个reducer来接收它们。由于所有的Mapper都使用相同的分区函数,所以无论是由哪个Mapper产生,对相同的key来说,生成的目标分区都是一样的。

单个分区是指传递到单个reduce任务的所有键值对(A single partition refers to all key/value pairs that will be sent to a single reduce task)。可以通过设置job.setNumReduceTasks,来配置多个Reducer。Hadoop的附带了一个默认的分区实现,即HashPartitioner,对记录的key进行hash,来确定记录在所属的分区。每个分区由一个reduce任务处理,因此分区数等于作业的reduce任务数(Each partition is processed by a reduce task, so the number of partitions is equal to the number of reduce tasks for the job)。

当map函数开始产生输出时,并不总是简单的写到磁盘上。每个Map任务都有一个环形内存缓冲区,用户存储Map函数的输出。当缓冲区的内容达到一定的阈值大小时,后台线程将开始将内容溢出到磁盘。在溢写磁盘的过程中,map函数的输出会继续被写到缓冲区,但如果在此期间缓冲区被填满,map会阻塞直到写磁盘过程完成。在写磁盘之前,线程会根据数据最终要传入到的Reducer,把缓冲区的数据划分成(默认是按照键)分区(Before it writes to disk, the thread first divides the data into partitions corresponding to the reducers that they will ultimately be sent to)。在每个分区中,后台线程按照键进行内存排序,此时如果有一个Combiner,它会在排序后的输出上运行(Within each partition, the background thread performs an in-memory sort by key, and if there is a combiner function, it is run on the output of the sort)。

2. Combiner

Combiners:MapReduce作业受到集群可用带宽的限制,因此它可以最大限度地减少map和reduce任务之间传输的数据。Hadoop允许用户在Mapper输出上运行Combiner - Combiner函数的输出格式与reduce函数的输入一致。Combiner是可选的,是MapReduce的一个优化技巧,因此对于一个特定Mapper输出记录,Hadoop也不会知道Combiner会运行几次。换句话说,Combiner运行0次,一次或者多次,reducer都会产生相同的输出结果。Combiner多次运行,并不影响输出结果,运行Combiner的意义在于使map输出的中间结果更紧凑,使得写到本地磁盘和传给Reducer的数据更少。我们可以把Combiners理解为发生在shuffle和sort阶段之前,对Mapper输出进行操作的"mini-reducers"。每个Combiner单独操作于一个Mapper,因此不能访问其他Mapper输出的中间结果。Combiner提供与每个键相关联的键和值(与Mapper输出键和值相同的类型)(The combiner is provided keys and values associated with each key (the same types as the mapper output keys and values))。关键的是,我们不能假设一个Combiner将有机会处理与同一个键相关联的所有值(Critically, one cannot assume that a combiner will have the opportunity to process all values associated with the same key),一个Combiner只能访问一个Mapper的中间输出结果,对于其他Mapper的中间输出结果无权访问。Combiner可以输出任意数量的键值对,但是键和值必须与Mapper输出具有相同的类型(与Reducer输入相同)。当一个操作满足结合律和交换律(例如,加法或乘法)的情况下,Reducer可以直接用作Combiner。然而,一般来说,Reducer和Combiner是不可互换的。

3. 区别

Partitioner与Combiner之间的区别在于,Partitioner根据Reducer的数量来划分数据,使得单个分区中的所有数据由单个Reducer执行。然而,Combiner功能类似于Reducer,处理每个分区中的数据。Combiner是Reducer的一种优化。根据key或者value的一些其他函数划分数据可能是有用处的,但是Combiner不一定会提供性能。你应该监视作业的行为,以查看Combiner输出的记录数是否明显小于记录数。你可以通过JobTracker Web UI轻松检查。

image


目录
相关文章
|
2月前
|
分布式计算 资源调度 Hadoop
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
大数据-80 Spark 简要概述 系统架构 部署模式 与Hadoop MapReduce对比
83 2
|
23天前
|
数据采集 分布式计算 Hadoop
使用Hadoop MapReduce进行大规模数据爬取
使用Hadoop MapReduce进行大规模数据爬取
|
2月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
119 3
|
2月前
|
分布式计算 资源调度 数据可视化
Hadoop-06-Hadoop集群 历史服务器配置 超详细 执行任务记录 JobHistoryServer MapReduce执行记录 日志聚合结果可视化查看
Hadoop-06-Hadoop集群 历史服务器配置 超详细 执行任务记录 JobHistoryServer MapReduce执行记录 日志聚合结果可视化查看
52 1
|
2月前
|
分布式计算 资源调度 Hadoop
Hadoop-05-Hadoop集群 集群WordCount 超详细 真正的分布式计算 上传HDFS MapReduce计算 YRAN查看任务 上传计算下载查看
Hadoop-05-Hadoop集群 集群WordCount 超详细 真正的分布式计算 上传HDFS MapReduce计算 YRAN查看任务 上传计算下载查看
59 1
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
110 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
52 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
60 0
|
4月前
|
缓存 分布式计算 算法
优化Hadoop MapReduce性能的最佳实践
【8月更文第28天】Hadoop MapReduce是一个用于处理大规模数据集的软件框架,适用于分布式计算环境。虽然MapReduce框架本身具有很好的可扩展性和容错性,但在某些情况下,任务执行可能会因为各种原因导致性能瓶颈。本文将探讨如何通过调整配置参数和优化算法逻辑来提高MapReduce任务的效率。
681 0
|
5月前
|
存储 分布式计算 Hadoop

相关实验场景

更多