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

Git LFS同步性能远逊于SVN+Rsync的问题排查与优化请求

Git LFS 大规模数据同步问题排查与优化建议

背景与架构

我们部署了一台自托管Git LFS服务器,采用AWS S3桶存储约700GB数据,另有20台只读EC2客户端通过脚本拉取数据。

当前架构

  • 开发团队提交/推送代码 → 自托管Git LFS服务器(AWS)→ 数据存储于S3 → 20台EC2客户端实例运行脚本拉取数据

原SVN架构

  • 开发团队提交/推送代码 → 自托管SVN服务器(AWS)→ 20台EC2客户端实例运行脚本通过rsync同步数据
    弃用SVN的原因是rsync同步700GB数据时会检查所有文件,导致延迟过高。切换至Git LFS旨在利用其仅拉取版本差异的特性缩短同步时间。

遇到的问题

  • Git LFS同步耗时超4小时,远慢于原rsync的5-10分钟
  • 原脚本未按预期仅下载修改后的文件
  • 修改后的脚本仅拉取LFS元数据,无法获取实际文件

寻求建议

  1. 为何Git同步耗时远超预期?
  2. 如何确保高效下载修改后的LFS文件(含实际数据而非仅元数据)?
  3. 处理700GB大数据集及多只读客户端有哪些更优策略?

使用的脚本

rsynchMotionRessources.sh(运行耗时超4小时)

# Main script setup
MOTION_DIR=/Users/ec2-user/Motion_Design

useGit() {
    echo "Using Git"
    init() {
        git config --global pull.rebase true
        git config --global credential.helper store
    }

    init_submodules() {
        echo "Started pulling modules at $(date +'%H:%M:%S')"
        git submodule update --init --recursive || { echo "ERROR: Git submodule update failed"; exit 1; }
    }

    clone() {
        echo "Started cloning at $(date +'%H:%M:%S')"
        rm -rf "$MOTION_DIR"
        git clone --depth=1 "https://oauth2:$MOTION_TOKEN@$GITLAB_ENDPOINT/Motion/$REPO.git" "$MOTION_DIR" --progress || { echo "ERROR: Cloning failed"; exit 1; }
        cd "$MOTION_DIR" || exit 1
        init_submodules
    }

    pull() {
        rm -rf "$MOTION_DIR/.git/modules/Ressources/index.lock"
        rm -rf "$MOTION_DIR/.git/index.lock"
        
        cd "$MOTION_DIR" || exit
        git reset --hard
        git checkout main
        git pull -X theirs origin main
    }

    if [ ! -d "$MOTION_DIR/.git" ]; then
        clone
    else
        cd "$MOTION_DIR" || exit 1
        pull
    fi
}

useGit

revised_rsynchMotionRessources.sh(仅拉取LFS元数据,不包含实际文件)

MOTION_DIR=/Users/ec2-user/Motion_Design

useGit() {
    echo "Using Git"
    init() {
        git config --global pull.rebase true
        git config --global credential.helper store
    }

    init_submodules() {
        echo "Started pulling modules at $(date +'%H:%M:%S')"
        git submodule update --init --recursive || { echo "Error: Git submodule update failed"; exit 1; }
    }

    clone() {
        echo "Started cloning at $(date +'%H:%M:%S')"
        rm -rf "$MOTION_DIR"
        git clone --depth=1 "https://oauth2:$MOTION_TOKEN@$GITLAB_ENDPOINT/Motion/$REPO.git" "$MOTION_DIR" --progress || { echo "Error: Cloning failed"; exit 1; }
        cd "$MOTION_DIR" || exit 1
        init_submodules
    }

    pull() {
        echo "Started fetching at $(date +'%H:%M:%S')"
        export GIT_LFS_SKIP_SMUDGE=1
        git fetch --depth=1 origin main --progress || { echo "Error: Git fetch failed"; exit 1; }
        git reset --hard origin/main || { echo "Error: Git reset failed"; exit 1; }

        export CHANGED_FILES=$(git diff --name-status --diff-filter=AMRDCT origin/main HEAD)
        echo "Changed files: $CHANGED_FILES"
        IFS=$'\n' read -rd '' -a FILE_ARRAY <<< "$CHANGED_FILES"

        for file in "${FILE_ARRAY[@]}"; do
            file_status=$(echo "$file" | awk '{print $1}')
            old_file=$(echo "$file" | awk '{print $2}')
            new_file=$(echo "$file" | awk '{print $3}')

            case $file_status in
                R) git checkout origin/main -- "$new_file" || { echo "Error checking out renamed file $new_file"; exit 1; } ;; 
                D) [ -f "$old_file" ] && git rm "$old_file" ;; 
                A|M|C|T) git checkout origin/main -- "$old_file" ;; 
            esac
        done
    }

    if [ ! -d "$MOTION_DIR/.git" ]; then
        clone
    else
        cd "$MOTION_DIR" || exit 1
        pull
    fi
}

useGit

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:44:57