【问题标题】:hadoop converting \r\n to \n and breaking ARC formathadoop 将 \r\n 转换为 \n 并打破 ARC 格式
【发布时间】:2012-01-25 08:32:35
【问题描述】:

我正在尝试使用 hadoop 流解析来自 commoncrawl.org 的数据。我设置了一个本地 hadoop 来测试我的代码,并有一个使用流式 ARCfile 阅读器的简单 Ruby 映射器。当我像自己一样调用我的代码时

cat 1262876244253_18.arc.gz | mapper.rb | reducer.rb

它按预期工作。

似乎 hadoop 会自动看到文件具有 .gz 扩展名并在将其交给映射器之前对其进行解压缩 - 但是在这样做的同时它将流中的 \r\n 换行符转换为 \n。由于 ARC 依赖于标题行中的记录长度,因此更改会破坏解析器(因为数据长度已更改)。

为了仔细检查,我将映射器更改为期望未压缩的数据,然后:

cat 1262876244253_18.arc.gz | zcat | mapper.rb | reducer.rb

而且它有效。

我不介意 hadoop 自动解压缩(尽管我可以很高兴地处理流式传输的 .gz 文件),但如果确实如此,我需要它以“二进制”形式解压缩,而无需进行任何换行转换或类似操作。我相信默认行为是将解压缩的文件提供给每个文件一个映射器,这是完美的。

我怎样才能要求它不要解压缩 .gz(重命名文件不是一个选项)或让它正确解压缩?如果可能的话,我宁愿不使用必须装在罐子里的特殊 InputFormat 类。

所有这些最终都将在 AWS ElasticMapReduce 上运行。

【问题讨论】:

标签: hadoop mapreduce elastic-map-reduce


【解决方案1】:

看起来应该归咎于 Hadoop PipeMapper.java(至少在 0.20.2 中):

在第 106 行附近,来自 TextInputFormat 的输入被传递到此映射器(在该阶段 \r\n 已被剥离),并且 PipeMapper 将其写入 stdout,仅带有一个 \n。

建议修改 PipeMapper.java 的源代码,检查此“功能”是否仍然存在,并根据需要进行修改(可能允许通过配置属性进行设置)。

【讨论】:

  • 好人!你会因为在这里如此乐于助人而得到很多人的支持。我想也许我首先要使用 TextInputFormat 来解决这个问题。如果我关心字节级别的字符编码,我应该使用 SequenceFileInput。那有意义吗?同样,这是一个巨大的帮助——如果 Hadoop 保留原始文件的行尾,那就太好了。
  • @ghayes SequenceFileInputFormat 不会有帮助,除非输入文件采用这种格式。您可能需要编写自己的输入格式
  • 是啊.. 在一天结束的时候,发现逐行输入伪二进制文件是不合适的。我建议使用不同的 InputFormat(例如 ArcFileFormat),但这需要在 Java 中深入研究才能完成 Steaming Ruby MapReduce 作业。或者,我采用标准的懦夫方式,将输入设为文件列表(因为 gzip 压缩的文件无论如何都是可拆分的),然后自己处理它们。 MapReduce 默认类型本身并不是通用的。 :-\
猜你喜欢
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 2010-09-07
相关资源
最近更新 更多