P2P 파일 분배의 원리와 비트토렌트 프로토콜 이해하기

2025년 8월 15일 · 읽는 시간 18

thumbnail

지금까지 우리가 일상적으로 사용하는 대부분의 애플리케이션(웹, 이메일, DNS 등)은 항상 켜져 있는 인프라스트럭처 서버에 크게 의존하는 클라이언트-서버 구조를 채택하고 있습니다. 하지만 P2P(Peer-to-Peer) 구조는 이와는 전혀 다른 접근 방식을 사용합니다. 이번 포스트에서는 P2P 파일 분배의 원리를 수학적으로 분석하고, 가장 성공적인 P2P 프로토콜인 비트토렌트의 동작 방식을 상세히 알아보겠습니다.

P2P 구조의 기본 개념

P2P 구조에서는 항상 켜져 있는 인프라스트럭처 서버에 최소한으로 의존하거나 전혀 의존하지 않습니다. 대신 애플리케이션은 피어(peer) 라고 부르는 간헐적으로 연결된 호스트 쌍이 서로 직접 통신하게 합니다.

피어는 서비스 제공자가 소유하는 것이 아니라 사용자들이 제어하는 데스크톱, 랩톱, 스마트폰 등입니다. 대부분의 피어들은 가정, 대학, 사무실에 위치합니다. 특정 서버를 통하지 않고 피어가 직접 통신하므로 이 구조를 피어 투 피어(Peer-to-Peer, P2P)라고 부릅니다.

P2P 구조의 핵심 특성

P2P 구조의 가장 주목할 만한 특성은 자가 확장성(self-scalability) 입니다. P2P 파일 공유 애플리케이션에서 각 피어들이 파일을 요구함으로써 작업 부하를 만들어내지만, 동시에 각 피어들은 파일을 다른 피어들에게 분배함으로써 시스템에 서비스 능력을 추가합니다.

이러한 특성은 P2P 구조를 매우 비용 효율적으로 만듭니다. 일반적으로 상당한 서버 인프라스트럭처와 서버 대역폭을 요구하지 않기 때문입니다(데이터 센터의 클라이언트-서버 설계와는 대조적으로). 하지만 P2P 애플리케이션들은 고도의 분산 구조 특성으로 인해 보안, 성능, 신뢰성 면에서 도전 과제를 안고 있습니다.

P2P vs 클라이언트-서버: 파일 분배 성능 비교

이제 클라이언트-서버 구조와 P2P 구조에서 한 파일을 고정된 수의 피어들에게 분배하는 시간을 수학적으로 분석해보겠습니다. 이를 통해 P2P 고유의 자가 확장성을 명확히 이해할 수 있습니다.

p2p file distribution example

모델 설정

다음과 같은 표기법을 사용합니다.

  • usu_s: 서버의 업로드 속도
  • uiu_i: ii번째 피어의 업로드 속도
  • did_i: ii번째 피어의 다운로드 속도
  • FF: 분배되는 파일의 크기 (비트 단위)
  • NN: 파일의 복사본을 얻고자 하는 피어들의 수
  • 분배 시간(distribution time): 모든 NN개의 피어들이 파일의 복사본을 얻는 데 걸리는 시간

분석을 위한 가정

  • 인터넷 코어는 충분한 대역폭을 갖고 있음 (모든 병목 현상은 네트워크 접속 부분에서 발생)
  • 클라이언트와 서버는 다른 네트워크 애플리케이션에 참여하지 않음

클라이언트-서버 구조의 분배 시간 분석

클라이언트-서버 구조에서는 어떤 피어도 파일을 분배하는 데 도움을 주지 않습니다. 분배 시간 DcsD_{cs}를 결정하기 위해 다음을 관찰할 수 있습니다.

  1. 서버 관점: 서버는 파일 복사본을 NN개의 피어 각각에게 전송해야 합니다. 따라서 서버는 NFNF 비트를 전송해야 합니다. 서버의 업로드 속도가 usu_s이므로, 파일을 분배하는 시간은 적어도 NF/usNF/u_s입니다.

  2. 피어 관점: dmin=min{d1,d2,...,dN}d_{min} = \min\{d_1, d_2, ..., d_N\}이라고 하면, 가장 낮은 다운로드 속도를 가진 피어는 F/dminF/d_{min}초보다 적은 시간에 파일의 모든 FF 비트를 얻을 수 없습니다.

따라서 클라이언트-서버 구조의 최소 분배 시간은 다음과 같이 채택할 수 있습니다.

Dcs=max{NFus,Fdmin}D_{cs} = \max \left\{ \frac{NF}{u_s}, \frac{F}{d_{min}} \right\}

이 식에서 중요한 점은 충분히 큰 NN에 대해 분배 시간이 NF/usNF/u_s로 주어진다는 것입니다. 즉, 분배 시간이 피어의 수 NN에 따라 선형적으로 증가합니다. 예를 들어, 피어의 수가 1,000에서 1,000,000으로 천 배 증가하면, 파일을 모든 피어에게 분배하는 데 필요한 시간도 천 배 증가합니다.

P2P 구조의 분배 시간 분석

P2P 구조에서는 각 피어들이 서버가 파일을 분배하는 데 도움을 줄 수 있습니다. 한 피어가 파일 데이터 일부를 수신하면, 그 데이터를 다른 피어들에게 재분배하는 데 자신의 업로드 용량을 사용할 수 있습니다.

P2P 구조의 최소 분배 시간 DP2PD_{P2P}를 구하기 위해 다음을 관찰합니다.

  1. 서버의 초기 전송: 분배가 시작되면 서버만이 파일을 갖고 있습니다. 파일이 피어 커뮤니티에 도달하려면, 서버는 적어도 한 번은 파일의 각 비트를 보내야 합니다. 따라서 최소 분배 시간은 적어도 F/usF/u_s입니다.

  2. 최저 다운로드 속도 제약: 클라이언트-서버 구조와 마찬가지로, 다운로드 속도가 가장 낮은 피어는 F/dminF/d_{min}초보다 적은 시간 안에 파일을 받을 수 없습니다.

  3. 전체 업로드 용량 제약: 시스템의 전체 업로드 용량은 서버와 모든 피어들의 업로드 속도 합입니다. utotal=us+u1++uNu_{total} = u_s + u_1 + \cdots + u_N

    시스템은 NN개 피어들 각각에게 FF 비트를 전달해야 하므로, 최소 분배 시간은 적어도, 다음 식과 같습니다. NFus+i=1Nui\frac{NF}{u_s + \sum_{i=1}^{N} u_i}

이러한 관찰을 결합하면, P2P 구조의 최소 분배 시간은 이렇게 표현할 수 있습니다. (단, 각 피어가 비트를 수신하자마자 그 비트를 재분배할 수 있다고 가정했을 때)

DP2P=max{Fus,Fdmin,NFus+i=1Nui}D_{P2P} = \max \left\{ \frac{F}{u_s}, \frac{F}{d_{min}}, \frac{NF}{u_s + \sum_{i=1}^{N} u_i} \right\}

P2P의 자가 확장성 증명

모든 피어가 같은 업로드 속도 uu를 갖는다고 가정하면,

DP2P=max{Fus,Fdmin,NFus+Nu}D_{P2P} = \max \left\{ \frac{F}{u_s}, \frac{F}{d_{min}}, \frac{NF}{u_s + Nu} \right\}

NN이 충분히 클 때, 세 번째 항이 지배적이 되며

DP2PNFus+Nu=Fus/N+uD_{P2P} \approx \frac{NF}{u_s + Nu} = \frac{F}{u_s/N + u}

NN이 증가하면 us/Nu_s/N은 0에 가까워지므로

limNDP2P=Fu\lim_{N \to \infty} D_{P2P} = \frac{F}{u}

p2p and client server distribution graph

놀랍게도 P2P 구조에서는 피어 수가 아무리 증가해도 분배 시간이 일정한 값으로 수렴합니다. 이것이 바로 P2P 구조의 자가 확장성입니다. 피어가 비트의 소비자이자 재분배자 역할을 동시에 수행하기 때문입니다.

비트토렌트: 가장 성공적인 P2P 프로토콜

비트토렌트는 2001년 브람 코헨(Bram Cohen)이 개발한 파일 분배를 위한 P2P 프로토콜입니다. 2024년 현재까지도 가장 널리 사용되는 P2P 파일 공유 프로토콜로, 수십만 개의 토렌트에서 동시에 수백만의 피어들이 활발히 파일을 공유하고 있습니다.

비트토렌트의 기본 용어

비트토렌트를 이해하려면 먼저 몇 가지 용어를 알아야 합니다. 토렌트(torrent) 는 특정 파일의 분배에 참여하는 모든 피어의 모임을 말합니다. 파일은 보통 256KB 크기의 청크(chunk) 라는 작은 조각으로 나뉘어 전송되며, 트래커(tracker) 라는 인프라스트럭처 노드가 토렌트에 참여하는 피어들을 추적합니다. 파일 전체를 갖고 있는 피어를 시더(seeder) 라고 부르고, 파일의 일부만 갖고 있는 피어를 리처(leecher) 라고 부릅니다.

비트토렌트의 동작 과정

file distribution bittorrent

1. 토렌트 가입과 피어 발견

새로운 피어가 토렌트에 가입할 때는 흥미로운 과정을 거칩니다. 예를 들어 앨리스라는 피어가 토렌트에 참여한다고 가정해봅시다. 먼저 앨리스는 트래커에 자신을 등록합니다. 그러면 트래커는 현재 참여 중인 피어들 중에서 임의로 50개를 선택해 그들의 IP 주소를 앨리스에게 전송합니다. 앨리스는 받은 IP 주소들을 이용해 피어들과 TCP 연결을 시도하고, 성공적으로 연결된 피어들이 앨리스의 "이웃 피어"가 됩니다. 시간이 지나면서 일부 피어는 떠나고 새로운 피어가 추가되어 이웃 피어 구성이 동적으로 변화합니다.

2. 청크 선택 전략: Rarest First

비트토렌트의 핵심 아이디어 중 하나는 청크 선택 전략입니다. 앨리스는 주기적으로 이웃 피어들에게 그들이 보유한 청크 목록을 요청합니다. 어떤 청크를 먼저 요청할지 결정할 때 "가장 드문 것 먼저(rarest first)" 전략을 사용하는데, 이는 자신이 갖고 있지 않은 청크 중에서 이웃들 사이에 가장 적게 복사된 청크를 파악하고 그 청크를 먼저 요청하는 방식입니다.

이 전략이 똑똑한 이유는 희귀한 청크가 빠르게 재분배되면서 토렌트 내 각 청크의 복사본 수가 균등해지고, 결과적으로 파일의 가용성이 향상되기 때문입니다. 만약 모든 피어가 가장 흔한 청크부터 다운로드한다면, 희귀한 청크를 가진 시더가 떠났을 때 파일 전체를 구할 수 없게 되는 상황이 발생할 수 있습니다.

3. 피어 선택 전략: Tit-for-Tat

비트토렌트가 성공한 또 다른 이유는 공정한 교환을 보장하는 TFT(Tit-for-Tat) 알고리즘입니다. 기본 원칙은 간단합니다. 가장 빠른 속도로 데이터를 제공하는 피어에게 우선순위를 부여하는 것입니다.

구체적으로 어떻게 작동하냐면, 각 피어는 10초마다 이웃들로부터 받는 다운로드 속도를 측정해서 가장 빠른 4개의 피어를 선택합니다. 이들을 unchoked 상태로 만들어 청크를 업로드합니다. 재미있는 부분은 30초마다 실행되는 낙관적 언초킹(optimistic unchoking) 입니다. 임의로 1개의 피어를 추가로 선택해서 청크를 보내는데, 이를 통해 새운 피어가 네트워크에 참여할 기회를 제공하고 더 나은 교역 파트너를 발견할 가능성을 열어둡니다. 나머지 피어들은 choked 상태가 되어 업로드를 받지 못합니다.

이 메커니즘이 절묘한 이유는 비슷한 업로드 능력을 가진 피어들끼리 자연스럽게 서로를 찾아 교역하게 되고, 무임승차(free-riding)를 효과적으로 방지하면서도 새로운 피어에게 기회를 주는 균형을 맞추기 때문입니다.

비트토렌트의 추가 최적화 기법

비트토렌트는 기본 메커니즘 외에도 성능을 더욱 향상시키기 위한 여러 기법들을 사용합니다. 파이프라이닝(pipelining) 을 통해 여러 청크 요청을 동시에 처리하여 대기 시간을 줄이고, 처음 몇 개 청크는 무작위 우선 선택(random first selection) 방식으로 빠르게 다운로드를 시작할 수 있게 합니다. 다운로드가 거의 끝나갈 때는 엔드게임 모드(endgame mode) 를 활성화하여 마지막 몇 개 청크를 여러 피어에게 동시에 요청함으로써 완료 시간을 단축시킵니다. 또한 안티스너빙(anti-snubbing) 메커니즘으로 오랫동안 응답이 없는 피어를 자동으로 다른 피어로 교체합니다.

마치며

computer networking book

오랜만에 휴일을 맞아 P2P를 정리하고 공부하면서 느낀 점은, 현재 P2P 기술은 우리 일상 곳곳에 스며들어 있는 것 같다는 점입니다. OS 업데이트나 대형 게임 패치는 물론이고, 블록체인과 암호화폐의 핵심 인프라가 되었습니다. (제가 몸담고 있는?) 라이브 스트리밍 서비스에서도 CDN 비용은 엄청난 부담인데, 실제로 많은 스트리밍 플랫폼들이 P2P CDN을 도입해 네트워크 대역폭을 효율적으로 활용하고 있습니다. 시청자가 많을수록 오히려 스트리밍 품질이 좋아지는 P2P의 특성은 대규모 라이브 이벤트 중계에 특히 유용합니다.

이렇게 중앙 집중식 시스템의 한계가 명확해지는 시대에, P2P가 제시하는 분산형 패러다임은 더욱 중요해질 것 같습니다. 엣지 컴퓨팅, WEB 3.0, 그리고 미래의 인터넷 인프라에서 P2P 기술이 어떤 역할을 하게 될지 기대가 됩니다 :)

참고 자료

About Me
@onseok
배움을 배포하기