개발

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를 적용했다.