Hadoop 在HDFS文件的一部分上运行MR作业

Hadoop 在HDFS文件的一部分上运行MR作业,hadoop,Hadoop,假设您在hdtf中存储了一个包含结构化数据的大文件。现在的目标是只处理文件中的一部分数据,就像文件中第二列值介于so和so之间的所有行一样。是否可以启动MR作业,使hdfs仅流式传输文件的相关部分,而不是将所有内容流式传输到映射器 原因是我想通过只处理我需要的部分来加快工作速度。可能有一种方法是运行MR作业来创建新文件,但我想知道是否可以避免这种情况 请注意,目标是将数据保存在HDFS中,我不想从数据库中读写。HDFS将文件存储为块中的一组字节,并且没有索引,因此无法仅读取文件的一部分(至少在撰

假设您在hdtf中存储了一个包含结构化数据的大文件。现在的目标是只处理文件中的一部分数据,就像文件中第二列值介于so和so之间的所有行一样。是否可以启动MR作业,使hdfs仅流式传输文件的相关部分,而不是将所有内容流式传输到映射器

原因是我想通过只处理我需要的部分来加快工作速度。可能有一种方法是运行MR作业来创建新文件,但我想知道是否可以避免这种情况


请注意,目标是将数据保存在HDFS中,我不想从数据库中读写。

HDFS将文件存储为块中的一组字节,并且没有索引,因此无法仅读取文件的一部分(至少在撰写本文时是这样)。此外,任何给定的映射程序都可能获得文件的第一个块或第400个块,而您无法控制该块

也就是说,MapReduce的全部目的是将负载分配到多台机器上。在我们的集群中,我们一次最多运行28个映射器(4个节点上每个节点7个),因此如果我的输入文件是1TB,每个映射槽可能只读取总文件的3%,或者大约30GB。只需在映射器中执行所需的过滤器,并仅处理感兴趣的行


如果您确实需要过滤访问,您可能需要考虑将数据存储在HBase中。它可以作为MapReduce作业的本机源,提供过滤读取,并将其数据存储在HDFS上,因此您仍然处于分布式世界中。

一个答案是查看hive解决此问题的方法。数据在“表”中,这些表实际上只是关于磁盘上文件的元数据。配置单元允许您设置对表进行分区的列。这将为每个分区创建一个单独的文件夹,因此,如果您按日期对文件进行分区,您将:

/mytable/2011-12-01
/mytable/2011-12-02
日期目录的内部将是您的实际文件。因此,如果然后运行如下查询:

SELECT * FROM mytable WHERE dt ='2011-12-01'
只有/mytable/2011-12-01中的文件才会输入作业


底线是,如果您想要这样的功能,您要么想使用更高级别的语言(hive/pig),要么需要推出自己的解决方案。

处理成本的很大一部分是数据解析,以生成映射器的关键值。我们(通常)为每个值创建一个java对象+一些容器。它在CPU和垃圾收集器压力方面都很昂贵
我建议“中间”解决方案。您可以编写输入格式,读取输入流并在早期跳过不相关的数据(例如,通过查看字符串的前几个字节)
因此,您将读取所有数据,但实际上只解析并传递给映射程序的一部分。

另一种方法是使用RCfile格式(或其他柱形格式),并注意相关和不相关的数据将位于不同的列中。

< P>如果要处理的文件对文件名有一些独特的属性(如扩展名或部分文件名匹配),您还可以使用FileInputFormat的setInputPathFilter方法忽略除MR作业所需的以外的所有内容。默认情况下,Hadoop会忽略所有“.xxx”和xxx”文件/dir,但您可以使用setInputPathFilter进行扩展


正如上面其他人所指出的,您可能会从集群中获得次优性能,这样做打破了“每个映射器一个块”的模式,但有时这是可以接受的。有时可能需要更多的时间才能“正确完成”“,尤其是在处理少量数据时&重新构建和/或重新转储到HBase所需的时间将抵消以次优方式运行作业所需的额外时间。

0.92中引入的协处理器也可用于筛选出与筛选器类似的数据。不确定协处理器和过滤器的区别是什么。我认为,过滤器是在客户端定义的,而协处理器是在服务器上定义的。因此,协处理器可以跨客户端重用。需要注意的一点是,过滤器和协处理器都在服务器上执行,并减少发送到客户机的数据。但我的理解是协处理器只用于base,而不是普通的HDFS M/RChris——你是指HBase而不是base吗?是什么阻止了在MR中使用协处理器?我在HBase组中发布了一个关于协处理器和过滤器之间差异的查询,但没有得到响应。是的,这是一个打字错误,意思是HBase。我的意思是OP询问本地HDFS上的M/R—我刚才提到HBase,因为他询问的是只读取部分数据。仅供参考,这种技术称为“分区”。它在关系数据库中使用了相当长的一段时间。