컴퓨터 네트워킹(하향식 접근) - 02 애플리케이션 계층(5/7)

최준석·2022년 12월 18일
0

애플리케이션 계층

2.5 P2P 파일 분배

지금까지 이 장에서 기술한 애플리케이션(웹, 전자메일, DNS 등) 모두는 항상 켜져 있는 인프라스트럭처 서버에 상당히 의존하는 클라이언트-서버 구조를 채택하고 있다. 2.1.1절에서 P2P 구조는 항상 켜져 있는 인프라스트럭처 서버에 최소한으로(혹은 전혀 안함) 의존한다는 것을 기억하라. 대신 간헐적으로 연결되는 호스트 쌍들(피어라고 부름)이 서로 직접 통신한다. 피어는 서비스 제공자가 소유하는 것이 아니라 사용자가 제어하는 데 스크톱과 랩톱, 스마트폰이 소유한다.

이 절에서 커다란 파일을 한 서버에서 다수의 호스트(피어라고 부름)로 분배하는 매우 자연적인 P2P 애플리케이션을 다룰 것이다. 이 파일은 리눅스 운영체제의 새로운 버전, 기존 운영체제 혹은 애플리케이션을 위한 소프트웨어 패치(patch), MP3 음악파일 혹은 MPEG 비디오 파일일 수 있다. 클라이언트-서버 파일 분배에서 서버는 파일 복사본을 각 피어들에게 보내야 한다(서버에게 커다란 부하를 주고 많은 양의 서버 대역폭을 소비한다). P2P 파일 분배에서 각 피어는 수신한 파일의 임의의 부분을 다른 피어들에게 재분배할 수 있어서 서버의 분배 프로세스를 도울 수 있다. 2020년에 가장 인기 있는 P2P 파일 분배 프로토콜은 비트토렌트다. 원래 브람 코헨(Bram Cohen)이 개발했으며, 지금은 비트토렌트 프로토콜을 따르는 다른 많은 독립적인 비트토렌트 클라이언트들이 있다. 이는 HTTP 프로토콜을 따른 많은 수의 웹 브라우저 클라이언트가 있는 것과 같다. 이 절에서는 먼저 파일 분배 관점에서 P2P 구조의 자가 확장성을 사라펴볼 것이다. 그러고 나서 비트토렌트의 가장 중요한 특성과 특징을 살펴봄으로써 좀 더 자세히 기술할 것이다.

P2P 구조의 확장성

클라이언트-서버 구조와 P2P 구조를 비교하기 위해, 그리고 P2P 고유의 자가 확장성을 설명하기 위해 이제 두 가지 구조 유형에 대해 한 파일을 고정된 수의 피어들에게 분배하는 간다나한 양적 모델을 고려한다. 아래 그림에 보이는 것처럼, 서버와 피어들은 접속링크로 인터넷에 연결되어 있다.

서버의 접속 링크 업로드 속도를 us로, i번째 피어의 접속 링크 업로드 속도는 ui로, 그리고 i번째 피어의 접속 링크 다운로드 속도는 di로 나타낸다. 또한 분배되는 파일의 크기는 F(단위는 비트)로, 파일의 복사본을 얻고자 하는 피어들의 수는 N으로 나타낸다. 분배시간(distribution time) 은 모든 N개의 피어들이 파일의 복사본을 얻는 데 걸리는 시간이다. 다음 분배 시간에 대한 분석에서 클라이언트-서버와 P2P 구조 모두의 경우, 인터넷 코어가 풍부한 대역폭을 갖고 있다는 간단한(그리고 일반적으로 정확한) 가정을 하며, 이는 모든 병목 현상은 네트워크 접속 부분에 있음을 의미한다. 또한 클라이언트-서버는 다른 네트워크 애플리케이션에 참여하지 않아서 이들의 모든 업로드와 다운로드 접속 대역폭은 이 파일 분배에 모두 사용된다고 가정한다.

먼저 클라이언트-서버 구조에 대한 분배 시간(Dcs로 표기)을 결정하자. 클라이언트-서버 구조에서는 어떤 피어도 파일을 분배하는 데 도움을 주지 않는다. 우리는 다음과 같은 관찰을 할 수 있다.

  • 서버는 파일 복사본을 N개의 피어 각각에게 전송해야 한다. 따라서 서버는 NF 비트를 전송해야 한다. 서버의 업로드 속도가 us이기 때문에 파일을 분배하는 시간은 적어도 NF/us다.
  • dmin이 가장 낮은 다운로드 속도를 가진 피어의 다운로드 속도를 나타낸다고 하자. 즉, dmin=min{d1, d2, ..., dN}이다. 가장 낮은 다운로드 속도를 가진 피어는 F/dmin초보다 적은 시간에 파일의 모든 F비트를 얻을 수 없다. 따라서 최소 분배 시간은 적어도 F/dmin이다.

이러한 관찰을 결합하면 다음 수식을 얻는다.

Dcsmax{NFus,Fdmin}D_{cs} \geq max\{{NF\over u_s}, {F\over d_{min}}\}

이는 클라이언트-서버 구조에 대한 최소 분배 시간의 하한값을 제공한다. 뒤이 나오는 과제에서는 하한값을 실제로 얻을 수 있도록 서버가 전송을 스케줄링할 수 있게 하는 문제를 제시할 것이다. 그러므로 위에서 제공된 하한값을 실제 분배 시간으로 채택하자. 즉,

Dcs=max{NFus,Fdmin}D_{cs} = max\{{NF\over u_s}, {F\over d_{min}}\} (2.1)

식 (2,1)에서 충분히 큰 N에 대해 클라이언트-서버 분배 시간은 NF/us로 주어진다는 사실을 알 수 있다. 따라서 분배 시간은 피어의 수 N에 따라 선형적으로 증가한다. 예를 들어, 한 주에서 다음 주까지 피어의 수가 천에서 백만으로 천 배 증가한다면, 파일을 모든 피어에게 분배하는 데 필요한 시간도 천 배 증가한다.

이제 P2P 구조에 대해 비슷한 분석을 해보자. 여기서는 각 피어들이 서버가 파일을 분배하는 데 도움을 줄 수 있다. 특히 한 피어가 파일 데이터 일부를 수신할 떄, 피어는 그 데이터를 다른 피어들에게 재분배하는 데 자신의 업로드 용량을 이용할 수 있다. P2P 구조에 대한 분배 시간을 계산하는 방법을 클라이언트-서버 구조의 경우보다 좀 더 복잡하다. 왜냐하면 분배 시간이 각 피어가 다른 피어들에게 파일의 일부를 어떻게 분배하느냐에 달려 있기 때문이다. 그럼에도 불구하고 최소 분배 시간에 대한 간단한 수식을 얻을 수 있다. 이를 위해 먼저 다음을 관찰한다.

  • 분배가 시작되면 서버만이 파일을 갖고 있다. 이 파일이 피어 커뮤니티에 도달할 수 있도록 하기 위해, 서버는 적어도 한 번 접속 링크로 파일의 각 비트를 보내야 한다. 따라서 최소 분배 시간은 적어도 F/us다(서버가 한 번 보낸 비트는 서버가 다시 보낼 필요가 없는데, 이는 클라이언트-서버와 달리 피어들이 그들 사이에 이 비트를 재분배할 수 있기 때문이다).
  • 클라이언트-서버 구조와 마찬가지로 다운로드 속도가 가장 낮은 피어는 F/dmin초보다 적은 시간 안에 파일의 모든 F비트를 얻을 수 없다. 따라서 최소 분배 시간은 적어도 F/dmin이다.
  • 마지막으로, 시스템의 전체 업로드 용량은 전체적으로 서버의 업로드 속도와 각 피어들의 업로드 속도를 더한 것이다. 즉, utotal = (us + ul + ... + uN)이다.

이러한 세 가지 관찰을 결합하면, P2P에 대한 최소 분배 시간(DP2P로 표기)을 다음과 같이 얻을 수 있다.

DP2Pmax{Fus,Fdmin,NFus+i=1Nui}D_{P2P} \geq max\{{F\over u_s}, {F\over d_{min}}, {NF\over u_s + \displaystyle\sum_{i=1}^{\N}{u_i}}\} (2.2)

식 (2.2)는 P2P 구조에 대한 최소 분배 시간에 대한 하한값을 제공한다. 만약 각 피어가 비트를 수신하자마자 그 비트를 재분배할 수 있다고 가정한다면 이 하한값을 실제로 얻는 재분배 방식이 있다. 현실에서는 개별적인 비트보다는 파일의 청크(chunk)가 재분배되는데, 식(2.2)는 실제 최소 분배 시간에 대한 좋은 근삿값을 제공한다. 따라서 식 (2.2)가 제공하는 하한값을 실제 최소 분배 시간으로 채택하자. 즉,

DP2P=max{Fus,Fdmin,NFus+i=1Nui}D_{P2P} = max\{{F\over u_s}, {F\over d_{min}}, {NF\over u_s + \displaystyle\sum_{i=1}^{\N}{u_i}}\} (2.3)

아래 그림은 모든 피어가 같은 업로드 속도 u를 갖고 있다고 가정하고 클라이언트-서버와 P2P 구조에 대한 최소 분배 시간을 비교하고 있다.

위 그림에서 F/u = 1시간, us = 10u, dmin \geq로 설정했다. 따라서 피어는 전체 파일을 한 시간 안에 보낼 수 있고, 서버 전송률은 피어 업로드 속도의 10배이며, 피어 다운로드 속도는 영향을 받지 않을 정도로 충분히 크게 설정된다. 위 그림으로부터, 클라이언트-서버의 경우 피어의 수가 증가함에 따라 분배 시간이 선형적으로 그리고 한계 없이 증가하는 것을 알 수 있다. 그러나 P2P 구조의 경우 최소 분배 시간이 클라이언트-서버 구조의 분배 시간보다 항상 작지는 않다. 또한 임의의 피어 수 N에 대한 한 시간보다 작다. 따라서 P2P 구조를 가진 애플리케이션은 자가 확장성을 갖는다. 이 확장성은 피어가 비트의 소비자이자 재분배자인 것의 직접적인 결과다.

비트토렌트

비트토렌트는 파일 분배를 위한 인기 있는 P2P 프로토콜이다. 비트토렌트 용어로 특정 파일의 분배에 참여하는 모든 피어의 모임을 토렌트라고 부른다. 토렌트에 참여하는 피어들은 서로에게서 같은 크기의 청크(chunk)를 다운로드한다. 일반적인 청크의 크기는 256킬로바이트다. 피어가 처음으로 토렌트에 가입하면, 그 피어에는 청크가 없지만 시간이 지남에 따라 점점 많은 청크를 쌓을 수 있다. 피어가 청크를 다운로드할 때 피어는 또한 청크를 다른 피어들에게 업로드한다. 일단 한 피어가 전체파일을 얻으면, 토렌트는 떠날 수 있거나 혹은 토렌트에 남아서 다른 피어들로 청크를 계속해서 업로드할 수 있다. 또한 어떤 피어는 일부 청크만을 가진 채로 토렌트를 떠날 수 있으며, 나중에 토렌트에 재가입할 수 있다.

이제 비트토렌트가 어떻게 동작하는지 자세히 살펴보자. 비트토렌트는 좀 복잡한 프로토콜이기 때문에 가장 중요한 기법들만을 기술할 것이다. 이렇게 해서 나무를 통해 숲을 보게 될 것이다. 각 토렌트는 트래커라고 부르는 인프라스트럭처 노드를 갖고 있다. 한 피어가 토렌트에 가입할 때 트래커에 자신을 등록하고 주기적으로 자신이 아직 토렌트에 있음을 알린다. 이러한 방식으로 트래커는 토렌트에 참여하는 피어들을 추적한다. 주어진 토렌트는 어느 순간에 수백 혹은 수천의 피어들이 참여하고 있을 수 있다.

아래 그림에보이는 것처럼, 새로운 피어 앨리스가 토렌트에 가입할 때 트래커는 참여하고 있는 피어 집합에서 임의로 피어들의 부분집합(정확히는 50)을 선택하여 이 50개 피어들의 IP 주소를 앨리스에게 보낸다.

이 피어들의 목록을 얻고 나서, 앨리스는 이 목록에 있는 모든 피어와 동시에 TCP 연결을 설정한다. 앨리스가 성공적으로 TCP 연결을 설정한 모든 피어를 '이웃 피어'라고 부르자. 시간이 지남에 따라 이러한 피어들 중 일부는 떠나고 다른 피어들이 앨리스와 TCP 연결을 시도한다. 그래서 피어의 이웃 피어들은 시간에 따라 변동한다.

임의의 주어진 시간에 각 피어는 파일 청크들의 일부를 갖고 있을 것이며, 서로 다른 피어들은 다른 부분을 갖고 있을 것이다. 주기적으로 앨리스는 이웃 피어들 각각에게(TCP 연결을 통해) 그들이 갖고 있는 청크 목록을 요구한다. 만약 앨리스가 L개의 이웃을 갖고 있다면, 그녀는 L개의 청크 목록을 얻을 것이다. 이를 바탕으로 앨리스는 지금 갖고 있지 않은 청크에 대해 (TCP 연결을 통해) 요구한다.

그래서 어느 임의의 주어진 시간에 앨리스는 청크의 일부를 가질 것이고 이웃들이 어느 청크를 갖고 있는지를 알게 될 것이다. 이 정보를 바탕으로 앨리스는 두 가지 중요한 결정을 할 것이다. 첫째, 이웃으로부터 어느 청크를 먼저 요구할 것인가? 둘째 이웃들 중 어느 피어에게 청크를 요청할 것인가? 어느 청크를 요청할 것인지를 결정할 때 앨리스는 가장 드문 것 먼저(rarest first) 라고 하는 기술을 사용한다. 이 아이디어는 그녀가 갖고 있지 않은 청크 중에서, 이웃 가운데 가장 드문 청크(즉, 이웃들 중 가장 적은 반복 복사본을 가진 청크)를 결정하고 그 다음에 가장 드문 청크를 먼저 요구하는 것이다. 이러한 방법으로 가장 드문 청크들은 더 빨리 재분배 될 수 있어서 토렌트에 각 청크의 복사본수가(대략적으로) 동일해진다.

어느 요청에 그녀가 응답할지를 결정하기 위해 비트토렌트는 현명한 교역 알고리즘을 사용한다. 기본 아이디어는 앨리스가 가장 빠른 속도로 그녀에게 데이터를 제공하는 이웃에게 우선순위를 주는 것이다. 특히 그녀의 각 이웃에 대해, 앨리스는 계속해서 그녀가 비트를 수신하는 속도를 측정하고 가장 빠르게 전송하는 4개의 피어를 결정한다. 그리고 나서 그녀는 이 4개의 피어에게 청크를 보냄으로써 보답한다. 그녀는 10초마다 속도를 재계산하고 4개의 피어 집합을 수정한다. 비트토렌트 용어로 이러한 4개의 피어를 활성화 되었다고 한다. 그녀는 또한 30초마다 임의로 피어 하나를 추가로 선택하여 그것에게 청크를 보낸다는 점이 중요하다. 임의로 선택된 피어를 밥이라고하자. 비트토렌트 용어로 밥은 낙관적으로 활성화(optimistically unshoked) 되었다고 한다. 앨리스가 밥에게 데이터를 보내고 있기 때문에 그녀는 밥의 4개의 업로더 중 하나가 될 수 있으며, 이 경우 밥은 앨리스에게 데이터를 보내기 시작한다. 밥이 데이터를 앨리스에게 보내는 속도가 충분히 높으면, 밥은 이제 다시 앨리스의 4개 업로더 중 하나가 될 수 있다. 다시 말해, 30초마다 앨리스는 임의로 새로운 교역 파트너를 선택하고 그 파트너와 교역을 시작한다. 두 피어들이 교역에 만족하면 그들은 서로를 4개의 목록에 넣을 것이고 피어 중 누구 하나가 더 좋은 파트너를 만날 때까지 서로와 교역을 계속할 것이다. 그 효과는 양립할 수 있는 속도로 업로드할 능력을 가진 피어들이 서로를 찾으려는 경향이 있다는 것이다. 또한 임의의 이웃 선택은 새로운 피어들이 청크를 얻게 하여 그들이 교역할 수 있는 무엇인가를 가질 수 있다. 이러한 5개 피어(4개의 '상위' 피어와 하나의 탐색(probing) 피어) 외의 모든 이웃 피어는 '비활성화(choked)', 즉 이들은 앨리스로부터 어떠한 청크도 받지 않는다. 비트토렌트는 여기서는 논의하지 않은 조각(pieces, 미니청크), 파이프라이닝(pipelining), 무작위 우선 선택(random first selection), 마지막 게임 모드(endgame mode), 안티스너빙(anti-snubbing) 등을 포함하는 많은 흥미로운 기법을 갖고있다.

이제 기술한 교역을 위한 보상 방식을 TFT(tit-for-tat)라고 한다. 이 보상 방식은 회피할 수 있다. 그럼에도 불구하고, 비트토렌트 생태계는 매우 성공적이며, 수십만 개의 토렌트에서 동시에 수백만의 피어들이 능동적으로 파일을 공유하고 있다. 비트토렌트가 TFT(혹은 그 변형) 없이 설계되었다면, 대부분의 사용자들은 '무임승차족(free-rider)'이기 때문에 비트토렌트는 지금 존재하지도 않았을 것이다.

우선 P2P에 대한 토론, 즉 DHT(Distributed Hast Table)라는 P2P의 다른 애플리케이션을 간단히 언급함으로써 P2P에 대한 논의를 마무리하려 한다. 분산 해시 테이블은 데이터베이스 레코드가 P2P 시스템 피어에 분산되어 있는 단순한 데이터베이스다. DHT는 다양하게 구현되어 있으며 광범위한 연구 대상이 되었다. 간략한 설명은 비디오노트(VideoNote) 웹사이트에서 제공된다.

profile
Back-End Web Developer

0개의 댓글