2장 업로드 경로: 청크 분할, 동시성 및 이어 올리기(핵심)

업로드 측의 목표는 변동이 심한 네트워크에서도 “대역폭을 최대한 꽉 채우는” 데 가능한 한 가까워지면서, 실패로 인한 비용은 최소한으로 줄이는 것입니다(실패한 청크만 다시 전송). 이 두 가지 목표가 업로드가 더 빠르게 느껴지는 이유의 대부분을 설명해 줍니다.

2.1 청크 분할

  • 클라이언트는 파일을 여러 청크로 반드시 분할해야 하며, 청크는 업로드와 재시도의 최소 단위입니다.
  • 동시성 스케줄링과 상태 표현을 단순하게 하려면 청크는 고정 크기(또는 파일별 크기 정책)를 사용하는 것이 좋습니다.
  • 즉각적인 이점: 어떤 실패든 파일 전체가 아니라 청크 하나에만 영향을 줍니다.

2.2 병렬 업로드

동시성의 목적은 “스레드를 더 많이 쓰는 것”이 아니라, 실제 네트워크에서 단일 연결이 갖는 세 가지 현실적인 한계를 피하는 것입니다.

  • 슬로 스타트와 윈도 증가: 단일 연결은 속도가 천천히 올라가며, 특히 리전 간 RTT가 길 때 더 그렇습니다.
  • 링크 지터: 한 연결에서 생기는 지터가 전체 속도를 떨어뜨릴 수 있으며, 동시성은 그 영향을 완만하게 만듭니다.
  • 플로우별 속도 제한: 일부 네트워크는 단일 플로우의 속도를 제한하며, 여러 플로우를 사용하면 대역폭 상한에 더 가까워질 수 있습니다(규정 준수 범위 내에서).
  • 클라이언트는 제한된 동시성(예: 4–12)을 사용하는 것이 좋으며, 메모리 급증을 막기 위해 사양이 낮은 기기에서는 동시성을 낮추는 것이 좋습니다.
  • 클라이언트는 동시성을 적응적으로 조절할 수 있습니다. 처리량이 올라가면 늘리고, 오류율이 올라가면 줄입니다.

2.3 멱등성 및 재시도

  • 같은 청크를 반복해서 업로드해도 반드시 멱등적이어야 합니다. 중복 제출이 이미 완료된 상태를 손상시켜서는 안 됩니다.
  • 서버는 (transferId, fileId, chunkIndex) 또는 이에 상응하는 제약 조건으로 고유성을 보장하는 것이 좋습니다.
  • 클라이언트는 지수 백오프 재시도를 반드시 구현해야 하며, 실패 시에는 실패한 청크만 재시도하는 것이 좋습니다.

2.4 이어 올리기(재개 가능한 업로드)

  • 서버는 “어떤 청크가 이미 업로드되었는지”에 답할 수 있어야 하며, 이를 통해 클라이언트가 완료된 청크를 건너뛸 수 있습니다.
  • 업로드 완료 집합은 비트맵 또는 범위 집합으로 표현하여, 상태 크기가 청크 수에 비례해 늘어나지 않도록 하는 것이 좋습니다.
  • 속도 측면의 이점: 네트워크 중단, 브라우저 충돌, 네트워크 전환이 있어도 0%부터 다시 시작하지 않고 이어서 업로드합니다.

2.5 “업로드하면서 공유”(선택 사항)

  • 시스템은 전달 워크플로를 앞당기기 위해, 업로드가 아직 진행 중인 동안에도 사용 가능한 전송 식별자와 공유 링크를 생성할 수 있습니다.
  • 업로드가 끝나기 전에 공유를 허용한다면, 수신자에게 무엇이 보이는지를 반드시 명확히 해야 합니다. 즉, 불완전한 콘텐츠는 아직 다운로드할 수 없거나 진행 상황만 표시됩니다.