mapreduce python_Python开发MapReduce系列(二)Python实现MapReduce分桶

2023-05-16

版权声明:本文为博主原创文章,未经博主允许不得转载

首先,先引出两点来展开下面的话题。

(1)map阶段的排序是在hash之后,写入磁盘之前进行。排序的两个关键字是partition(分区编号)和key。

(2)map结束后,并不是马上写到磁盘的,而是有个环形缓冲区,数据写到缓冲区中,默认溢出率是80%(这个值可以通过属性设置 io.sort.mb),每达到溢出条件就溢出生成一个小文件,直到全部数据写完,最后把所有的小文件合并成一个大文件,并写到磁盘中。这样做的目的是减少磁盘寻道时间,让每个map只输出一个文件,并为这个文件提供索引文件,记录下每个reduce对应数据的偏移量.(其实就是为map与reduce之间的分发建立映射关系)

1、默认情况介绍

在hadoop streaming的默认情况下,是以”\t”作为分隔符的。对于标准输入来说,以每行读取到的数据的第一个”\t”为分界线, 在其之前的部分为key,在其之后的为value。如果一个 "\t" 字符没有,则整行都被当做是key处理。

2、MapReduce shuffler过程中的sort和partition阶段

mapper阶段除了用户代码,最重要的是shuffle 过程,这个过程是MapReduce耗时和消耗资源的主要地方,因为其涉及到磁盘的写入等操作。这里先不谈优化方面的处理,只研究shuffle 过程中的sort和partition两个过程。为什么只研究这两个过程,因为,sort和partition是MapReduce的核心思想,整个过程就是在不断的重复 排列和分割 的操作。

从第1点可以知道,MapReduce的key默认是以 \t 分割得到的,我们能不能根据自己的需要来获取到特定形式的key?实现类似分桶、根据指定列的排序之类的自由排序呢?答案是可以的。我们可以通过以下的参数来实现:

3、相关的参数介绍

3.1map阶段

-jobconf mapred.reduce.tasks=2【此属性针对下面的例子都有效】

map.output.key.field.separator:指定map输出对之后,其中key内部的分割符。

num.key.fields.for.partition:指定分桶时,按照分隔符切割后,用于分桶key所占的列数。-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner:前两个参数,要配合这个partitioner,没有的话会报错

例如:map.output.key.field.separator=,

num.key.fields.for.partition=2

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

一行数据:1 , 2 , 3 , 4 , 5(在这里1 2之间的逗号是key内部的分隔符,并且1,2格式key的数据分为到同一桶)

stream.map.output.field.separator: map中的key与value的分隔符

stream.num.map.output.key.fields:指定map输出按照分隔符切割后,key所占有的列数,之前的是key,之后的是value

例如:map.output.key.field.separator=,

num.key.fields.for.partition=2

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

stream.map.output.field.separator=:stream.num.map.output.key.fields=3输入:1 , 2 , 3 , 4 , 5

1 , 2 , 2 , 4 , 5

1 , 3 , 4 , 4 , 5

1 , 3 , 3 , 4 , 5输出part-00000:1 , 2 , 2 : 4 , 5

1 , 2 , 3 : 4 , 5输出part-00000:1 , 3 , 3 : 4 , 5

1 , 3 , 4 : 4 , 5

1 , 2 是分桶值,1 , 2 , 3是key, 4 , 5是value。在这里1 2 之间的逗号是key内部的分隔符,1 , 2格式key的数据分为到同一桶

3.2 reduce阶段

stream.reduce.output.field.separator:reduce中key与value的分隔符

stream.num.reduce.output.key.fields:reduce中分隔符的位置

3、分桶测试

run.sh脚本(作为一个会偷懒的程序猿,能偷懒就偷懒,写个脚本省掉每次写入一大串指令的烦恼)

HADOOP_CMD="/home/hadoop/hadoop/bin/hadoop"STREAM_JAR_PATH="/home/hadoop/hadoop/contrib/streaming/hadoop-streaming-1.2.1.jar"INPUT_PATH_A="/a.txt"INPUT_PATH_B="/b.txt"OUTPUT_PATH="/output"$HADOOP_CMD fs-rmr $OUTPUT_PATH #mapreduce在运行时,文件系统不能存在output目录(目录名字随意)

$HADOOP_CMD jar $STREAM_JAR_PATH \-input $INPUT_FILE_PATH_A,$INPUT_FILE_PATH_B\-output $OUTPUT_SORT_PATH \-mapper "python map.py"\-reducer "python red.py"\-file ./map.py \-file ./red.py \-jobconf mapred.reduce.tasks=2\-jobconf map.output.key.field.separator=, \-jobconf num.key.fields.for.partition=2\-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \-jobconf stream.map.output.field.separator=: \-jobconf stream.num.map.output.key.fields=3

a.txt内容

1,2,3:hadoop1,2,1:hadoop1,2,5:hadoop1,3,4:hadoop1,2,9:hadoop1,2,11:hadoop1,2,7:hadoop1,3,15:hadoop1,3,14:hadoop1,2,19:hadoop

b.txt内容

1,2,0:java1,2,2:java1,2,8:java1,3,4:java1,2,2:java1,2,14:java1,2,12:java1,3,1:java1,3,5:java1,2,3:java

4、结果输出

【part-00000】输出内容如下:

1,2,0:java1,2,1:hadoop1,2,2:java1,2,2:java1,2,3:hadoop1,2,3:java1,2,5:hadoop1,2,7:hadoop1,2,8:java1,2,9:hadoop1,2,11:hadoop1,2,14:java1,2,19:hadoop

【part-00001】输出内容如下:

1,3,1:java1,3,4:hadoop1,3,4:java1,3,5:java1,3,14:hadoop1,3,15:hadoop

5、结果分析

由结果可以看出:

(1)以前2列为分桶标志,因为part-00000,part-00001分别以1,2和1,3开头。

(2)以前3列为key,并且第3列为分桶之后排序的key。

(3)key内部之间是以 , 分隔。

(4)key与value之间是以 : 分隔。

参考:

(1)《Hadoop技术内幕:深入解析MapReduce架构设计与实现原理》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mapreduce python_Python开发MapReduce系列(二)Python实现MapReduce分桶 的相关文章

  • 为什么应用程序会在 sys.exit 命令之后显示?

    我正在关注这个教程 http zetcode com tutorials pyqt4 firstprograms http zetcode com tutorials pyqt4 firstprograms 在第一个示例中 我不明白为什么应
  • 在 python + openCV 中使用网络摄像头的问题

    我正在使用以下代码使用 openCV python 访问我的网络摄像头 import cv cv NamedWindow webcam feed cv CV WINDOW AUTOSIZE cam cv CaptureFromCAM 1 然
  • 如何测试顶级窗口是否打开?

    我感觉 Python 编程可能不是我的菜 我创建了一个 tkinter GUI 它使用按钮回调来打开另一个窗口 其他搜索说这个窗口应该是顶级窗口 并且它工作得很好 但是每次按下按钮时它都会打开另一个相同的窗口 如据我所知 窗口 问题 如何测
  • 使用 Marshmallow 中的数据更新行 (SQLAlchemy)

    我正在使用 Flask Flask SQLAlchemy Flask Marshmallow marshmallow sqlalchemy 尝试实现 REST api PUT 方法 我还没有找到任何使用 SQLA 和 Marshmallow
  • 更改 Inkscape 的 Python 解释器

    在使用 Inkscape 时 我不断收到错误 这似乎意味着未满足 python 2 vs 3 的期望 尽管我已经安装了它们 例如 当我尝试从模板生成新文档时 我得到 Traceback most recent call last File
  • 按 ListProperty (NDB) 对查询进行排序

    如何按 ListProperty 对查询进行排序 该模型 class Chapter ndb Model title ndb StringProperty required True version ndb IntegerProperty
  • 如何编写高效的配对算法?

    我需要一种算法的帮助 该算法可以有效地将人们分组 并确保以前的配对不会重复 例如 假设我们有 10 位候选人 candidates 0 1 2 3 4 5 6 7 8 9 并假设我们有一个先前匹配的字典 这样每个键值对即candidate
  • Python - 为什么这段代码被视为生成器?

    我有一个名为 mb 的列表 其格式为 Company Name Rep Mth 1 Calls Mth 1 Inv Totals Mth 1 Inv Vol Mth 2 等等 在下面的代码中 我只是添加了一个包含 38 个 0 的新列表 这
  • Python 中的二进制相移键控

    我目前正在编写一些代码 以使用音频转换通过激光传输消息 文件 和其他数据 我当前的代码使用 python 中 binascii 模块中的 hexlify 函数将数据转换为二进制 然后为 1 发出一个音调 为 0 发出不同的音调 这在理论上是
  • 代理阻止网络套接字?如何绕行

    我有一个用 Python 编写的正在运行的 websocket 服务器 来自https github com opiate SimpleWebSocketServer https github com opiate SimpleWebSoc
  • Python3模拟用另一个函数替换函数

    如何使用 python 中的另一个函数来模拟一个函数 该函数也将提供一个模拟对象 我有类似以下操作的代码 def foo arg1 arg2 r bar arg1 does interesting things 我想替换的实现bar函数 让
  • python 语言环境奇怪的错误。这究竟是怎么回事?

    所以今天我升级到了 bazaar 2 0 2 我开始收到这条消息 顺便说一句 我在雪豹上 bzr warning unknown locale UTF 8 Could not determine what text encoding to
  • 检查对象数组中的多个属性匹配

    我有一个对象数组 它们都是相同的对象类型 并且它们有多个属性 有没有办法返回一个较小的对象数组 其中所有属性都与测试用例 字符串匹配 无论该属性类型是什么 使用列表理解all http docs python org 3 library f
  • Selenium 网页抓取与动态内容和隐藏数据表上的美丽汤

    真的需要这个社区的帮助 我正在使用 Selenium 和 Beautiful Soup 对 Python 中的动态内容进行网页抓取 问题是定价数据表无法解析为 Python 即使使用以下代码 html browser execute scr
  • 指定 Parquet 属性 pyspark

    如何在 PySpark 中指定 Parquet 块大小和页面大小 我到处搜索 但找不到任何有关函数调用或导入库的文档 根据火花用户档案 https mail archives apache org mod mbox spark user 2
  • 将 ASCII 字符转换为“”unicode 表示法的脚本

    我正在对 Linux 区域设置文件进行一些更改 usr share i18n locales like pt BR 并且需要格式化字符串 例如 d m Y H M 必须以 Unicode 指定 其中每个 在本例中为 ASCII 字符表示为
  • 如何从c++调用python

    我是Python新手 我尝试像这样从 C 调用 python 脚本 在 Raspberry Pi 中 std string pythonCommand python Callee py a b int res system pythonCo
  • 从 subprocess.Popen 获取整个输出

    我通过调用 subprocess Popen 得到了一个有点奇怪的结果 我怀疑这与我对 Python 的陌生有很大关系 args cscript USERPROFILE tools jslint js USERPROFILE tools j
  • 带有整数的 np.sqrt 和 where 条件返回错误结果

    当我将 numpy sqrt 方法应用于带有 a 的整数数组时 我得到了奇怪的结果where健康 状况 见下文 对于整数 a np array 1 4 9 np sqrt a where a gt 5 Out 3 array 0 0 5 3
  • 如何指定一个变量作为类或类实例的成员变量?

    在最新的 Python 2 7 x 中 给定类定义内的任何成员变量 该成员变量是否始终处于类级别 因为它是由该类的所有实例共享的单个变量 在类的定义中 如何指定 类定义中的哪些成员变量属于该类 因此由该类的所有实例共享 以及 哪些属于该类的

随机推荐