Hadoop MapReduce访问减速器中的映射器输出编号

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop MapReduce访问减速器中的映射器输出编号相关的知识,希望对你有一定的参考价值。

我有一个映射器输出一个句子中的每个字母,这是键,数字1作为其值。例如,我的mapper输出'你好吗'

H 1
o 1
w 1
a 1
r 1
e 1
y 1
o 1
u 1

我的reducer使用它并使用1来计算每个字母的出现次数。例如,它会输出字母'o'作为键,输出2作为其值,因为它出现两次。

我的问题是我想计算一个句子中每个字母出现的频率。为此,我需要访问句子中的字母总数(映射器的输出数量)。我是mapreduce的新手,所以我不确定最好的方法。

答案

假设您的映射器正在获得一个完整的句子,您正在尝试查找频率,并且您正在使用Java API,则可以通过context.write(...)函数从映射器输出两个键:

mapper的java语法:public void map(LongWritable key, Text value, Context context)

  1. 关键:<lineNo_Letter>;价值:c_m
  2. 关键:<lineNo_Letter>;价值:t_n

哪里

lineNo = same as key to the mapper (the first parameter to the above function)
letter = your desired letter
m = <total number of letters in the line (the 2nd parameter to the above function) input to the mapper>
n = <number of occurrence of letter in the line (the 2nd parameter to the above function) mapper input line>

c_a_只是识别计数类型的前缀。 c代表信件的出现;而t代表总发生次数。

基本上我们在这里利用这个概念,你可以从mapper / reducer中编写你想要的许多键值。

现在减速器将获得类似Key:<lineNo_letter>值:ListOf[c_m, t_n]

现在,只需迭代列表,用分隔符_和标识符前缀(tc)分隔它;你在减速机中有所需的值。即

Total number of letter in the sentence = m
Total number of occurrence of the letter = n

编辑:添加伪逻辑

举个例子,假设映射器函数public void map(LongWritable key, Text value, Context context)的输入行是

LongWritable key = 1
Text value = howareyou

mapper的输出应该是:

-- Output length of the Text Value against each letter
context.write("1_h", "t_9");
context.write("1_o", "t_9");
context.write("1_w", "t_9");
context.write("1_a", "t_9");
context.write("1_r", "t_9");
context.write("1_e", "t_9");
context.write("1_y", "t_9");
context.write("1_u", "t_9");

请注意,上述输出是映射器中每个字母的一次输出。这就是为什么字母o只输出一次(即使它在输入中出现两次)。

映射器代码的更多输出将是

-- Output individual letter count in the input text as 
context.write("1_h", "c_1");
context.write("1_o", "c_2");
context.write("1_w", "c_1");
context.write("1_a", "c_1");
context.write("1_r", "c_1");
context.write("1_e", "c_1");
context.write("1_y", "c_1");
context.write("1_u", "c_1");

再次,你可以看到字母o的值为c_2,因为它在句子中出现两次。

现在将产生8个减速器,每个减速器将获得以下一个键值对:

key: "1_h" value: ListOf["t_9", "c_1"]
key: "1_o" value: ListOf["t_9", "c_2"]
key: "1_w" value: ListOf["t_9", "c_1"]
key: "1_a" value: ListOf["t_9", "c_1"]
key: "1_r" value: ListOf["t_9", "c_1"]
key: "1_e" value: ListOf["t_9", "c_1"]
key: "1_y" value: ListOf["t_9", "c_1"]
key: "1_u" value: ListOf["t_9", "c_1"]

现在在每个reducer中,拆分键以获取行号和字母。遍历值列表以提取总数和字母出现次数。

第1行中字母h的频率= Integer.parseInt("c_1".split("_")[1])/Integer.parseInt("t_9".split("_")[1])

这是一个伪逻辑供您实现。

另一答案

不要在看到的时候立即写下每个字母。计算所有字符,然后将这些字符与字符一起写入。

然后根据您编写值的方式,您的减速器将会看到

o, [(1,9), (1,9)]

对这些进行求和,并提取任何一个9,然后除

另一答案

自己完成了:使用全局计数器访问MAP_OUTPUT_RECORDS以获取reducer中映射器输出的总数。

码:

Configuration conf = context.getConfiguration();
Cluster cluster = new Cluster(conf);
Job currentJob = cluster.getJob(context.getJobID());
long totalCharacters = currentJob.getCounters().findCounter(TaskCounter.MAP_OUTPUT_RECORDS).getValue();

以上是关于Hadoop MapReduce访问减速器中的映射器输出编号的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop MapReduce:context.write 更改值

在 mapreduce 中操作迭代器

Hadoop整理三(Hadoop分布式计算框架MapReduce)

如何在 Hadoop 流中设置每个节点的最大减速器数量?

具有单个映射器和两个不同减速器的 hadoop 作业

简单的字数 MapReduce 示例产生奇怪的结果