C.W.K.
Stream
Lesson 01 of 05 · published

lease token + heartbeat

~11 min · lease, token, heartbeat, fencing

Level 0Empty Shelf
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"worker 는 job 을 소유하지 않아. 타이머 걸고, 임대가 아직 유효함을 증명하는 token 을 들고 빌려."

문제: 지금 이 job 을 누가 소유해?

여러 worker 가 긴 job 하나의 queue 에서 당겨. 하나보다 많아지는 순간, 위험한 질문이 나타나: 뭐가 두 worker 가 같은 job 을 잡는 걸, 아니면 다들 죽은 줄 알았던 worker 가 깨어나 재배정된 job 을 짓밟는 걸 막아? 소유권이 흐릿하면, 두 worker 가 같은 영상을 전사하거나, 좀비 worker 가 남이 이미 재실행 중인 job 의 결과를 제출해. '이 정확한 worker 가 지금 이 job 을 소유하고, 아무도 아니다' 를 확실히 말할 방법이 필요해.

atomic 하게 claim, token 으로 증명

Recall 의 답은 lease 야. job claim 은 단일 atomic DB 트랜잭션 안에서 일어나: job 이 queued 에서 leased 로 옮기고, claim 한 worker 가 랜덤 lease token 을 받아. 그 token 이 소유의 증명이야. 그때부터 worker 가 그 job 에 하는 모든 행위 — heartbeat, 실패 보고, 결과 제출 — 이 token 을 제시해야 해. control plane 이 확인하고 owner, token, status 가 안 맞는 변형은 거부해. job 을 claim 한 적 없는 두 번째 worker 는 token 이 없고; lease 만료된 worker 는 control plane 이 더는 인정 안 하는 token 을 가져. 소유권이 신뢰의 문제이길 멈추고 증명의 문제가 돼.

이건 분산 락의 fencing-token 아이디어야: 그냥 '쥐고 있는' 락은 아직 있다고 생각하는 동안 조용히 잃을 수 있어서, 안전한 패턴은 리소스 자체가 매 write 마다 검증하는 token 을 지니는 거야. 멈춤에서 재개된 worker 는 아직 job 을 소유한다고 믿을 수 있어 — 근데 token 이 stale 이라 write 가 튕겨. 변형 지점에서 확인되는 token 이 lease 를 희망 섞인 관례가 아니라 안전하게 만들어.

heartbeat 가 lease 를 살려둬

lease 는 일부러 시간 제한이야 — Recall 은 2시간 창을 써 — 사라진 worker 가 job 을 영영 못 쥐게. 근데 진짜 전사 작업엔 길고 block 되는 구간이 있어: 오디오 준비, provider 대기. lease 가 작업 중 만료되는 걸 막으려고, worker 가 heartbeat 를 보내 — 유료 호출 전, 완료된 chunk 마다, 그리고 백그라운드 heartbeater 로, 긴 block 작업 중에도. 각 heartbeat 가 lease 를 갱신해. heartbeat 의 존재가 '나 살아 있고 아직 일해' 라 말하고; 그 부재가 정확히 control plane 이 job 을 되찾는 데 쓰는 신호야(다음 레슨). 그래서 lease 는 살아 있는 거야: token 으로 쥐고, heartbeat 로 따뜻하게 유지하고, worker 가 더는 거기 있음을 증명 못 하는 순간 — 자발적으로든 timeout 으로든 — 놓아.

Code

트랜잭션에서 claim, 그다음 token 으로 소유 증명·python
# Claim: atomic 전이 + 이 worker 에 묶인 랜덤 token.
with db.transaction():
    job = db.claim_next_queued(worker_id)   # queued -> leased
    token = random_token()
    job.lease_token = token
    job.lease_expires_at = now_plus(hours=2)

# 이후 모든 행위가 token 을 제시해야 함. 불일치 -> 거부.
control_plane.heartbeat(job.id, worker_id, token)   # lease 갱신
control_plane.submit_result(job.id, worker_id, token, result)

# 현재 token 없는 stale/두 번째 worker 는 job 을 변형 못 한다.
# 소유권은 한 번 가정되는 게 아니라 행위마다 증명된다.

External links

Exercise

네 일에서 worker, cron job, 프로세스가 task 를 '가져다' 작업하는 곳을 찾아 — queue 소비자, 예약 job, lock 파일. 물어: 그게 둘 돌거나, 하나가 멈췄다 재개하면, 둘 다 같은 task 에 행위할 수 있어? lease 를 설계해: atomic claim, worker 에 묶인 token, 그리고 모든 상태 변경 행위에서 그 token 검증. stale 소유자의 write 가 이제 어디서 거부될지 적어봐.
Hint
취약점은 결과 쓰는 순간 재-증명 안 되는 모든 'claim' 이야. worker 가 claim 하고, lease 를 지나 멈추고, job 이 재배정되고, 깨어나 제출할 수 있어 — 재배정된 작업을 오염시키며. 고침은 매 변형마다 확인되는 token, 그리고 살아 있는 동안 소유를 갱신하는 heartbeat 야. 소유권은 claim 시점만이 아니라 write 마다 증명 가능해야 해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.