분산 프로토콜이 추가하는 복잡도 레이어
03 — DISTRIBUTED PROTOCOL
분산 프로토콜이 추가하는 복잡도 레이어
이제 컴퓨터 한 대를 벗어나 보자. 분산이란 한 대가 하던 일을 여러 대가 나눠 하는 것이다. 듣기엔 단순한데, 소프트웨어 세계에는 오래된 격언이 있다. 네트워크 경계를 넘는 순간 모든 것이 어려워진다. 같은 컴퓨터 안에서는 공짜였던 것들 — 서로 믿기, 말 걸기, 죽었는지 확인하기 — 이 전부 직접 만들어야 하는 시스템이 된다.

한 대 안에서는 공짜였던 것들이 네트워크 경계를 넘는 순간 전부 만들어야 할 시스템이 된다
3.1 레이어별 복잡도 증가
예를 들어 신뢰부터 보자. 내 컴퓨터 안에서 프로그램끼리는 서로를 의심하지 않는다. 같은 집에 사는 가족이다. 그런데 네트워크 건너편의 Worker는 누군지 모른다. 신분증을 확인하고(키 검증), 위조를 막고(전자 서명), 대화를 도청당하지 않게(암호화) 해야 한다. 현관문 하나 없던 집에 보안 시스템을 통째로 다는 일이다.

신뢰 레이어 하나만 해도 이렇다 — 이런 레이어가 일곱 개다
| 레이어 | 개인 하네스 | 분산 하네스 추가 사항 | 배수 |
|---|---|---|---|
| 신뢰 Trust | 같은 프로세스, 암묵적 | Ed25519 keypair, TLS, 서명, 세션 토큰, nonce/replay 방어, pubkey 화이트리스트 | ×5 |
| 가입 Join | 코드에서 즉시 등록 | 승인 게이트 + pubkey 화이트리스트 + 운영자 UI + PENDING→APPROVED 상태머신 | ×3 |
| 통신 Comm | 함수 호출 / IPC | WebSocket over TLS + JSON-RPC 2.0 + 서명 메시지 + permessage-deflate | ×4 |
| 장애 Failure | 프로세스 단위 | 네트워크 파티션, 노드 다운, Heartbeat(10s/30s/60s), idempotency_key, 중복 결과 처리 | ×6 |
| 능력 Capability | 정적 코드 명시 | 동적 Capability Manifest + 런타임 갱신 + dispatch 매칭 | ×3 |
| 결과 검증 | 로컬 QA 게이트 | Schema 검증 + 서명 검증 + redundant execution(선택) + Aggregator | ×3 |
| 관찰성 | 로컬 로그 + 텔레그램 | Audit Log(append-only) + Worker/Host/Task별 메트릭 + trace_id 분산 추적 | ×3 |
표의 일곱 줄을 사람 말로 번역하면
신뢰 = 처음 보는 일꾼을 믿을 수 있게 만들기. Ed25519는 위조가 사실상 불가능한 전자 서명 방식이고, TLS는 대화를 도청당하지 않게 하는 암호화 통신이다. nonce/replay 방어는 누가 어제의 지시문을 녹음해 뒀다가 다시 틀어도 안 속게 하는 장치. 가입 = 새 일꾼을 받는 절차(지원 → 승인 대기 → 승인). 통신 = 일꾼들끼리 쓰는 표준 대화 규격. 장애 = 누가 갑자기 죽거나 연락이 끊겼을 때의 대처 매뉴얼 — Heartbeat는 10초마다 보내는 나 살아 있어요 신호고, idempotency_key는 같은 주문이 실수로 두 번 접수돼도 한 번만 처리되게 하는 주문번호다. 능력 = 일꾼마다 들고 다니는 이력서(나는 뭘 할 줄 안다). 결과 검증 = 받아 온 결과물을 믿어도 되는지 재검사. 관찰성 = 무슨 일이 있었는지 전부 기록하고 추적하는 CCTV.
잠깐, 배수를 곱하는 게 맞나
레이어들이 서로 독립적이지 않으니 9,720이라는 숫자 자체는 공학적 측정값이 아니라 체감을 구조화한 추정이다. 요점은 정확한 숫자가 아니라 방향이다 — 복잡도가 더해지는 게 아니라 곱해진다는 것. 보안을 챙기면 장애 처리가 어려워지고, 장애 처리를 챙기면 통신이 복잡해지는 식으로 레이어끼리 서로를 증폭한다.
3.2 상태 머신의 폭발
상태란 일이 지금 어느 단계에 있는지를 말한다. 택배로 치면 배송 준비 → 배송 중 → 배송 완료다. 개인 하네스의 작업도 그 정도면 된다. 대기, 진행 중, 완료. 끝이다.
분산이 되면 택배 상태가 이렇게 변한다. 접수됨, 기사 배정됨, 기사가 수락함, 배송 중, 완료, 시간 초과, 재접수, 기사가 거부함, 다른 기사 재배정. 게다가 기사(Worker)에게도 상태가 생긴다. 승인 대기, 승인됨, 근무 중, 응답 없음, 퇴근, 자격 박탈. 작업 상태 7가지 × 기사 상태 6가지 = 42가지 조합이 나오고, 조합마다 어떻게 처리할지 코드를 짜야 한다.
3.3 장애 시나리오 매트릭스
분산 시스템 설계의 절반은 뭔가 죽었을 때 어떻게 할 것인가다. 표를 보면 차이가 잡힌다.
| 장애 | 개인 하네스 | 분산 하네스 |
|---|---|---|
| 프로세스 크래시 | 재시작 | Heartbeat 타임아웃 → STALE → 재할당 |
| 중간 결과 손실 | 로컬 파일 복구 | idempotency_key 기반 재시도 + 중복 결과 dedup |
| 능력 부족 | 즉시 에러 | TASK_REJECT → 다른 Worker 선택 → 능력 매칭 재실행 |
| 부분 실패 | 전체 재시도 | fail-fast / best-effort / retry-then-fail 정책 선택 |
| Host 다운 | N/A | Worker 로컬 큐 저장 → 재연결 시 flush → audit log 복원 |
개인 하네스 열은 한 단어로 끝난다. 분산 하네스 열은 전부 시스템이다.
한 줄만 예로 풀면 — 중간 결과 손실
혼자 쓸 때는 컴퓨터가 죽으면 파일을 다시 열면 된다. 분산에서는 이런 상황이 생긴다. 일꾼 A에게 보고서 작성을 시켰는데 완성 직전에 연락이 끊겼다. 다른 일꾼 B에게 다시 시켰다. 그런데 A가 살아 돌아와서 자기가 만든 보고서를 제출한다. 이제 보고서가 두 개다. 어느 걸 쓰나? 같은 일을 두 번 한 비용은? 이걸 막는 장치가 주문번호(idempotency_key)와 중복 제거(dedup)다. 한 줄짜리 표 항목 하나가 이만큼의 설계를 요구한다.