
P2P 시스템의 기술들은 cloud computing 의 많은 분야에서 활용됩니다. 뒤에서 배울 Chord P2P hashing 같은 경우는 Cassandra, Voldmort 등의 key-value store 에서 쓰이고 있습니다.

최초에 peer 는 서버에게 메세지를 보내 P2P 시스템에 가입했다는 사실을 알립니다.
Napster 에서는 중앙에 서버를 두어, 파일이 저장된 peer 를 기록합니다. 각 peer 는 파일이 어디있는지 검색하기 위해 중앙 서버에 질의해야 합니다. 그림에서 볼 수 있듯이, 각 파일은 서버가 아니라 클라이언트 에 저장되어 있습니다. 파일이 어느 클라이언트(peer) 에 저장되어있는지 알게되면, ping 을 날려 살아있는지 확인 후 파일을 다운 받습니다.
Napster 의 문제점은
Gnutella 는 Napster 시스템에서 서버를 제거했습니다. 각 클라이언트 (peer) 는 파일이 어디 저장되어있는지 파악하기 위해 서로 통신하지요. 이처럼 클라이언트가 서버처럼 행동하기때문에 servent 라 부르기도 합니다.

위 슬라이드에서 알 수 있듯이, 각 피어는 근처에 있는 피어로의 링크를 가지고 있습니다. 이 링크는 overlay graph 라 부르기도 합니다.
gnutella 에서 피어간 통신에 사용되는 주요 메세지 타입은


위 그림에서 TTL = 2 이기 때문에 query 메세지는 2-hop 까지만 전파됩니다. 그리고 gnutella 에서는 각 피어가 최근에 퍼트린 query 메세지 리스트를 유지하고 있기 때문에 같은 메세지를 다시 전파하지 않습니다.


피어가 보낸 query 에 대해 해당하는 파일을 가지고 있다는 응답은 query hit 메세지를 통해 전달됩니다.
gnutella 에서는 과도한 트래픽을 방지하기 위해 다음의 방법을 사용합니다.
DescriptorID) forwarded only onceDescriptorIDDescriptorID and Payload descriptor are droppedDescriptorID for which Query not seen is dropped
QueryHit 메세지를 requestor 가 받으면 최적의 responder 를 고르고, HTTP 를 이용해서 몇번의 통신을 한 뒤 파일을 전송받습니다. 여기서 gnutella 가 HTTP 를 이용하는 이유는, HTTP 가 standard, well-debugged, widely used 이기 때문입니다.
그런데 만약, responder 가 방화벽(firewall) 뒤에 있으면 어떻게 될까요? 일반적으로 방화벽은 incomming message 를 필터링 합니다. gnutella 는 이럴 경우 대비해 push 를 만들어 놓았습니다.

query hit 메세지를 받은 후에 requestor 가 보내는 HTTP 메세지에 responder 가 응답하지 않으면 overlay link (이미 연결되어있는) 을 통해서 push 메세지를 requestor 가 보냅니다. responder 는 방화벽 뒤에 있어도, overlay link 를 통해 받은 push 메세지를 확인하고 파일 전송을 시작합니다.
만약 requestor 가 방화벽 뒤에 있다면, gnutella 프로토콜로는 파일을 전송 받을 수 없습니다.
gnutella 에서 생기는 문제점은
FastTrac 은 Kazza, KazzaLite, Grokster 라는 기술을 기반으로 한 Napster Gnutella 의 하이브리드입니다.
healthier participants 를 이용하겠다는 기본적인 아이디어로부터 출발했습니다. gnutella 와 비슷하지만 노드중 일부가 supernode 가 되어, 특별한 역할을 수행합니다.

<file name, peer point> 리스트를 저장합니다이 reputation system 은 Kazaalite 처럼 upload 한 파일의 양으로 결정할 수도 있고, 경제학적인 원리를 적용한 방법도 있습니다
이전에 언급했듯이 다운만 받는 peer 도 존재할 수 있습니다. BitTorrent 는 업로드 하는 peer 에게 보상을 해 주어, peer 들의 업로드를 더 이끌어 낼 수 있습니다.

BitTorrent 네트워크 구성은 위 슬라이드와 같습니다.
BitTorrent 에서는 블럭단위로 파일을 전송하는데, 이 때 사용하는 몇 가지 규칙이 있습니다.
optimistic unchoke 기법은 주기적으로 랜덤한 neighbor 를 unchoke 해서, unchoked set 을 fresh 하게 유지합니다. 여기서 random choice choking 을 쓰는 이유는
지금까지 본 Napster, Gnutella, FastTrac 은 일종의 DHT, Distribute Hash Table 입니다.
DHT 에서의 performance concerns 는
우리가 배울 Chord 는 이런 구조가 적용된 structured peer to peer system 입니다.

Napster 는 peer 의 경우 파일을 저장하지 않기 때문에 메모리가 많이 들지 않지만, server 에서 많은 메모리를 요구합니다. 서버로 질의가 가기때문에 lookup latency 나 lookup 을 위한 메세지 수 자체는 많지 않지만, 서버의 부하가 상당히 심할 수 있습니다.
반면 Gnutella 에서는 서버가 없습니다. 그렇기 때문에 피어는 파일이 저장되어있는 주변 피어의 목록을 가지고 있어야 하는데, N 만큼의 이웃이 주변에 있을 수 있습니다. 따라서 한 피어에서 필요한 메모리 양은 O(N) 입니다.
그리고 네트워크가 직선으로 구성되어 있다고 할때, lookup latency 는 O(N) (N-1) 이고 룩업을 위한 메세지 수도 O(N) (2(N-1)) 입니다.
반면 Chord 는 모두 O(log N) 입니다. 이론적으로 constant 는 아니지만, real world 에서는 상당히 낮은 수가 될 수 있습니다.
Chord 는 Berkeley 와 MIT 에서 개발된 P2P 프로토콜입니다.latency 와 message cost of routing (lookups/inserts) 를 줄이기 위해 지능적으로 neighbor 를 선택하고 Consistent Hashing 기법을 사용합니다.
Consistent Hasing 값은 peer 에 부여되는 주소값으로
m 비트로 절단해서 사용합니다2^m - 1 입니다2^m 개의 점이 되어 하나의 원을 구성합니다

각 노드는 (반) 시계방향으로의 successor 를 가지고 있고, 다른 노드를 가리키기 위한 finger table 을 가지고 있습니다.

파일도 마찬가지로 SHA-1 으로 해싱해서, 160 비트로 짜른 뒤 mod 2^m 연산해서, 같은 값이거나 그보다 큰 값을 가지는 peer 에 저장합니다.
만약 균일하게 해싱된다면 K 개의 키, N 개의 피어에서 파일은 각 피어당 K/N 개씩 저장되므로 피어당 걸리는 부하는 O(K/N) 입니다.

위 그림에서 N80 피어가 K42 파일을 찾을때,
42 가 없으므로 최대한 먼 N16 에 질의하고,N16 은 N32 와 N80 밖에 모르므로 N32 를 거쳐 N45 로 질의합니다.
chrod search 는 O(log N) 의 시간이 듭니다. 증명에 대한 intuition 은 쉽습니다.
만약 현재 Here 에서 Key 를 모른다고 합시다. 그러면 그 거리의 1/2 만큼은 점프를 해야합니다. 그것보다 더 적게 점프하면 거리를 d 라 합시다. finger table entry 값은 2배씩 증가하기 때문에, 2d 만큼 점프할 수 있는 엔트리가 있어야 하고, 그럼 애초부터 2d 만큼 점프했어야 했기 때문에 모순입니다.
log(N) 만큼의 점프 뒤에는 key 까지의 거리는 아무리 멀어봐야 2^m / N 입니다. 균일하게 분포되는 해싱을 쓴다 가정하면, 이 사이에는 적은 수의 노드만 있습니다. 따라서 O(logN) 만큼만 더 점프한다면 높은 확률로 key 를 찾을 수 있습니다. O(logN) + O(logN) = O(logN) 이므로, search 는 O(logN) 입니다.
insertion 도 searching 과 마찬가지로 O(logN) 입니다. 그러나 이 성능은 finger table 과 successor 가 잘못되지 않았을 경우에만 참입니다.

chrod 는 successor 한개만 가질땐 failure 에 취약하기 때문에, 위 그림처럼 다수개의 successor 를 가질 수 있습니다. 이 경우 성능은 어떻게될까요?

2log(N) 개의 successor 를 유지할 경우를 한번 생각해 봅시다. 50% 씩 failure 가 발생하면
50%) 에서 참일때, 다시 말해서 모든 노드에서 적어도 하나의 successor 가 존재할 확률은 N 이 매우 클때
O(logN) other finger entires in the system, on averageO(logN * logN)
join, leave, failure 등 churn 이 자주 일어나므로 loop 가 있는지 없는지 검사하기 위해 주기적으로 stabilization protocol 를 사용합니다.


Pastry 는 chord 처럼 node 에 id 를 부여합니다. routing table 은 prefix matching 에 기반하기 때문에 log(N) 의 성능을 보여줍니다. 그리고 짧은 prefix 일 수록 가까이에 있을 확률이 높습니다.



Kelips 는 1-hop lookup 을 보여줍니다. 이럴 수 있는 이유는 위 그림에서 보듯이 affinity group 이란걸 사용하기 때문입니다. 루트 N 에 가까운 숫자 k 를 정하고, 이 수로 mod 연산을 해, 그룹을 만듭니다. 각각의 그룹은 내에 있는 모든 노드는 서로 어떤 파일을 저장하는지 알고 있습니다. 그리고 각 노드는 다른 그룹으로의 링크를 하나씩 가지고 있습니다. 따라서 어딜가든 거의 1번 혹은 2번 내에 lookup 이 가능합니다.
chord 에 비해 메모리를 더 잡아먹긴 합니다. O(logN) 보단 많은 양이지만, 그렇게 많지도 않습니다. 메모리가 귀하다면 chord 나 pastry 를, 그렇지 않고 lookup 속도가 중요하다면 kelips 를 사용하면 됩니다.

membership 은 gossip-based 프로토콜로 관리할 수 있습니다.
(1) Title Image
(2) Cloud Computing Concept 1 by Indranil Gupta, Coursera