Map-Reduce是一种编程模型,主要分为两个阶段,即Map阶段和Reduce阶段。它旨在并行处理分布在各种机器(节点)上的数据。 Hadoop Java程序由Mapper 类和Reducer 类以及驱动程序类组成。 Reducer 是 Map-Reduce 编程模型的第二部分。 Mapper 以键值对的形式产生输出,作为 Reducer 的输入。
但是在将这个中间键值对直接发送给Reducer之前,会进行一些过程,根据键值对键值对进行打乱和排序,这意味着键的值是排序的主要决定因素。 Reducer 生成的输出将是最终输出,然后存储在 HDFS(Hadoop 分布式文件系统)上。 Reducer 主要执行一些计算操作,如加法、过滤和聚合。默认情况下,用于处理 Mapper 输出的 reducer 数量为 1,这是可配置的,用户可以根据需要进行更改。
我们来了解一下 Map-Reduce 中的 Reducer:
在这里,在上图中,我们可以观察到有多个 Mapper 正在生成键值对作为输出。每个映射器的输出被发送到排序器,排序器将根据其键值对键值对进行排序。在排序过程中也会发生混洗,输出将发送到 Reducer 部分并产生最终输出。
让我们举个例子来理解 Reducer 的工作。假设我们将所有院系的大学教职员工的数据存储在一个 CSV 文件中。如果我们想根据他们的部门找到教师的工资总和,那么我们可以让他们的部门。标题为键,薪水为值。 Reducer 将对该数据集执行求和操作并产生所需的输出。
Map-Reduce 任务中的 Reducer 数量也会影响以下功能:
- 框架开销增加。
- 故障成本降低
- 增加负载均衡。
我们还需要记住的一件事是,Reducers 和键之间总是存在一对一的映射。整个 Reducer 过程完成后,输出将存储在 HDFS(Hadoop 分布式文件系统)上的部分文件(默认名称)中。在 HDFS 上的输出目录中,Map-Reduce 总是生成一个_SUCCESS文件和part-r-00000文件。零件文件的数量取决于减速器的数量,如果我们有 5 个减速器,则零件文件的数量将从 part-r-00000 到 part-r-00004。默认情况下,这些文件的名称为part-a-bbbbb类型。它可以手动更改,我们需要做的就是更改 Map-Reduce 驱动程序代码中的以下属性。
// Here we are changin output file name from part-r-00000 to GeeksForGeeks
job.getConfiguration().set("mapreduce.output.basename", "GeeksForGeeks")
Map-Reduce 的 Reducer 主要由 3 个过程/阶段组成:
- Shuffle:Shuffle有助于将数据从 Mapper 传送到所需的 Reducer。在 HTTP 的帮助下,框架在所有 Mappers 中调用适用的输出分区。
- 排序:在这个阶段,映射器的输出实际上是键值对,将根据其键值进行排序。
- Reduce:一旦shuffle和排序完成,Reducer将得到的结果组合起来,并按照要求进行计算操作。 OutputCollector.collect()属性用于将输出写入 HDFS。请记住,Reducer 的输出不会被排序。
注意: Shuffling 和 Sorting 都是并行执行的。
在 Map-Reduce 中设置 Reducer 的数量:
- 使用命令行:在执行我们的 Map-Reduce 程序时,我们可以使用控制器mapred.reduce.tasks手动更改 Reducer 的数量。
- 使用 JobConf 实例:在我们的驱动程序类中,我们可以使用job.setNumReduceTasks(int)的实例指定减速器的数量。
例如job.setNumReduceTasks(2),这里我们有2个Reducer。如果我们只需要一个 Map 作业,我们也可以将 Reducers 设为 0。
// Ideally The number of Reducers in a Map-Reduce must be set to:
0.95 or 1.75 multiplied by ( * )