대량 재전송을 100건씩 나눠 돌렸다. 웨이브마다 몇 건씩 실패해서 그때마다 로그를 조회해 사유를 분류했다.
Table of contents
Open Table of contents
결과 — 다섯으로 모인 사유
몇 웨이브를 돌리니 사유가 모였다.
카테고리와 옵션 매핑 불일치 가장 빈번
카테고리 코드 무효
옵션명 중복
상품 옵션 정보 없음
무음 스킵
무음 스킵 까지 다섯 종이 반복해서 나오고 새 사유가 더 나오지 않았다.
새로운 것이 안 나온다는 것 자체가 정보였다. 남은 웨이브에서도 이 다섯 안에서 실패할 것이라고 볼 수 있게 된다.
비율이 안정적이었다
실패율도 세어 봤다.
100건 웨이브 기준 2~3%
100건 짜리 웨이브마다 비슷하게 나왔다.
[비율을 모름] 얼마나 걸릴지 모름
[2~3%] 웨이브당 2~3건의 판정·원복
비율이 정해지면 남은 작업량을 미리 계산할 수 있다.
100건 웨이브를 열 번 돌리면 20건에서 30건의 후속 작업이 나온다는 뜻이다. 그만큼의 시간을 일정에 미리 넣어 둘 수 있게 됐다.
조치 — 사유별 사전 게이트
사유가 다섯으로 정해지니 미리 거를 수 있는 것이 보였다.
[전송 후 실패] 실패 처리 → 원복 → 재작업
[사전 게이트] 대상에서 미리 제외
각 사유를 전송 전에 확인 가능한 조건으로 바꾸면 된다.
카테고리 코드 무효 → 코드 유효성 사전 확인
옵션 정보 없음 → 옵션 존재 확인
옵션명 중복 → 중복 검사
카테고리 코드 무효 부터 옵션명 중복 까지 넷은 우리 쪽 자료만으로 판정할 수 있었다.
미리 거르면 보내는 건수가 줄고 상대 쪽 부담도 준다. 다만 그 조건이 틀리면 보낼 수 있는 건까지 빠지므로 거른 건수를 따로 세어 실패했을 수와 맞는지 대조했다.
다섯째가 달랐다
무음 스킵만 성격이 달랐다.
배치 호출은 200으로 수락
실패 목록도 비어 있음
그런데 생성 작업 자체가 안 만들어짐
200 을 받았는데 아무것도 안 생긴다.
[다른 넷] 작업이 생기고 실패 → 실패 로그가 남음
[무음 스킵] 작업이 안 생김 → 로그가 없음
stuck_reason 을 채우는 조회로는 이 종류가 잡히지 않는다.
앞서 정리한 것과 같은 모양이다. 오류는 목록에 남고 미발생은 아무 데도 안 남는다.
검증 — 건수 대조
없는 것을 찾으려면 다른 방법이 필요했다.
전송한 대상 목록
vs
실제로 생성된 작업 목록
보낸 COUNT(*) 와 생성된 COUNT(*) 를 맞춰 보면 그 차이가 무음 스킵 이다.
[로그 기반] 실패한 것을 찾음
[건수 대조] 없어진 것을 찾음
두 방법이 서로 다른 것을 잡으므로 로그만 보면 다섯 중 넷만 보인다.
분류한 사유는 작업 표에 컬럼을 두고 웨이브마다 기록했다.
UPDATE tracking SET stuck_reason = ? WHERE product_id = ?;
stuck_reason 을 쌓아 두니 분포를 볼 수 있게 됐다.
SELECT stuck_reason, COUNT(*) FROM tracking
WHERE stuck_reason IS NOT NULL GROUP BY 1;
기록하지 않고 웨이브마다 로그만 봤으면 사유가 다섯인지 열인지 몰랐을 것이다. 한 웨이브의 실패는 흩어져 보이고 열 웨이브의 실패는 분포를 만든다.
대응 — 재개 지점을 조건으로
여러 웨이브를 돌리니 어디부터 다시 할지가 필요해졌다.
SELECT product_id FROM tracking t
JOIN products p ON p.id = t.product_id
WHERE t.sent_at IS NULL
AND t.rollback_at IS NULL
AND t.stuck_reason IS NULL
AND p.status = 'normal'
ORDER BY t.product_id
LIMIT 100;
sent_at 과 rollback_at 과 stuck_reason 과 status 네 조건이 남은 대상을 고른다.
[진행 번호로] 어디까지 했는지 기억해야 함
[조건으로] 테이블이 상태를 갖고 있음
조건이 상태를 표현하니 중간에 멈춰도 같은 쿼리로 이어지고 stuck_reason 이 채워진 건은 자동으로 빠진다.
ORDER BY 를 넣은 것은 실행마다 순서가 달라지지 않게 하려는 것이었다. 순서가 고정되면 같은 대상이 같은 묶음에 들어가고 문제가 생겼을 때 어디까지 갔는지가 확실해진다.
확인된 실패건을 전량 원복할 수 있다는 것이 이 방식의 전제였다. 원복이 되니 웨이브를 계속 돌릴 수 있었고 그렇지 않았으면 한 건의 실패가 사고가 됐을 것이다.
정리
- 반복 실행하며 분류하니 실패 사유가 다섯으로 수렴했다
- 새 사유가 안 나온다는 것 자체가 정보다
- 비율이 안정적이면 후속 작업을 일정에 미리 넣을 수 있다
- 사유가 정해지면 사전 게이트로 미리 거를 수 있다
- 거른 건수를 실패했을 수와 대조해 그 조건을 검증한다
- 한 종류는 작업이 안 생겨 로그에 안 남는다
- 보낸 건수와 생성된 건수를 대조해야 잡힌다
- 로그 기반과 건수 대조가 서로 다른 것을 잡는다
- 사유를 누적 기록해야 수렴이 보인다
- 재개 지점을 조건으로 정의하면 중간에 멈춰도 이어진다
- 원복이 되는지가 얼마나 빠르게 진행할지를 정한다