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元数据,无法获取实际文件
寻求建议
- 为何Git同步耗时远超预期?
- 如何确保高效下载修改后的LFS文件(含实际数据而非仅元数据)?
- 处理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
相关产品推荐
相关产品推荐

