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

如何在GitHub Actions中加速6对S3桶数据复制?矩阵策略可行吗?

S3桶数据复制任务优化:Matrix策略适用性与Boto3提速问题

问题描述

我有一个GitHub Actions任务,负责将6个源S3桶的数据复制到另外6个目标S3桶。由于需要先清空目标桶,整个流程耗时约30分钟。当前任务代码如下:

restore-s3:
  runs-on: ubuntu-latest
  timeout-minutes: 60
  steps:
    - name: Assume Role
      uses: youyo/awscredswrap@v1.0.4
      with:
        role_arn: ${{ secrets.AWS_EKS_IAM_ROLE }}
        duration_seconds: 3600
        role_session_name: EKS
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_DEFAULT_REGION: ${{ env.AWS_ECR_REGION }}
    - name: restore S3 data
      id: s3_dir
      run: |
        release_version=${{ inputs.data_version }}
        echo $release_version
        aws s3 rm --recursive s3://test.qa.avatar.file-2027145436775700000001/ &
        aws s3 rm --recursive s3://test.qa.avatar.origin-2027145436939200000007/ &
        aws s3 rm --recursive s3://test.qa.documents.original-2027145436794600000003/ &
        aws s3 rm --recursive s3://test.qa.documents.sdf-2027145436895500000005/ &
        aws s3 rm --recursive s3://test.qa.templates.original-2027145436908800000006/ &
        aws s3 rm --recursive s3://test.qa.templates.sdf-2027145436788200000002/ &
        wait
        aws s3 cp --recursive "s3://test.qa.avatar.file/$release_version/" s3://test.qa.avatar.file-2027145436775700000001/ &
        aws s3 cp --recursive "s3://test.qa.avatar.origin/$release_version/" s3://test.qa.avatar.origin-2027145436939200000007/ &
        aws s3 cp --recursive "s3://test.qa.documents.original/$release_version/" s3://test.qa.documents.original-2027145436794600000003/ &
        aws s3 cp --recursive "s3://test.qa.documents.sdf/$release_version/" s3://test.qa.documents.sdf-2027145436895500000005/ &
        aws s3 cp --recursive "s3://test.qa.templates.original/$release_version/" s3://test.qa.templates.original-2027145436908800000006/ &
        aws s3 cp --recursive "s3://test.qa.templates.sdf/$release_version/" s3://test.qa.templates.sdf-2027145436788200000002/ &
        wait
        echo "Restore completed"

我想知道GitHub Actions的matrix策略是否适用于这个场景?另外我曾尝试编写Python Boto3脚本,但提速效果并不明显。

解答

1. GitHub Actions Matrix策略完全适用,且能显著提升效率

当前脚本是在单个runner实例内通过后台进程(& + wait)并行执行操作,但单个runner的CPU、网络带宽存在上限,无法充分利用多实例资源。Matrix策略可以将每一对桶的清空+复制操作分配到独立的runner实例中执行,突破单实例的资源瓶颈。

实现示例

jobs:
  restore-s3:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    strategy:
      matrix:
        bucket-pair:
          - source: "test.qa.avatar.file"
            target: "test.qa.avatar.file-2027145436775700000001"
          - source: "test.qa.avatar.origin"
            target: "test.qa.avatar.origin-2027145436939200000007"
          - source: "test.qa.documents.original"
            target: "test.qa.documents.original-2027145436794600000003"
          - source: "test.qa.documents.sdf"
            target: "test.qa.documents.sdf-2027145436895500000005"
          - source: "test.qa.templates.original"
            target: "test.qa.templates.original-2027145436908800000006"
          - source: "test.qa.templates.sdf"
            target: "test.qa.templates.sdf-2027145436788200000002"
    steps:
      - name: Assume Role
        uses: youyo/awscredswrap@v1.0.4
        with:
          role_arn: ${{ secrets.AWS_EKS_IAM_ROLE }}
          duration_seconds: 3600
          role_session_name: EKS
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: ${{ env.AWS_ECR_REGION }}
      - name: Restore S3 data for ${{ matrix.bucket-pair.target }}
        run: |
          release_version=${{ inputs.data_version }}
          echo "Processing: ${{ matrix.bucket-pair.source }} -> ${{ matrix.bucket-pair.target }}"
          # 清空目标桶
          aws s3 rm --recursive s3://${{ matrix.bucket-pair.target }}/
          # 复制指定版本数据
          aws s3 cp --recursive "s3://${{ matrix.bucket-pair.source }}/$release_version/" s3://${{ matrix.bucket-pair.target }}/
          echo "Completed restore for ${{ matrix.bucket-pair.target }}"

优势说明

  • 每个job独立运行,GitHub会同时启动最多6个runner(匹配你的6对桶),并行执行清空和复制操作,总耗时会接近单个桶操作的时间(而非6倍时间)。
  • 每个runner只处理一对桶,避免单实例内多进程竞争资源的问题,稳定性和效率都能提升。

2. Boto3脚本提速不明显的原因及优化方向

常见原因

  • 未配置高效并行策略:默认Boto3的传输配置并发数较低,若用单线程执行,效率和aws cli差距大。
  • 未启用分段传输:对于大文件,未开启Multipart Upload会导致传输速度受限。
  • 单实例带宽瓶颈:即使Boto3实现了并行,单个runner的网络带宽依然是上限,和原cli脚本的单实例并行效果差异不大。

优化建议

  • 调整Boto3传输配置:通过TransferConfig提升并发数和分段传输效率,示例代码:
    import boto3
    from boto3.s3.transfer import TransferConfig
    
    s3 = boto3.client('s3')
    config = TransferConfig(
        multipart_threshold=1024*25,  # 25MB以上文件启用分段
        max_concurrency=15,           # 并发请求数
        multipart_chunksize=1024*25,  # 分段大小
        use_threads=True              # 启用线程池
    )
    
    # 清空目标桶
    paginator = s3.get_paginator('list_objects_v2')
    for page in paginator.paginate(Bucket=target_bucket):
        if 'Contents' in page:
            s3.delete_objects(
                Bucket=target_bucket,
                Delete={'Objects': [{'Key': obj['Key']} for obj in page['Contents']]}
            )
    
    # 复制数据
    source_path = f"{source_bucket}/{release_version}/"
    paginator = s3.get_paginator('list_objects_v2')
    for page in paginator.paginate(Bucket=source_bucket, Prefix=f"{release_version}/"):
        if 'Contents' in page:
            for obj in page['Contents']:
                source_key = obj['Key']
                target_key = source_key.replace(f"{release_version}/", "")
                s3.copy(
                    {'Bucket': source_bucket, 'Key': source_key},
                    target_bucket,
                    target_key,
                    Config=config
                )
    
  • 结合Matrix策略:将优化后的Boto3脚本放到Matrix的每个job中,让每个runner处理一对桶,利用多实例带宽进一步提速。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:31:22