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

如何提升PyMongo读取MongoDB大集合的扩展性并以原始BSON写入S3?

解决方案:用原生BSON格式读取MongoDB集合并写入S3

完全可以用原始BSON格式处理,这比转JSON高效得多——BSON是MongoDB的原生存储格式,序列化/反序列化开销小,文件体积也更小,能大幅降低内存占用和处理时间,刚好解决你遇到的超时问题。

先说说你当前代码的几个关键问题:

  • 把col.find()的结果直接转成list,等于一次性把所有文档加载到内存里,数据量越大内存占用越高,Lambda的资源瓶颈会直接导致超时。
  • 循环里每次调用object.put(Body=...),会覆盖之前写入的内容,最后S3里只会保留最后一条文档,完全不符合批量备份的需求。

下面是优化后的代码思路和实现:

  1. 保留cursor的迭代器特性,不一次性加载所有文档,逐批处理
  2. 用bson.encode直接把文档序列化成BSON字节,跳过JSON转换的额外开销
  3. 把BSON数据批量写入S3(用内存缓冲区暂存后一次性上传,避免多次IO请求)

优化后的代码示例:

import boto3
import pymongo
from bson import encode
from datetime import date
from io import BytesIO

def lambda_handler(event, context):   
    # 连接MongoDB
    try:
        client = pymongo.MongoClient(
            "mongodb://<username>:<password>/?tls=true&tlsCAFile=rds-combined-ca-bundle.pem&retryWrites=false"
        )
        db = client["<db_name>"]
        col = db.<collection_name>
        # 保持cursor为迭代器,不转成list
        cursor = col.find().sort([("$natural", 1)]).limit(75000)
    except pymongo.errors.OperationFailure as e:
        return str(e)
    except Exception as e:
        return str(e)
    
    # 处理BSON数据并写入S3
    try:
        file_name = f"test_{date.today().strftime('%d-%m-%Y')}.bson"
        s3 = boto3.client('s3')
        bucket_name = "<bucket_name>"
        
        # 用内存缓冲区暂存BSON数据,避免写本地文件
        bson_buffer = BytesIO()
        
        # 逐文档序列化到缓冲区
        for doc in cursor:
            bson_buffer.write(encode(doc))
        
        # 重置缓冲区指针到开头,一次性上传到S3
        bson_buffer.seek(0)
        s3.put_object(
            Bucket=bucket_name,
            Key=file_name,
            Body=bson_buffer
        )
        
        return 'S3上传成功'
    except Exception as e:
        return str(e)

如果数据量极大到内存缓冲区也放不下,可以改成按批次拆分多个S3文件,比如每处理10000条就上传一个名为test_<日期>_part_1.bson的文件,避免内存溢出。

另外可以调整Lambda配置:把内存调高到1024MB以上(Lambda内存越高,CPU性能同步提升),超时时间拉到最大值15分钟,进一步降低超时概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:47:12