본문 바로가기
C.W.K.
Stream
Lesson 05 of 05 · published

재시작 뒤 복구

~12 min · restart, stale-running, lease, recovery

Level 0마른 펜촉
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"재시작 복구는 증거가 있는 상태 전환이지 청소 지름길이 아니야."

durable 행에서 복구해

job이 running이라고 말하는 동안 process가 죽을 수 있어. 현재 Inkwell은 local worker lane 하나를 돌려. 그 process가 시작할 때 남아 있는 running job은 이전 process가 버린 고아야.

고아 attempt를 기록해

startup은 running attempt를 failed로 표시하고, attempt가 하나도 없는 legacy job에만 failed attempt를 만든 뒤, running job을 error와 finished_at이 있는 failed로 바꿔. 별도 retry가 그 job을 queued로 돌려.

startup 복구가 안전하게 반복되게 해

running 행을 그대로 두면 single-worker queue가 영원히 좌초해. 복구를 반복해도 running 행만 대상이라 첫 pass 뒤에는 바꿀 것이 없어.

운영 불변식. 재시작 복구는 증거가 있는 상태 전환이지 청소 지름길이 아니야.

crash를 시간선에 넣어

이 설계는 평온한 demo가 아니라 아무 순간에 process가 사라지는 시간선에서 시험해야 해. 수락 전, commit 뒤, claim 뒤, 외부 호출 뒤, 결과 저장 뒤에 각각 crash를 놓고 database가 무엇을 말하는지 적어. 사용자가 같은 요청을 다시 보내도 돈과 문장이 두 번 생기지 않아야 해.

직접 설계해

죽은 single worker의 job을 복구하는 startup 절차를 써. status와 timestamp, error, attempt 행을 같이 써. 복구 script가 추측으로 행을 덮지 않고 어떤 증거로 전환하는지 설명해.

관찰 가능성이 복구 가능성이야

운영자가 SQL 한 번으로 queued, running, failed, done을 구분하고 다음 안전 행동을 알 수 있어야 해. 알 수 없는 침묵을 queue라고 부르면 기다림은 이미 데이터를 잃은 거야.

운영 증거를 남겨

startup scan은 이전 single worker가 남긴 running job과 attempt를 failed로 닫아. attempt가 없던 legacy job에만 한 줄을 보강하고, retry 뒤 다음 claim이 새 attempt를 만들게 해야 과거를 덮지 않아.

느린 외부 호출은 transaction 밖에 두고, claim과 완료만 짧고 atomic하게 만들어. 그래야 기다림이 database 전체를 잠그지 않아.

Code

만료된 claim만 복구해·sql
UPDATE job_attempts
SET status = 'failed',
    error = 'worker restarted',
    finished_at = CURRENT_TIMESTAMP
WHERE status = 'running'
  AND job_id IN (SELECT id FROM jobs WHERE status = 'running');

INSERT INTO job_attempts(
  job_id, attempt_number, status, error, started_at, finished_at
)
SELECT j.id, 1, 'failed', 'worker restarted',
       j.started_at, CURRENT_TIMESTAMP
FROM jobs AS j
WHERE j.status = 'running'
  AND NOT EXISTS (
    SELECT 1 FROM job_attempts AS a WHERE a.job_id = j.id
  );

UPDATE jobs
SET status = 'failed',
    error = 'worker restarted',
    finished_at = CURRENT_TIMESTAMP
WHERE status = 'running';

External links

Exercise

lease가 아직 유효한 작업을 훔치지 않으면서 죽은 worker를 복구하는 startup 절차를 써.
Hint
crash 위치를 하나씩 옮겨가며 데이터가 남는지 봐.

Progress

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

댓글 0

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

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