Hadoop noob在这里。
我已经搜索了一些有关hadoop和python入门的教程,但没有取得多大成功。我还不需要对映射器和缩减器进行任何操作,但它更多的是访问问题。
作为Hadoop集群的一部分, HDFS上有一堆.dat文件。
为了使用Python访问我的客户端(本地计算机)上的那些文件,
我需要在计算机上安装什么?
如何在HDFS上查询文件名?
任何链接也会有所帮助。
答案 0 :(得分:3)
我需要在计算机上安装什么?
你需要安装和运行Hadoop,以及Python。
如何在HDFS上查询文件名?
你可以在这里尝试这样的事情。我还没有对代码进行测试,所以不要只依赖它。
request.form['fred']
您还可以查看Pydoop这是Hadoop的Python API。
虽然我的示例包含from subprocess import Popen, PIPE
process = Popen('hdfs dfs -cat filename.dat',shell=True,stdout=PIPE, stderr=PIPE)
std_out, std_err = process.communicate()
check for returncode, std_err
if:
everything is OK, do whatever with stdout
else:
do something in else condition
,但您可以尝试在没有它的情况下运行,因为它存在安全风险。 Why you shouldn't use shell=True
?
答案 1 :(得分:3)
据我所知,没有开箱即用的解决方案,而且我发现的大多数答案都使用了对hdfs
命令的调用。我在Linux上运行,并遇到同样的挑战。我发现sh
包非常有用。这会处理为您运行o / s命令并管理stdin / out / err。
有关详细信息,请参阅此处:https://amoffat.github.io/sh/
不是最好的解决方案,但它是一行(ish)并使用标准包。
这是我删除HDFS目录列表的简化代码。它会列出文件和文件夹,因此如果您需要区分它们,可能需要修改它们。
import sh
hdfsdir = '/somedirectory'
filelist = [ line.rsplit(None,1)[-1] for line in sh.hdfs('dfs','-ls',hdfsdir).split('\n') if len(line.rsplit(None,1))][1:]
我的输出 - 在这种情况下,这些都是目录:
[u'/somedirectory/transaction_basket_fct/date_id=2015-01-01',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-02',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-03',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-04',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-05',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-06',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-07',
u'/somedirectory/transaction_basket_fct/date_id=2015-01-08']
让我们分解一下:
要运行hdfs dfs -ls /somedirectory
命令,我们可以像这样使用sh
包:
import sh
sh.hdfs('dfs','-ls',hdfsdir)
sh
允许您无缝地调用o / s命令,就好像它们是模块上的函数一样。您将命令参数作为函数参数传递。真的很整洁。
对我来说,这会返回类似的内容:
Found 366 items
drwxrwx---+ - impala hive 0 2016-05-10 13:52 /somedirectory/transaction_basket_fct/date_id=2015-01-01
drwxrwx---+ - impala hive 0 2016-05-10 13:52 /somedirectory/transaction_basket_fct/date_id=2015-01-02
drwxrwx---+ - impala hive 0 2016-05-10 13:52 /somedirectory/transaction_basket_fct/date_id=2015-01-03
drwxrwx---+ - impala hive 0 2016-05-10 13:52 /somedirectory/transaction_basket_fct/date_id=2015-01-04
drwxrwx---+ - impala hive 0 2016-05-10 13:52 /somedirectory/transaction_basket_fct/date_id=2015-01-05
使用.split('\n')
使用line.rsplit(None,1)[-1]
获取字符串中的最后一个'word'。
要防止列表中的空元素出现问题,请使用if len(line.rsplit(None,1))
最后使用Found 366 items
[1:]
)
答案 2 :(得分:2)
您应该拥有群集中节点的登录访问权限。让集群管理员选择节点并设置帐户,并告知您如何安全地访问节点。如果您是管理员,请告诉我集群是本地还是远程,如果是远程,那么它是托管在您的计算机上,公司内部还是第三方云上,如果是,那么我可以提供更多相关信息。< / p>
要在HDFS中查询文件名,请登录到群集节点并运行hadoop fs -ls [path]
。 路径是可选的,如果未提供,则会列出主目录中的文件。如果-R
作为选项提供,则它会以递归方式列出路径中的所有文件。此命令还有其他选项。有关此命令和其他Hadoop文件系统shell命令的更多信息,请参阅http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html。
在Python中查询HDFS文件名的一种简单方法是使用esutil.hdfs.ls(hdfs_url='', recurse=False, full=False)
,它在子进程中执行hadoop fs -ls hdfs_url
,此外它还具有许多其他Hadoop文件系统shell命令的功能(请参阅来源http://code.google.com/p/esutil/source/browse/trunk/esutil/hdfs.py)。 esutil 可以与pip install esutil
一起安装。它位于https://pypi.python.org/pypi/esutil的PyPI上,其文档位于http://code.google.com/p/esutil/,其GitHub网站为https://github.com/esheldon/esutil。
答案 3 :(得分:1)
仅使用python 3的原始子进程库来“查询HDFS上的文件名”
from subprocess import Popen, PIPE
hdfs_path = '/path/to/the/designated/folder'
process = Popen(f'hdfs dfs -ls -h {hdfs_path}', shell=True, stdout=PIPE, stderr=PIPE)
std_out, std_err = process.communicate()
list_of_file_names = [fn.split(' ')[-1].split('/')[-1] for fn in std_out.decode().split('\n')[1:]][:-1]
list_of_file_names_with_full_address = [fn.split(' ')[-1] for fn in std_out.decode().split('\n')[1:]][:-1]
答案 4 :(得分:0)
正如JGC所说,您可以做的最直接的事情是首先登录(通过ssh
)节点之一(参与Hadoop集群的服务器)并验证您是否具有正确的访问权限控制和特权:
hdfs dfs -ls
hdfs dfs -ls <absolute or relative path to HDFS directory>
然后,在Python中,您应该使用子进程和HDFS客户端访问感兴趣的路径,并使用-C
标志排除不必要的元数据(以避免以后进行丑陋的后处理)。
即Popen(['hdfs', 'dfs', '-ls', '-C', dirname])
然后,将输出分成新行,然后将获得路径列表。
以下是有关日志记录和错误处理的示例(包括目录/文件不存在时的示例):
from subprocess import Popen, PIPE
import logging
logger = logging.getLogger(__name__)
FAILED_TO_LIST_DIRECTORY_MSG = 'No such file or directory'
class HdfsException(Exception):
pass
def hdfs_ls(dirname):
"""Returns list of HDFS directory entries."""
logger.info('Listing HDFS directory ' + dirname)
proc = Popen(['hdfs', 'dfs', '-ls', '-C', dirname], stdout=PIPE, stderr=PIPE)
(out, err) = proc.communicate()
if out:
logger.debug('stdout:\n' + out)
if proc.returncode != 0:
errmsg = 'Failed to list HDFS directory "' + dirname + '", return code ' + str(proc.returncode)
logger.error(errmsg)
logger.error(err)
if not FAILED_TO_LIST_DIRECTORY_MSG in err:
raise HdfsException(errmsg)
return []
elif err:
logger.debug('stderr:\n' + err)
return out.splitlines()
# dat_files will contain a proper Python list of the paths to the '.dat' files you mentioned above.
dat_files = hdfs_ls('/hdfs-dir-with-dat-files/')