MapReduce持续执行



我正在使用Hadoop将现有的时间序列数据库系统转换为MapReduce模型。数据库系统同时具有历史和实时处理能力。到目前为止,我已经能够将批处理功能转换为Hadoop。

不幸的是,当谈到实时处理时,我发现MapReduce模型在概念上存在一些不一致。

我可以编写Hadoop的InputFormat接口的我自己的实现,该接口将连续向映射器提供新数据,以便映射器可以处理并持续发送数据。然而,由于在所有映射程序完成执行之前,不会调用reduce()方法,因此我的计算必然会停留在映射阶段。

我看到一些帖子提到了mapred.reduce.slowstart.completed.maps,但据我所知,这只控制reducer何时开始将数据拉到其本地目的地(shuffling)——实际的reduce方法只有在所有映射器完成执行后才能调用。

当然,有一种选择是通过使用连续的单独MR作业流在小时间间隔内处理小批量数据来模拟连续执行,但这会引入额外的延迟,这在我的情况下是不可接受的。

我也考虑过使用Storm或S4,但在进一步操作之前,我需要确保这不在Hadoop的范围内。

总之,人们似乎已经能够开发实时Hadoop应用程序(如Impala)或基于Hadoop构建的实时处理解决方案。问题是怎么做?

如果InputFormat/mappers连续发送数据,那么就永远不会调用reduce方法。原因是reduce方法必须迭代键的所有值,并且在映射阶段完成之前,完整的值集是未知的,因为要给reduce方法的值可能随时来自任何映射器。

reduce方法通过迭代器访问值,因此从API的角度来看,理论上可以提前调用reduce(),并使其在迭代器上永久阻塞运行,直到值可用。Hadoop之所以没有这个功能,是因为它需要将每个键的上下文保存在内存中,这对于大数据集的批处理没有意义。

在Hadoop MapReduce编程模型中实现数据流连续分析的一种方法是提交连续的小型MR作业流,每个作业分析一块数据。在这种情况下,处理额外延迟的方法是使用许多可用的Hadoop加速器之一(免责声明:我为一家名为ScaleOut Software的公司工作,该公司提供了这样一个加速器:ScaleOut hServer,可在免费社区版中获得)。ScaleOut hServer是内存中的MapReduce引擎,可以在毫秒内运行MR作业。它在作业之间重用JVM,因此与Hadoop相比,作业启动延迟最小。这非常适合在数据块上连续运行MapReduce作业,因为它针对适合内存的数据集的实时性能进行了优化。

上述所有情况的一个例外是,如果分析不需要减少阶段(即减少器的数量设置为0):如果算法只能表示为map,则可以通过一个Hadoop批处理作业连续完成。

Nathan Marz在即将出版的《大数据》一书中讨论了"Lambda架构",它融合了Storm和Hadoop,共同提供实时系统。

我还建议你看看Twitter Summingbird,它允许你拥有:"Streaming MapReduce"模型。

Summingbird是一个库,可以让您编写流式MapReduce程序,这些程序看起来像本地Scala或Java集合转换,并在许多知名的分布式MapReduce平台上执行,如Storm和Scalding。

我个人已经用MapReduce实现了一个流式解决方案,但它并不漂亮。每当你试图用MapReduce做一些开箱即用的事情时,它都会以某种方式失败。

MapReduce是专门为批处理而设计的,您正在寻找的流处理功能是Flume和Storm等技术出现的主要原因之一。这两种技术都被认为是hadoop生态系统中的实际标准,并且与hadoop的其他部分有很好的集成。


您提到您正在处理时间序列数据。你看过OpenTSDB吗?它是一个建立在HBase和HDFS之上的时间序列数据库。

最新更新