你能知道有多少输入值在Hadoop中有一个reducer而没有迭代它们吗?

时间:2012-08-04 04:33:06

标签: hadoop mapreduce hbase

我正在Hadoop中编写一个Reducer,我正在使用它的输入值来构建一个字节数组,该数组编码一个元素列表。我写入数据的缓冲区大小取决于reducer接收的值的数量。提前在内存中分配它的大小会很有效,但我不知道有多少值没有用“foreach”语句迭代它们。

Hadoop输出是一个HBase表。

更新 在使用映射器处理我的数据之后,reducer键具有幂律分布。这意味着只有少数键具有很多价值(最多9000),但大多数键只有几个值。我注意到通过分配4096字节的缓冲区,97.73%的值适合它。对于其余的,我可以尝试重新分配具有双倍容量的缓冲区,直到所有值都适合它。对于我的测试用例,这可以通过在最坏的情况下重新分配内存6次来完成,当一个密钥有9000个值时。

2 个答案:

答案 0 :(得分:2)

我假设在你分配了你的字节数组之后,无论如何你都要用for-each来完成它们,但你不想要在内存中缓冲所有记录(因为你只能循环遍历)你从值集合中获得的迭代器一次)。因此,你可以

  1. 运行一个计数减速器,输出每个输入记录,并将计数输出到与地图输出具有相同值类的记录,然后使用自定义排序对该结果运行“仅减少”作业把计数放在首位(推荐)
  2. 覆盖你用Hadoop得到的内置排序,在排序时将其计数并将该计数记录作为其输出的第一条记录注入(我不完全清楚如何完成覆盖,但任何事情都可能)
  3. 如果值是唯一的,您可能有一个有状态的排序比较器,它保留了调用它的值的哈希值(这看起来非常h​​acky且容易出错,但我打赌你可以让它工作,如果辅助排序的机制仅限于一个JVM中的一个类加载器
  4. 设计reducer以使用比字节数组更灵活的数据结构,并在必要时将结果转换为字节数组(强烈推荐)

答案 1 :(得分:0)

您可以使用以下范例:

映射:每个映射器保存从键到整数的映射,其中M [k]是用某个键k发出的值的数量。在输入结束时,地图也会发出键值对(k,M [k])。

排序:使用二级排序,使对(k,M [k])位于对(k,您的值)之前。

减少:说我们正在看关键的k。然后,reducer首先聚合来自不同映射器的计数M [k]以获得数n。这是你要找的号码。现在,您可以创建数据结构并进行计算。