hadoop streaming多路输出方法和注意点(附超大数据diff对比源码)
简介
hadoop 支持reduce多路输出的功能,一个reduce可以输出到多个part-xxxxx-X文件中,其中X是A-Z的字母之一,程序在输出<key,value>对的时候,在value的后面追加"#X"后缀,比如#A,输出的文件就是part-00000-A,不同的后缀可以把key,value输出到不同的文件中,方便做输出类型分类, #X仅仅用做指定输出文件后缀, 不会体现到输出的内容中
使用方法
启动脚本中需要指定-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleTextOutputFormat或者-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleSequenceFileOutputFormat, 输出就会按照多路输出的方式进行分文件输出
所有标准输出的value中都要加上 #X后缀,X代表A-Z, 不然会报invalid suffix错误
简单示例如下:
$HADOOP_HOME_PATH/bin/hadoop streaming \ -Dhadoop.job.ugi="$HADOOP_JOB_UGI" \ -file ./map.sh \ -file ./red.sh \ -file ./config.sh \ -mapper "sh -x map.sh" \ -reducer "sh -x red.sh" \ -input $NEW_INPUT_PATH \ -input $OLD_INPUT_PATH \ -output $OUTPUT_PATH \ -jobconf stream.num.map.output.key.fields=1 \ -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \ -outputformat org.apache.hadoop.mapred.lib.SuffixMultipleTextOutputFormat \ -jobconf mapred.job.name="test-shapherd-dist-diff" \ -jobconf mapred.job.priority=HIGH \ -jobconf mapred.job.map.capacity=100 \ -jobconf mapred.job.reduce.capacity=100 \ -jobconf mapred.reduce.tasks=3
在red脚本中可以所以的输出都加上后缀, 这样输出就是分part的了,比如大数据diff对比的脚本
map.sh如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | source . / config.sh awk 'BEGIN{ } { if (match( "'${map_input_file}'" , "'$OLD_INPUT_PATH'" )) { print $ 0 "\t" 0 next } if (match( "'${map_input_file}'" , "'$NEW_INPUT_PATH'" )) print $ 0 "\t" 1 }' exit 0 |
red.sh如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | awk - F "\t" 'BEGIN{ key = "" flag = 0 num = 0 old_num = 0 new_num = 0 diff_num = 0 } { if ($NF = = "0" ) old_num + + else new_num + + if ($ 1 ! = key) { if (key ! = "") { if (num < = 1 ) { diff_num + + if (flag = = "0" ) print $ 0 "#A" else print $ 0 "#B" } } key = $ 1 flag = $NF num = 1 next } if (key = = $ 1 ) { num + + next } } END{ if (num = = 1 ) { if (flag = = "0" ) print $ 0 "#A" else print $ 0 "#B" } print old_num "\tshapherd#C" print new_num "\tshapherd#D" print diff_num "\tshapherd#E" }' exit 0 |
我的两个大数据没有diff, 所以输出就是:
part-00000-C
part-00000-D
part-00000-E
part-00001-C
part-00001-D
part-00001-E
part-00002-C
part-00002-D
part-00002-E
没有A和B结尾的
注意事项
- 多路输出最多支持26路, 也就是字母只能是A-Z范围。
- reduce的输入key和value的分隔符默认是\t, 如果输出中没有\t,reduce脚本会把整行当作key, value就是空的,这时如果加了#X,会报invalid suffix错误,因为#X作为了key的一部分,这种问题一种是保证你的key和value是按照\t分隔的, 一种是指定自己想要的分隔符。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库