根据yahoo的hadoop教程中的附图,操作顺序是map>结合>分区后应该是reduce
这是我的地图操作
发出的示例键LongValueSum:geo_US|1311722400|E 1
假设有100个相同类型的密钥,则应将其组合为
geo_US|1311722400|E 100
然后我想按第一个管道(|)之前的值对键进行分区 http://hadoop.apache.org/common/docs/r0.20.2/streaming.html#A+Useful+Partitioner+Class+%28secondary+sort%2C+the+-partitioner+org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner+option%29
geo_US
所以这是我的流媒体命令
hadoop jar /usr/local/hadoop/contrib/streaming/hadoop-streaming-0.20.203.0.jar \
-D mapred.reduce.tasks=8 \
-D stream.num.map.output.key.fields=1 \
-D mapred.text.key.partitioner.options=-k1,1 \
-D stream.map.output.field.separator=\| \
-file mapper.py \
-mapper mapper.py \
-file reducer.py \
-reducer reducer.py \
-combiner org.apache.hadoop.mapred.lib.aggregate.ValueAggregatorReducer \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-input input_file \
-output output_path
这是我得到的错误
java.lang.NumberFormatException: For input string: "1311722400|E 1"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:419)
at java.lang.Long.parseLong(Long.java:468)
at org.apache.hadoop.mapred.lib.aggregate.LongValueSum.addNextValue(LongValueSum.java:48)
at org.apache.hadoop.mapred.lib.aggregate.ValueAggregatorReducer.reduce(ValueAggregatorReducer.java:59)
at org.apache.hadoop.mapred.lib.aggregate.ValueAggregatorReducer.reduce(ValueAggregatorReducer.java:35)
at org.apache.hadoop.mapred.Task$OldCombinerRunner.combine(Task.java:1349)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1435)
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1297)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:436)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.Child$4.run(Child.java:259)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:396)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1059)
at org.apache.hadoop.mapred.Child.main(Child.java:253)
我看起来分区程序正在 组合之前运行。有什么想法吗?
答案 0 :(得分:1)
无法保证Combo将实际用于hadoop版本> 0.16。
在hadoop 17中,如果单个<K,V>
占用整个排序缓冲区,则不会运行组合器。在版本&gt; 0.18,组合器可以在地图中多次运行并减少相位。
基本上你的算法不应该依赖于是否调用了Combine函数,因为它只是一个优化。有关详细信息,请查看书籍Haddop, A definitive guide ..在Google图书here上找到了关于合并功能的摘录
答案 1 :(得分:1)
我已经检查过&#34; Hadoop权威指南&#34;第6章随机排序。映射输出首先在内存中缓冲。当内存超过其阈值时,映射输出将写入磁盘。在写入磁盘之前,将对数据进行分区。在每个分区中,数据将按键排序。之后,如果有组合器功能,请组合排序输出。
磁盘上可能有许多溢出文件,如果至少有3个溢出文件,则在将输出写入磁盘之前,将再次运行组合器。
最后,所有溢出文件将合并到一个文件中,以减少IO数量。
简而言之, 对于mapper:map - &gt;分区 - &gt;排序---&gt;组合
和reduser:copy form mapper - &gt;合并(如果存在则称为组合器) - &gt;减少