1. 往map或reduce传入参数
-cmdenv name=value
name在reduce或map的机器上就是环境变量的名字,在python里可以使用:
os.environ['name'] 获取value;
2. 使用自己的python
-cacheArchive " /user/username/python.tar.gz#python"
python.tar.gz解压后里面为lib、bin、include文件夹,注意相对路径;在map.py里面就可以使用 #! ./python/bin/python;
用一个map.sh 将map.py封装,并且建立环境变量:
************************************************************************************************
#! /bin/bash
#
# Filename: map.sh
#
export LD_LIBRARY_PATH=./python/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=./python/include:$C_INCLUDE_PATH
export LIBRARY_PATH=./python/lib:$LIBRARY_PATH
export PYTHONHOME=./python
export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/lib/python2.7/site-packages
export PATH=./python/bin:$PYTHONHOME:$PYTHONPATH:$PATH
python map.py
**************************************************************************************************
-cacheArchive事实上是分发压缩文件的参数;
3.多路输出
使用reduce多路输出的功能,需要做三件事情:
- 确认hadoop客户端和集群都升级到hadoop-v2-u7或以上版本
- 使用-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleTextOutputFormat或者-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleSequenceFileOutputFormat指定使用带多输出的OutputFormat
- 在reduce的输出<key,value>变为输出<key,value#X>
使用reduce多路输出需要注意一下几点:
- 确认hadoop客户端和集群都升级到hadoop-v2-u7或以上版本
- 一定要使用-outputformat指定使用多路输出的outputformat
- reduce输出的每一个<key,value>都要在value的后面加上#X后缀
- #X后缀中X是一个A到Z的26个字符,后缀为#X的<key,value#X>输出到part-xxxxx-X文件(原来为part-xxxxx),出于打开文件数不能太多的考虑,目前最多只能有26路输出,应用在使用的过程中,尽量控制多路输出的数量在10以内
- reduce输出的后缀#X会被hadoop平台自动去除
- 对于TextInputFormat,reduce输出数据经常是一行一行的文本,如果一行的中间没有"\t"的话,就代表value为空,如果直接将"#X"后缀放在行尾,"#X"会作为key的一部分而不是value的一部分(因为加上后缀后一行中间仍然没有"\t")这样会导致出错,解决的方式是在#X后缀前面添加"\t"使它变成value的一部分而不是key的一部分
- 如果任务失败,错误信息中有"java.io.IOException: MROutput/MRErrThread failed:java.io.IOException: Invalid suffix :",说明reduce输出的value后缀错误,同时也会将错误的后缀也标示出来
4.使用hdfs上的文件
如果文件(如字典文件)存放在HDFS中,希望计算时在每个计算节点上将文件当作本地文件处理,可以使用-cacheFile hdfs://host:port/path/to/file#linkname选项在计算节点缓存文件,Streaming程序通过./linkname访问文件。
在使用的时候要注意路径名字:
如果TFFILE为hadoop上的一个文件/user/file
-cacheFile "hdfs://namenode:Port/${TFFILE}#tf"会解释为:
-cacheFile "hdfs://namenode:Port//user/file#tf";也就是在user前面有两个'/'有时候会出错。
5.读取输入路径
data=os.environ.get('map_input_file').split('.')