Windows单节点HDFS下Python读取Parquet文件报错求助
问题:Windows单节点HDFS跨机器读取Parquet文件报错FileNotFoundError
我参考教程搭建了Windows单节点HDFS,已上传Parquet文件,但从其他电脑读取时出错。Python代码如下:
import pyarrow as pa import pyarrow.parquet as pq hdfs_path = "hdfs://10.35.105.35:9820/tampo/oee_tampo.parquet" fs = pa.hdfs.connect() table = pq.read_table(hdfs_path, filesystem=fs) import pandas as pd df = table.to_pandas() fs.close()
运行时报错:
1522 # pipe will not close when the child process exits and the 1523 # ReadFile will hang. 1524 self._close_pipe_fds(p2cread, p2cwrite, 1525 c2pread, c2pwrite, 1526 errread, errwrite) FileNotFoundError: [WinError 2] The system cannot find the file specified
解决思路与方案
一、排查pyarrow HDFS连接依赖问题
这个报错核心原因是读取端机器缺少Hadoop客户端环境,或pyarrow无法找到Hadoop相关执行文件:
- 确保读取端安装与HDFS服务器同版本的Hadoop客户端,配置
HADOOP_HOME环境变量,并将%HADOOP_HOME%\bin添加到系统PATH。 - Windows环境需确认
%HADOOP_HOME%\bin目录下存在对应版本的winutils.exe和hadoop.dll,这两个文件是Windows运行Hadoop客户端的必要组件。 - 手动指定Hadoop路径连接,避免依赖自动查找:
fs = pa.hdfs.connect( host='10.35.105.35', port=9820, hdfs_path='C:/hadoop/bin/hdfs', # 替换为你的Hadoop客户端hdfs命令路径 user='your_username' # 替换为HDFS上的合法用户名 )
二、检查HDFS网络与权限配置
- 开放防火墙端口:确认HDFS服务器的9820(DataNode端口)、9000(NameNode端口)在防火墙中允许外部访问,读取端可通过
telnet 10.35.105.35 9820测试连通性。 - 调整文件权限:在HDFS服务器上执行命令,确保读取端用户有文件读取权限:
hdfs dfs -chmod 755 /tampo/oee_tampo.parquet
- 修正HDFS配置:检查服务器
core-site.xml中的fs.defaultFS配置,需使用服务器真实IP或hostname,而非localhost,确保外部机器能正确解析。
三、替代读取方案
如果pyarrow的HDFS连接问题难以快速解决,可尝试以下替代方法:
1. 使用hdfs3库连接
from hdfs3 import HDFileSystem import pyarrow.parquet as pq fs = HDFileSystem(host='10.35.105.35', port=9820) with fs.open('/tampo/oee_tampo.parquet', 'rb') as f: table = pq.read_table(f) df = table.to_pandas()
2. 通过WebHDFS接口读取
若HDFS开启了WebHDFS服务(默认端口50070),可直接通过HTTP请求下载文件:
import requests import pyarrow.parquet as pq from io import BytesIO url = 'http://10.35.105.35:50070/webhdfs/v1/tampo/oee_tampo.parquet?op=OPEN' response = requests.get(url, stream=True) with BytesIO(response.content) as f: table = pq.read_table(f) df = table.to_pandas()
3. 用pandas结合hdfscli读取
from hdfs import InsecureClient import pandas as pd client = InsecureClient('http://10.35.105.35:50070', user='your_username') with client.read('/tampo/oee_tampo.parquet') as f: df = pd.read_parquet(f)
内容的提问来源于stack exchange,提问作者Aji Goja
相关产品推荐
相关产品推荐

