如何在hadoop流媒体中使用“typedbytes”或“rawbytes”?

roqulrg3  于 2021-06-03  发布在  Hadoop
关注(0)|答案(3)|浏览(411)

我有一个问题可以通过hadoop以“typedbytes”或“rawbytes”模式进行流处理来解决,它允许用java以外的语言分析二进制数据(否则,流将某些字符(通常是\t和\n)解释为分隔符,并抱怨非utf-8字符。将所有二进制数据转换为base64会减慢工作流程,从而无法实现此目的。)
这些二进制模式是由hadoop-1722添加的。在调用hadoop流作业的命令行上,“-io rawbytes”允许您将数据定义为32位整数大小,后跟该大小的原始数据,“-io typedbytes”允许您将数据定义为1位零(表示原始字节),后跟32位整数大小,后跟该大小的原始数据。我已经用这些格式创建了文件(有一条或多条记录),并通过与typedbytes.py的输出进行检查来验证它们的格式是否正确。我还尝试了所有可能的变体(大端、小端、不同的字节偏移量等)。我使用的是来自cdh4的hadoop0.20,它有实现typedbytes处理的类,当设置“-io”开关时,它将进入这些类。
我用“hadoopfs-copyfromlocal”将二进制文件复制到hdfs。当我尝试使用它作为map reduce作业的输入时,它会失败,并在尝试生成长度为我指定的字节数组(例如3字节)的行中出现outofmemoryerror。它一定是读取错误的数字,并试图分配一个巨大的块,而不是。尽管如此,它还是设法向Map器获取一条记录(上一条记录?不确定),它将它写入标准错误以便我可以看到它。记录的开头总是有太多字节:例如,如果文件是“\x00\x00\x00\x00\x03hey”,Map程序将看到“\x04\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x08\x00\x00\x00\x00\x03hey”(可复制的位,但我看不到模式)。
从这篇演讲的第5页,我了解到流式处理有“loadtb”和“dumptb”子命令,它们一步复制到hdfs或从hdfs复制并 Package /展开sequencefile中键入的字节。当与“-inputformat org.apache.hadoop.mapred.sequencefileasbinaryinputformat”一起使用时,hadoop正确地解压了sequencefile,但随后以完全相同的方式误解了其中包含的typedbytes。
此外,我找不到有关此功能的文档。2月7日(我给自己发了一封电子邮件),apache上的streaming.html页面中简要地提到了这个问题,但这个r0.21.0页面后来被删除了,r1.1.1的等效页面没有提到rawbytes或typedbytes。
所以我的问题是:在hadoop流媒体中使用rawbytes或typedbytes的正确方法是什么?有人用过吗?如果是的话,有人能贴出食谱吗?对于任何想在hadoop流媒体中使用二进制数据的人来说,这似乎都是一个问题,这应该是一个相当广泛的群体。
p、 我注意到dumbo、hadoopy和rmr都使用这个特性,但是应该有一种直接使用它的方法,而不需要基于python或基于r的框架。

yfwxisqw

yfwxisqw1#

显然有一个用于流式处理的justbytes io模式的补丁,它将整个输入文件提供给mapper命令:
https://issues.apache.org/jira/browse/mapreduce-5018

m4pnthwp

m4pnthwp2#

我们解决了二进制数据的问题,在将数据向下流到Map器时,在拆分级别对数据进行六边形编码。这将利用并提高操作的并行效率,而不是在节点上处理之前先转换数据。

piah890a

piah890a3#

好吧,我找到了一个有效的组合,但很奇怪。
按照文档或通过模仿typedbytes.py,在本地文件系统中准备一个有效的typedbytes文件。
使用

hadoop jar path/to/streaming.jar loadtb path/on/HDFS.sequencefile < local/typedbytes.tb

将typedbytes Package 到sequencefile中并将其放入hdfs,只需一步。
使用

hadoop jar path/to/streaming.jar -inputformat org.apache.hadoop.mapred.SequenceFileAsBinaryInputFormat ...

运行map reduce作业,其中Map程序从sequencefile获取输入。请注意 -io typedbytes 或者 -D stream.map.input=typedbytes 不应该使用---显式地要求typedbytes会导致我在问题中描述的误解。但不要担心:hadoop流媒体在二进制记录边界上而不是在'\n'字符上分割输入。数据以“\t”和“\n”分隔的“rawdata”形式到达Map器,如下所示:
32位有符号整数,表示长度(注:无类型字符)
这个长度的原始二进制块:这是关键
'\t'(制表符。。。为什么?)
32位有符号整数,表示长度
具有该长度的原始二进制块:这是值
'\n'(换行符…?)
如果您还想将原始数据从mapper发送到reducer,请添加

-D stream.map.output=typedbytes -D stream.reduce.input=typedbytes

将Map器的输出和reducer的预期输入格式化为有效的typedbytes。它们也交替用于键值对,但这次使用类型字符,而不使用'\t'和'\n'。hadoop流正确地在二进制记录边界上拆分这些对,并按键分组。
关于 stream.map.output 以及 stream.reduce.input 我能找到的是hadoop-1722交换,从2009年2月6日开始(前面的讨论考虑了一种不同的格式参数化方法。)
这个方法没有为输入提供强类型:类型字符在创建sequencefile并用 -inputformat . 但是,它确实提供了二进制记录边界的拆分,而不是真正重要的'\n',以及Map器和还原器之间的强类型。

相关问题