HDFS 将数据存储在 64MB/128MB 的块中,并以这些块大小在任务节点之间复制数据。这些块存储在节点的硬盘中。如果我在此声明中错了,请纠正我。
该块是完全加载到 RAM 中还是需要逐行流式传输?还是两者都有可能?
假设我有一个 1GB 的 CSV 文件,我想在该文件上执行一些不独立于该 CSV 文件中的每一行的计算。我的意思是计算需要处理 10 个连续的行。例如:计算行 1:10,然后是 2:11,然后是 3:12 等等。我有什么选择?将这个 1 GB 多行数据转换为单行数据,然后将其作为单个矩阵加载是一个好主意(我想如果计算复杂,在整个 64MB/128MB 块上计算,这会溢出 RAM)?
3 回答
1)你是对的(块大小是可配置的,但我将简要介绍一下 Hadoop 架构。Hadoop 有一个主/从架构,有两个守护进程组:NameNode/DataNode/SecondaryNameNode (SNN) 和 JobTracker/TaskTracker。NameNode 是负责跟踪数据文件如何分解为文件块以及它们驻留在哪些数据节点中。NameNodes 通常不兼作 DataNodes。DataNodes 将 HDFS 块读取和写入本地文件系统(磁盘)并与其他 DataNodes 通信SNN 是一个与 NameNode 通信的辅助守护进程,用于在单点故障 NameNode 出现故障的情况下最大限度地减少停机时间和数据丢失。JobTracker master 确定代码的执行计划,TaskTracker slave 执行 JobTracker 分配的各个任务。
2) NameNode 跟踪 RAM 中的所有数据节点命名空间。数据加载到 HDFS 后,会从磁盘流式传输以进行处理(HDFS 针对顺序数据访问进行了优化)流式传输仅受存储数据的驱动器的最大 I/O 速率限制。请参阅此 Cloudera 帖子以了解最佳 HDFS 块大小http://blog.cloudera.com/blog/2009/02/the-small-files-problem/
3)你能再描述一下你的用例吗?您可能必须定义自己的 InputSplits,这可能会相当参与(参见:http: //developer.yahoo.com/hadoop/tutorial/module4.html)。如果您可以控制数据集,则可以对其进行预处理。或者,如果您可以控制文件大小,您可以将文件以块的形式写入,比如说 62MB,块大小为 64MB。
1)数据沿数据节点复制。在大多数配置中,您希望您的任务节点也是数据节点。是的,它是物理存储的。
2)如果您使用标准阅读器,则 Hadoop 用户在输入拆分和“流式传输”数据上逐行“流式传输”数据。还有其他阅读器,您也可以实现自己的阅读器
3)如果你想处理一个文件的 10 行,有几种方法可以做到这一点。一种是将您的文件设置为不可分割的。然后保证整个 CSV 由一个映射器处理。您可以自己拆分文件以让很多映射器工作。我能想到的其他方法要复杂得多,或者在块边界上存在问题。我认为加载整个文件不是最好的主意,当您的 .csv 将来变得更大时,您的方法必须失败。
如果您的工作是仅地图工作,您可以添加一个 reduce 阶段并为这 10 行计算一个特殊键(例如,它们与一个特殊问题等相关)并在您的 reducer 中获取所有相关的行。不幸的是,我对你的工作了解得不够具体
如果您是 hadoop 新手,该链接可能会帮助您进入它
回答 3):
如果您不介意丢失 10 行集合中的一小部分,一个非常简单且快速的解决方案是围绕LineReader构建一些代码- 当映射器第一次请求键/值对时,您的版本LineReader 读取 10 行,对于所有后续调用,您逐行读取。这只需要几行额外的代码。