S3 삭제 감사 로그 유실 — append 동시성과 FIFO SQS
S3 버킷에 쌓인 파일을 오래되면 자동으로 지우도록 라이프사이클 규칙을 걸어뒀습니다. 그런데 “무엇이 언제 지워졌는지” 는 어딘가 남겨둬야 나중에 확인할 수 있습니다. 그래서 파일이 삭제될 때마다 그 기록을 구글 스프레드시트에 한 줄씩 남기는 감사(audit) 파이프라인을 만들었습니다.
구조는 AWS 서비스 몇 개를 이어 붙인 형태입니다.
- S3 라이프사이클 이 오래된 파일을 삭제하면,
- EventBridge(AWS 이벤트 버스)가 그 삭제 이벤트를 잡아,
- SQS(메시지 큐)에 넣고,
- Lambda(이벤트로 실행되는 함수)가 그 메시지를 받아 스프레드시트에 한 줄을 덧붙입니다(append).
어느 날 보니 32개가 삭제됐는데 시트엔 25줄만 있었습니다. 7개가 사라진 겁니다.
모든 단계 지표는 32로 정상
각 단계를 다 확인했는데 어디도 이상이 없었습니다.
| 단계 | 수 |
|---|---|
| EventBridge 매칭 | 32 |
| SQS sent / received / deleted | 32 |
| Lambda invocation | 32 |
| Lambda error | 0 |
| 시트 최종 | 25 |
메시지도 안 잃고, Lambda 도 다 돌았고, 에러도 0 인데 시트만 모자랍니다.
원인 — 컨테이너 재사용 + append의 동시성 한계
스트림별 Lambda 로그를 뜯어보니, 한 실행 안에서 Appended row 가 두 번
찍힌 게 있었습니다. Lambda 컨테이너 재사용으로 거의 동시에 두 append 호출이
나갔습니다.
그리고 Google Sheets 의 append 에는 문서화된 한계가 있습니다. 동시에
들어온 append 들이 같은 셀 범위를 잡아 서로 덮어씁니다. “다음 빈 줄” 을 각자
계산하는데, 동시에 계산하면 같은 줄을 가리켜 하나가 다른 하나를 밀어냅니다.
그래서 호출은 다 성공했는데 결과 줄만 모자랍니다. 에러가 없으니 지표론 안
잡힙니다.
해결 — FIFO SQS로 직렬화
동시성이 문제니 처리를 직렬화하면 됩니다. Standard SQS 를 FIFO 로 바꾸고,
모든 메시지에 같은 MessageGroupId 를 줬습니다.
MessageGroupId를 하나로 고정 → 그 그룹은 한 번에 하나씩만 처리- Lambda 배치 크기 1 → 한 번에 한 건
EventBridge 도 SQS FIFO 타겟을 지원해서(SqsParameters 의 MessageGroupId),
파이프라인 구조를 크게 안 바꾸고 직렬화만 걸 수 있었습니다. 이후로 32개가
빠짐없이 기록됐습니다.
지표는 정상인데 결과가 모자랄 때 — 동시 덮어쓰기
“모든 단계 지표가 정상인데 최종 결과만 모자란다” 면 동시에 들어와 서로 덮어쓴 것 를 의심합니다. 호출이 다 성공해도, 그 호출들이 같은 자원(여기선 시트의 다음 빈 줄)을 동시에 잡으면 결과가 유실됩니다. 에러가 안 나니 지표로는 안 보입니다. 순서가 중요한 append 성 작업은 FIFO 큐 + 단일 MessageGroupId 로 직렬화하는 게 확실합니다. 병렬로 빨리 처리하는 것보다, 겹치지 않게 하는 게 목적일 때가 있습니다.
댓글 0