PyArrow从Google Cloud Storage Blob创建ParquetFile失败求助
问题描述
在Google Cloud Storage中存储了1000个约17MB的Parquet文件,循环遍历Blob并为每个文件初始化ParquetFile对象,仅打印少量信息。处理数百个文件后出现如下报错:
File "/usr/local/lib/python3.10/dist-packages/pyarrow/parquet/core.py", line 319, in __init__ source = filesystem.open_input_file(source) File "pyarrow/_fs.pyx", line 770, in pyarrow._fs.FileSystem.open_input_file File "pyarrow/error.pxi", line 144, in pyarrow.lib.pyarrow_internal_check_status File "pyarrow/error.pxi", line 138, in pyarrow.lib.check_status pyarrow.lib.ArrowException: Unknown error: google::cloud::Status(UNKNOWN: Permanent error GetObjectMetadata: WaitForHandles(): unexpected error code in curl_multi_*, [12]=Unrecoverable error in select/poll)
创建ParquetFile的核心代码大致如下:
path = "gs://..." fs = GcsFileSystem(access_token='...', credential_token_expiration=...) file = ParquetFile(path, filesystem=fs)
解决思路
- 强制资源释放:每次处理完一个
ParquetFile后,显式调用file.close()释放文件句柄,同时在循环内执行del file并触发垃圾回收(gc.collect()),避免长时间运行后句柄泄漏耗尽系统资源。 - 复用GcsFileSystem实例:不要在循环内重复创建
GcsFileSystem对象,全局复用同一个实例,减少连接建立和销毁的开销,避免连接池耗尽。 - 添加重试机制:针对GCS请求的临时异常,用自定义逻辑或
tenacity库包裹ParquetFile初始化代码,捕获ArrowException后重试2-3次,同时跳过确实损坏的文件。 - 调整curl连接参数:通过环境变量调整pyarrow依赖的curl配置,比如增大
CURLMOPT_MAXCONNECTS限制并发连接数,或设置合适的超时参数,避免select/poll资源耗尽。 - 批量处理加间隔:每处理100个左右的文件,暂停3-5秒再继续,给系统留出资源回收的时间,降低并发压力。
- 升级依赖版本:将pyarrow、google-cloud-storage升级到最新稳定版,这类curl底层的连接异常可能已在新版本中修复。
- 优化认证方式:避免手动传入
access_token,改用GCP服务账号密钥文件或默认应用凭据,减少令牌过期或认证环节的连接异常。
内容的提问来源于stack exchange,提问作者zpz
相关产品推荐
相关产品推荐

