"한 호스트는 결정해. 한 호스트는 실행해. 일부러 같은 호스트가 아냐."
역할이 넷이지, 동료가 넷인 게 아냐
Recall 의 일은 기계 여러 대에 퍼져 있어. 근데 그 분리는 '빠르게 하려고 컴퓨터 더 붙였다' 가 아냐. 역할마다 뭘 소유해도 되는지로 정해져 있어.
- control plane — 항상 켜진 호스트 하나. 데이터베이스, job queue, 받아들인 증거, 그리고 모든 상태 전이를 소유해. 단일 진실의 원천이야. 얘가 job 끝났다고 하면, 끝난 거야.
- executor — 또 다른 항상 켜진 호스트. 아카이브를 스캔하고, 오디오를 트랜스코딩하고, 유료 전사 API 를 불러. canonical 상태는 하나도 소유 안 해. 로컬 파일은 그냥 캐시야. 재구축할 수 있고, 버려도 되고, 절대 진실이 아니고.
- 스토리지(NAS) — 원본 영상 바이트를 소유해. 아무도 그걸 DB 로 복사 안 해.
- 개발 client(노트북) — 코드 편집하고, 작은 테스트 돌리고, git 에 push 해. job 을 소유한 적도 없고 무거운 아카이브 일을 돌린 적도 없어.
이것들은 서로 바꿔 끼울 수 있는 동료가 아냐. 권리가 서로 다른 역할들이고, 그 권리가 곧 아키텍처야.
왜 결정과 실행을 분리해
executor 가 맡은 일은 죄다 느리고, 비싸고, 실패하기 쉬워. hang 걸릴 수 있는 네트워크 파일시스템, 트랜스코딩해야 하는 몇 기가짜리 영상, 타임아웃 나는 유료 API 호출. 진실의 원천에 절대 붙이고 싶지 않은 종류의 일이지. 붙여놓으면 멈춘 네트워크 마운트 하나가 DB 를 얼리고, 트랜스코딩 중 크래시 하나가 queue 를 오염시켜.
나눠놓으면 blast radius 가 줄어. executor 는 job 중에 크래시하든 hang 걸리든 죽든 상관없어. control plane 의 진실은 멀쩡하거든. executor 한테는 애초에 진실을 쓸 권한이 없었으니까. 결과를 제안만 할 수 있고, 받을지 말지는 control plane 이 정해. 두뇌랑 손을 떠올려 봐. 위험한 일은 손이 하지만, 실제로 뭐가 일어났는지는 두뇌가 정하잖아.
executor 는 진실이 아니라 lease 를 쥐어
구체적으로 보면 이래. executor 는 파일을 쥐듯이 job 을 '가진' 게 아냐. control plane 에서 하나 claim 하고, 시간 제한 lease 아래 작업하고, 결과를 수락받으려고 도로 제출해. 죽으면 lease 가 만료되고, control plane 이 job 을 다른 쪽에 넘겨. 잃는 건 없어. executor 가 중요한 걸 쥐고 있었던 적이 없으니까. 그 lease 가 어떻게 도는지는 트랙 6 전체가 다뤄. 지금은 모양만 기억해 두면 돼. 무거운 일은 아무것도 소유하지 않는 호스트에서 돈다.