251. 3단계 커밋 (3PC, Three-Phase Commit) - 2PC의 블로킹 한계 보완 분산 트랜잭션 Pre-Commit 단계 추가 코디네이터 단일 장애점 완화
핵심 인사이트: (249번 2PC의 무한 블로킹을 막으려던 발악) "야 ㅆㅂ! 2PC 쓰니까 사령관(코디네이터) 놈이 중간에 심장마비로 뒈지면, 밑에 병사(참여자) 100만 명이 자물쇠(Lock) 꽉 쥔 채로 사령관 살아날 때까지 영원히 멈춰버리는(무한 블로킹) 끔찍한 일이 터지잖아!! 왜 멈추는지 알아?! 사령관이 죽었을 때 병사들이 서로 모여서 '야 넌 방금 사령관한테 뭔 얘기 들었어? COMMIT이래, 취소래?' 하고 서로의 상태를 몰라서 눈치 보느라 자물쇠를 못 푸는 거야!! 그래서 1단계(준비)랑 2단계(확정) 사이에 얇은 스펀지 '1.5단계(Pre-Commit 사전 확정)'를 하나 억지로 끼워 넣어(3단계로 찢음)!! 병사들이 '준비 완료(Ready)'를 쏘고 나면 사령관이 '오케이, 다들 준비됐으니까 이제 우리끼리 5초 뒤에 도장(Commit) 찍기로 미리 약속(Pre-Commit)하자!' 라고 중간 힌트 메시지를 싹 다 한 번씩 뿌려둬!! 그럼 그 5초 사이에 사령관이 뒈져도, 병사들끼리 '야 아까 사령관이 Pre-Commit 힌트 줬잖아! 사령관 죽었지만 그냥 우리끼리 다 같이 COMMIT 때려버리자!!' 라며 무한 대기 안 타고 스스로 살아남을 구멍을 만들 수 있잖아!!" 사령관의 죽음을 대비해 병사들에게 미리 정답 힌트를 찔러주어 블로킹을 우회하려 한 꼼수, 3단계 커밋(3PC)이다.
Ⅰ. 2PC의 절대적 단점 복습 (무한 대기 Blocking)
- 2PC의 2단계에서 코디네이터(사령관)가 "너네 전부
Ready했네? 좋아COMMIT갈겨!"라고 마음먹고 아직 무전을 치기 0.1초 전에 죽어버립니다. - 참여자 병사들은 자물쇠(Lock)를 쥐고 있습니다. 사령관이 죽었으니 명령이 안 옵니다. 병사들은 지 맘대로
COMMIT할까요ROLLBACK할까요? 사령관이 속으로 무슨 생각을 하고 죽었는지 알 길이 없으니 맘대로 행동했다간 1놈은 커밋, 1놈은 롤백 되어 DB 데이터 모순(원자성 파괴)이 터집니다. - 결국 병사들은 사령관이 부팅되어 살아날 때까지 영원히 자물쇠를 풀지 않고 무한 대기(Blocking)를 탑니다. 시스템 폭파.
Ⅱ. 3단계 커밋 (3PC, Three-Phase Commit)의 개념 🌟
- 1981년 Dale Skeen이 고안한 프로토콜입니다.
- 개념: 2PC의 치명적인 '무한 블로킹(Blocking)' 현상을 줄이기 위해, 기존 2단계 구조 한가운데에 '사전 커밋(Pre-Commit)'이라는 중간 버퍼 단계를 하나 추가하여 총 3단계(준비 ➜ 사전 확정 ➜ 최종 확정)로 쪼개어, 코디네이터가 죽었을 때 참여자들이 스스로 상태를 유추해 락을 풀고 빠져나갈 수 있게 만든 타협형 합의 프로토콜입니다.
Ⅲ. 3PC의 작동 3단계 페이즈 🌟 핵심 🌟
가운데에 이정표(힌트)를 하나 더 세우는 것이 핵심입니다.
- Phase 1 (CanCommit / 투표 단계):
- 사령관: "야 너네 엑셀 칠 준비됐어?" / 병사들: "네! 준비 완료!(Yes)"
- Phase 2 (PreCommit / 사전 확정 단계) 🌟 추가된 1.5단계 마법 🌟:
- 2PC라면 여기서 바로 쇳덩어리에 "덮어써(Commit)!" 라고 갈겼을 겁니다.
- 3PC는 다릅니다. 사령관은 병사들 모두가
Yes를 외친 걸 확인한 후, 바로 확정 도장을 찍으라고 명령하지 않습니다. 대신 "오케이 100명 다 Yes 외친 거 확인했음! 이제 우리 5초 뒤에 덮어쓸(Commit) 거니까 마음의 준비 딱 하고 대기 타라! (Pre-Commit 힌트 발송)" - 병사들은 이 Pre-Commit 힌트 무전을 받으면 "아하, 딴 놈들도 다 Ready 해서 사령관님이 곧 Commit 명령을 내리겠구나!"라는 '글로벌 상태(분위기)'를 눈치채고 확신하게 됩니다.
- Phase 3 (DoCommit / 최종 확정 단계):
- 사령관: "자 이제 진짜 덮어써(Do Commit)!" / 병사들: "도장 쾅!"
Ⅳ. 왜 이게 마법인가? (사령관 암살 시나리오 대처법)
- 가장 위험한 순간인 2단계(PreCommit) 무전을 치고 3단계(DoCommit) 명령을 내리기 찰나의 1초! 이때 사령관이 심장마비로 뒈졌습니다!
- 병사들은 사령관을 무한정 기다릴까요(Blocking)? 아닙니다!
- 병사들 100명이 서로 텔레파시 핑퐁을 칩니다. "야, 너 방금 사령관 죽기 전에 무슨 무전 들었어?" "어 나 아까
Pre-Commit힌트 무전 들었는데? 너도?" "오 나도!" - 기적의 결과: 병사들은 "아! 사령관이 죽기 직전에 이미 우리 100명 모두가
Yes라고 대답한 걸 다 취합해서 알고 있었고, 그래서Pre-Commit힌트를 날린 거였구나! 그럼 사령관 명령 안 기다리고 그냥 우리끼리 합의해서 다 같이 Do Commit 때려버리자!!" 라며 스스로 무한 대기 늪을 빠져나와 자물쇠를 풀고 우주를 구원해 냅니다.
Ⅴ. 3PC의 비참한 최후 (왜 실무에서 안 쓸까?)
- 이론상으론 데드락(블로킹)을 푼 천재적 묘수였지만, 현실의 구름(클라우드 네트워크)은 미치도록 척박합니다.
- 사령관이 병사들에게
Pre-Commit무전을 치는 도중 네트워크가 두 동강(네트워크 파티션 장애) 나서, 병사 50명은Pre-Commit힌트를 듣고 50명은 못 들은 채로 사령관이 뒈졌습니다. - 들은 50명은 지들끼리 으쌰으쌰해서 엑셀에
COMMIT도장을 쳤는데, 못 들은 50명은 쫄아서 엑셀을ROLLBACK쳐버립니다. 결국 데이터가 갈기갈기 찢어지는 끔찍한 모순 폭발(원자성 붕괴)이 터져버렸습니다. 게다가 무전을 한 번 더 치니 네트워크 딜레이(지연 속도)가 미친 듯이 늘어납니다. - 결국 3PC는 "이론은 예쁘지만 현실 네트워크에선 성능 구데기에 에러만 더 터지는 똥"으로 취급받고 버려지며, 대안으로 무자비한 메시지 큐(비동기)를 활용한 252번 사가(Saga) 패턴이 MSA의 구원자로 등판합니다.
📢 섹션 요약 비유: **3단계 커밋(3PC)**은 오케스트라 지휘자가 심장마비로 죽었을 때 연주자들이 멈추지 않게 하려고 만든 **'지휘봉 한 박자 쉬어가기(Pre-Commit 힌트) 꼼수'**입니다. 2PC라는 구형 연주법에서는 지휘자가 숨을 들이켜고 바로 지휘봉을 확 내려치며 "연주 시작(Commit)!"을 외쳤습니다. 지휘봉을 내리치기 직전 지휘자가 쓰러지면 연주자들은 쫄아서 눈만 데굴데굴 굴리며 10시간 동안 활을 멈춘 채 석상이 되었습니다(무한 블로킹). 3PC 지휘자는 룰을 바꿉니다. "자, 활 다 올렸지(Ready)? 내가 바로 지휘봉 안 내려칠게. 허공에 지휘봉을 3초간 딱 멈춰서 보여줄게(Pre-Commit 힌트 1.5단계 추가)! 이 멈춘 지휘봉을 보면 '아, 모두가 준비 끝났고 곧 연주가 시작되겠구나' 하고 마음속으로 확신해라! 그리고 3초 뒤에 내가 진짜 지휘봉을 내려치면(Do Commit) 연주해!" 이렇게 룰을 바꾸면, 지휘자가 허공에 지휘봉을 멈추고 폼을 잡다가(Pre-Commit 발송 직후) 심장마비로 쓰러져 뒈져도? 연주자들은 이미 허공의 지휘봉 힌트를 봤기 때문에 "야! 방금 지휘자님이 힌트 줬잖아! 그냥 우리끼리 눈치껏 1, 2, 3 하고 연주(Commit) 갈겨버리자!!" 라며 스스로 석상 상태(블로킹)를 풀고 연주를 무사히 마칠 수 있습니다. 하지만 극장이 너무 넓어 절반의 연주자는 힌트를 보고 절반은 기둥에 가려 힌트를 못 봤을 때, 절반만 연주해 버리는 끔찍한 불협화음(네트워크 분할 데이터 붕괴)을 막지 못해 역사 속으로 사라진 비운의 실험작입니다.