226. 이벤트 소싱 (Event Sourcing) - 상태 변경 이력 이벤트 스트림 저장 CQRS 연계 마이크로서비스 동기화 불변 데이터 데이터베이스 복원
핵심 인사이트: (225번 CQRS의 영원한 짝꿍) 내 통장에 현재 잔고가 '10만 원'이라고 찍혀있다. 근데 이 10만 원이 어제 엄마가 준 건지, 내가 알바를 한 건지, 어떻게 10만 원이 된 건지 추적하려면 은행 장부를 싹 다 뒤져야 한다. 멍청한 DB는 '현재 결과(상태)' 딱 1개만 덮어쓰기로 엑셀에 남겨두기 때문이다. "야! 왜 멍청하게 잔고 엑셀 칸을 지우고 덮어쓰고 지우고 덮어쓰는 거야! 과거가 싹 지워지잖아!! 앞으로 잔고 숫자 자체를 DB에 저장하지 마! 대신 네가 태어나서 지금까지 발생한 '모든 입출금 영수증 내역(Event)' 수만 장을 시간 순서대로 차곡차곡 무한대로 쌓아서 저장해(이벤트 소싱)!! 그리고 현재 잔고가 얼만지 알고 싶어? 그 수만 장의 영수증을 처음부터 끝까지 1초 만에 촤라락! 다시 계산(Replay)해서 '아, 현재 10만 원이네요'라고 보여주면 되잖아!!" 데이터의 파괴(Update)를 멈추고 역사를 기록하는 블록체인급 무결성 뼈대, 이벤트 소싱이다.
Ⅰ. 상태(State) 중심 데이터베이스의 한계 (덮어쓰기의 비극)
- 구형 게시판이나 쇼핑몰은 UPDATE라는 쿼리를 씁니다.
- 홍길동의 주소가 '서울'이었는데 '부산'으로 엑셀을
UPDATE덮어써버렸습니다. - 재앙: 해커가 내일 당장 "너 원래 주소 어딨어 증명해 봐!"라고 하면 증명할 방법이 없습니다. 덮어써버려서 '서울'이라는 과거 데이터가 디스크에서 아예 갈려버렸기 때문입니다. 데이터의 역사(History)가 소멸하는 치명적 구조입니다.
Ⅱ. 이벤트 소싱 (Event Sourcing)의 개념 🌟
- 개념: 데이터의 최종 결과값(현재 상태) 자체를 DB에 저장하는 것을 포기하고, 대신 그 데이터에 가해진 모든 '상태 변경 행위(Event, 예: 5만 원 입금됨, 3만 원 출금됨)'의 내역들을 절대 지워지지 않는(Append-only) 영수증 다발의 스트림(Stream) 형태로 차곡차곡 저장하는 아키텍처 패턴입니다.
Ⅲ. 이벤트 소싱의 3대 핵심 마법 🌟 핵심 기출 🌟
1. 절대 불변(Immutable)의 장부 (Append-only)
- 이벤트 소싱 DB (주로 카프카(Kafka)나 이벤트 스토어)에는
UPDATE나DELETE라는 명령어가 아예 물리학적으로 존재하지 않습니다! 오직 엑셀 맨 밑줄에 새로운 줄을 무조건 '추가(INSERT/Append)'만 할 수 있습니다. - 해커가 값을 고치려 해도 덮어쓸 수 없기 때문에, 데이터의 무결성과 감사(Audit) 추적이 100% 완벽하게 보장되는 신의 장부입니다. (블록체인 장부 원리와 같습니다.)
2. 타임머신 복원 (Replay 릴레이 연산)
- DB가 날아갔습니다! 어떻게 복구할까요?
- 아주 쉽습니다. 서버를 켜고 첫 번째 영수증(가입함)부터 방금 전 마지막 영수증(1만 원 출금함)까지 수십만 개의 이벤트를 **빛의 속도로 순서대로 촤라락 다시 덧셈 뺄셈 재생(Replay)시켜버리면, 서버가 터지기 0.1초 전의 최종 현재 상태(잔고 10만 원)가 1초 만에 100% 완벽하게 부활(재건)**해 냅니다.
- "어제 오후 3시 시점의 장바구니로 돌아가 줘"라는 타임머신 조작도 식은 죽 먹기로 가능합니다.
3. 225번 CQRS와의 영혼의 파트너십 🌟 (결정적 콤보)
- 단점: 고객이 잔고 조회 버튼을 눌렀는데, 그때마다 수만 장의 영수증을 1번부터 다 더해서 계산(Replay)해주려면 너무 느려서 폰이 터지겠죠?
- 해결책 (CQRS 결합):
- 쓰기 DB (Command): 무한대로 영수증(Event)만 쌓는 이벤트 스토어를 둡니다.
- 읽기 DB (Query): 이 영수증이 하나 추가될 때마다 잽싸게 계산기 돌려서 '최종 잔고 10만 원'이라는 단일 결과값만 엑셀 1칸에 딸깍! 저장해 두는 **조회 전용 캐시 DB(Redis 등)**를 따로 만듭니다.
- 유저는 무조건 이 빠르고 넓적한 읽기 DB(조회 전용)만 때려서 잔고를 0.001초 만에 확인합니다. F1 레이싱급 최적화의 완성입니다.
Ⅳ. 도입 시나리오
- 금융권(은행 원장), 회계 장부, 마이크로서비스(MSA) 간의 완벽한 비동기 데이터 동기화 파이프라인에서 무조건 1순위로 채택되는 고급 기술입니다. 반면 단순한 쇼핑몰 공지사항 게시판에 쓰면 배보다 배꼽이 큰 미친 짓(오버 엔지니어링)이 됩니다.
📢 섹션 요약 비유: 기존의 **상태 기반 데이터베이스(CRUD)**는 선생님이 칠판에 적힌 숫자를 지우개로 빡빡 지우고 **'새로운 답(현재 상태)만 계속 덮어쓰는 짓'**입니다. 칠판에 '10'이 적혀있는데, 학생이 "선생님, 아까 3시간 전에는 저 숫자가 뭐였어요?"라고 물으면 선생님은 멘붕에 빠집니다(과거가 삭제됨). 이를 뒤집어엎은 **이벤트 소싱(Event Sourcing)**은 칠판을 버리고 **'무한히 긴 영수증 두루마리(이벤트 스트림)'**를 꺼내 든 것입니다. 선생님은 숫자를 지우지 않습니다. 오직 두루마리 끝에 "+5", "-2", "+7" 이라는 행위(이벤트)만 줄줄이 볼펜으로 영원히 추가(Append-only)해 나갈 뿐입니다. 학생이 "현재 답이 뭐예요?"라고 물으면, 선생님은 두루마리 맨 위부터 끝까지 촤라락 빛의 속도로 덧셈 뺄셈을 다시 재생(Replay)해서 "답은 10이다!"라고 말해줍니다. 지우개가 없으므로 누군가 조작할 수도 없고(절대 무결성), 3시간 전으로 돌아가고 싶으면 두루마리를 3시간 전까지만 잘라서 덧셈하면 끝나는, 데이터의 모든 파괴 행위를 금지하고 역사 그 자체를 시스템의 뼈대로 만들어버린 궁극의 진실 추적 아키텍처입니다.