Hadoop环境中使用STDIN还是文件作为mapper输入?
在非Hadoop环境中,我需要读取一堆文件到mapper里,我使用了 os.walk(dir)
和 file=open(path, mode)
来逐个读取每个文件。
但是在Hadoop环境中,我了解到HadoopStreaming会把文件输入转换成mapper的标准输入(STDIN),并把reducer的标准输出(stdout)转换成文件输出。我有几个关于如何输入文件的问题:
我们是否需要在mapper.py中设置从STDIN读取输入,让HadoopStreaming把HDFS输入目录里的文件转换成STDIN?
如果我想逐个读取每个文件并解析每一行,我该如何在mapper.py中设置从文件读取输入?
我之前在非Hadoop环境中的Python代码是这样的: for root, dirs, files in os.walk('非hdfs的路径') .....
但是在Hadoop环境中,我需要把'非hdfs的路径'改成HDFS的路径,也就是我用copyFromLocal命令复制到的地方,但我尝试了很多都没有成功,比如 os.walk('/user/hadoop/in')
——这是我通过运行bin/hadoop dfs -ls检查过的,还有 os.walk('home/hadoop/files')
——这是我在非Hadoop环境中的本地路径,甚至还有 os.walk('hdfs://host:fs_port/user/hadoop/in')
....
有没有人能告诉我,我是否可以在mapper.py中使用文件操作来从文件输入,还是必须从STDIN输入?
谢谢。
1 个回答
Hadoop Streaming必须从标准输入(STDIN)获取数据。我觉得你困惑的地方在于,你试图写一些代码来完成Hadoop Streaming已经为你做的事情。我刚开始使用Hadoop的时候也犯过这个错误。
Hadoop Streaming可以读取多个文件,甚至是多个压缩文件,然后它会逐行解析这些文件,把内容送到你的映射器(mapper)的标准输入中。这种处理方式很方便,因为你可以让你的映射器不依赖于文件名或文件位置。这样一来,你就可以把映射器和归约器(reducer)用于任何输入,这在后面会很有用。而且,你不希望你的映射器去直接获取文件,因为你无法预知将来会有多少个映射器。如果文件在映射器中被硬编码,那么如果某个映射器出错,你就永远无法从那个映射器中获取到硬编码的文件的输出。所以,让Hadoop来处理文件管理,让你的代码尽可能通用。