You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从S3加载json.gz到Python时程序无响应,求排查方案

问题分析

你的代码看似用了stream=True,但实际上没有实现真正的流式处理,这是导致程序卡住的核心原因:

  1. r.content会一次性将整个3.1GB的压缩文件下载到内存中,大文件的网络下载本身耗时极久,还会占用大量内存资源。
  2. gzip.decompress(r.content)会把整个压缩包解压后全部加载到内存,3.1GB的gzip文件解压后通常会膨胀数倍(甚至几十GB),直接撑爆内存,导致系统调度卡顿,程序看起来像卡住。
  3. 代码中未导入json模块(你用了j.loads但未定义j),不过你提到没报错,应该是代码漏写了导入,但这不是卡住的关键问题。
优化建议

1. 实现真正的流式处理(分块下载+解压)

利用requests的流式响应结合gzip.GzipFile边下载边解压,避免一次性加载大文件到内存:

import json
import gzip
import requests

def parse(url: str):
    raw_data = []
    with requests.get(url, stream=True) as r:
        # 流式读取并解压数据
        with gzip.GzipFile(fileobj=r.raw) as gz_file:
            # 逐行解析解压后的JSON数据
            for line in gz_file:
                raw_data.append(json.loads(line.decode("utf-8")))
    return raw_data

raw_data = parse('https://s3-eu-west-1.amazonaws.com/path/of/bucket.json.gz')

2. 避免将所有数据存入内存

如果解压后的数据量极大,把所有内容存入列表会再次占用大量内存,可按需处理:

  • 逐行写入本地文件(JSON Lines格式):
import json
import gzip
import requests

def parse(url: str, output_path: str):
    with requests.get(url, stream=True) as r:
        with gzip.GzipFile(fileobj=r.raw) as gz_file:
            with open(output_path, 'w', encoding='utf-8') as f:
                for line in gz_file:
                    data = json.loads(line.decode("utf-8"))
                    json.dump(data, f)
                    f.write('\n')

parse('https://s3-eu-west-1.amazonaws.com/path/of/bucket.json.gz', 'output.jsonl')
  • 用生成器逐行返回数据,按需迭代处理:
import json
import gzip
import requests

def parse(url: str):
    with requests.get(url, stream=True) as r:
        with gzip.GzipFile(fileobj=r.raw) as gz_file:
            for line in gz_file:
                yield json.loads(line.decode("utf-8"))

# 按需处理每一条数据
for item in parse('https://s3-eu-west-1.amazonaws.com/path/of/bucket.json.gz'):
    # 这里可以做数据清洗、入库等操作
    print(item)

3. 优化网络访问效率

  • 如果你所在区域和S3的eu-west-1区域距离较远,网络延迟会拖慢下载速度。可以考虑使用AWS SDK(如boto3)直接访问S3,SDK会自动优化请求路径和重试机制:
import json
import gzip
import boto3
from io import BytesIO

s3 = boto3.client('s3')
bucket_name = 'your-bucket-name'
key = 'path/of/bucket.json.gz'

def parse_s3(bucket, key):
    response = s3.get_object(Bucket=bucket, Key=key)
    with gzip.GzipFile(fileobj=BytesIO(response['Body'].read())) as gz_file:
        for line in gz_file:
            yield json.loads(line.decode("utf-8"))

for item in parse_s3(bucket_name, key):
    # 处理单条数据
    pass

4. 监控程序运行状态

在循环中加入进度打印,确认程序是否在正常运行而非真的卡住:

import json
import gzip
import requests

def parse(url: str):
    raw_data = []
    line_count = 0
    with requests.get(url, stream=True) as r:
        with gzip.GzipFile(fileobj=r.raw) as gz_file:
            for line in gz_file:
                raw_data.append(json.loads(line.decode("utf-8")))
                line_count += 1
                if line_count % 1000 == 0:
                    print(f"已处理 {line_count} 行数据")
    return raw_data

内容的提问来源于stack exchange,提问作者bbgghh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:35:41