使用Dask从文件系统/ S3并行读取文件块?

时间:2016-05-16 00:33:26

标签: distributed-computing dask

我正在整理一个概念验证,我希望在分布式环境中使用PyCuda处理大字符数据文件(每个任务一个文件大约8GB) - 具体来说,AWS。我知道HDFS会对数据文件进行分段并将其分发给工作人员,但我试图让我的环境尽可能简单,如果我没有安装,我宁愿不安装Hadoop至。

我最近在Continuum Analytics上观看了几个关于他们的Dask框架的网络研讨会,看起来它将完全符合我的需求。鉴于上面的段落和Dask框架,文件系统的当前建议是什么?我是坚持使用HDFS还是有更好/更简单的解决方案?

1 个答案:

答案 0 :(得分:3)

大多数文件系统都能够只读取文件的一部分,包括HDFS,本地文件系统和S3(AWS实例的标准批量数据存储)。这允许并行计算框架(如Dask)将大文件划分为许多较小的位,工作者可以并行处理这些小位。

dask.bytes.read_bytes

对于大多数用例,这会自动发生在幕后(read_textread_csv的用户无需担心这一点。)听起来你有自定义文件格式,所以我会引导您进入read_bytes函数。对于S3,其工作原理如下:

from dask.bytes import read_bytes
sample, partitions = read_bytes('s3://bucket/keys.*.foo', 
                                blocksize=100000000)

示例将是您的数据的短10kB样本,partitions将是dask.delayed对象的列表,您可以使用常规for循环来构建计算。

如果您的数据具有您希望dask尊重的某种分隔符,则可以使用delimiter=关键字参数提供该分隔符。

此功能适用于其他系统,例如本地文件系统或HDFS(如果已安装并导入hdfs3distributed)。

sample, partitions = read_bytes('local://bucket/keys.*.foo', blocksize=100000000)
sample, partitions = read_bytes('hdfs://bucket/keys.*.foo')

实施例

例如,以下是我们如何实施dask.dataframe.read_csv

的错误但说明性的版本
from dask import delayed
import pandas as pd
import dask.dataframe as dd

def read_csv(path, **kwargs):
    sample, partitions = read_bytes(path, blocksize=100000000, delimiter=b'\n')
    dataframes = [delayed(pd.read_csv)(part, **kwargs) for part in partitions]
    return dd.from_delayed(dataframes)

这是不正确的,因为pd.read_csv实际上需要一个BytesIO对象,我们没有强有力地处理关键字参数,而且我们也没有很好地从样本(列,dtypes等)管理数据帧元数据。这些细节虽然妨碍了一般性的观点,但可能超出了这个问题的利益。

编辑:在更常见的情况下使用其他功能

人们一直将这个问题称为“我如何从S3读取数据?”这个更一般的问题的答案。大多数人不使用read_bytes接口,这是一个较低级别。相反,大多数用户可能希望使用以下更高级别的功能之一:

import dask.bag as db
records = db.read_text('s3://bucket/keys.*.json').map(json.loads)

import dask.dataframe as dd
df = dd.read_csv('s3://bucket/keys.*.csv')