코디네이터
클라이언트 요청을 받아 그 일을 실제로 맡을 노드들에게 뿌리고, 돌아온 답을 모아 클라이언트에게 돌려주는 노드입니다. 데이터가 여러 대에 흩어진 시스템에서는 요청 하나가 여러 대에 걸칩니다. 그 앞에 서서 뿌리고 모으는 쪽을 이렇게 부릅니다.
상세
사무실 전화가 울리면 마침 가까이 있던 사람이 받습니다. 받은 사람은 답을 아는 동료 몇에게 물어, 자기가 아는 답까지 쳐서 필요한 만큼 모이면 수화기 너머로 그대로 전합니다. 통화가 끝나면 그 사람은 다시 제 일로 돌아갑니다.
코디네이터는 클라이언트 요청 하나를 받아 그 요청을 끝까지 진행시키는 노드입니다. 따로 두는 노드는 아닙니다. 요청 하나가 처리되는 동안 어느 노드가 잠깐 맡는 역할입니다. 하는 일은 셋입니다. 요청이 건드릴 데이터를 가진 노드가 어디인지 정합니다. 그 노드들에 요청을 보냅니다. 돌아온 응답이 정해진 수를 채웠는지 세어 클라이언트에게 답합니다.
요청을 받은 노드가 언제나 그 요청을 맡는 것은 아닙니다. 담당 자격이 정해져 있는 시스템에서는 자격 없는 노드가 요청을 받으면 그 요청을 자격 있는 노드로 넘깁니다. 넘겨받은 노드가 코디네이터가 됩니다. 자격을 두는 까닭은 대개 그 노드만 할 수 있는 일이 있기 때문입니다. 새 판에 붙일 버전 표식을 만드는 일이 그런 자리입니다.
코디네이터가 데이터를 들고 있어야 하는 것도 아닙니다. 자기가 담당 복제본 가운데 하나일 수도 있고, 데이터는 한 조각도 없이 뿌리고 모으기만 할 수도 있습니다. 이 역할이 정하는 것은 데이터를 어디에 두느냐가 아니라 요청 하나의 진행을 누가 맡느냐입니다.
배경
데이터를 한 대에만 두면 그 한 대가 죽는 순간 서비스가 멈춥니다. 그래서 같은 데이터를 여러 대에 복제하고, 양이 크면 여러 대로 나눠 담습니다. 그러면 물음이 둘 생깁니다. 이 요청은 어느 대로 가야 하는가. 몇 대가 답해야 끝난 것으로 칠 것인가.
누군가는 그 두 물음에 답해야 합니다. 클라이언트 요청이 노드들에 고르게 배정되는 시스템에서는 어느 노드가 요청을 받을지 미리 정해져 있지 않습니다. 어느 노드든 읽기 요청의 조정을 맡을 수 있습니다. 그래서 요청을 받은 노드가 그 자리에서 담당 노드를 계산하고 응답을 세는 일을 떠맡습니다. 이 일을 맡은 참여자를 조정하는 쪽이라는 뜻에서 코디네이터라 부릅니다.
조정을 꼭 서버 쪽 노드가 해야 하는 것은 아닙니다. 조정을 담당하는 상태 기계를 클라이언트 쪽으로 옮기는 방법이 있습니다. 클라이언트 애플리케이션이 라이브러리를 써서 조정을 자기 쪽에서 하는 방식입니다. 클라이언트는 주기적으로 노드 하나를 임의로 골라 그 노드가 보는 멤버십 상태를 내려받습니다. 그 정보로 어떤 노드 집합이 주어진 키의 담당인지를 스스로 정합니다. 이렇게 하면 로드밸런서가 임의의 노드에 요청을 배정할 때 생기는 네트워크 홉 하나를 읽기에서 피할 수 있습니다. 어느 쪽을 골라도 조정하는 쪽은 사라지지 않습니다. 그 자리가 서버 안이냐 클라이언트 안이냐만 달라집니다.
동작
코디네이터가 요청 하나를 처리하는 동안 밟는 단계는 대체로 같습니다. 받고, 담당을 정하고, 보내고, 세고, 답합니다.
flowchart TD
A["요청 수신"] --> B["키로 담당 복제본 산출"]
B --> C["담당 복제본에 요청 발송"]
C --> D["돌아온 응답 세기"]
D --> E{"요구한 수를 채웠나"}
E -->|아니오| D
E -->|예| F["결과를 합쳐 클라이언트에 반환"]
첫 단계는 담당 복제본을 정하는 것입니다. Apache Cassandra 공식 문서는 변경이 생기면 코디네이터가 파티션 키를 해싱해 그 데이터가 속한 토큰 범위를 알아낸다고 적습니다. 그 다음 복제 전략에 따라 그 데이터의 복제본들에 변경을 복제합니다. 모든 복제 전략은 복제 계수(replication factor, RF)라는 개념을 갖습니다. 이 값은 한 파티션의 사본이 몇 벌 있어야 하는지를 정합니다. 복제 계수가 3 인 키스페이스라면 데이터는 서로 다른 복제본 세 곳에 쓰입니다.
다음은 보내고 세는 단계입니다. 여기서 읽기와 쓰기가 갈립니다. 같은 문서는 쓰기가 일관성 수준과 무관하게 언제나 모든 복제본에 보내진다고 적습니다. 일관성 수준은 코디네이터가 클라이언트에 응답하기 전에 몇 개의 응답을 기다릴지만 정합니다. 읽기는 다릅니다. 코디네이터는 대체로 일관성 수준을 채울 만큼의 복제본에만 읽기 명령을 냅니다.
Dynamo 논문은 같은 단계를 R 과 W 라는 두 값으로 적습니다. R 은 읽기 하나가 성공하려면 참여해야 하는 최소 노드 수, W 는 쓰기 하나가 성공하려면 참여해야 하는 최소 노드 수입니다. 쓰기 요청을 받은 코디네이터는 새 판의 벡터 시계를 만들고 새 판을 자기 쪽에 먼저 씁니다. 그 다음 도달 가능한 상위 N 개 노드에 새 판을 보냅니다. 최소 W-1 개 노드가 응답하면 그 쓰기는 성공으로 칩니다. 읽기 요청이면 코디네이터가 그 키의 선호 목록에서 도달 가능한 상위 N 개 노드에 그 키의 모든 판을 요청합니다. 그리고 R 개의 응답을 기다린 뒤 결과를 클라이언트에 돌려줍니다. 모인 판이 여럿이고 서로 인과적으로 무관하다고 판단되면 그 판들을 모두 돌려줍니다.
마지막은 합치는 단계입니다. 검색처럼 여러 노드의 결과를 하나로 줄여야 하는 요청에서는 이 단계에 이름이 붙어 있습니다. Elasticsearch 공식 문서는 검색 요청이 두 단계로 실행되고 그 두 단계를 클라이언트 요청을 받은 노드가 조정한다고 적습니다. 흩는 단계에서 그 노드는 데이터를 가진 데이터 노드들에 요청을 넘깁니다. 각 데이터 노드는 요청을 자기 쪽에서 실행해 결과를 돌려줍니다. 모으는 단계에서 그 노드는 각 데이터 노드의 결과를 하나의 전역 결과 집합으로 줄입니다.
예시
Apache Cassandra 의 일관성 수준
Cassandra 는 읽기와 쓰기에 참여해야 하는 노드 수를 운영자가 메뉴에서 고르게 합니다. 복제 계수를 몰라도 R 과 W 의 행동을 고를 수 있게 만든 손잡이입니다.
ONE 복제본 하나만 응답하면 된다
TWO 복제본 둘이 응답해야 한다
THREE 복제본 셋이 응답해야 한다
QUORUM 복제본의 과반(N/2 + 1)이 응답해야 한다
ALL 복제본 전부가 응답해야 한다
LOCAL_QUORUM 코디네이터가 속한 데이터센터의 복제본 과반이 응답해야 한다
EACH_QUORUM 각 데이터센터의 복제본 과반이 응답해야 한다
LOCAL_ONE 복제본 하나만 응답하면 된다. 읽기가 원격 데이터센터의 복제본으로 가지 않는다
ANY 복제본 하나가 응답하거나, 코디네이터가 힌트를 저장해도 된다
이 메뉴에서 코디네이터가 두 번 이름으로 등장합니다. LOCAL_QUORUM 은 과반을 세는 범위를
코디네이터가 속한 데이터센터로 좁힙니다. ANY 는 복제본 응답이 없어도 코디네이터가 힌트를
저장하는 것으로 쓰기를 성립시킵니다. 힌트를 저장했으면 코디네이터가 나중에 그 힌트를 재생해
복제본에 변경을 전달하려 시도합니다. 이 수준은 쓰기 연산에만 허용됩니다.
Elasticsearch 의 node.roles: []
Elasticsearch 는 이 역할을 코디네이팅 노드라 부릅니다. 모든 노드가 암묵적으로 코디네이팅
노드입니다. node.roles 설정에 빈 목록을 명시한 노드는 코디네이팅 노드로만 동작하고, 그 역할은
끌 수 없습니다. 그래서 이런 노드는 모으는 단계를 감당할 만큼의 메모리와 CPU(Central Processing
Unit, 중앙처리장치)를 갖춰야 합니다.
node.roles: []
마스터 임무, 데이터 보관, 문서 전처리를 모두 떼어 내면 요청을 라우팅하고 검색의 줄이는 단계를 처리하고 대량 색인을 분배하는 노드만 남습니다. 공식 문서는 이 전용 노드를 로드밸런서에 빗댑니다. 이 노드도 다른 노드와 똑같이 클러스터에 합류해 전체 클러스터 상태를 받습니다. 그 상태를 써서 요청을 적절한 자리로 직접 라우팅합니다. 큰 클러스터에서는 데이터 노드와 마스터 후보 노드가 지고 있던 코디네이팅 역할을 이 노드로 덜어 낼 수 있습니다.
MongoDB 의 mongos
MongoDB 는 샤딩된 클러스터에서 같은 일을 하는 물건에 다른 이름을 붙였습니다. mongos
인스턴스이고, 공식 문서는 이것을 질의 라우터라 부릅니다.
mongos 는 질의를 이렇게 라우팅합니다. 먼저 그 질의를 받아야 하는 샤드 목록을 정합니다. 대상이
된 모든 샤드에 커서를 엽니다. 그 다음 각 대상 샤드에서 온 데이터를 병합해 결과 문서를
돌려줍니다. 정렬 같은 일부 질의 수식어는 mongos 가 결과를 가져오기 전에 각 샤드에서
수행됩니다.
관련 항목
응답 성립을 판정하는 기준
정족수 · 일관성 수준 · 복제 계수
담당 복제본을 찾는 데이터 단위
파티션 키 · 토큰 범위 · 키스페이스 · 파티션
담당을 정하는 방법
생겨난 배경
요청을 보내는 대상
노드 · 복제본 · 데이터센터
복제로 지키는 성질
응답이 모자랄 때 쓰는 장치
실제로 구현·채택한 시스템
Dynamo · Apache Cassandra · Elasticsearch · MongoDB
가리키는 다른 이름
로드 밸런서 · 질의 라우터 · mongos
이름이 겹치는 다른 개념
2단계 커밋 · 그룹 코디네이터 · 코디네이터 핫스팟
역할이 나뉘는 두 방식
서버 주도 조정 · 클라이언트 주도 조정
다른 이름: coordinator · coordinator node · coordinating node · 조정자