说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

利用Hadoop Streaming处理二进制格式文件

HTML文档下载 WORD文档下载 PDF文档下载
Hadoop Streaming是Hadoop提供的多语言编程工具,用户可以使用自己擅长的编程语言(比如python、php或C#等)编写Mapper和Reducer处理文本数据。Hadoop Streaming自带了一些配置参数可友好地支持多字段文本数据的处理

编者按:Streaming是Hadoop的一个工具,用来创建和运行一类特殊的Map/Reduce作业。Streaming使用“标准输入”和“标准输出”与我们编写的Map和Reduce进行数据的交换。由此可知,任何能够使用“标准输入”和“标准输出”的编程语言都可以用来编写MapReduce程序。今天给大家分享一篇来自董西成的博文“利用Hadoop Streaming处理二进制格式文件”,文中介绍了如何使用Streaming处理二进制格式的文件。


CSDN推荐:欢迎免费订阅《Hadoop与大数据周刊》获取更多Hadoop技术文献、大数据技术分析、企业实战经验,生态圈发展趋势。


Hadoop Streaming是Hadoop提供的多语言编程工具,用户可以使用自己擅长的编程语言(比如python、php或C#等)编写Mapper和Reducer处理文本数据。Hadoop Streaming自带了一些配置参数可友好地支持多字段文本数据的处理,参与Hadoop Streaming介绍和编程,可参考我的这篇文章:“Hadoop Streaming编程实例”。然而,随着Hadoop应用越来越广泛,用户希望Hadoop Streaming不局限在处理文本数据上,而是具备更加强大的功能,包括能够处理二进制数据;能够支持多语言编写Combiner等组件。随着Hadoop 2.x的发布,这些功能已经基本上得到了完整的实现,本文将介绍如何使用Hadoop Streaming处理二进制格式的文件,包括SequenceFile,HFile等。

注:本文用到的程序实例可在百度云:hadoop-streaming-binary-examples 下载。

在详细介绍操作步骤之前,先介绍本文给出的实例。假设有这样的SequenceFile,它保存了手机通讯录信息,其中,key是好友名,value是描述该好友的一个结构体或者对象,为此,本文使用了google开源的protocol buffer这一序列化/反序列化框架,protocol buffer结构体定义如下:

option java_package = "";
option java_outer_classname="PersonInfo";
message Person {
  optional string name = 1;
  optional int32 age = 2;
  optional int64 phone = 3;
  optional string address = 4;
}

SequenceFile文件中的value便是保存的Person对象序列化后的字符串,这是典型的二进制数据,不能像文本数据那样可通过换行符解析出每条记录,因为二进制数据的每条记录中可能包含任意字符,包括换行符。

一旦有了这样的SequenceFile之后,我们将使用Hadoop Streaming编写这样的MapReduce程序:这个MapReduce程序只有Map Task,任务是解析出文件中的每条好友记录,并以name \t age,phone,address的文本格式保存到HDFS上。

1. 准备数据

首先,我们需要准备上面介绍的SequenceFile数据,生成数据的核心代码如下:

final SequenceFile.Writer out =
        SequenceFile.createWriter(fs, getConf(), new Path(args[0]),
                Text.class, BytesWritable.class);
Text nameWrapper = new Text();
BytesWritable personWrapper = new BytesWritable();
System.out.println("Generating " + num + " Records......");
for(int i = 0; i < num; i++) {
  genOnePerson(nameWrapper, personWrapper);
  System.out.println("Generating " + i + " Records," + nameWrapper.toString() + "......");
  out.append(nameWrapper, personWrapper);
}
out.close();

当然,为了验证我们产生的数据是否正确,需要编写一个解析程序,核心代码如下:

Reader reader = new Reader(fs, new Path(args[0]), getConf());
Text key = new Text();
BytesWritable value = new BytesWritable();
while(reader.next(key, value)) {
  System.out.println("key:" + key.toString());
  value.setCapacity(value.getSize()); // Very important!!! Very Tricky!!!
  PersonInfo.Person person = PersonInfo.Person.parseFrom(value.getBytes());
  System.out.println("age:" + person.getAge()
          + ",address:" + person.getAddress()
          +",phone:" + person.getPhone());
}
reader.close();

需要注意的,Value保存类型为BytesWritable,使用这个类型非常容易犯错误。当你把一堆byte[]数据保存到BytesWritable后,通过BytesWritable.getBytes()再读到的数据并不一定是原数据,可能变长了很多,这是因为BytesWritable采用了自动内存增长算法,你保存的数据长度为size时,它可能将数据保存到了长度为capacity(capacity>size)的buffer中,这时候,你通过BytesWritable.getBytes()得到的数据最后一些字符是多余的,如果里面保存的是protocol buffer序列化后的字符串,则无法反序列化,这时候可以使用BytesWritable.setCapacity (value.getSize())将后面多余空间剔除掉。

2. 使用Hadoop Streaming编写C++程序

为了说明Hadoop Streaming如何处理二进制格式数据,本文仅仅以C++语言为例进行说明,其他语言的设计方法类似。

先简单说一下原理。当输入数据是二进制格式时,Hadoop Streaming会对输入key和value进行编码后,通过标准输入传递给你的Hadoop Streaming程序,目前提供了两种编码格式,分别是rawtypes和  typedbytes,你可以设计你想采用的格式,这两种编码规则如下(具体在文章“Hadoop Streaming高级编程”中已经介绍了):

rawbytes:key和value均用【4个字节的长度+原始字节】表示

typedbytes:key和value均用【1字节类型+4字节长度+原始字节】表示

本文将采用第一种编码格式进行说明。采用这种编码意味着你不能想文本数据那样一次获得一行内容,而是依次获得key和value序列,其中key和value都由两部分组成,第一部分是长度(4个字节),第二部分是字节内容,比如你的key是dongxicheng,value是goodman,则传递给hadoop streaming程序的输入数据格式为11 dongxicheng 7 goodman。为此,我们编写下面的Mapper程序解析这种数据:

int main() {
 string key, value;
 while(!cin.eof()) {
  if(!FileUtil::ReadString(key, cin))
   break;
  FileUtil::ReadString(value, cin);
  Person person;
  ProtoUtil::ParseFromString(value, person);
  cout << person.name() << "\t" << person.age()
       << "," << person.address()
       << "," << person.phone() << endl;
 }
 return 0;
}

其中,辅助函数实现如下:

class ProtoUtil {
 public:
  static bool ParseFromString(const string& str, Person &person) {
   if(person.ParseFromString(str))
    return true;
   return false;
  }
};
class FileUtil {
 public:
  static bool ReadInt(unsigned int *len, istream &stream) {
   if(!stream.read((char *)len, sizeof(unsigned int)))
    return false;
   *len = bswap_32(*len);
   return true;
  }
  static bool ReadString(string &str, istream &stream) {
   unsigned int len;
   if(!ReadInt(&len, stream))
    return false;
   str.resize(len);
   if(!ReadBytes(&str[0], len, stream))
    return false;
   return true;
  }
  static bool ReadBytes(char *ptr, unsigned int len, istream &stream) {
   stream.read(ptr, sizeof(unsigned char) * len);
   if(stream.eof()) return false;
   return true;
  }
};

该程序需要注意以下几点:

(1)注意大小端编码规则,解析key和value长度时,需要对长度进行字节翻转。

(2)注意循环结束条件,仅仅靠!cin.eof()判定是不够的,仅靠这个判定会导致多输出一条重复数据。

(3)本程序只能运行在linux系统下,windows操作系统下将无法运行,因为windows下的标准输入cin并直接支持二进制数据读取,需要将其强制以二进制模式重新打开后再使用。

3. 程序测试与运行

程序写好后,第一步是编译C++程序。由于该程序需要运行在多节点的Hadoop集群上,为了避免部署或者分发动态库带来的麻烦,我们直接采用静态编译方式,这也是编写Hadoop C++程序的基本规则。为了静态编译以上MapReduce程序,安装protocol buffers时,需采用以下流程(强调第一步),

./configure –disable-shared
make –j4
make install

然后使用以下命令编译程序,生成可执行文件ProtoMapper:

g++ -o ProtoMapper ProtoMapper.cpp person.pb.cc `pkg-config –cflags –static –libs protobuf` -lpthread

在正式将程序提交到Hadoop集群之前,需要先在本地进行测试,本地测试运行脚本如下:

#!/bin/bash
HADOOP_HOME=/opt/dong/yarn-client
INPUT_PATH=/tmp/person.seq
OUTPUT_PATH=file:///tmp/output111
echo "Clearing output path: $OUTPUT_PATH"
$HADOOP_HOME/bin/hadoop fs -rmr $OUTPUT_PATH
${HADOOP_HOME}/bin/hadoop jar\
   ${HADOOP_HOME}/share/hadoop/tools/lib/hadoop-streaming-2.2.0.jar\
  -D mapred.reduce.tasks=0\
  -D stream.map.input=rawbytes\
  -files ProtoMapper\
  -jt local\
  -fs local\
  -input $INPUT_PATH\
  -output $OUTPUT_PATH\
  -inputformat SequenceFileInputFormat\
  -mapper ProtoMapper

注意以下几点:

(1)使用stream.map.input指定输入数据解析成rawbytes格式

(2) 使用-jt和-fs两个参数将程序运行模式设置为local模式

(3)使用-inputformat指定输入数据格式为SequenceFileInputFormat

(4)使用mapred.reduce.tasks将Reduce Task数目设置为0

在本地tmp/output111目录下查看测试结果是否正确,如果没问题,可改写该脚本(去掉-fs和-jt两个参数,将输入和输出目录设置成HDFS上的目录),将程序直接运行在Hadoop上。

原文链接:利用Hadoop Streaming处理二进制格式文件       (编辑/刘亚琼  审校/仲浩)

扎克伯格豪掷3000万美元购四套房 梅耶尔和拉里佩奇也居于此 IBM研究人员:仅200条微博 就可构建人格剖析图 MDCC重磅讲师:Pebble CEO Eric Migicovsky 历届中国大数据技术大会PPT精粹(一) 通讯也“跨界”:几行代码,API+SDK,用PaaS实现移动互联 MIT风景线:丝绸雕塑、VR代码、机器人、智能按钮及保时捷 深度学习新算法,完成字里行间的情绪识别 如何在开发项目里和难缠的程序员合作? 移动周报:七大无需编程的DIY开发工具 手把手教学,用jQuery Mobile创建Web App 别惊讶,Android绿色机器人标志灵感来自于卫生间标识 Google TV更名为Android TV 智能电视的路不好走 CTO如何避免决策失控(四)——通盘考虑 做到技术业务不分家 重塑世界!历届MDCC重磅嘉宾演讲大回顾 从贝佐斯的14句言论看商业成功之道 5大宠物可穿戴式设备 Google CIO Ben Fried谈内部工具文化 【开源专访】Fourinone创始人彭渊:打造多合一的分布式并行计算框架 API优先架构或者胖瘦服务器之争 Windows Phone 8迎来Update3更新:支持更大屏幕 更多磁贴 AMD院士站台 异构计算与OpenCL编程师资培训首站清华开讲 Twitter、Square开创者Jack Dorsey的奇趣人生 利用CSS、JavaScript及Ajax实现图片预加载的三大方法 经典电影里的数学 15亿美元!软银联合GungHo收购手游巨头Supercell Oracle“炮轰”开源:称其永远无法在军事领域取得一席之地 零客户端:下一代计算分布模型 苹果聘奢侈品公司巴宝莉CEO Angela Ahrendts为零售主管 看看你会几个?9大最火的移动开发技能 为了进一步拴住用户:传亚马逊与HTC合作开发智能手机 三年?又三年!今年MDCC2013大不相同! 关于Swing的GridBagLayout WINDOWS 高级编程 和 核心编程 这两本书内容有什么区别吗? 我公司用ISA作为代理服务器,要求只能让装了ISA客户端的机器才能上网,不能通过IE的属性中设置代理服务器来上网(为了安全性) 如何设置光标形状 各位好心人,帮帮忙,送100分!!是关于WIN2000 ADV SERVER的配置!! 请问谁有jpeg格式读写的程序? 怎样用Treeview对满足条件的文件进行遍历(非数据库) 微积分求救!!!! 我的WEB程序用了VB开发的组件,请问用INSTALLSHIELD安装怎样连带组件一起安装? 急!求多表,多选查询sql语句 这个ActiveX控件如何实现 求教~~~ 在Sqlserver2000的function中能用。。。。。 关于虚拟主机的数据库服务器 VC、DELPHI问题 模拟串口问题。 高分相送。 截屏问题 一个很奇怪的问题??? ping值总是不稳是什么原因? 初次接触GIS,有什么书可以入门的介绍一下 和一MM聊天,开始很投机,后来一见面就对骂! 怎么批量插入数据 大家都来看看吧,顺便散点分 我的FLASH在没有装FLASH的IE怎么不可以自动下载FLASH? linux 断电后,启动失败,该如何处理!? 初级菜鸟问题,求助 终于解封了,多谢没头脑,偶以后再也不倒粪和刷屏了! 各位大侠,救命!亟待解决! 如何使一个数据库用户的所有对象只读,不可写? 有没有DOS很熟的仁兄?纯DOS下和WIN NT4.0联网 怎样动态生成一个adoquery,并能进行数据库查询,小妹急用,100分奉上 怎么转换这个SQL Server的存储过程为oracle的 多语言数据库的应用程序,象DBGRID字段里的这些标题我应放在哪里好? 最简单的语句,最奇怪的问题。&&&&&&& 在线等待!!! D3D的简单问题 如何控制LineTo划线的颜色和宽度? 高分求《面向对象分析与设计》杨正甫编这本书下载地址。。。 学习DELPHI用铁道出版的乔林《参透Delphi/Kylix》 如何? 请问是否有比较简便的方法可以知道,程序中哪些变量定义完后根本不用? 按钮提交并链接不同页面的问题。 简单的问题 请教VC++高手:在MFC中,如何把剪贴板中的位图按原比例打印出来? 分不够再加! 怎么样在vb中读取bmp的位图信息,将图中所有黑颜色的象素 谁在20分钟内答出以下问题能拿高薪 如何修改注册表的键的默认键值? WINXP开始运行宽带播号程序缓慢,什么原因? newwish2 给我一个例子,邮箱:make_a_wish@163.com!!!着急呢!! evc4.0中文显示的问题! struts--html:select 为何出不来? 讨论:关于WinXP下开发的COM+的分发问题!! 菜鸟的小问题!! 一个关于东芝笔记本的故障 帮忙起的外号,可以当名字使的,霸气点的!本人属于健壮型的,想起的霸气点的外号,带浩字的,或明字的! 冰块怎么保温 紧接上文再写一个句子:要求:1.另举一个事例2.句式与括弧句式相同 我国优秀的古典文学作品 语言紧接上文再写一个句子:要求:1.另举一个事例2.句式与括弧句式相同我国优秀的古典文学作品 到了下面的步骤就不懂该如何思考下去了,思路中断了.请救救我.一件工作,甲、乙两人合作30天可以完成,共同做了6天后,甲离开了,由乙继续做了40天才完成.如果这件工作由甲或乙单独完成各需 使用十倍速影像阅读法之后,自我感觉没什么印象,但在晚上会做噩梦怎样才能学会? 1、在下面的横线上紧接上文,再写一个句子.要求:(1)另举一个例子;(2)句式与划线部分相同.纵观宇宙万物,天下凡速成的东西往往都是短命的.美人蕉一年能长出一米多,但美人蕉禁不起 马克思主义怎样通过生产过程的二重性来说明资本主义目的的 教育目标分类学的目标领域是什么 一次函数的性质若正比例函数y=(3-2m)x的图象经过点A(x1,y1),B(x2,y2),当x1小于x2时,y1大于y2则m的取值范围是------ 百岁老人生日送什么礼物 日常生活中什么东西可以代替保温袋 我可以再问你们一道吗? 求函数极限 大一的 dirty kiss是什么意思? 求解初中数学问题(第十题) 小学语文古诗如何讲解 在长方形上只剪一刀,剩下的角只有直角和钝角 谁帮我解下这个数列题目啊Sn是数列{An}的前N项和 且总有Sn=qAn+1(q大于0且不等于1)求{An}的通向公式 概率矩估计的一个小计算我想问据估计的最后一步将均值和参数转换的步骤.比如 均值=θ /θ -1如何得出 ^θ =均值/均值-1 英语翻译A man was angry with his 3-year-old daughter,because she wasted a roll of gold wrapping paper.The family was poor.the girl tried to decorate a box to put under the Christmas tree. an=1/n对于一切n>1的自然数,不等式an+1 + an+2 + …… + a2n >1/12 loga (a-1) + 2/3恒成立,试求实数a的范围. 求大一极限函数问题.第四小题. 小学四年级文明在哪里征文不少400-500字 设数列{an}的通项公式是关于n的一次函数(n∈N+),已知a8=15,且a₂,a5,a₄成等比数列.(1)求数列{an}的通项公式,(2)求a3+a6+a9+a12+…+a36 地震是因为三峡吗?这两次据说都是 dirty kiss 我想学这首歌曲 发音有木有 求一个 最好能看懂的 本人英文不好I'm the one of those little freaky trouble makersSo give me love and start me upUntil I'm out of it causeYou sayI'm shocking shockingYeah I'm shocking sho 在各项均为正的数列{An}{Bn}中,A1=2,B1=4,且An、Bn、An+1成等差数列,Bn、An+1、Bn+1(以上n、n+1均为角标)成等比数列,求(1)An、Bn(2)(1/A1+B1)+(1/A2+B2)+(1/A3+B3)+.+(1/An+Bn) 把教育目标分成三个领域的那个布鲁姆是什么年代的人?20世纪50年代后,他对世界教育产生了影响了吗? 用一个平面在正方体上切正六变形 求图解 3个连续奇数的和是最大的两位数,这三个数是?谁知道, 第九届春蕾杯题目 去姥姥家英语作文 奇数中最大的两位数少75这个数是几 简答布鲁姆在认知方面的目标的主要内容是什么? 我这是什么眼睛呢?是吊眼还是斗鸡眼啊?都说我的眼睛不好看. 如何把图式理论应用于初中英语的阅读教学 猫头鹰除了吃田鼠还吃什么昆虫 斗鸡眼是怎么形成的? 新版初一政治上册内容速度快点 第九届春蕾杯选题是什么? 小东买了0.8元和2元的邮票共16枚,花了18.8元,那么小东买了0.8元邮票多少枚? 初一上册数学的内容 初一科学小小小小小问题1.我国已进行了,“神州”号载人航天飞船的试验,不久的将来我国的宇航员将乘坐着宇宙飞船遨游太空.宇航员在太空舱中可以和地球上一样自由的直接对话,这是因为 燃烧的火英文怎么读 初一上册语文要背的内容 三峡是怎样的?是美丽的 如图,AD是△ABC的角平分线,EF是AD的垂直平分线 求证∠EAD=∠EDA DE∥AC ∠EAC=∠B 既是3的倍数又是5的倍数的最大两位奇数是( ) 长江三峡究竟是怎样的? 孙思邈究竟活了多少岁? 孙思邈是活了101岁还是141岁? 霸气狗名 怎样形容长江三峡(填形容词)的长江三峡2011年4月1日18:00~18:30 给我一个最佳答案 △ABC中,∠BAC=80°,AB,AC的垂直平分线分别与BC交于D,E求∠EAD. 请在其他的空格中填入数字1~9,是1~9中的每个数字在每一行、每一列和每一宫中都只出现1次.空格我就用0表示了500070300090500400004000700051037289302080604008052137035000900609000823080023006 国内翻译布鲁姆目标教学书目 如图,在三角形ABC中,∠ABC=80°,∠BAC=40°,AB的垂直平分线分别与AC、AB交于D、E.(1)用圆规和直尺在图中做出AB的垂直平分线DE,并连结BD(2)证明:三角形ABC相似三角形BDC 在其他空格上填入1-9的数字.使1-9每个数字在每一行,每一列和每一宫中都只出现一次九宫格数独问题()()()/()(5)(7)/()(8)() (3)()()/()()()/()()( 保温袋里可放冰块吗? 药王活了多少岁药王孙思邈活了多少岁 孙杨可自选拘留时间 新女友浮出水面亦德国拒绝为斯诺登提供庇护 避免影响德刚果(金)政府宣布该国打击反政府武装俄注重文化保护 文化事业拨款70%用穆尔西审判延后 分析指与穆沙拉夫审判科索沃举行地方政府选举 投票点遭蒙面印尼巴厘岛男子咖啡地中发现2000多美参众两院大佬不宽恕斯诺登 将派“安三中全会前夕高层密集调研民生 为改革李克强登上拖拉机驾驶室与农机手交谈梁振英:菲人质事件若1个月没成果将采曝湛江国资委官员带女下属开房 视频男李克强:农业改革要尊重群众意愿和首创德国拒绝为斯诺登提供庇护 避免影响德最高法通报失信被执行人名单信息制度五越南总理坚持推动TPP谈判 争取年内科索沃举行地方政府选举 投票点遭蒙面杭州商品房库存量达10.5万套新高 清华剑桥等名校联手研究北京雾霾天出行日媒:安倍上任后已打13次高尔夫 展印度今日雄心勃勃探火星 媒体议论“与好奇心是创业的“永动机”山东保险行业协会特色工作简介福利院的叔叔阿姨们:交通银行启用首笔中韩货币互换资金债基涨势超宝宝军团成理财大黑马中国 阿拉伯国家合作共建\"一带一路中国东方红五号卫星平台顺利完成结构静港报:东海也好南海也罢 “美国出兵”驻迪拜总领事唐卫斌走访中乔嘉志集团四川宜宾遭暴雨袭击2.2万余人受灾河南息县5人从事\"全能神\"邪教活温哥华成加拿大第一“堵”城闽清:16岁少年为筹网费多次拦路抢劫KTV内口角之争捅伤人 鼓楼法院宣告海口调整企业退休人员养老金 人均增加女子闪婚后得知丈夫不是处男 向法院起奥巴马出访欧洲三国朝鲜要求与滞留韩国渔民会面遭韩方拒绝新加坡华裔水兵遭意外被截肢 艰苦康复通讯:中国学子在荷兰模拟法庭崭露头角港报:东海也好南海也罢 “美国出兵”
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘