Hadoop的三个组件之一是 Map Reduce。 Hadoop 的第一个组件,即 Hadoop 分布式文件系统 (HDFS) 负责存储文件。第二个组件,即 Map Reduce 负责处理文件。
假设有一个包含一些文本的单词文件。让我们将此文件命名为sample.txt
。请注意,我们使用 Hadoop 来处理大文件,但这里为了便于说明,我们以文本文件为例。因此,让我们假设这个sample.txt
文件包含几行文本。文件内容如下:
Hello I am GeeksforGeeks
How can I help you
How can I assist you
Are you an engineer
Are you looking for coding
Are you looking for interview questions
what are you doing these days
what are your strengths
因此,以上 8 行是文件的内容。让我们假设,同时存储在Hadoop中这个文件,HDFS打破了这个文件分为四个部分,并命名为每个部分为first.txt
, second.txt
, third.txt
和fourth.txt
。所以,你可以很容易地看到,上面的文件将被分成四个相等的部分,每个部分将包含 2 行。前两行将在文件first.txt
,接下来的两行在second.txt
,接下来的两third.txt
,最后两行将存储在fourth.txt
third.txt
中。所有这些文件都将存储在数据节点中,名称节点将包含有关它们的元数据。所有这些都是 HDFS 的任务。
现在,假设用户想要处理这个文件。这就是 Map-Reduce 的作用。假设这个用户想要在这个 sample.txt 上运行一个查询。因此,我们不会将sample.txt
带到本地计算机上,而是将这个查询发送到数据上。为了跟踪我们的请求,我们使用了Job Tracker (一个主服务)。 Job Tracker 会捕获我们的请求并对其进行跟踪。
现在假设用户想要在sample.txt
上运行他的查询并希望在result.output
文件中输出。让包含查询的文件的名称是query.jar
。因此,用户将编写如下查询:
J$hadoop jar query.jar DriverCode sample.txt result.output
- query.jar :需要在输入文件上处理的查询文件。
- sample.txt :输入文件。
- result.output :将接收处理输出的目录。
因此,现在 Job Tracker 捕获此请求并要求 Name Node 在sample.txt
上运行此请求。 Name Node 然后将元数据提供给 Job Tracker。作业调度器现在知道sample.txt
存储在first.txt
, second.txt
, third.txt
和fourth.txt
。由于所有这四个文件都在 HDFS 中存储了三个副本,因此作业跟踪器与每个文件的任务跟踪器(从属服务)进行通信,但它仅与驻留在离它最近的每个文件的一个副本通信。
注意:将想要的代码应用到本地的first.txt
、 second.txt
、 third.txt
和fourth.txt
third.txt
是一个过程,这个过程叫做Map 。
在 Hadoop 术语中,主文件sample.txt
称为输入文件,其四个子文件称为输入拆分。因此,在 Hadoop 中,输入文件的映射器数量等于该输入文件的输入拆分数量。在上述情况下,输入文件sample.txt
有四个输入拆分,因此将运行四个映射器来处理它。处理这些映射器的责任是 Job Tracker。
请注意,任务跟踪器是作业跟踪器的从属服务。因此,如果任何本地机器出现故障,则对该部分文件的处理将停止并停止整个过程。因此,每个任务跟踪器每 3 秒向 Job Tracker 发送心跳和它的槽数。这称为任务跟踪器的状态。如果任何任务跟踪器出现故障,Job Tracker 然后等待 10 次心跳时间,即 30 秒,即使在此之后,如果它没有获得任何状态,则它假定任务跟踪器已死或非常忙.因此,它然后与同一文件的另一个副本的任务跟踪器进行通信,并指示它通过它处理所需的代码。类似地,作业跟踪器使用槽信息来跟踪任务跟踪器当前正在服务的任务数量以及可以分配给它的任务数量。通过这种方式,Job Tracker 会跟踪我们的请求。
现在,假设该系统已生成单独的输出first.txt
, second.txt
, third.txt
和fourth.txt
。但这不是用户想要的输出。为了产生所需的输出,所有这些单独的输出必须合并或减少为单个输出。将多个输出减少到单个输出也是一个由REDUCER完成的过程。在 Hadoop 中,由于存在许多减速器,因此会生成大量输出文件。默认情况下,每个集群总是有一个减速器。
注: Map 和 Reduce 是 Hadoop 的第二个组件 Map Reduce 的两个不同进程。这些也称为Map Reduce 阶段。因此我们可以说 Map Reduce 有两个阶段。第一阶段是映射,第二阶段是减少。
Map Reduce的作用
现在,让我们回到具有相同内容的sample.txt
文件。再次它被分成四个输入分割即, first.txt
, second.txt
, third.txt
,和fourth.txt
。现在,假设我们要计算文件中每个单词的数量。那是文件的内容看起来像:
Hello I am GeeksforGeeks
How can I help you
How can I assist you
Are you an engineer
Are you looking for coding
Are you looking for interview questions
what are you doing these days
what are your strengths
然后“字数统计”代码的输出将如下所示:
Hello - 1
I - 1
am - 1
geeksforgeeks - 1
How - 2 (How is written two times in the entire file)
Similarly
Are - 3
are - 2
….and so on
因此,为了获得此输出,用户必须发送他对数据的查询。假设查询“字数”在文件wordcount.jar
。因此,查询将如下所示:
J$hadoop jar wordcount.jar DriverCode sample.txt result.output
Hadoop 中的文件格式类型
现在,我们知道有四个输入拆分,因此将运行四个映射器。每个输入拆分一个。但是,映射器不直接在输入拆分上运行。这是因为输入拆分包含文本但映射器不理解文本。映射器仅理解 (key, value) 对。因此,输入拆分中的文本首先需要转换为 (key, value) 对。这是由Record Readers实现的。因此,我们也可以说,有多少个输入拆分,就有多少个记录读取器。
在 Hadoop 术语中,文本中的每一行都称为“记录” 。记录阅读器如何将此文本转换为 (key, value) 对取决于文件的格式。在 Hadoop 中,文件有四种格式。这些格式是 Hadoop 中的预定义类。
四种类型的格式是:
- 文本输入格式
- 键值文本输入格式
- 序列文件输入格式
- SequenceFileAsTextInputFormat
默认情况下,文件采用 TextInputFormat。记录阅读器一次读取一条记录(行)。在阅读时,它不考虑文件的格式。但是,它会根据其格式将每条记录转换为 (key, value) 对。暂时,我们假设第一个输入 split first.txt
在 TextInputFormat 中。现在,处理此输入拆分的记录阅读器以(byte offset, entire line)的形式转换记录。例如first.txt
有内容:
Hello I am GeeksforGeeks
How can I help you
因此,记录阅读器的输出有两对(因为文件中有两条记录)。第一对看起来像(0, Hello I am geeksforgeeks) ,第二对看起来像(26, How can I help you) 。注意,第二对具有字节的26偏移,因为有在第一线25点的字符和换行运算符(\ n)也被认为是字符。因此,在记录读取器有多少条记录之后,就有那么多(键,值)对。现在,映射器将为这些对中的每一对运行一次。类似地,其他映射器也正在运行不同输入拆分的 (key, value) 对。因此,通过这种方式,Hadoop 将一个大任务分解为更小的任务并并行执行。
洗牌和排序
现在,映射器提供与记录读取器提供的每个(键、值)对相对应的输出。让我们取first.txt
的第一个输入拆分。记录阅读器为此文件生成的两对是 (0, Hello I am GeeksforGeeks) 和 (26, How can I help you)。现在 mapper 一次获取这些对中的一个,并为第一对产生像 (Hello, 1), (I, 1), (am, 1) 和 (GeeksforGeeks, 1) 和 (How, 1), (can , 1), (I, 1), (help, 1) and (you, 1) 为第二对。同样,我们有所有映射器的输出。请注意,此数据包含重复键,如 (I, 1) 和进一步的 (how, 1) 等。这些重复键也需要注意。此数据也称为中间数据。在将这些中间数据传递给 reducer 之前,它首先要通过另外两个阶段,称为Shuffling 和 Sorting 。
- 洗牌阶段:此阶段将与相同键关联的所有值组合在一起。例如, (Are, 1) 在输入文件中有 3 次。因此,在混洗阶段之后,输出将类似于 (Are, [1,1,1])。
- 排序阶段:洗牌完成后,输出将发送到排序阶段,所有(键,值)对都会自动排序。在 Hadoop 中,排序是一个自动过程,因为存在称为WritableComparableInterface的内置接口。
在完成混洗和排序阶段后,将结果输出发送到减速器。现在,如果在 shuffle 和排序阶段之后有 n (key, value) 对,那么 reducer 会运行 n 次,从而产生最终结果,其中最终处理的输出在那里。在上述情况下,reducer 处理后的结果输出将存储在为处理数据查询而编写的查询代码中指定的目录 result.output 中。