使用dask有效地从blob存储上的parquet文件中读取一些列[重复]
Posted
技术标签:
【中文标题】使用dask有效地从blob存储上的parquet文件中读取一些列[重复]【英文标题】:Efficiently reading only some columns from parquet file on blob storage using dask [duplicate] 【发布时间】:2020-03-26 13:14:18 【问题描述】:如何有效地仅读取托管在云 blob 存储(例如 S3/Azure Blob 存储)中的 parquet 文件的某些列?
列式结构是 parquet 文件格式的主要优势之一,因此选择性地读取列可以减少 I/O 负载。将数据存储在 blob 存储中以在云上运行大规模工作负载也是很自然的。但是,一旦将 parquet 文件存储为 blob,大多数库(dask、fastparquet、pyarrow)就无法真正利用这一点,因为底层的fseek
并不能直接在 blob 上——这意味着无论哪些列被选中的人必须在阅读之前将整个文件下载到本地文件系统。
因此,如果我的用例是单独的应用程序需要不同的列,并且仅下载几列的整个文件的性能成本是不可接受的,那么最佳做法是什么?我是否应该为每列存储不同的镶木地板文件以及一个公共索引,然后使用 pandas/dask 等在应用程序级别合并? apache parquet 格式是否具有按列拆分数据集的一些内置支持 - 类似于 hive 格式按分区然后按分区拆分的方式?
感谢任何使用 dask 或 fastparquet 的帮助/具体示例。
【问题讨论】:
【参考方案1】:(fsspec 和 fastparquet 写作的作者)
简短回答:是的,Dask 读取 parquet 将仅从远程存储中选择您需要的列,并且在某些情况下只能从整个数据集中读取分区的子部分。如果您事先知道,最好在对read_parquet
的调用中定义columns=
的集合,但Dask 会尝试从您的计算图中推断出正确的值;例如,dd.read_parquet(...).column1.compute()
只会获取“column1”。对于更复杂的计算,这种推理可能会失败。
即使像(azure blob 和 datalake、s3、gcsfs)这样的键值对后端存储,仍然支持范围请求,这意味着工作人员只会下载感兴趣的字节。
不过,也有一些微妙之处。与磁盘相比,远程存储的延迟(第一个字节的时间)要高得多,因此数据吞吐量在很大程度上取决于男性请求的数量:在文件中查找将具有可变的效率,具体取决于预读/缓存采用的策略。您可以使用 storage_options
参数来微调此行为。
不,没有特别支持单独存储列,尽管连接相同的索引通常应该是有效的。但是,它通常不是必需的,更重要的是其他考虑因素,例如要使用的正确数据类型和分区大小。这些事情通常取决于大小写,您的特定数据存储的延迟可能是一个重要因素。
另请参阅https://github.com/fsspec/filesystem_spec/issues/885,了解专为 parquet 数据量身定制的 fsspec 缓存方案。
【讨论】:
你提到了一些微妙之处和某些情况。您能否更明确地说一下它何时只读取选定列中的数据 - 还是它基本上总是这样做,您只需要知道结果会有一些延迟? 我添加了一些相关的细节。以上是关于使用dask有效地从blob存储上的parquet文件中读取一些列[重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 dask/fastparquet 从多个目录中读取多个 parquet 文件(具有相同架构)
使用 to_parquet() 将 dask 数据帧写入镶木地板结果“RuntimeError:文件元数据仅在写入器关闭后可用”