Q.at-least-once와 exactly-once 중 무엇을 선택하시겠어요? 판단 근거를 설명해주세요
at-least-once 를 고르고 소비자를 멱등하게 만듭니다. 대부분의 실무 선택입니다.
| 보장 | 의미 | 대가 |
|---|
| at-most-once | 중복은 없지만 유실 가능 | 유실을 감수한다 |
| at-least-once | 유실은 없지만 중복 가능 | 소비자가 중복을 걸러야 한다 |
| exactly-once | 정확히 한 번 | 범위가 제한되고 비용이 크다 |
이유는 exactly-once 가 브로커와 소비자 사이의 특정 조건에서만 성립하기 때문입니다. 외부 API 호출이나 다른 DB 쓰기가 끼면 보장이 깨집니다.
그리고 중복 처리는 해결 방법이 명확합니다. 처리 키를 저장하고 이미 처리한 것을 건너뛰면 됩니다. 유실은 그런 사후 대응이 없습니다. 한 번 사라진 메시지는 복구할 방법이 없습니다.
at-most-once 를 고르는 경우도 있습니다. 실시간 위치 정보나 지표 수집처럼 다음 값이 곧 오는 데이터는 하나 잃어도 상관없고, 중복 처리 비용을 아끼는 편이 낫습니다.
흔한 실수: exactly-once 를 지원하는 브로커라 중복 처리를 안 해도 된다고 답하는 것. 그 보장이 어디까지 미치는지 확인해야 합니다.
Q.Kafka의 exactly-once가 외부 결제 API 호출까지 보장하지 못하는 이유는?
Kafka 의 보장은 읽기와 쓰기가 모두 Kafka 안에서 일어날 때 성립합니다. 소비한 오프셋 커밋과 결과 메시지 발행을 하나의 트랜잭션으로 묶는 방식이기 때문입니다.
외부 API 호출은 그 트랜잭션에 들어올 수 없습니다.
| 순서 | 상황 |
|---|
| 1 | 메시지를 소비한다 |
| 2 | 결제 API 를 호출한다. 성공했다 |
| 3 | 오프셋 커밋 전에 프로세스가 죽는다 |
| 4 | 재시작하면 같은 메시지를 다시 받는다 |
| 5 | 결제를 다시 호출한다 |
2번은 이미 되돌릴 수 없습니다. 외부 시스템은 우리 트랜잭션을 모릅니다.
| 해결 | 내용 |
|---|
| 외부 API 에 멱등 키 | 같은 키의 요청을 상대가 걸러낸다 |
| 우리 DB 에 처리 이력 | 호출 전에 기록하고, 이미 있으면 건너뛴다 |
| 상태 조회 | 호출 전에 상대에게 그 건의 처리 여부를 묻는다 |
첫 번째가 가장 확실합니다. 그래서 결제 API 들은 대개 멱등 키를 받습니다.
흔한 실수: 브로커의 exactly-once 를 종단 간 보장으로 읽는 것. 경계를 넘는 순간 보장은 끝납니다. 외부와 닿는 지점마다 멱등성을 따로 만들어야 합니다.
Q.오프셋 커밋을 처리 전에 하도록 바꾸면 어떤 문제가 생기나요?
처리 중에 죽으면 그 메시지는 사라집니다. 커밋된 오프셋 뒤부터 다시 읽기 때문입니다.
| 커밋 시점 | 죽었을 때 | 보장 |
|---|
| 처리 전 | 그 메시지를 잃는다 | at-most-once |
| 처리 후 | 그 메시지를 다시 받는다 | at-least-once |
처리 전 커밋이 나쁜 이유는 유실이 조용하다는 것입니다. 오류 로그도 없고 지표도 정상입니다. 나중에 데이터가 비어 있는 것을 발견하지만 어느 메시지였는지 알 수 없습니다.
자동 커밋을 쓰면 의도하지 않게 이 상태가 됩니다. 일정 간격으로 백그라운드에서 커밋하므로, 아직 처리하지 않은 메시지의 오프셋이 커밋될 수 있습니다.
| 안전한 구성 | 내용 |
|---|
| 자동 커밋을 끈다 | 처리 완료 후 명시적으로 커밋 |
| 묶음 처리라면 | 묶음 전체 처리 후 마지막 오프셋을 커밋 |
| 실패 시 | 커밋하지 않고 재시도하거나 실패 큐로 보낸다 |
흔한 실수: 처리 전 커밋을 성능 개선으로 여기는 것. 커밋 비용이 병목인 경우는 드물고, 필요하면 묶음 단위 커밋으로 횟수를 줄이는 편이 안전합니다.
Q.메시지 유실을 감수해도 되는 데이터는 어떤 기준으로 판단하나요?
다음 값이 곧 오는지, 없어진 것을 알아챌 수 있는지로 봅니다.
| 감수 가능 | 이유 |
|---|
| 실시간 위치, 센서 값 | 1초 뒤 다음 값이 온다 |
| 지표와 통계 표본 | 표본이 하나 빠져도 결론이 바뀌지 않는다 |
| 캐시 무효화 알림 | 만료 시간이 대신 처리한다 |
| 화면 갱신 알림 | 사용자가 새로고침하면 된다 |
| 감수 불가 | 이유 |
|---|
| 결제, 정산 | 돈이 움직인다 |
| 주문 상태 변경 | 다음 값으로 덮이지 않는다 |
| 재고 차감 | 누적 계산이라 하나 빠지면 계속 어긋난다 |
| 감사 로그 | 없어진 것을 증명할 수 없다 |
기준이 하나 더 있습니다. 누적 계산인지 최신값 덮어쓰기인지입니다. 재고 차감처럼 이전 값에 더하는 방식은 하나를 잃으면 영구히 어긋나지만, 위치 정보처럼 최신값으로 덮는 방식은 다음 값이 복구해 줍니다.
흔한 실수: 중요도로 판단하는 것. 중요한 지표도 표본 하나쯤은 잃어도 되고, 사소해 보이는 재고 이벤트는 하나도 잃으면 안 됩니다. 데이터의 성격이 기준입니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
메시징 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.