用python + hadoop streaming 编写分布式程序(三) -- 自定义功能
又是期末又是实训TA的事耽搁了好久……先把写好的放上博客吧
相关随笔:
- Hadoop-1.0.4集群搭建笔记
- 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试
- 用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控
使用额外的文件
假如你跑的job除了输入以外还需要一些额外的文件(side data),有两种选择:
大文件
所谓的大文件就是大小大于设置的local.cache.size的文件,默认是10GB。这个时候可以用-file来分发。除此之外代码本身也可以用file来分发。
格式:假如我要加多一个sideData.txt给python脚本用:
$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
-input iputDir \
-output outputDir \
-mapper mapper.py \
-file mapper.py \
-reducer reduer.py \
-file reducer.py \
-file sideDate.txt
在python脚本里,只要把这个文件当成自己同一目录下的本地文件来打开就可以了。比如:
f = open("sideData.txt")
注意这个file是只读的,不可以写。
小文件
如果是比较小的文件,想要提高读写速度可以将它放在distributed cache里(也就是每台机器都有自己的一份copy,不需要网络IO就可以拿到数据)。这里要用到的参数是-cachefile,写法和用法上一个一样,就是-file改成-cachefile而已。
控制partitioner
partitioning指的是数据经过mapper处理后,被分发到reducer上的过程。partitioner控制的,就是“怎样的mapper输出会被分发到哪一个reducer上”。
Hadoop有几个自带的partitioner,解释可以看这里。默认的是HashPartitioner,也就是把第一个tab前的key做hash之后用于分配partition。写Hadoop Streaming程序是可以选择其他partitioner的,你可以选择自带的其他几种里的一种,也可以自己写一个继承Partitioner的java类然后编译成jar,在运行参数里指定为你用的partitioner。
官方自带的partitioner里最常用的是KeyFieldBasedPartitioner(源代码可以看这里)。它会按照key的一部分来做partition,而不是用整个key来做partition。
在学会用KeyFieldBasedPartitioner之前,必然要先学怎么控制key-value的分割。分割key的步骤可以分为两步,用python来描述一下大约是
fields = output.split(seperator)
key = fields[:numKeyfields]
选择用什么符号来分割key,也就是选择seperator
map.output.key.field.separator可以指定用于分隔key的符号。比如指定为一点的话,就要加上参数
-D stream.map.output.field.separator=.
假设你的mapper输出是
11.22.33.44
这时会先看准[11, 22, 33, 44]这里的其中一个或几个作为key
选择key的范围,也就是选择numKeyfields
控制key的范围的参数是这个,假设我要设置被分割出的前2个元素为key:
-D stream.num.map.output.key.fields=2
那么key就是上面的 1122。值得注意的是假如这个数字设置到覆盖整个输出,在这个例子里是4的话,那么整一行都会变成key。
上面分割出key之后, KeyFieldBasedPartitioner还需要知道你想要用key里的哪部分作为partition的依据。它进行配置的过程可以看源代码来理解。
假设在上一步我们通过使用
-D stream.map.output.field.separator=. \
-D stream.num.map.output.key.fields=4 \
将11.22.33.44的整个字符串都设置成了key,下一步就是在这个key的内部再进行一次分割。map.output.key.field.separator可以用来设置第二次分割用的分割符,mapred.text.key.partitioner.options可以接受参数来划分被分割出来的partition key,比如:
-D map.output.key.field.separator=. \
-D mapred.text.key.partitioner.options=-k1,2 \
指的就是在key的内部里,将第1到第2个被点分割的元素作为partition key,这个例子里也就是1122。这里的值-ki,j表示从i到j个元素(inclusive)会作为partition key。如果终点省略不写,像-ki的话,那么i和i之后的元素都会作为partition key。
partition key相同的输出会保证分到同一个reducer上,也就是所有11.22.xx.xx的输出都会到同一个partitioner,11.22换成其他各种组合也是一样。
实例说明一下,就是这样的:
mapper的输出是
11.12.1.2
11.14.2.3
11.11.4.1
11.12.1.1
11.14.2.2
指定前4个元素做key,key里的前两个元素做partition key,分成3个partition的话,就会被分成
11.11.4.1
-----------
11.12.1.2
11.12.1.1
-----------
11.14.2.3
11.14.2.2
下一步reducer会对自己得到的每个partition内进行排序,结果就是
11.11.4.1
-----------
11.12.1.1
11.12.1.2
-----------
11.14.2.2
11.14.2.3
命令格式大约就是长这样
$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
-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 \
-input inputDir \
-output outputDir \
-mapper mapper.py -file mapper.py \
-reducer reducer.py -file reducer.py \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner
注意-D参数放在前面,指定用KeyFieldBasedPartitioner的-partitioner要放在下面。
控制comparator与自定义排序
上面说到mapper的输出被partition到各个reducer之后,会有一步排序。这个排序的标准也是可以通过设置comparator控制的。和上面一样,要先设置分割出key用的分隔符、key的范围,key内部分割用的分隔符
-D stream.map.output.field.separator=. \
-D stream.num.map.output.key.fields=4 \
-D map.output.key.field.separator=. \
这里要控制的就是key内部的哪些元素用来做排序依据,是排字典序还是数字序,倒序还是正序。用来控制的参数是mapred.text.key.comparator.options,接受的值格式类似于unix sort。比如我要按第二个元素的数字序(默认字典序)+倒序来排元素的话,就用
-D mapred.text.key.comparator.options=-k2,2nr
n表示数字序,r表示倒序。这样一来
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
用python + hadoop streaming 编写分布式程序(三) -- 自定义功能的更多相关文章
- 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试
相关随笔: Hadoop-1.0.4集群搭建笔记 用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控 用python + hadoop streami ...
- 用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控
写在前面 相关随笔: Hadoop-1.0.4集群搭建笔记 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试 用python + hado ...
- python练习:编写一个程序,检查3个变量x,y,z,输出其中最大的奇数。如果其中没有奇数,就输出一个消息进行说明。
python练习:编写一个程序,检查3个变量x,y,z,输出其中最大的奇数.如果其中没有奇数,就输出一个消息进行说明. 笔者是只使用条件语句实行的.(if-else) 重难点:先把三个数进行由小到大的 ...
- python练习:编写一个程序,要求用户输入10个整数,然后输出其中最大的奇数,如果用户没有输入奇数,则输出一个消息进行说明。
python练习:编写一个程序,要求用户输入10个整数,然后输出其中最大的奇数,如果用户没有输入奇数,则输出一个消息进行说明. 重难点:通过input函数输入的行消息为字符串格式,必须转换为整型,否则 ...
- python练习:编写一个程序,要求用户输入一个整数,然后输出两个整数root和pwr,满足0<pwr<6,并且root**pwr等于用户输入的整数。如果不存在这样一对整数,则输入一条消息进行说明。
python练习:编写一个程序,要求用户输入一个整数,然后输出两个整数root和pwr,满足0<pwr<6,并且root**pwr等于用户输入的整数.如果不存在这样一对整数,则输入一条消息 ...
- 一脸懵逼学习Hadoop中的MapReduce程序中自定义分组的实现
1:首先搞好实体类对象: write 是把每个对象序列化到输出流,readFields是把输入流字节反序列化,实现WritableComparable,Java值对象的比较:一般需要重写toStrin ...
- 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码
第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...
- 三十六 Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码
scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开源模块 scrapy-redis的依赖 Python 2.7, 3.4 or 3.5,Python支持版本 Redis & ...
- Hadoop Streaming例子(python)
以前总是用java写一些MapReduce程序现举一个例子使用Python通过Hadoop Streaming来实现Mapreduce. 任务描述: HDFS上有两个目录/a和/b,里面数据均有3列, ...
随机推荐
- 怎样在wordpress后台显示日志 ID
有时我们需要在wordpress后台编辑特定的文章,找了大半天眼睛都花了,不禁会吐槽一下.有没有什么办法可以直接在日志列表查看日志 ID 呢?我们可以通过下面的代码实现: <?php /* Pl ...
- 帝国cms栏目别名怎样调用?栏目名称太短了
在用帝国cms创建栏目时一般会填写栏目名称(较短)和栏目别名(为空则与栏目名相同),栏目别名可以设置长一些作为栏目标题,可是如何调用帝国cms栏目别名呢?默认的模板标题调用是<title> ...
- android侧滑删除,模仿qq跟进item显示删除按钮
今天所写的代码只是为了个人以后查询方便,如果你参考了并且在使用中遇到问题也可以在这里直接回复我 SwipeDelMenuLayout: 效果图: item布局: <?xml version=&q ...
- Java之构造器和构造方法的使用和意义
我总是要把构造器和方法混淆,后来发现, 方法,实际上,是需要用于执行java代码的,而构造器, 构造器,,,是一个类的实例!!(我的理解,构造器是一个对象) 为什么呢? 类的实例,我们需要用类来创建对 ...
- shell应用技巧
Shell 应用技巧 Shell是一个命令解释器,是在内核之上和内核交互的一个层面. Shell有很多种,我们所使用的的带提示符的那种属于/bin/bash,几乎所有的linux系统缺省就是这种she ...
- chrome浏览器使用
1.如何打开多个历史网页.这个需求是这样的,有时候开了多个网页查找资料,但是又还没有做完,然后又需要重启电脑.显然重启电脑后再开启浏览器,一般都是显示浏览器的主页了,上次开的那些网页全部在历史记录里面 ...
- UVM中的regmodel建模(二)
UVM的寄存器模型,对一个寄存器bit中有两种数值,mirror值,尽可能的反映DUT中寄存器的值.expected值,尽可能的反映用户期望的值. 几种常用的操作: read/write:可以前门访问 ...
- cygwin本地.bashrc配置
echo -e "====================================================================================== ...
- html文件上传控件file自定义样式
问题: HTML自带的file上传按钮因在各种浏览器里显示样式不一.不易自定义样式给我们带来很大的麻烦. 解决思路: 将input[type=file]控件隐藏,使用一个input[type=text ...
- Shell脚本实现检测某ip网络畅通情况,实战用例
Shell脚本实现检测某ip网络畅通情况,实战用例 环境准备,linux shell 发送email 邮件:1.安装sendmailyum -y install sendmail安装好sendmail ...