【问题标题】:s3 - how to get fast line count of file? wc -l is too slows3 - 如何获得文件的快速行数? wc -l 太慢了
【发布时间】:2018-09-15 23:00:46
【问题描述】:

有没有人可以快速获取托管在 S3 中的文件的行数?最好使用 CLI、s3api,但我也对 python/boto 持开放态度。 注意:解决方案必须以非交互方式运行,即隔夜批处理。

是的,我正在这样做,它可以工作,但 20GB 文件需要大约 10 分钟:

 aws cp s3://foo/bar - | wc -l

【问题讨论】:

  • 您的命令行操作将整个文件内容复制到本地计算机以执行wc。如果您要对文件其他 执行任何操作而不是计算其行数,那么您可能会受益于支付该价格一次并在本地复制它。如果您只关心行数,您可能会发现简单估计更有用。

标签: amazon-web-services amazon-s3 boto boto3 aws-cli


【解决方案1】:

这里有两种方法可能对你有用...

Amazon S3 有一个名为 S3 Select 的新功能,可让您查询存储在 S3 上的文件。

您可以计算文件中的记录(行)数,它甚至可以处理 GZIP 文件。结果可能因您的文件格式而异。

Amazon Athena 也是一个可能合适的类似选项。它可以查询存储在 Amazon S3 中的文件。

【讨论】:

  • Amazon Athena has an SDK 或者可以是 called from the AWS CLI。显然有一个适用于 Java 和 Python 的 S3 Select SDK,但我找不到它。
  • S3 Select 的一个限制是它仅适用于 CSV 或 JSON 文件,而不适用于任意“行”。关于 SDK,新 API 的发布确实需要很短的时间。
  • 这不适用于超过 128MB 的文件。
  • @HrushikeshPatel “不工作”是什么意思?您收到的错误信息是什么?
  • AWS 说“超过了 128 MB 的最大输入文件大小。此文件为 397.6 MB。要处理更大的文件,请使用 API。”
【解决方案2】:

是的,Amazon S3 具有 SELECT 功能,在从 SELECT 选项卡执行任何查询时也要留意成本。 例如,这是@Jun2018 的价格(可能会有所不同) S3 Select 定价基于输入、输出和传输数据的大小。 每个查询将花费每 GB 扫描 0.002 美元,加上每 GB 返回 0.0007 美元。

【讨论】:

    【解决方案3】:

    您可以使用 python/boto3 来完成。 定义bucket_name和前缀:

    colsep = ','
    s3          = boto3.client('s3')
    bucket_name = 'my-data-test'
    s3_key = 'in/file.parquet'
    

    请注意,S3 SELECT 一次只能访问一个文件。

    现在你可以打开 S3 SELECT 光标了:

    sql_stmt    = """SELECT count(*) FROM s3object S"""  
    req_fact =s3.select_object_content(
        Bucket  = bucket_name,
        Key     = s3_key,
        ExpressionType  = 'SQL',
        Expression      = sql_stmt,
        InputSerialization={'Parquet': {}},
        OutputSerialization = {'CSV': {
                    'RecordDelimiter': os.linesep,
                    'FieldDelimiter': colsep}},
        
    )
    

    现在遍历返回的记录:

    for event in req_fact['Payload']:
        if 'Records' in event:
            rr=event['Records']['Payload'].decode('utf-8')
            for i, rec in enumerate(rr.split(linesep)):
                if rec:
                    row=rec.split(colsep)
                    if row:
                        print('File line count:', row[0])
    

    如果您想计算给定 S3 目录中所有 parquet 文件中的记录,请查看此 python/boto3 脚本:S3-parquet-files-row-counter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多