我正在开发一个应用程序来使用 Hadoop 框架处理(和合并)几个大型 java 序列化对象(顺序 GB 大小)。 Hadoop 存储将文件块分布在不同的主机上。但由于反序列化需要所有块都存在于单个主机上,因此它会极大地影响性能。我该如何处理这种情况,即与文本文件不同,必须单独处理不同的块?
有两个问题:一个是每个文件必须(在初始阶段)被整体处理:看到第一个字节的映射器必须处理该文件的所有其余部分。另一个问题是局部性:为了获得最佳效率,您希望每个此类文件的所有块都驻留在同一主机上。
整体处理文件:
一个简单的技巧是让第一阶段映射器处理文件名列表,而不是它们的内容。如果您希望运行 50 个映射作业,请使用该部分文件名创建 50 个文件。这很简单,并且可以与 java 或流式 hadoop 一起使用。
或者,使用不可分割的输入格式,例如NonSplitableTextInputFormat
.
欲了解更多详情,请参阅“如何处理文件(每个地图一个)? http://hadoop.apache.org/common/docs/current/streaming.html#How+do+I+process+files%2C+one+per+map%3F" and "如何让我的每一张地图都能在一个完整的输入文件上工作? http://wiki.apache.org/hadoop/FAQ#A10“在 hadoop wiki 上。
地点:
然而,这留下了一个问题,即您正在读取的块分布在整个 HDFS 中:通常是性能增益,但这里是一个真正的问题。我不相信有任何方法可以链接某些块在 HDFS 中一起传输。
是否可以将文件放在每个节点的本地存储中?这实际上是解决此问题的最高效且最简单的方法:让每台机器启动作业来处理例如中的所有文件。/data/1/**/*.data
(尽可能聪明地高效使用本地分区和 CPU 核心数量)。
如果文件源自 SAN 或 s3,请尝试直接从那里拉取:它是为处理集群而构建的。
关于使用第一个技巧的注意事项:如果某些文件比其他文件大得多,请将它们单独放在最早命名的列表中,以避免推测执行的问题。如果任务可靠并且您不希望多次处理某些批次,则无论如何您都可以关闭此类作业的推测执行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)