Hadoop的便携式键值数据文件格式?

时间:2012-04-18 21:04:42

标签: c++ python hadoop portability key-value

我正在寻找一种可移植的键值数据文件格式,它可以作为Hadoop的输入和输出格式,除了Hadoop之外,还可以直接在C ++,Java和Python中进行读写。一个问题......我需要支持使用非java映射器和reducer(特别是通过Hadoop管道的c ++)进行处理。

有什么想法吗?我应该编写自己的可移植键值文件格式,与Hadoop和Hadoop管道互操作吗?这种新格式对社区有用吗?

长版: 在使用Hadoop时,Hadoop Sequence文件(及其同类Map,Set,Array和BloomMap)似乎是高效二进制键值数据存储的标准。 Sequence Files的一个缺点是它们只能用Java读写(它们是用序列化的java对象指定的)。我想构建一个复杂的多阶段MapReduce管道,其中各个阶段的输入和输出必须可以从C ++,java和python中读写。此外,我需要能够使用java以外的语言(即c ++)编写映射器和缩减器,以便在映射阶段使用大型且高度优化的c ++库。

我考虑了各种变通方法,但它们似乎都不具备吸引力。

  1. 转换:在每个MapReduce阶段之前和之后添加额外的转换阶段,以转换阶段文件之间的阶段输入和输出以及与其他语言兼容的可移植格式。
    • 问题:阶段之间消耗和生成的数据非常大(TB)......在每个阶段多次复制数据以获得不同编程语言的读/写访问是很昂贵的。有10个阶段,这对我来说是太多的开支($$$)。
  2. Avro文件:使用Avro的便携式数据文件格式。
    • 问题:虽然似乎有代码允许便携式Avro数据文件在MapReduce中用作输入或输出格式,但它只适用于用Java编写的映射器和缩减器。我已经看过几个关于通过avro / mapred / tether包创建其他语言的映射器支持的讨论,但目前只支持java。从文档:“目前只有一个Java框架已经实现,出于测试目的,所以这个功能还没有用。” http://avro.apache.org/docs/1.5.4/api/java/org/apache/avro/mapred/tether/package-summary.html
  3. Avro File + SWIG :将Avro数据格式与Java映射器一起使用,该映射器调用从分布式缓存访问的自定义SWIG包装的c ++库来进行实际处理。
    • java字符串的不变性使得编写SWIG包装器变得痛苦而且效率低下,因为需要复制。此外,这么多层包装开始成为维护,调试和配置的噩梦!
  4. 我正在考虑基于与Hadoop和Hadoop管道互操作的H-File格式编写自己的语言便携式Key-Value文件格式......是否有更好的现成替代方案?这种便携式格式对社区有用吗?

1 个答案:

答案 0 :(得分:1)

我认为你做了几个错误的假设:

  

Sequence Files的一个缺点是它们只能用Java读写(它们是用序列化的java对象指定的)

取决于序列化java对象的含义。 Hadoop使用WritableSerialization类来提供序列化机制,而不是默认的Java序列化机制。您可以将hadoop配置为使用默认Java序列化(JavaSerialization),或者您选择的任何自定义实现(通过io.serializations配置属性)。

因此,如果您使用Hadoop Writable机制,您只需编写一个可以解释序列文件的C ++读取器,然后编写您希望序列化的类的c ++ / python等价物(但这将是一个难以维护的,并导致你的第二个问题,Avro)

  

此外,我需要能够使用java以外的语言(即c ++)编写映射器和缩减器,以便在映射阶段使用大型且高度优化的c ++库

您可以在python / c ++ /中使用Hadoop Streaming编写映射器/缩减器,并使用序列文件存储中间格式。所有流媒体需要的是你的mapper / reducer / combiner期望在key\tvalue对中的stdin上的输入(你可以自定义分隔符而不是tab),并以类似的格式输出(也可以自定义)。

那么如果你想向流式映射器/缩减器传递更复杂的键/值对会怎样呢?在这种情况下,我想看看自定义contrib /流源代码,特别是PipeMapper,PipeReducer和PipeMapRed类。例如,您可以将输出/输入修改为<Type-int/str,Length-int,Value-byte[]>元组,然后修改python / c ++代码以进行适当的解释。

通过这些修改,您可以使用Avro来管理hadoop流式框架(Java)和c ++ / python代码之间的序列化代码。您甚至可以使用Avro。

最后 - 你看过AvroAsTextInputFormatAvroTextOutputFormat类,它们可能正是你想要的(警告,我从未使用过它们)