본문 바로가기
C.W.K.
Stream
Lesson 01 of 04 · published

배달은 적어도 한 번, 의도는 정확히 한 번

~12 min · distributed-systems, at-least-once, idempotency, reliability

Level 0신호 없음
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"네트워크가 정확히 한 번 배달하게 만들 순 없어. 두 번 도착한 같은 배달이 한 번의 뜻만 갖게 만들 순 있어."

네트워크에 관한 불편한 진실

튼튼한 클라이언트라면 언젠가는 마주치는 사실이 있어. 불안한 네트워크 위에서는 정확히 한 번 배달을 얻어낼 수가 없다는 거. 더 열심히 한다고 되는 문제가 아냐. 고전적인 함정이 이래. 요청이 백엔드에 닿고, 백엔드가 처리하고, 그다음 응답이 돌아오다가 떨어져. 폰 입장에선 요청이 실패한 거야. 근데 아니지. 확인만 못 받은 거고. 여기서 클라이언트가 재시도하면 백엔드는 같은 요청을 두 번째로 보게 돼. 배달은 적어도 한 번이야. 메시지가 0번 올 수도, 한 번 올 수도, 여러 번 올 수도 있는데 클라이언트는 바깥에서 그 차이를 알아낼 방법이 없어.

보장을 한 층 위로 올려

배달을 못 고치니까 의미를 고치는 거야. 목표는 정확히 한 번 배달이 아냐. 그건 불가능하고. 정확히 한 번 의도야. 요청이 물리적으로 몇 번을 도착하든 효과는 한 번만 나게 하는 거. 그게 멱등성이 사주는 거고. 몇 번을 적용해도 한 번 적용한 거랑 결과가 같은 연산 말이야. 재시도가 안전해지는 건 반복이 안 일어난다고 보장해서가 아니라, 반복이 무해해서야.

  • 배달 층. 불안하고, 적어도 한 번이고, 네 손 밖이야. 그냥 받아들여.
  • 의도 층. 믿을 만하고, 정확히 한 번이고, dedupe 키만 있으면 온전히 네 손안이야. 여길 만들어.

이 트랙 전체가 이 생각의 전환에 걸려 있어. 선 위에서 중복을 막으려고 하지 마. 중복이 상관없어지게 만드는 쪽으로 가.

왜 이게 마음 놓고 재시도할 자유를 주나

중복이 무해해지면 재시도가 안 무서워져. 재연결될 때 다시 보내고, 앱 켤 때 다시 보내고, 사용자가 탭할 때 다시 보내. 신뢰성이 필요하다는 만큼 자주. 의도 층이 그 도착들을 전부 효과 하나로 접어 주니까. 재시도를 무서워하는 클라이언트는 결국 덜 해주게 돼. 안전하자고 그냥 버리거든. 멱등한 의도를 가진 클라이언트는 넉넉히 재시도하면서도 두 번 행동하는 법이 없고. 다음 레슨들이 이걸 진짜로 만들어 줄 dedupe 키를 만들어. device turn ID 야.

Code

정확히 한 번 배달을 불가능하게 만드는 ack 떨굼 함정·text
폰                            백엔드
  |  --- ask (turn X) ------->  |
  |                            |  X 처리, 답함
  |  X    응답 -------------- |   <-- 전송 중 떨궈짐
  |  (실패로 봄)               |
  |  --- ask (turn X) 다시 --> |   <-- 같은 의도가 두 번 도착
  |                            |  X 를 알아봐야 함, 다시 하면 안 됨

// 폰은 '요청 잃음'이랑 '응답 잃음'을 구분 못 해.
// 그래서 재시도해. turn X 의 dedupe 키만이 효과를 정확히 한 번으로 지켜.

External links

Exercise

ack 이 떨어지는 시나리오를 단계별로 적어 봐. 요청 성공, 응답 유실, 클라이언트 재시도. 단계마다 폰은 뭘 믿고 있고 백엔드는 뭘 믿고 있는지 써. 그다음 폰 쪽에서 재시도를 아무리 손보고 타임아웃을 아무리 조절해도 왜 배달이 정확히 한 번이 안 되는지, 그리고 대신 어떤 장치 하나가 의도 층에서 그걸 해결하는지 설명해. 힌트는 안 바뀌는 키야.
Hint
폰이랑 백엔드가 어긋나는 이유는 딱 하나야. 첫 시도가 성공했다는 걸 폰이 못 들었거든. 타임아웃으로는 그 어긋남을 못 풀어. 두 번째로 도착했을 때 백엔드가 알아볼 수 있는 공유 dedupe 키라야 풀려. 그 키가 device turn ID 고.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.