R arrow包read_parquet读取大文件报错:非R线程调用seek()求助
问题描述
我使用R的arrow包中的read_parquet()函数读取Parquet文件,该任务每晚处理数十个文件,但今日起部分文件读取失败,报错信息:
Call to R (seek() on R connection) from a non-R thread from an unsupported context
报错与文件大小相关,首个失败的文件是第一个超过2^20行、1000万个单元格的文件;调整文件处理顺序后,仍在首个“大文件”处失败。昨日处理更大文件一切正常,且arrow包未更新、运行任务的代理不会自动安装更新;本地机器用相同函数读取该文件可正常运行,问题出在运行任务的代理上,但不知排查方向。
报错发生在执行以下代码时:
arrow::read_parquet(file = con)
其中con是通过以下代码创建的rawConnection对象:
con <- rawConnection(raw(0), "r+")
con中的数据通过以下代码从Azure数据湖存储下载:
AzureStor::download_adls_file(dest = con)
其他文件处理均成功,问题仅针对该大文件。
解决方法
该报错的核心原因是:R的rawConnection不是线程安全的,当arrow处理大文件时会启用多线程读取,此时尝试在非R主线程中调用seek()操作内存连接就会触发这个错误。
对应的解决方式可选择任意一种:
- 避免使用内存连接,将文件先下载到本地临时文件再读取:
temp_file <- tempfile(fileext = ".parquet") AzureStor::download_adls_file(dest = temp_file) df <- arrow::read_parquet(temp_file) file.remove(temp_file) # 处理完成后删除临时文件 - 使用
arrow包原生的Azure存储支持直接读取文件,无需手动下载:# 先创建Azure存储的FileSystem对象 fs <- arrow::s3_bucket( "your-container-name", endpoint_override = "https://your-storage-account.dfs.core.windows.net", access_key = "your-access-key" ) df <- arrow::read_parquet(fs$path("your-file-path.parquet"))
内容的提问来源于stack exchange,提问作者pmac0451
相关产品推荐
相关产品推荐

