1 hadoop streaming
- Hadoop streaming是和hadoop一起发布的实用程序。它允许用户创建和执行使用任何程序或者脚本编写的map或者reduce的mapreducejobs。譬如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper /bin/cat
- -reducer /bin/wc
2hadoop straming工作方式
- 在上面的例子中,mapper和reducer都是可执行程序,mapper的输入是读取stdin,reducer的输出是输出到stdout。Hadoopstreaming可以创建mapreduce任务,提交任务到正确的cluster,监控任务的执行过程直到任务完成。
- 当mapper定义为可执行程序时,每个mapper task初始化都会独立启动该进程。Mappertask运行时,将输入的文件转换成行来处理,然后传入到stdin;同时,将输出处理为key-value,作为mapper的输出;默认情况下,每行数据第一个tab前面的数据是key,剩下的作为value。如果某行数据中没有tab,则将整行数据作为key,value值为null。然而,这些也可以自定义处理。
- 当reducer定义为可执行程序时,每个reducer task初始化都会独立启动该进程。Reducertask运行时,将输入的key-value数据转换成行数据,作为reducer的输入。同时,reducer收集行数据,将行数据转换成key-value形式输出。默认情况下,每行数据第一个tab前面的数据是key,剩下的作为value。然而,这些也可以自定义处理。
- 这是mapreduce框架和hadoop streaming之间的基本通信协议。
- 用户也可以定义java类作为mapper和reducer,例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper org.apache.hadoop.mapred.lib.IdentityMapper
- -reducer /bin/wc
- 用户可以定义stream.non.zero.exit.is.failure的值为true或者false来表示streaming任务是成功还是失败退出。
3Job提交设置file选项
- 用户可以定义任何程序作为mapper或者reducer。这些可执行程序不需要预先存放在集群的机器上。如果不能,可以通过-file选项来设置程序,提交给job。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper myPythonScript.py
- -reducer /bin/wc
- -file myPythonScript.py
- 该例子将python可执行程序作为mapper。选项-filemyPythonScript.py导致python脚本作为job提交的一部分被传送到集群的机器上。除了可执行程序文件,用户也可以打包一些其他的可能被mapper或者reducer使用的文件。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper myPythonScript.py
- -reducer /bin/wc
- -file myPythonScript.py
- -file myDictionary.txt
4streaming选项和用法
4.1只有mapper的job
- 有时候,用户仅仅需要通过mapper函数对输入数据进行处理。要做到这些,可以设置mapred.reduce.tasks=0。这样,mapreduce框架就不会创建reducetask。并且,mapper的输出就是job的最终输出。为了支持向下兼容,hadoop streaming也支持选项-reduceNONE,等价于-D mapred.reduce.tasks=0。 如果map内存溢出,可以将map内存设大点,如-D mapred.job.map.memory.mb=1024,一个map任务预留的内存上限!很重要啊,经常遇到的问题
4.2定义jobs的其他选项
- 作为一个正常的mapreduce job,用户可以定义hadoop streaming job的其他选项,
- -inputformat JavaClassName
- -outputformat JavaClassName
- -partitioner JavaClassName
- -combiner JavaClassName
- 设置input format的类应该返回text类的key-value键值对。如果没有设置inputformat类,默认的是TextInputFormat。TextInputFormat返回LongWritable类的keys,它并不是输入数据的一部分,keys可能被舍弃;只有values被传送到streamingmapper中。设置output format的类应该是text类的key-value键值对。如果没有定义outputformat类,默认的是TextOutputFormat。
4.3 hadoop streaming中的大文件和文件档案
- -files 和–archives选项允许用户设置task的文件和文件档案。参数是已经在hdfs上的文件和文件档案的URI。这些文件和文件档案在job中缓存。用户可以从fs.default.name配置变量中获取host和fs_port的值。例如,-files选项,
- -files hdfs://host:fs_port/user/testfile.txt#testlink
- 在这个例子中,url中#后面的部分是当前工作任务路径的符号链接。因此,这些任务拥有指向本地文件的符号链接。多个输入可以作如下设置,
- -files hdfs://host:fs_port/user/testfile1.txt#testlink1
- -files hdfs://host:fs_port/user/testfile2.txt#testlink2
- -archives选项允许用户复制jar包到当前任务的工作路径,并且自动解压jar包。例如,
- -archives hdfs://host:fs_port/user/testfile.jar#testlink3
- 在这个例子中,符号链接testlink3创建在当前任务的工作路径中。符号链接指向存放解压jar包的文件路径。
- -archives选项的另外一些例子,input.txt文件有两行数据,定义两个文件的名称,testlink/cache.txt和testlink/cache2.txt。testlink指向文件目录的符号链接,拥有两个文件cache.txt 和cache2.txt。
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input"/user/me/samples/cachefile/input.txt"
- -mapper "xargs cat"
- -reducer "cat"
- -output"/user/me/samples/cachefile/out"
- -archives
- 'hdfs://hadoop-nn1.example.com/user/me/samples/cachefile/cachedir.jar#testlink'
- -D mapred.map.tasks=1
- -D mapred.reduce.tasks=1
- -Dmapred.job.name="Experiment"
- $ ls test_jar/
- cache.txt cache2.txt
- $ jar cvf cachedir.jar -C test_jar/ .
- added manifest
- adding: cache.txt(in = 30) (out= 29)(deflated 3%)
- adding: cache2.txt(in = 37) (out= 35)(deflated 5%)
- $ hadoop dfs -put cachedir.jar samples/cachefile
- $ hadoop dfs -cat /user/me/samples/cachefile/input.txt
- testlink/cache.txt
- testlink/cache2.txt
- $ cat test_jar/cache.txt
- This is just the cache string
- $ cat test_jar/cache2.txt
- This is just the second cache string
- $ hadoop dfs -ls /user/me/samples/cachefile/out
- Found 1 items
- /user/me/samples/cachefile/out/part-00000 <r3> 69
- $ hadoop dfs -cat /user/me/samples/cachefile/out/part-00000
- This is just the cache string
- This is just the second cache string
4.4为jobs定义其他的配置变量
- 用户可以使用-D<n>=<v>定义其他配置变量。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper org.apache.hadoop.mapred.lib.IdentityMapper
- -reducer /bin/wc
- -D mapred.reduce.tasks=2
- 选项-D mapred.reduce.tasks=2定义job的reducer为2。
4.5其他支持的选项
Streaming支持hadoop常用命令行选项。支持的参数主要有下面这些:
bin/hadoop command [genericOptions] [commandOptions]
- 改变本地临时文件夹
- -D dfs.data.dir=/tmp
- 定义其他本地临时文件夹
- -D mapred.local.dir=/tmp/local
- -D mapred.system.dir=/tmp/system
- -D mapred.temp.dir=/tmp/temp
- 在streaming命令中设置环境变量
- -cmdenv EXAMPLE_DIR=/home/example/dictionaries/
5更多的用法实例
5.1自定义将行数据划分为key-value键值对
- 当mapreduce框架从mapper的stdout中读取每行数据时,它将每行数据划分为key-value键值对。默认情况下,每行数据的第一个tab前的数据是key,剩下的是value(除去tab)。
- 然而,用户可以自定义该默认设置。用户可以自定义分隔符(除了默认的tab),并且用户也可以定义第n个字符作为kae-value的分隔符。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper org.apache.hadoop.mapred.lib.IdentityMapper
- -reducer org.apache.hadoop.mapred.lib.IdentityReducer
- -D stream.map.output.field.separator=.
- -D stream.num.map.output.key.fields=4
- 选项-D stream.map.output.field.separator=.定义mapoutput字段的分隔符为.。第四个.前面的是key,后面的是value。如果该行.的个数少于四个,则整行数据就是key,value是空。
- 同样,也可以设置选项-Dstream.reduce.output.field.separator=SEP和-Dstream.num.reduce.output.fields=NUM来设置reduce输出的key-value。
5.2有用的Partitioner类
- Hadoop拥有类KeyFieldBasedPartitioner,对很多应用程序有用。该类在某些key字段的基础上允许mapreduce框架划分map的输出。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper org.apache.hadoop.mapred.lib.IdentityMapper
- -reducer org.apache.hadoop.mapred.lib.IdentityReducer
- -partitionerorg.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner
- -D stream.map.output.field.separator=.
- -D stream.num.map.output.key.fields=4
- -D map.output.key.field.separator=.
- -D mapred.text.key.partitioner.options=-k1,2
- 附注:-k1,2 指定对key进行划分后第1 2个域进行划分(上述解释没有找到相关文档,也不属于原文)
- -D mapred.reduce.tasks=12
- 例如,
- Output输出(keys)
- 11.12.1.2
- 11.14.2.3
- 11.11.4.1
- 11.12.1.1
- 11.14.2.2
- 划分到3个reducer(前面2个字段作为partition的keys)
- 11.11.4.1
- -----------
- 11.12.1.2
- 11.12.1.1
- -----------
- 11.14.2.3
- 11.14.2.2
- Reducer的每个划分内排序(4个字段同时用于排序)
- 11.11.4.1
- -----------
- 11.12.1.1
- 11.12.1.2
- -----------
- 11.14.2.2
- 11.14.2.3
5.3Comparator类
- Hadoop拥有类KeyFieldBasedComparator,在很多程序中得到应用。例如,
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapper org.apache.hadoop.mapred.lib.IdentityMapper
- -reducer org.apache.hadoop.mapred.lib.IdentityReducer
- -D
- mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator
- -D stream.map.output.field.separator=.
- -D stream.num.map.output.key.fields=4
- -D map.output.key.field.separator=.
- -D mapred.text.key.comparator.options=-k2,2nr
- -D mapred.reduce.tasks=12
- Map输出(keys)
- 11.12.1.2
- 11.14.2.3
- 11.11.4.1
- 11.12.1.1
- 11.14.2.2
- Reducer的输出(使用第二个字段进行排序)
- 11.14.2.3
- 11.14.2.2
- 11.12.1.2
- 11.12.1.1
- 11.11.4.1
5.4Hadoop Aggregate包(-reduce aggregate选项)
- -D mapred.reduce.tasks=12
- Python文件AggregatorForKeyCount.py
- #!/usr/bin/python
- import sys;
- def generateLongCountToken(id):
- return "LongValueSum:" + id +"t" +"1"
- def main(argv):
- line = sys.stdin.readline();
- try:
- while line:
- line = line[:-1];
- fields = line.split("t");
- print generateLongCountToken(fields[0]);
- line = sys.stdin.readline();
- except "end of file":
- return None
- if __name__ == "__main__":
- main(sys.argv)
5.5字段选择
- Hadoop有类org.apache.hadoop.mapred.lib.FieldSelectionMapReduce。该类允许用户像unix工具中的cut命令来处理文本数据。该类中的Map函数将每个输入的键值对作为字段列表,用户可以自定义字段分隔符。用户可以选择字段列表作为map的输出的key,其他的字段列表作为map的输出的value。Reduce函数与此类似。
- $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar
- -input myInputDirs
- -output myOutputDir
- -mapperorg.apache.hadoop.mapred.lib.FieldSelectionMapReduce
- -reducerorg.apache.hadoop.mapred.lib.FieldSelectionMapReduce
- -partitionerorg.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner
- -D map.output.key.field.separa=.
- -D mapred.text.key.partitioner.options=-k1,2
- -D mapred.data.field.separator=.
- -D map.output.key.value.fields.spec=6,5,1-3:0-
- -D reduce.output.key.value.fields.spec=0-2:5-
- -D mapred.reduce.tasks=12
5.6 mapred尝试任务失败次数控制及map任务失败率控制
- -D mapred.map.max.attempts="3" \
- -D mapred.reduce.max.attempts="3" \
- -D mapred.max.map.failures.percent="1" \ 设置map任务失败率容忍率
5.7 mapred限制java读取数据行的最大长度(防止mapred程序执行时进度停滞且报heatbeat错误):
- -D mapred.linerecordreader.maxlength = 409600