Skip to content
isdnetworks
Go back

원인을 확정한 시각 뭉침

(수정됨)

resend:products 대량 재전송 작업을 웨이브로 나눠 수십 개 웨이브에 걸쳐 수만 건을 사고 없이 처리했다. 그러고 나서 이어 돌린 다음 배치에서 처음으로 사고가 났다.

Table of contents

Open Table of contents

배경 — 응답과 다른 실제 상태

배치를 아홉 청크로 나눠 보냈는데 전부 200 이고 응답의 failed 목록도 비어 있었다. 응답만 놓고 보면 아무 문제도 없어 보이는 결과였고 그대로 넘어갈 수 있는 상황이었다.

응답을 믿지 않고 channel_products.status 를 되읽어 보니 수십 건 중 삼분의 일이 OFF_SALE 로 전환돼 있었다. 이 사후 검사를 안 했으면 이 배치도 아무 표시 없이 완료로 넘어갔을 것이다.

검증 — 인과를 확정할 근거

여기서 전송 직후에 전환됐다는 것과 전송이 전환시켰다는 것은 서로 다른 얘기다. 우연히 그 시간대에 전혀 다른 이유로 전환됐을 가능성도 남아 있었다.

전송 전 스냅숏을 떠 놓지 않았으므로 전후를 비교할 대상 자체가 없었다. 두 가지 방법이 있었는데 채널 쪽에 문의해 그쪽 로그를 받는 것과 우리 쪽 updated_at 분포로 판별하는 것이다. 뒤쪽을 골랐다. 이유는 채널 문의는 며칠이 걸리고 그동안 배치를 세워 둬야 해서다. 대신 채널 쪽 원인은 이 방법으로 못 보는 것을 감수했다. 전환된 건들의 updated_at 을 전부 조회해서 그 분포가 어떤 모양인지를 봤다.

원인 — 분포가 가른 것

그 삼분의 일의 updated_at 이 1분이 안 되는 구간에 순차적으로 몰려 있었고 sent_at 이 바로 그 직전이었다. 개별 상품의 사유로 전환된 것이라면 그 시각이 여기저기 흩어져 있어야 한다.

짧은 구간에 순차로 몰린 분포는 개별 사유로 나올 수 없으므로 군집 하나로 전송 기인성이 확정됐다. 사전 스냅숏이 없어도 갱신 시각은 어차피 있으므로 이 판별은 언제든 쓸 수 있다.

주의 — 실적이 보장하지 않는 안전

이 사고에서 얻은 교훈이 하나 더 있었는데 실적에 관한 것이었다. 앞선 수십 개 웨이브가 전부 무사고였는데 이 배치에서는 삼분의 일이 OFF_SALE 로 전환됐기 때문이다.

누적 실적이 안전을 보장하지 않는다는 뜻이므로 웨이브 전체 무사고 실적을 다음 배치의 안전 근거로 삼지 않기로 했다. 매 배치마다 사후 검사를 하고 지금까지 괜찮았으니 이번도 괜찮으리라는 판단을 쓰지 않는다.

조치 — 완료로 표시하지 않기

사고를 발견하고 즉시 중단하면서 그 배치의 wave_no 태깅까지 함께 보류해 뒀다. 태깅하면 처리 완료로 표시돼 재처리 대상에서 빠져 버리기 때문이다.

전송이 원인이라는 것은 확정됐지만 왜 그렇게 되는지는 미확정으로 뒀다. 자체 교정 루프와 외부 삭제로 인한 전환 오류와 extend:sale 미동작 세 가설의 시그니처가 비슷해서 셋을 배제하기 전에는 원인을 단정하지 않기로 했고 전환된 건들의 product_id 범위가 다른 배치보다 넓다는 관측도 단정 없이 INCIDENT.md 에 단서로 기록했다.

정리


Share this post on:

Previous Post
드롭다운에서 조용히 사라지는 항목
Next Post
상태 변경 하나가 만든 수만 건