유산 시스템에서 이벤트 소싱으로: 단계별 마이그레이션 가이드
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
DevOps
대상자
- 개발자 및 DevOps 엔지니어
- 유산 시스템 마이그레이션 경험
- 중간~고급 난이도 (이벤트 소싱, 점진적 마이그레이션 이해 필요)
핵심 요약
- 핵심 전략: 고가치 영역(결제, 주문 처리 등)부터 이벤트 소싱 적용
- 기존 코드 유지: ActiveRecord 사용 유지, 프로젝션으로 읽기 전환
- 피해야 할 함정: 이벤트 스키마 변경 → upcaster 사용, 프로젝션 드리프트 → 체크섬 + 재구성
- 성공 조건: 점진적 마이그레이션 + 팀 교육 + 리더십 지원
섹션별 세부 요약
1. 고가치 영역 선택
- 대상: 감사 흐름(결제, 사용자 접근), 복잡한 워크플로우(주문 충족), 자주 발생하는 디버깅 필요 영역
- 피해야 할 것: 정적 참조 데이터(예: 상품 카탈로그)
- 예시:
Order
모델에서after_update
훅으로OrderStatusChanged
이벤트 발행
2. 프로젝션 기반 테스트
- 구현:
OrderProjection
클래스로 이벤트 저장소에서 이벤트 로드 및 상태 업데이트 - 검증:
LegacyOrder.find(123).status == OrderProjection.for(123).status
로 동기화 확인 - 코드 예시:
class OrderProjection
def self.apply(state, event)
case event
when OrderStatusChanged
state.merge(status: event.new_status)
end
end
end
3. 점진적 롤아웃 전략
- 단계:
- 새 기능 → 프로젝션 사용
- 기존 코드 → ActiveRecord 유지
- 불일치 모니터링 → 30일간 100% 일치 확인
- 최종 단계:
- 모든 읽기 요청 → 프로젝션으로 리디렉션
- 사용되지 않는 테이블 삭제
4. 주요 함정 및 해결책
- 이벤트 스키마 변경: upcaster 사용하여 이벤트 버전 관리
- 프로젝션 드리프트: 이벤트 기반 재구성 + 체크섬 추가
- 성능 저하: 핫한 에그리게이트에 스냅샷 추가
5. 500개 모델 대응 전략
- 1단계: 유계 맥락(예: 결제) 선정
- 2단계: 가치 증명(감사 개선, 디버깅 속도 향상 등)
- 3단계: 반복적 확장 (이터레이티브 애그리게이트 추가)
결론
- 핵심 팁: 이벤트 소싱 마이그레이션은 점진적 접근이 필수 (예:
Order
모델부터 시작) - 성공 전제: 팀 교육, 리더십 지원, upcaster/체크섬/스냅샷 도입
- 예시:
ShipOrderCommand.call(order_id: order.id)
로 명령 패턴 적용 후 프로젝션 대체 - 결론: "2주 리팩토링" 기대보다 유계 맥락별 점진적 이터레이션이 실무 적용에 효과적