개발
Chunk를 사용하여 대용량 파일 전송하기
31514
2025. 1. 17. 17:33
회사에 A 서버의 내부망에서 돌아가는 Postgres 서버가 있다.
우리에게 필요한 데이터는 매일 A 서번에 적재된다.
하지만 웹 개발은 B 서버의 Postgres를 통해 진행된다.
따라서 웹 개발팀에서 최신 데이터를 사용하기 위해서 매일 A 서버로부터 데이터를 B 서버로 옮겨야한다.
이를 해결하기 위해 Airflow와 Chunk를 사용하여 매일 새벽 3시에 두 서버의 Postgres를 동기화했다.
Chunk
chunk가 무엇일까?
chunk는 데이터를 일정한 크기로 나눈 조각을 말한다.
한 번에 전체 파일을 메모리에 올리지 않고, 작은 단위로 읽고 쓰거나 네트워크를 통해 전송하여 메모리 사용량을 줄인다.
postgres의 특정 데이터베이스를 DUMP 하면 그 파일의 용량이 만만치 않다.
이를 효율적으로 옮기기 위해서 여러 방법을 고민하다가, 제한적인 환경에서 chunk를 활용했다.
Chunk의 장점
- 메모리 효율성
- 대용량 파일을 처리할 때 메모리 부족 문제를 방지한다.
- 전송 안정성
- 전송 도중 오류가 발생해도 부분적으로 데이터를 재전송하거나 복구하기 쉽다.
- 네트워크 효율성
- 데이터를 청크 단위로 나누어 전송하면 네트워크 부하를 줄일 수 있다.
Chunk 구현 예시
import paramiko
CHUNK_SIZE = 1024 * 1024 # 1MB 단위로 처리
try:
# Step 1: 소스 서버 연결 및 파일 열기
source_ssh = paramiko.SSHClient()
source_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
source_ssh.connect(hostname=source_host, port=source_port, username=source_username, password=source_password)
source_sftp = source_ssh.open_sftp()
source_file = source_sftp.open(source_path, "rb") # 읽기 모드로 파일 열기
# Step 2: 대상 서버 연결 및 파일 열기
destination_ssh = paramiko.SSHClient()
destination_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
destination_ssh.connect(hostname=destination_host, port=destination_port, username=destination_username, password=destination_password)
destination_sftp = destination_ssh.open_sftp()
destination_file = destination_sftp.open(destination_path, "wb") # 쓰기 모드로 파일 열기
# Step 3: 청크 단위로 파일 읽고 쓰기
while True:
data = source_file.read(CHUNK_SIZE) # 청크 크기만큼 읽기
if not data: # 데이터가 없으면 종료
print("No DATA")
break
destination_file.write(data) # 대상 서버에 데이터 쓰기
# Step 4: 파일 및 연결 닫기
source_file.close()
source_sftp.close()
source_ssh.close()
destination_file.close()
destination_sftp.close()
destination_ssh.close()
print(f"Successfully transferred large file from {source_host}:{source_path} to {destination_host}:{destination_path}")
except Exception as e:
print(f"Error during file transfer: {e}")
파이썬의 경우 SFTP를 지원하는 방법이 여러가지 있지만, 서버의 키 없이 호스트 이름과 비밀번호로 통신할 수 있는 `paramiko`를 선택하여 chunk를 적용했다.