컴퓨팅에서 **Chord**(코드)는 peer-to-peer 분산 해시 테이블에 대한 프로토콜 및 알고리즘이다. 분산 해시 테이블은 다른 컴퓨터(노드)에 키를 할당하여 키-값 쌍을 저장한다 (노드는 그것이 담당하는 모든 키에 대한 값을 저장한다). Chord는 노드에 키가 할당되는 방법과 주어진 키에 해당하는 첫번째 노드를 찾아 해당 키에 대한 값을 해당 노드가 찾을 수 있는 방법을 정한다.

Chord는 CAN, Tapestry 그리고 Pastry와 함께, 4개의 원조 분산 해시 테이블 프로토콜 중 하나이다. 이 프로토콜은 Ion Stoica, Robert Morris, David  Karger, Frans Kaashoek, Hari Balakrishnan가 도입했으며, MIT에서 개발되었다.

## 개요
노드와 키는 일관된 해싱을 통해 -비트 식별자를 할당 받는다. SHA-1 알고리즘은 일관된 해싱을 위한 기반 해싱 함수이다. 일관된 해싱은 Chord의 견고함과 성능을 위해 필수적인데, 이는 키와 노드(정확히는 노드의 IP 주소)가 동일한 식별 공간 내에 무시할 만한 충돌 가능성과 함께 균일하게 분산되기 때문이다. 따라서, 방해 없이 노드를 네트워크에 참가시키거나 내보내는 것이 가능하다. 해당 프로토콜 내에서, 노드라는 용어는 모호할 것 없이 노드 자체와 그것의 식별자(ID) 모두를 가리킨다. '키'라는 용어도 마찬가지이다.

Chord 탐색 프로토콜을 사용하면, 노드와 키는 은 충돌을 피할 수 있을 만큼 충분히 커야 한다). 이러한 노드 중 일부는 컴퓨터 나 키에 매핑되는 반면 다른 노드는 대부분 비어 있다.

각 노드는 '다음 노드(successor)'와 '이전 노드(predecessor)'를 가지고 있다. 다음 노드는 식별 서클 내에서 시계 방향에 있는 노드이다. 이전 노드는 시계 반대 방향에 있는 노드이다. 모든 ID 각각에 대해 하나의 노드가 있는 경우 노드 0의 다음 노드는 노드 1이며, 노드 0의 이전 노드는 노드 이다. 그러나 보통 시퀀스 내에는 "구멍"이 있다. 예를 들어, 노드 154부터 노드 166까지 존재하지 않으면 노드 153의 다음 노드는 노드 167가 되며 노드 167의 이전 노드는 노드 153가 된다.

다음 노드에 대한 개념은 키의 경우에도 사용될 수 있다. 키 를 조회하는 것이다.

한 노드의 다음 노드(혹은 이전 노드)가 (오류나 이탈로 인해) 네트워크에서 사라질 수도 있기 때문에, 각 노드는 서클 내에서 자신과 인접한 세그먼트 전체를 기록한다. 이 리스트는 문제의 네트워크가 높은 오류율을 겪고 있더라도, 높은 확률로 자신의 다음 노드 혹은 이전 노드를 정확하게 찾게 해준다.

## 프로토콜 상세

### 기본적인 조회
Chord 프로토콜의 핵심 용도는 클라이언트(노드)에서 키를 조회, 즉  은 링 내 머신의 개수이다.

### 핑거 테이블
위에서 선형 검색을 피하기 위해, Chord는 각 노드가  의 가장 가까운 다음 노드 또는 이전 노드에 쿼리를 전달한다.

그런 핑거 테이블을 사용해, N-노드 네트워크 내에서 다음 노드를 찾기 위해 반드시 접촉되어야 하는 노드의 개수는 이다. (아래에서 증명한다)

### 노드 조인
새로운 노드가 들어올 때면, 세 가지 불변 사항들이 유지되어야 한다(첫 두 가지는 정확성을 보장하는 것이고 마지막 것은 조회를 빠르게 유지한다):
이 세 가지 불변 사항들을 만족하려면, 각 노드에 대해 'predecessor' 필드가 유지되어야 한다. 다음 노드가 핑거 테이블의 첫번째 엔트리이므로, 이 필드를 개별적으로 유지할 필요가 전혀 없다. 다음 작업들이 새로 들어오는 노드 에 대해 이루어져야 한다:
 이 걸립니다.

### 안정화
정확한 탐색을 보장하기 위해, 모든 다음 노드를은 항상 최신으로 유지되어야 한다. => 백그라운드에서 주기적으로 실행되는 안정화 프로토콜. 핑거 테이블과 다음 노드 포인터의 갱신. 안정화 프로토콜: Stabilize: n은 자신의 다음 노드에게 이전 노드 p에 대해 묻고 대신해서 p가 이전 노드가 되어야 하는지 결정한다(이는 p가 최근에 시스템에 들어온 경우를 말한다. Notify: 으로 변경할 수 있다. Fix_fingers: 핑거 테이블을 갱신한다.

## 증명 스케치
'높은 개연성을 가지고, Chord는 -노드 네트워크 내에서 다음 노드를 찾는다.'

노드  까지의 새로운 거리는 초기 거리의 절반 이하이다.

남은 거리를 반으로 나누는 이 과정이 반복되므로, 이 된다.

Chord가  개의 이전 노드 및 다음 노드에 대한 트래킹을 유지할 경우, 또 각 노드가 실패할 확률이 1/4인 경우, find_successor (아래 참고)와 find_predecessor (see below)가 정확한 노드를 반환할 확률이 높다.

단순히, 모든 이며, 이는 낮은 확률이다. 그러므로 그들 중 한 개는 살아있고 노드는 정확한 포인터를 가질 가능성이 높다.

## 의사 코드
아이디에 대한 'successor' 노드를 찾는 의사 코드는 다음과 같다:
 // ask node n to find the successor of id
 n.find_successor(id)
 //Yes, that should be a closing square bracket to match the opening parenthesis.
 //It is a half closed interval.
 if (id ∈ 
 return successor;
 else
 // forward the query around the circle
 n0 = successor.closest_preceding_node(id);
 return n0.find_successor(id);

 // search the local table for the highest predecessor of id
 n.closest_preceding_node(id)
 for i = m downto 1
 if (finger[i]∈)
 return finger[i];
 return n;

노드 참가나 이탈 이후 Chord 링 혹은 서클을 안정화하는 의사 코드는 다음과 같다:
 // create a new Chord ring.
 n.create
 predecessor = nil;
 successor = n;

 // join a Chord ring containing node n'.
 n.join(n')
 predecessor = nil;
 successor = n'.find_successor(n);

 // called periodically. n asks the successor
 // about its predecessor, verifies if n's immediate
 // successor is consistent, and tells the successor about n
 n.stabilize
 x = successor.predecessor;
 if (x∈)
 successor = x;
 successor.notify(n);

 // n' thinks it might be our predecessor.
 n.notify(n')
 if (predecessor is nil or n'∈)
 predecessor = n';

 // called periodically. refreshes finger table entries.
 // next stores the index of the finger to fix
 n.fix_fingers
 next = next + 1;
 if (next > m)
 next = 1;
 finger[next] = find_successor(n+2^{next-1});

 // called periodically. checks whether predecessor has failed.
 n.check_predecessor
 if (predecessor has failed)
 predecessor = nil;