这是我的问题:我有一个HDFS文件可能很大(=不足以满足所有内存)
我想要做的是避免将此文件缓存在内存中,并且只像我对常规文件那样逐行处理:
for line in open("myfile", "r"):
# do some processing
我希望看看是否有一种简单的方法可以在不使用外部库的情况下完成这项工作。我可能会使它与libpyhdfs或python-hdfs一起工作,但我希望尽可能避免在系统中引入新的依赖项和未经测试的库,特别是因为这两者似乎都没有得到很大的维护和状态它们不应该用于生产。
我正在考虑使用Python subprocess
模块使用标准的“hadoop”命令行工具来做这件事,但由于没有命令行工具,我似乎无法做到我需要的工作。会做我的处理,我想以流式方式为每一行执行Python函数。
有没有办法使用子进程模块将Python函数应用为管道的正确操作数?或者甚至更好,像文件一样打开它作为生成器,这样我可以轻松处理每一行?
cat = subprocess.Popen(["hadoop", "fs", "-cat", "/path/to/myfile"], stdout=subprocess.PIPE)
如果有另一种方法可以在不使用外部库的情况下实现上述描述,我也非常开放。
感谢您的帮助!
答案 0 :(得分:28)
如果你想避免不惜任何代价添加外部依赖,Keith的答案是要走的路。另一方面,Pydoop可以让您的生活更轻松:
import pydoop.hdfs as hdfs
with hdfs.open('/user/myuser/filename') as f:
for line in f:
do_something(line)
关于您的担忧,Pydoop正在积极开发并已在CRS4生产多年,主要用于计算生物学应用。
西蒙
答案 1 :(得分:1)
在过去两年中,Hadoop-Streaming上有很多动议。根据Cloudera的说法,这是非常快的:http://blog.cloudera.com/blog/2013/01/a-guide-to-python-frameworks-for-hadoop/我已经取得了很大的成功。
答案 2 :(得分:0)
您可以使用WebHDFS Python库(基于urllib3构建):
from hdfs import InsecureClient
client_hdfs = InsecureClient('http://host:port', user='root')
with client_hdfs.write(access_path) as writer:
dump(records, writer) # tested for pickle and json (doesnt work for joblib)
或者您可以将python中的请求包用作:
import requests
from json import dumps
params = (('op', 'CREATE')
('buffersize', 256))
data = dumps(file) # some file or object - also tested for pickle library
response = requests.put('http://host:port/path', params=params, data=data) # response 200 = successful
希望这会有所帮助!