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

利用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处理二进制格式文件       (编辑/刘亚琼  审校/仲浩)

“撒娇”的豌豆荚?被百度手机助手屏蔽太糟心! 【工具推荐】Pgcli—自动完成和语法高亮的Postgres命令行工具 CES 2015:挑一款机器人带回家? 夜行、睡眠与健康:CES 2015十款酷炫的可穿戴产品 Java 9中新的货币API 唯“简”不破,Apple Watch App的设计之道 Google Glass从X labs“毕业”,更换项目负责人 不进化,则消亡——互联网时代企业管理的十项实践 RedMonk 2015年1月编程语言排行榜:进击的Swift! 微信开放JS SDK,这场web巨变意味着什么? 盘点一些iOS开发技巧:Swift和Objective-C 2014年,那些“颜值”爆表的UI动画 《近匠》爱加密:谁说iOS应用不需要保护? SwiftColorArt:开源易用的Swift图片类库 人气爆棚 干货满满 中国电信天翼开放平台开放日圆满落幕 必须Mark!43个优秀的Swift开源项目推荐 治拖延、疗懒癌!安利12款提高工作效率工具 把ES6带进Node社区 Io.js 1.0.0正式发布 Java 2014:10个最热门、最具争议性的话题 回顾:2014年最流行前端开发框架对比评测 实例讲解SQL注入攻击 调试大规模服务器集群的五大策略 .NET编译平台Rosly将迁移到Github Wasai虚拟现实头盔与体验馆发布:虚拟现实的线下经济 订票系统不再瘫痪 阿里云确认与12306合作 Apple前工程师Warren Moore:Swift中Metal使用初体验 手把手教学:详解Swift中的iOS设计模式 见微知著,那些触动人心的应用细节设计(一) 设计优秀API七大要诀 需求 细节 BI项目成功的五大要素 BI项目成功的五大要诀 一个applet的问题!70分,在线等待 当字段的值为null时,怎样获取? 向各路高手求助,哪里有novell网操作方面的书籍或者资料 ********很久没来这了,我今天升级两颗星啦,心情高兴,大散分啦!******** 哪里有比较好的网上书店?(计算机类) 请看这句有什么问题 dll的路径常识,大家帮我回答一下 在Web Forms里用Windows Forms控件 大家想一想! 在校程序员的困惑 要把服務器放在家里.現有條件:ADSL,LINUX 7.3,國際域名一個.可以嗎?還要什麼設置?thx 怎样消除11001#socket错误? 如何得到文件的长度,很简单的问题 脚本错误? 物化视图的数据整理问题 如何实现把一个BMP等比例缩放. 强烈建议版主封掉 theHanOfCC(我流) 的ID,他是一个人渣!! 同意的请进来签名!!! 在校程序员的困惑 有关PB数据窗口的检索参数 哪里有比较多的计算机书籍下载,请推荐几个。 急~~~高分求救~! 谢谢duduwolf,请来领分 类似这样的字符串“Thu Sep 5 14:05:56 2002”,怎么转化为Date对象? 安装问题,很简单,小弟菜鸟,望各位兄长多多关照啦!谢了! MDI窗口出错 新手请教。如何在cgi程序中得到由url传递过来的值 ISA 2K发布多个WEB 服务器问题,(我都要疯了) 我的xp怎么不能装vc6.0?再线等待!(20分) 急~~~高分求救~! 请教各位师兄。这个可以实现吗? 向高手请教(如何把客户端的图片传到服务器?) 各位大虾.水晶报表的关键一步了.实现了我就可以水晶报表的打印了! 急急!!!!怎样才能取得java函数传过来的参数呢? %%%%非高手勿進%%% CSDN有些人素质太差! IShellFolder::GetDisplayNameOf 如何获得全名? 代理Type分别为transparent,anonymous,high anonymity,优劣? 为感谢computersim在大力相助,特奉送100分,快来拿啊 请教网上书店系统的设计思想和例子。 VC中使用FLASH的OCX控件如何取得Movie的原始大小,且如何按指定比例缩放?问题解决后必给分。 有关“隐藏”,“覆盖”的一些问题: 如何把A库中A表原样复制到B库中去? 怎样取得鼠标点击DataGrid控件时是哪一行,哪一列呢?(C#) ISA 2K发布多个WEB 服务器问题,(我都要疯了)高分求救 这个问题怎么办?? (ADO OPEN) Up 有分! 母亲生日,你觉得送什么礼物为好? 用c++ 写的 hello 程序在unix g++ 编译通过后,运行出错 如下几个初级问题要问,高手们请进-> SQLSERVER高手进来聊聊........ 怎样用代码实现两台电脑之间的文件传输? 哪位知道Microsoft Firewall Client 的下载地址? 缩写下文(去掉定语从句、宾语从句、插入语) Self reflection means stopping the mad rush of activityand calming yourself and your mind so your brain can evaluate(评价) the input it has already received.Some people prefer to do th 心功能分几级,是如何分级的? 将0.1mol两种气态烃组成的混合气体完全燃烧后得3.36L(标准状况)CO2和3.6gH2O.下面说法正确的是?A.一定有烯烃B.一定有甲烷C.一定没有甲烷D.一定没有乙烷为什么?请写出完整的解题过程, 怎么写reflection 小石潭记中全石以为底,以什么意思 硝酸铵 是酸还是碱书上 问我 它是碱 还是盐。 请高手帮忙写几句类似rush to the dead summer的英文,谢谢.要求:每句话包括一个季节,句式最好和例句一样,谢谢大家了. 卷石底以出 (<小石潭记>) 以 有没有便携式硬度计啊,谁知道有这样的吗 解决中小企业融资难意义在于? 会车灯是什么灯? 小石潭记写石,写树各有什么特点? 昨天老师给那个男孩颁奖 英语翻译 必须有award 汽车车灯灯泡问题想换对灯泡,谁知道飞利浦的银战士好还是欧司朗的夜行者好啊?我不想换氙气灯! 在古文中,"卷石底以出" 的 "以" 2个氮原子2个氢气分子亚铁离子氢氧根离子+2价的钙元素五氧化二磷写上以上的化学符号 这个车灯符号是指什么灯?如题. 请问如何调整生物钟?是这样的,放了一个月的暑假,生物钟比平时晚了很多,每天都是半夜1.2点才睡得着,要睡到白天12才醒.快要开学了,请问怎样调整过来啊?急!平常是晚上11:30左右睡觉,早上6 氢氧根离子.2个氢分子.亚铁离子.+2价的钙元素用化学符号表示. 现在还有哪些汽车车灯是跳灯的?哪些车带前跳灯的汽车,最好是实用的汽车. 怎么调整生物钟工作原因 长达一年的时候都是晚上4点多只有睡 中午12点才起现在换了份工作 每天早上需要8点起 可是晚上基本都是2点才能正常入睡 第2天起来精神不佳 请问怎么样才可以调 根据自己的理解描述一下计算机操作系统的作用及其重要性. 除铁除锰对地下水处理超标的问题?大神们帮帮忙 怎样快速的调整生物钟? 我想自己录唱歌想找一个简单操作的,但处理声音也较好,有很多功能的软件,谁有? 车灯的灯泡一般在多少瓦之间? 纤维素、固醇、酶、DNA共有的元素是?A:C/H/O/N/PB:C/H/O/NC:C/H/OD:O/H 生命有多长 怎么调节水的PH值?用什么?我主要用于除铁除锰的水处理中 快速调整生物钟的办法 各种鱼类的英文名今天要和老外去日本餐厅.谁能告诉我各种常见鱼类的英文名谢谢 第三节 元素周期表的应用【填表格】 纤维素、酶、RNA、ATP 哪个不含氮元素谢谢了, 生命有多长啊 There __an NBA basketball game in ten minutes.为什么选will be不选is going to have? 怎么样调整生物钟暑假整个生物钟都乱了.晚上要12点多才睡得着.早上最早也九点多醒.我有试过早早醒,可到晚上还是睡不着.实在是太郁闷了,要怎么调整哦? 个人认为现在的中学英语教学有一点问题.我们知道了一大堆“高级词汇”,却对生活中常见事物不知其英文名.请提供尽可能多的鱼类动物的英文名. 第三节 元素周期表的应用【只填第一个表格】第一竖行第一个:F 第一竖行2个:CL 第一竖行3个:Br 第一竖行4个: I 中国历史的朝代更替示意图 生命到底有多长其实生命只在呼吸间 There ( ) an NBA basketball game in two minutes.A.will be B.is going to be为什么不选A?急,说明理由 1岁小孩锰元素高怎么回事 高手帮起个英文名~(和“鱼”谐音的)英文高手帮忙给起个英文名吧,要求要和瑜字谐音~~~~~ their team is going to have a game__________our team 中国历史上为什么总会有朝代更替?中国历史上为什么总会有朝代更替,并且总有一些人在朝代更替后希望恢复原来的朝代? 黄狐狸鱼英文名 求 一氧化氮中氮元素的化合价 小孩锰偏高怎么办?患者信息:女 3岁 广东 惠州 病情描述(发病时间、主要症状等):锰偏高.想得到怎样的帮助:锰偏高怎么办?曾经治疗情况及是否有过敏、遗传病史:无 有木有和鱼或者三月有关的英文名字~ 已知一氧化氮气体与二氧化氮气体含有相同质量的氮元素,则这两种气体的质量之比是多少? 锰元素多少超标 喝水为什么会打噶 无机盐分哪些种类?这些种类的作用分别是什么? cuo与cu 如何分离如何分离CUO与CU 要操作 试剂 和化学方程式除杂 KNO3中 有BA(NO3)2 怎么办? 等质量的二氧化碳和一氧化碳,则两者所含氧元素的质量比是________. 分钟线的种类与作用分别是什么?本人只想具体的了解一些技术,与具体股票无关,只想单纯满足下求知欲,不懂者请不要发言,否则举报!诚意求教!可以简单介绍下, Cu(I)的化合物一般呈无色或白色,为什么? Self reflection means stopping the mad rush of activity and calming yourself and your mind 汉语意思Self reflection means stopping the mad rush of activity and calming yourself and your mind so your brain can evaluate the input it has already rece 制冷压缩机的作用是什么,如何分类 高中烃中H质量分数计算
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘