event-driven-architecture

2 개의 포스트

VLOps: 이벤트 기반 MLO (새 탭에서 열림)

VLOps는 학습, 평가, 배포 과정을 Typed Message 단위로 정의하고 이를 감지해 자율적으로 실행하는 이벤트 기반 MLOps 시스템입니다. 기존 파이프라인 방식의 복잡성을 해결하고 시스템 간 느슨한 결합을 통해 클라우드 호환성과 기능 확장성을 극대화한 것이 특징입니다. 이를 통해 사용자는 내부의 복잡한 오케스트레이션 구조를 몰라도 메시지 발행만으로 효율적인 모델 관리 파이프라인을 구동할 수 있습니다. **이벤트 기반 MLOps의 핵심 구조** * 학습, 평가, 배포 등 MLOps의 각 단계를 Typed Message라는 독립적인 데이터 단위로 정의하여 관리합니다. * Event Sensor가 발행된 메시지를 실시간으로 감지하고, 정의된 로직에 따라 적절한 작업을 자율적으로 수행하는 구조를 가집니다. * 메시지 중심의 설계를 통해 각 시스템 간 의존성을 낮추는 느슨한 결합(Loose Coupling)을 실현하여, 특정 클라우드 환경에 종속되지 않는 호환성을 확보했습니다. **기존 파이프라인 방식과의 차별점** * Kubeflow와 같은 전통적인 파이프라인 도구와 달리, 전체 워크플로우에 대한 엄격한 버전 관리가 강제되지 않아 운영의 유연성이 높습니다. * 새로운 기능을 추가할 때 전체 시스템을 재설계할 필요 없이, 단순히 새로운 메시지 타입을 정의하고 추가하는 것만으로 기능을 확장할 수 있습니다. * 사용자는 복잡한 내부 인프라 로직을 이해할 필요 없이 표준화된 메시지만 발행하면 동일한 파이프라인 결과를 얻을 수 있어 개발 경험이 개선됩니다. **Omni-Evaluator와 대시보드를 통한 통합 관리** * Omni-Evaluator는 파편화된 다양한 모델 엔진과 벤치마크 도구들을 하나로 통합하여 일관된 평가 환경을 제공합니다. * VLOps Dashboard를 통해 전체 작업의 진행 상태를 실시간으로 모니터링하고 시각화된 결과 지표를 한눈에 파악할 수 있습니다. * 시스템에 의한 자동 트리거뿐만 아니라, 사용자가 필요 시 직접 이벤트를 발생시켜 특정 평가나 배포를 수행할 수 있는 사용자 주도적 제어 기능을 지원합니다. 모델의 규모가 커지고 복잡해지는 멀티모달 LLM 환경에서는 경직된 파이프라인보다 이벤트 기반의 비동기 아키텍처가 변화에 더 유연하게 대응할 수 있습니다. 인프라의 복잡도를 추상화하고 메시지 기반의 확장성을 확보하려는 조직에게 VLOps와 같은 접근 방식은 매우 실용적인 대안이 될 것입니다.

레거시 결제 원장을 확장 가능한 시스템으로 (새 탭에서 열림)

토스페이먼츠는 20년 된 레거시 결제 원장의 구조적 한계와 도메인 간 강한 결합을 해결하기 위해 MySQL 기반의 신규 원장 시스템을 구축했습니다. 데이터 불변성을 보장하는 INSERT-only 원칙과 이벤트 기반 아키텍처를 도입하여 복합 결제 지원 등 비즈니스 확장성을 확보했습니다. 이 과정에서 발생한 데이터 불일치와 타임아웃 문제를 해결하며 시스템의 자가 회복 능력을 강화하고 안정적인 운영 환경을 마련했습니다. ### 레거시 원장 시스템의 한계와 과제 - **데이터 구조의 불일치:** 결제수단별로 테이블 구조가 다르고, 동일한 성격의 데이터가 서로 다른 테이블에 저장되어 유지보수와 온보딩에 큰 비용이 발생했습니다. - **도메인 간 강한 결합:** 결제, 정산, 회계 등 여러 서비스가 하나의 원장 테이블과 컬럼을 공유하여, 작은 기능 수정 시에도 전사적인 영향도 분석이 필요했습니다. - **구조적 확장성 부족:** 결제와 결제수단이 1:1 관계로 묶여 있어, 더치페이나 복합 결제(카드+포인트)와 같은 현대적인 결제 시나리오를 지원할 수 없었습니다. ### 신규 원장 설계의 3가지 전략 - **데이터 불변성과 일관성:** 모든 승인 내역을 공통 테이블(`approve`)에 저장하고, 수정 대신 INSERT-only 방식을 채택하여 데이터의 정합성을 높이고 데드락을 방지했습니다. - **이벤트 기반의 도메인 분리:** 각 도메인이 직접 DB를 조회하는 대신 Kafka 이벤트를 구독하여 데이터를 처리하게 함으로써 도메인 간 의존성을 제거했습니다. - **결제와 승인 개념의 분리:** '결제'는 주문의 상태를, '승인'은 실제 결제수단의 실행을 의미하도록 분리하여 하나의 결제에 여러 승인 수단이 연결될 수 있는 유연한 구조를 만들었습니다. ### 무중단 마이그레이션 및 정합성 검증 - **비동기 점진적 적재:** 실서비스 장애를 방지하기 위해 기존 원장에 먼저 저장한 후, 신규 원장에는 별도의 ThreadPool을 통한 비동기 방식으로 데이터를 적재했습니다. - **검증 배치 운영:** 비동기 적재 중 발생할 수 있는 누락을 방지하기 위해, 매 5분마다 Read-Only DB를 기반으로 기존 원장과 신규 원장의 데이터를 비교하고 보정하는 배치를 실행했습니다. - **고성능 이관 작업:** 수억 건의 데이터 이관을 위해 Bulk Insert를 도입하고, 네트워크 지연 최소화를 위해 마이그레이션 서버를 DB와 동일한 가용 영역(AZ)에 배치했습니다. ### 운영 중 장애 대응과 시스템 고도화 - **쿼리 최적화:** 옵티마이저의 판단 오류로 발생한 풀 스캔(Full Scan) 문제를 인덱스 힌트(Index Hint) 추가와 롤백 시스템을 통해 빠르게 해결했습니다. - **타임아웃 및 정합성 관리:** MSA 구조에서 서버 간 타임아웃 설정을 일치시키고, 외부 원천사와의 상태 불일치를 해결하기 위한 망취소(Network Cancellation) 로직을 강화했습니다. - **이벤트 처리의 신뢰성:** 아웃박스(Outbox) 패턴과 로그 기반 복구를 통해 이벤트 누락을 방지하고, 헤더에 멱등키를 포함해 중복 이벤트 처리 문제를 해결했습니다. 신규 시스템으로의 전환은 단순한 DB 교체가 아니라 시스템의 지속 가능성을 확보하는 과정입니다. 초기 설계의 완벽함보다 중요한 것은 운영 중 발생하는 예외 상황에 시스템이 스스로 대응하고 회복할 수 있는 '자가 회복 구조'를 갖추는 것이며, 이를 위해 데이터 보정 배치와 로깅 시스템 같은 안전장치를 반드시 고려해야 합니다.