본문 바로가기
SA/Migration

[Migration] Rsync를 이용한 대용량 데이터 마이그레이션

by okms1017 2023. 11. 7.
728x90

✍ Posted by Immersive Builder  Seong

 
1. 시작하며
 

고객사 클라우드 전환 사업을 수행하면서 정보시스템별로 최소 GB 단위에서 시작하여 최대 TB 단위에 이르는 대용량 파일 데이터(텍스트, 이미지, 영상, 문서 등 첨부파일)를 이관하기 위해 제가 사용한 Rsync 명령어와 스크립트를 소개하고자 합니다. 
 
한 번은 정리하겠다고 마음만 먹은지 1년.. 프로젝트를 수행한지 어언 1년이 지나버렸습니다. 
시간이 더 지나기 전에 글로 정리하여 기록으로 남기고자 합니다. 
 



2. Rsync 소개 
 
1) Rsync 란?

Rsync는 네트워크를 통해서 로컬 서버와 원격 서버 간 데이터를 동기화하는 프로그램입니다. 
일반적으로 파일 이관, 동기화, 그리고 백업을 하기 위한 용도로 사용합니다. 
 
※ CentOS 7.8 이상에서 기본적으로 Rsync 기능을 제공하고 있습니다. 
    그 외 OS 에서는 별도 유틸리티를 내려받아 설치를 진행하여야 합니다. 

 

2) Rsync 장점 
 

  • 특정 디렉토리와 파일을 지정하여 원격으로 복사 및 동기화할 수 있습니다. 
  • 변경분만 체크하여 동기화를 수행하므로 SCP와 비교하여 속도가 빠릅니다. 
  • 디렉토리와 파일의 권한 및 속성을 그대로 가져올 수 있습니다. 

 

 
3) 명령어 형식 및 옵션

3-1) 명령어 형식
 

# Local 서버의 파일을 Remote 서버로 동기화 
rsync -avzh [로컬 디렉토리경로] [계정]@[원격 서버 IP]:[원격 디렉토리경로]

# Remote 서버의 파일을 Local 서버로 동기화 
rsync -avzh [계정]@[원격 서버 IP]:[원격 디렉토리경로] [로컬 디렉토리경로]

 

3-2) 옵션
 

Option Description
-a   Archive mode, 권한 및 속성 유지 
-v  자세한 정보를 출력 
-z  데이터 압축하여 전송 
-h  사람이 해독가능한 포맷으로 출력 
-e  별도의 명령어 추가 적용 

 
 
3-3) 사용 예시 
 

# 원격서버로 파일 내보내기
rsync -avzh /data root@192.168.10.10:/data

# 로컬서버로 파일 가져오기
rsync -avzh root@192.168.10.10:/data /data

 


 
3. 적용 사례 
 

제가 참여한 프로젝트는 고객사 IDC 환경의 데이터를 클라우드 환경으로 이관하는 케이스였습니다. 
특히 대용량의 데이터를 얼마나 안전하고 신속하게 이관할수 있느냐가 주요 관건이었습니다. 
 
따라서 데이터의 안전성을 위해 고객사 IDC 환경과 클라우드 환경 간에 IPSecVPN을 구축하는 방안과 함께 
신속성을 위해 Data Teleporter 장비를 대여하는 방안을 고려하게 되었습니다. 
(※ Data Teleporter : 대규모 스토리지 용량을 가진 전용 어플라이언스를 대여하여 네트워크 비용 및 보안에 대한 걱정없이 대용량 데이터를 클라우드로 이관하는 네이버클라우드서비스) 
 
그러나 때는 공공기관 마이그레이션 사업이 한창 진행되던 시기로,
Data Teleporter 장비는 4분기까지 예약이 마감되어 있었고 실질적으로 다른 대안이 필요한 상황이었습니다. 
 
되도록이면 추가 비용이 발생하지 않는 방향으로 별도의 솔루션 도입없이 데이터를 이관할 수 있는 방안이 필요했고,
그 때부터 저는 Rsync를 이용한 데이터 이관 병렬 처리 쉘 스크립트를 작성하기 시작합니다. 
 
물론 서버에 접속하여 Rsync 명령어를 수행하는 방식으로 진행해도 가능하긴 하나, 
그러기에는 정보시스템별 서버가 워낙 많았으며 모든 서버에 일일이 접속하여 명령어를 수행한다는 건 굉장히 번거로운 일이었습니다. 
 
따라서 쉘 스크립트를 작성하기로 결정하였고, 쉘 스크립트를 작성함으로써 얻는 효과는 다음과 같았습니다. 

 

  • 반복적이고 일관된 작업을 자동화하여 생산성을 높일 수 있었습니다. 
  • 로그 파일을 남김으로써 쉘 스크립트의 수행 결과를 확인할 수 있었습니다. 
  • 변수 설정을 통해 소스 디렉토리, 타켓 디렉토리, IP 주소 등을 지정할 수 있었고, 언제든지 재사용이 가능했습니다. 
  • 명령어를 순차적으로 실행하므로 디버깅이 용이하며 가독성이 높았습니다. 
  • 프로세스를 병렬로 실행시켜서 부하를 분담하고 처리 속도를 향상시킬 수 있었습니다. 
  • 쉘 스크립트를 백그라운드로 실행시킴으로써 세션을 끊어도 문제가 없었으며, 주기적으로 모니터링이 가능했습니다. 

스크립트를 작성하면서 가장 집중한 부분은 Rsync 프로세스 병렬 실행 및 처리 부분이었습니다. 
예를 들어 6Core 서버에서 단일 프로세스를 실행할 때 하나의 CPU를 사용한다고 하면, 
여섯 개의 프로세스를 실행하여 시스템 자원을 모두 할당함으로써 데이터 전송을 위한 처리 성능을 높였던 것이죠. 
단, 서비스 영향도가 있을 수 있으므로 사전에 고객사와 작업 기간을 협의하여 진행하여야 합니다.
 
그리고 도입한 IPSecVPN 장비의 성능은 최대 1.9Gbps, 사설단말과 연결된 케이블의 대역폭은 1Gbps로
--bwlimit 옵션을 주어 프로세스가 사용하는 네트워크 최대 대역폭을 1Gbps로 제한함으로써 데이터 전송을 최적화하였습니다. 
 
IPSecVPN을 구축하기 이전에는 로컬환경에서 약 일주일 간 스크립트 작성 및 수십 번의 테스트를 진행하였고, 
IPSecVPN을 구축한 후에는 고객사 IDC 환경과 클라우드 환경 간 통신테스트 및 서버 자동로그인 설정, SSH 접속 설정 등을 추가로 진행하였습니다. 
 
서버 자동로그인 설정은 프로세스를 실행할 때 원격 서버의 계정 패스워드를 입력하는 과정을 생략해줍니다. 
SSH 접속 설정은 일반 계정으로 데이터를 전송하는 경우 일부 디렉토리와 파일의 권한 및 속성값이 변경되는 현상이 발생하는데 이런 경우를 피하고자 'PermitRootLogin' 항목을 'no'로 변경하였으며, 해당 설정은 OS 보안 취약점 점검 항목에 해당하므로 이관 작업이 완료되면 반드시 'yes'로 변경해주어야 합니다.
 
총 데이터 이관 용량은 약 7TB 정도였습니다. 
 
병렬 처리 스크립트를 실행하여 작업 수행 시간을 측정한 결과, 
한 시간에 20GB씩 전송하여 데이터를 전부 이관하는데 약 이주일 가량이 소요되었습니다. 
 


 
4. 병렬 처리 쉘 스크립트 
 
1) 대상 디렉토리 하나 

 
로컬 서버의 특정 디렉토리 하나를 지정하여 원격 서버로 이관하기 위한 병렬 처리 스크립트입니다. 
 

#!/bin/bash 
# Usage : Syn & Replication
#
# rsync.sh 
set -ex

# Number of rsync processes
p=6

# Number of rsync arguments
n=1

# Local host address
local="127.0.0.1"

# Remote host address
remote="123.456.789.111"

# Local directory path 
sourDir="/source/"

# Remote directory path to synchronize 
tarDir="/rsync_target_dir/"

# Make a temporary directory for saving a debug file
tmpDir="/tmp/tmpDir/"
mkdir -p $tmpDir 

# List of files or directories in local server 
get-list() {
	rsync -avzP --dry-run $sourDir \
	| sort -n 
}
get-list > $tmpDir/meta.txt

# Excute parallel rsync processes
parallel() {
	ls $sourDir \
	| xargs -I {} -P $p -n $n \
	rsync -avz --progress \
	$sourDir{} \
	$remote:$tarDir
}

parallel

# End

 

 
2) 대상 디렉토리 N개 

 
로컬 서버에서 경로가 서로 다른 디렉토리 여러 개를 지정하여 원격 서버로 이관하기 위한 병렬 처리 스크립트입니다. 
디렉토리의 리스트를 "list.txt" 파일에 저장하여 스크립트의 Input 값으로 넣어주는 부분이 1)과 다른 부분입니다. 추가로 스크립트 실행 및 종료 시간, 로그 파일 생성, 기타 옵션 등을 보완하여 완성물에 훨씬 가깝습니다. 
 

#!/bin/bash 
# Usage : Syn & Replication
#
# rsync.sh 
StartDate=$(date "+%Y-%m-%d %H:%M:%S")
StartTime=$(date +%s)
#echo $StartDate
#echo $StartTime

set -ex

# Number of rsync processes
p=6

# Number of rsync arguments
n=1

# Local host address
local="127.0.0.1"

# Remote host address
remote="123.456.789.111"

# Read text file containing list of local directory path
# We absolutely need to a "list.txt" file in current path 
IFS_back=$IFS
IFS=$'\n'

currentPath=$(pwd)
list=$(cat $currentPath/list.txt)
list=($list)

echo ${list[0]}
echo ${list[1]}
echo ${list[2]}

# Make a temporary directory for saving a debug file
tmpDir="/tmp/tmpDir/"
mkdir -p $tmpDir 

# List of files or directories in local server 
for sourDir in ${list[@]}
do 
	rsync -avzP --dry-run $sourDir \
	| sort -n \
	>> $tmpDir/meta.txt
done

# Excute parallel rsync processes
parallel() {
	for sourDir in ${list[@]}
	do
		ls $sourDir \
		| xargs -I {} -P $p -n $n \
		rsync -avz -e "ssh -p 22" --progress --bwlimit=1000000 \
		$sourDir{} \
		$remote:$sourDir
	done
}

parallel 

EndDate=$(date "+%Y-%m-%d %H:%M:%S")
EndTime=$(date +%s)

# Output working time to text file
echo "Start Time: $StartDate" >> $tmpDir/mig_time_result.txt
echo "End Time: $EndDate" >> $tmpDir/mig_time_result.txt
echo "Elapsed Time: $(($EndTime-$StartTime))" >> $tmpDir/mig_time_result.txt

# End

 


 
5. 마치며 
 

개인적으로 무척 공들여 작성한 이관 스크립트입니다. 
 
아쉬운 점은 Ansible을 이용하여 스크립트 파일을 자동으로 배포하고 실행하였으면 어땠을까라는 생각이 듭니다.  
 
이 포스팅을 보시는 분들 중에 분명 마이그레이션 업무를 수행하시는 분들도 있을 것이고,
어쩌면 저와 같은 고민을 하면서 고군분투하고 있을 분들에게 조금이나마 도움이 되었으면 좋겠습니다.  
 
저의 경험을 이렇게라도 작은 글로 나눌 수 있어서 뿌듯합니다. 
 
다음 번에 더 좋은 글로 찾아뵙겠습니다. 
감사합니다. 
 
 


[출처] 나의 경험 

728x90