java - Hadoop:处理大型序列化对象

标签 java performance object hadoop

我正在开发一个应用程序,以使用 Hadoop 框架处理(和合并)几个大型 Java 序列化对象(大小为 GB)。 Hadoop 存储将文件 block 分布在不同的主机上。但是由于反序列化将要求所有 block 都存在于单个主机上,因此它会极大地影响性能。与文本文件不同,我该如何处理不同 block 必须单独处理的情况?

最佳答案

有两个问题:一个是每个文件必须(在初始阶段)被整体处理:看到第一个字节的映射器必须处理该文件的所有其余部分。另一个问题是局部性:为了获得最佳效率,您希望每个此类文件的所有 block 都位于同一主机上。


整体处理文件:

一个简单的技巧是让第一阶段映射器处理一个文件名列表,而不是它们的内容。如果要运行 50 个 map 作业,请使用该部分文件名制作 50 个文件。这很简单,可以与 java 或流式 hadoop 一起使用。

或者,使用不可拆分的输入格式,例如 NonSplitableTextInputFormat

有关详细信息,请参阅 hadoop wiki 上的“How do I process files, one per map?”和“How do I get each of my maps to work on one complete input-file?”。


地区:

然而,这留下了一个问题,即您正在读取的 block 分布在整个 HDFS 中:通常是性能提升,这里是一个真正的问题。我不相信有任何方法可以将某些 block 链接起来在 HDFS 中一起移动。

是否可以将文件放在每个节点的本地存储中?这实际上是解决这个问题的最有效和最简单的方法:让每台机器启 Action 业来处理所有文件,例如/data/1/**/*.data(尽可能聪明地高效使用本地分区和 CPU 内核数)。

如果文件源自 SAN 或 s3,请尝试直接从那里拉取:它是为处理集群而构建的。


关于使用第一个技巧的注意事项:如果某些文件比其他文件大得多,请将它们单独放在最早命名的列表中,以避免推测执行的问题。如果任务是可靠的并且您不希望某些批处理被多次处理,那么无论如何您都可以关闭此类作业的推测执行。

关于java - Hadoop:处理大型序列化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3012121/

相关文章:

java,两个对象,object1 = object2 = class/type ...没看懂

java - org.mockito.exceptions.misusing.NotAMockException

java - 使用 HTTPS 保护 Netbeans 6.7 tomcat 管理器 URL

c# - Reflection.Emit 的 Java 等价物

.net - 复杂查询的ORM(尤其是NHibernate)性能

object - 有没有一种方法可以将Map()对象传递给不同屏幕中的不同状态小部件?

javascript - 覆盖 javascript 文件对象

java - 启动 Scala 解释器时的 "Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar"

linux - 在编译时启用 AVX512 支持会显着降低性能

performance - Canvas 标签 - drawarc vs image