이 노트는 중단 알림을 복구의 전제조건이 아니라 최적화된 정리 기회로 취급합니다. 실제 복구 가능성은 알림의 도착 여부가 아니라 내구 checkpoint, 재실행 시 같은 논리 작업을 식별하는 키, 늦은 worker의 쓰기를 막는 소유권 전환에 달려 있습니다.
중단 알림과 작업 생존 보장의 분리
Spot 중단 통지가 도착하면 새 작업 수락을 멈추고 진행 중인 작업을 checkpoint하거나 끝낼 시간을 확보할 수 있습니다. 하지만 통지 경로가 실패하거나 남은 시간이 부족할 수 있으므로, 통지가 전혀 없는 갑작스러운 노드 손실에서도 같은 작업을 재전달해 복구하는 경로가 필요합니다. Karpenter의 interruption 처리와 node drain은 앱의 원장과 메모리 세션을 자동으로 복원하지 않으므로, 복구 가능한 상태를 별도로 내구 저장해야 합니다.
heartbeat timeout, Node 상태, broker 재전달, 중단 이벤트는 각각 다른 경로에서 작업 손실을 알려 주므로 하나의 신호만 확정 증거로 사용하지 않습니다. heartbeat timeout은 옛 worker가 죽었다는 뜻이 아니라 통신만 끊긴 상태일 수도 있어, 새 owner가 작업을 맡을 때 세대 번호를 비교하고 이전 owner의 늦은 쓰기를 막는 fencing을 적용해야 합니다.
중단 알림은 “지금 정리할 시간이 있을 수 있음”을 알려 주는 신호이고, heartbeat·broker 재전달은 “현재 owner가 계속 책임지는지 불확실함”을 알려 주는 신호입니다. 새 owner가 작업을 맡을 때 lease나 generation을 갱신하고 옛 owner의 늦은 checkpoint·효과를 거절해야 두 신호가 서로 다른 순서로 도착해도 안전합니다.
Job 성공 상태와 외부 효과의 분리
Pod가 DB에 포인트를 지급하고 exit 0·Job 완료가 관찰되기 전에 노드가 사라지면 다시 실행될 수 있습니다. restartPolicy에 따라 같은 Pod의 컨테이너 재시작 또는 새 Pod 시도가 생길 수 있고, Job의 backoffLimit·activeDeadlineSeconds·실패 정책은 실행 수명을 다룹니다. 외부 지급을 정확히 한 번으로 만들지는 않습니다.
논리 작업 ID는 제출할 때 한 번 만들고 Job 재시도에서도 그대로 전달해야 합니다. 예를 들어 worker가 재시도마다 새 UUID를 만들면 같은 지급을 두 작업으로 보아 중복 처리할 수 있으므로, 처리 마커·원장 변경·결과를 같은 DB 거래로 확정합니다. 외부 API를 호출해야 한다면 그 API에는 별도 멱등 키와 결과 조회 계약을 사용하고, CronJob의 동시 실행 정책만으로 모든 중복 제출이나 외부 효과가 사라진다고 가정하지 않습니다.
재실행 추적은 제출 시 만든 논리 작업 ID가 모든 Pod 시도에 같은지부터 확인합니다. effect key를 DB marker와 업무 원장 변경에 같은 거래로 묶으면 첫 시도가 효과 후 죽고 두 번째 시도가 다시 들어와도 두 번째는 이미 처리된 경계를 식별할 수 있습니다. Job complete나 exit 0은 이 외부 효과의 정확히 한 번을 대신 증명하지 않습니다.
Checkpoint의 안전한 확정 위치 의미
| 기록 순서 | 중단 결과 | 필요한 수정 |
|---|---|---|
| checkpoint 먼저, 효과 나중 | 진행 위치만 앞서 누락 | 같은 거래 또는 안전한 상태 전이 |
| 효과 먼저, checkpoint 나중 | 재개 때 중복 효과 | 안정된 effect key·결과 조회 |
| 효과와 위치를 원자 확정 | 해당 경계의 안전한 재개 | 외부 저장소는 별도 대사 |
100개씩 처리해 checkpoint를 기록하는 예에서 250개 효과를 반영한 뒤 중단하고 안전 위치는 200이라면 201부터 다시 확인합니다. 201~250은 이미 반영됐을 수 있으므로 같은 효과 키로 중복 적용하지 않아야 합니다. 처리량·항목 비용이 다르면 단순 항목 수뿐 아니라 바이트·시간·외부 비용도 재작업 예산에 넣습니다.
그림을 글로 읽기
- 안전 checkpoint 읽기
- 범위 작업·멱등 효과
- 효과·진행 위치 확정
- 다음 범위 또는 완료
- 안전 checkpoint 읽기 → 범위 작업·멱등 효과: 같은 입력·버전
- 범위 작업·멱등 효과 → 효과·진행 위치 확정: 원자 경계
- 효과·진행 위치 확정 → 다음 범위 또는 완료: 내구 성공 확인
250개까지 효과가 반영되었지만 checkpoint가 200인 상태를 재개할 때, 201~250을 단순히 건너뛰면 유실 위험이 있고 무조건 새 효과로 다시 적용하면 중복 위험이 있습니다. 따라서 재개 범위는 effect key로 멱등 확인하고, checkpoint·marker·효과가 같은 원자 경계인지에 따라 복구 절차를 정합니다. 입력 snapshot이 달라졌다면 같은 cursor라도 같은 작업이 아니므로 version도 비교해야 합니다.
기록 주기와 비용·복구 지연의 균형
고정 비용 checkpoint가 c초이고 작업 간격이 T초라면 기록 비중은 단순 모형에서 대략 c/T에 관련됩니다. 중단이 균등하게 발생한다는 추가 가정 아래 평균 재작업은 대략 T/2이지만 실제 장애·작업 비용·동기 기록은 이 가정을 깨뜨릴 수 있습니다. 보편 최적 주기로 쓰지 말고 최대 허용 재작업·기록 비용·입력 보관 기간으로 정합니다.
checkpoint에는 입력 snapshot·cursor·스키마 버전·논리 작업 ID·결과를 재구성할 충분한 상태가 있어야 합니다. 원본이 삭제되거나 바뀌면 위치만 남아도 재개할 수 없습니다. 기록 자체가 부분 노출되지 않도록 원자 게시·검증·보관을 적용합니다.
통지 이후 잔여 시간 내 종료
새 fetch·새 세션 수락을 막고 현재 작업을 끝낼지 checkpoint 후 재전달할지 결정합니다. 효과를 확정하기 전에 ACK하면 노드 손실로 작업이 사라질 수 있습니다. 효과 후 ACK 유실은 정상적인 중복 전달 경로로 처리합니다. 알림 유예와 Pod grace를 별도의 무한 시간처럼 더하지 않습니다.
게임은 큐 항목과 달리 현재 틱·입력·소유자·메모리 상태를 복구해야 합니다. snapshot·입력 재생·마지막 승인 위치·owner 전환으로 새 서버를 정하고 옛 서버의 늦은 결과를 거절합니다. 메모리 전체를 짧은 통지 시간 안에 항상 옮길 수 있다고 가정하지 않습니다.
Spot 손실 이후 핵심 용량의 결정
평소 총 replica가 충분해도 Spot이 상관되어 회수되면 핵심 용량이 부족할 수 있습니다. on-demand·다른 영역에 유지할 최소 처리량과 비핵심 지연·거절 정책을 계산합니다. on-demand도 모든 영역 장애나 클라우드 capacity 부족을 없애는 것은 아니므로 독립 영역과 실제 공급 지연을 고려합니다.
후보 인스턴스 다양성·비용 상한·warm 용량을 정하고 대체 노드 준비가 drain 시간보다 길면 사전 여유가 필요합니다. 비용 절감에는 재작업·재접속·운영 복구 비용까지 포함합니다.
알림 유무·Commit 위치별 재개 검증
테스트 환경에서 통지 있음·없음·대체 capacity 없음·효과 후 checkpoint 전 중단·ACK 전 중단·중복 Job을 나눕니다. 재개 위치·최종 효과 수·유실 범위·복구 시간·핵심 SLO를 확인합니다. 현재 작업에서는 Spot·Kubernetes Job 중단을 실행하지 않았으며 본문은 내구 실행과 용량 설계입니다.
최소 판정표에는 통지 도착/미도착, 효과 전·후, checkpoint 전·후, ACK 전·후, 중복 Job을 행으로 둡니다. 각 행에서 최종 효과 수가 논리 작업 수와 일치하는지, 재개 위치가 안전 경계인지, 옛 owner의 쓰기가 거절되는지 확인합니다. 실제 Spot·Kubernetes 환경을 이 작업에서 실행하지 않았으므로 공급 지연이나 grace 기간 수치는 검증 결과로 제시하지 않습니다.