Hadoop Streaming介绍

Hadoop Streaming介绍

0x01 基础概念

1.1 简介

用户可以使用Hadoop Streaming来用任意语言(如python)来编写、运行MR作业,下面是一个官方示例:

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper /bin/cat \
    -reducer /bin/wc

上面的例子中的mapperreducer都是可执行的文件,他们从标准输入stdin中按行读取输入然后将输出发送到标准输出stdout中。随后Hadoop Streaming会创建一个MR作业,提交该任务到集群并持续监控直到任务完成。

1.2 原理

首先上一张HadoopStreaming的运行流程图:
HadoopStreaming过程

1.2.1 Mapper

当一个可执行包被指定为mapper时,每个mapper任务在初始化时会以单独的进程的方式来执行该程序包。在mapper任务运行后会将会把自己的input转化为多行然后喂给前面说的进程的stdin。同时,mapper会从该进程的stdout中搜集面向行的output并将每一行转化为<key,value>的键值对,将他们作为该mapper的输出。

默认情况下,一行数据从开始到第一个制表符(\t)前视作key,其余部分(不包括制表符)作为value。也就是说如果一行中没有制表符,那么key就是整行,value为null。当然,这是可配的。

1.2.2 Reducer

当一个可执行包被指定为reducer时,每个reducer任务在初始化时会以单独的进程的方式来执行该程序包。在reducer任务运行后会将会把自己的<key,value>形式的input转化为多行然后喂给前面说的进程的stdin。同时,reducer会从该进程的stdout中搜集面向行的output并将每一行转化为<key,value>的键值对,将他们作为该reducer的输出。

跟mapper一样,在默认情况下,一行数据从开始到第一个制表符(\t)前视作key,其余部分(不包括制表符)作为value。也就是说如果一行中没有制表符,那么key就是整行,value为null。当然,这也是可配的。

1.3 缺点

需要注意的是,HadoopStreming也有一些缺点:

  • 默认只能处理文本数据,无法直接对二进制数据进行处理;
  • Streaming中的mapper和reducer默认只能从stdin和stdout输入输出
  • 因为有中间转换过程,相对于原生的java mr来说会有一定的性能开销

0x02 基础参数

作为python程序员,了解Hadoop Streaming的常用参数含义是十分有必要的。

通常来说,一个Hadoop Streaming程序的提交命令格式如下:

hadoop command [genericOptions] [streamingOptions]

注意,通用命令选项必须放在 Streaming Command Options的前面,否则会导致失败

2.1 Generic Command Options-通用命令选项

2.1.1 D

选填;-D property=value一般是用来设mr任务的一些属性值

# 指定map任务数量,默认是2,用于在很小的任务时配置
-D mapreduce.job.maps=1
# 指定reduce任务数量。以下参数就是指定不运行reduce任务
-D mapreduce.job.reduces=0
2.1.2 files

选填;该参数是URI,指向已经被上传到HDFS的文件。这些文件会可跨作业缓存。多个文件以逗号分隔。任务可以通过该参数来使用files。

-files会在任务的当前工作目录中创建符号链接(软连接),指向该文件的本地副本。

下面是一个示例:

-files hdfs://host:fs_port/data/a.txt,hdfs://host:fs_port/data/b.txt \
-mapper "python test.py a.txt b.txt" 

上面这条命令会让Hadoop在当前任务的工作空间目录中自动创建名为a.txtb.txt的软连接,分别指向这两个文件在本地的副本。

如果你想重命名软连接,可以使用如下命令:

-files hdfs://host:fs_port/user/a.txt#customA
-mapper "python test.py customA" 
2.1.3 archives

选填;该参数是URI,指向已经被上传到HDFS的archive file。这些archive file会可跨作业缓存。多个archive file以逗号分隔。任务可以通过该参数来使用archive file,支持文件夹嵌套和自动解压。

在下面的例子中
临时缓存文件会被分发到各个计算节点的hadoop.tmp.dir(core-site.xml中配置)路径下
比如data.tar.gz 会在解压后设定一个软连接data -> data/rel/所以使用时 要用 data/data/fileName

-archives hdfs://host:fs_port/data.tar.gz#data \
-mapper "python map.py data/data/ip_area.txt data/data/area_detail.txt" \
2.1.4 其他
# 选填;指定一个app配置文件
-conf configuration_file
# 选填;指定一个namenode
-fs host:port or local	Optional	Specify a namenode
# 选填;指定需要被拷贝到MR任务节点classpath的jar文件,多个以逗号分隔。
-libjars	Optional	Specify comma-separated jar files to include in the classpath

2.2 Streaming Command Options 流式命令选项

2.2.1 Mapper
 # 必填;指定mapper运行命令
 -mapper "python map_step1.py" \
2.2.2 Reducer
 # 必填; 指定reducer运行命令,这里 area_detail.txt和$TOP_N为参数传递到reduce_step1.py
 -reducer "python reduce_step1.py area_detail.txt $TOP_N" \
2.2.3 输入输出
# 定义的一些INPUT文件夹HDFS路径
INPUT_PATH1="/user/chengc/test/output/ad_bi/20180729"
INPUT_PATH2="/user/chengc/test/output/ad_bi/20180730"
INPUT_PATH3="/user/chengc/test/output/ad_bi/20180731"
# MR任务输出HDFS路径
OUTPUT_PATH_STEP1="/user/chengc/test/output/ad_bi/pv/step1"

# 必填;指定map任务数据输入路径
-input $INPUT_PATH1,$INPUT_PATH2,$INPUT_PATH3 \
# 必填;指定MR任务完成后结果数据输出路径
-output $OUTPUT_PATH_STEP1 \
2.2.4 文件上传
TOP_N=$1
 # 选填;-file 指定依赖的本地文件,会上传到hdfs临时目录
 -file ./map_step1.py \
 -file ./reduce_step1.py \
 -file /Users/chengc/cc/study/小象大数据实战/python/Python基础代码/python_basic_project/ad_bi/etl/area_detail.txt 
2.2.5 作业插件

跟通常MR作业相同,可以指定以下插件:

# 选填;默认是TextInputFormat。用来指定读取、切分Text为<key,value>对儿的Java类
-inputformat JavaClassName
# 选填;默认是TextOutputformat。
-outputformat JavaClassName
# 选填;指定key的分区方式。
-partitioner JavaClassName
# 选填;map输出中使用的combiner。
-combiner streamingCommand or JavaClassName

0x03 高级参数

3.1 Partitioner-数据切分

前面提到过,一行数据从开始到第一个制表符(\t)前视作key,其余部分(不包括制表符)作为value。这一小节讲讲怎么通过配置进行自定义设置。

# 指定mapper从stdout中读出的每行数据切分key的分隔符为 "."
-D stream.map.output.field.separator=. \
# 指定前行头到第四个 "."号间的数据为key,"."以后的数据(不包括".") 作为value
-D stream.num.map.output.key.fields=4 \
# 指定partition时分隔符为"."
-D map.output.key.field.separator=. \
# 指定partition时 使用第一个和第二个field
-D mapreduce.partition.keypartitioner.options=-k1,2 

在以上例子中,如果一行数据少于4个"."号,那么整行就会被作为key而value是一个空的Text Object(相当于new Text(""))。
而后两个配置可以让key中的前两个field相同的<key,value>被分区到相同的reducer进行处理。

既然有了以上例子,那么自然就可以想到使用-D stream.reduce.output.field.separator=-D stream.num.reduce.output.fields=NUM指定reducer输出时的切分以及用stream.map.input.field.separatorstream.reduce.input.field.separator分别为mapper和reducer任务指定输入分隔符(默认为制表符)。

下面说一个将前两个field作为partition key的实例:
首先看看数据示意图:

11.12.1.2
11.14.2.3
11.11.4.1
11.12.1.1
11.14.2.2

好,我们现在看看reducer partition示意图:

11.11.4.1
-----------
11.12.1.2
11.12.1.1
-----------
11.14.2.3
11.14.2.2

然后,请谨记,sort默认以整个key作为比较的主体,下面是排序示意图:

11.11.4.1
-----------
11.12.1.1
11.12.1.2
-----------
11.14.2.2
11.14.2.3

可以看到,11.12.1.1排在了11.12.1.2前面,11.14.2.2排在了11.14.2.3前面。

3.2 Comparator-排序比较

Hadoop Streaming中可以自定义排序规则,下面是一个示例:

hadoop jar hadoop-streaming-2.7.6.jar \
# 该类可以支持mr任务输出的key自定义排序
  -D mapreduce.job.output.key.comparator.class=org.apache.hadoop.mapreduce.lib.partition.KeyFieldBasedComparator \
  -D stream.map.output.field.separator=. \
  -D stream.num.map.output.key.fields=4 \
  # mr任务输出的key中的field以.分隔
  -D mapreduce.map.output.key.field.separator=. \
  # MR框架会使用key中的第二个field来排序输出结果
  # n表示number(数字),r表示reversed(逆序)
  -D mapreduce.partition.keycomparator.options=-k2,2nr \
  -D mapreduce.job.reduces=1 \
  -input myInputDirs \
  -output myOutputDir \
  -mapper cat \
  -reducer cat

看完了命令,我们看下实例,下面是一个map任务的key输出:

11.12.1.2
11.14.2.3
11.11.4.1
11.12.1.1
11.14.2.2

经过上面的脚本排序后的结果如下:

11.14.2.3
11.14.2.2
11.12.1.2
11.12.1.1
11.11.4.1

可以看到,直接将第二个fileld作为标准进行比较排序。

3.3 Aggregate Package

关于聚合功能,作者暂未使用,有兴趣的请点击这里

3.4 Field Selection Class

这个功能可以指定map/reduce输出key和value的field构成,详情请点击这里

0x04 FAQ

官方文档中列出一些常见问题,请点击这里

0xFF 参考文档

Apache Hadoop Streaming 2.7.6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值