우선 이벤트 소싱과 CQRS에 대한 개념부터 짚고 넘어가겠습니다. 카프카에 대한 개념은 이 동영상을 참고해주세요.
이벤트 소싱 패턴
이벤트 소싱은 배치성 데이터 저장소에 현재 상태만 저장하는 것이 아니라 이벤트 브로커(전용 저장소)에 발생된 모든 이벤트 기록(레코드)들을 기록하는 것을 뜻합니다. 이를 통해 데이터 모델과 비즈니스 도메인을 동기화할 필요가 없어지고 성능, 확장성, 응답성이 향상되어 도메인 태스크를 간소화 할수 있습니다.
기존에는 배치성 데이터 저장소(오라클, mysql 등)에 서비스에 들어오는 명령(또는 이벤트)이 발생할 때 마다 항상 동기화 했었습니다. 간단한 구조와 적은 데이터 접근만 일어날 때는 큰 이슈가 없지만, 데이터과 이벤트가 많아질 수록 데이터에 대한 CRUD와 같은 접근으로 인해 몇가지 이슈가 생길 수 있습니다.
- CRUD시스템은 데이터 저장소를 기준으로 작업을 수행하므로 성능, 응답속도가 저하되고 확장성이 제한될 수 있습니다.
- 많은 이벤트가 동시에 일어나서 데이터에 동시접근을 함으로서 트랜잭션 경합으로 인한 한계가 발생합니다.
- 이벤트에 대한 기록을 하지 않고 데이터를 동기화 하므로 기록이 유실될 수 있습니다.
이벤트 소싱 패턴을 활용함으로서 아래와 같은 장점들을 가질 수 있습니다.
- 발생한 이벤트를 백그라운드에서 실행할 수 있습니다. 그리고 트랜잭션 처리 중 경합이 발생하지 않으므로 서비스의 성능과 확장성이 높아집니다.
- 각 이벤트를 처리하는 서비스 애플리케이션들은 작은 단위의 로직입니다. 이를 통해 구현과 관리를 간소화 할 수 있습니다.
- 직접 데이터 저장소의 데이터를 업데이트 하지 않아도 되기 때문에 동시 업데이트로 인한 충돌을 방지할 수 있습니다.
- 언제든지 이벤트를 재실행(reprocess)하여 현재 상태를 다시 구현할 수 있습니다.
하지만 이벤트 소싱이 은탄환(silver bullet)은 아닙니다. 이벤트 소싱을 통해 발현된 데이터의 스키마가 변경될 수 있기 때문에 스키마 변경에 대한 버전 관리를 해야만 합니다. 그리고 다중 스레드 애플리케이션과 여러 애플리케이션 인스턴스가 이벤트 브로커에 접근하기 때문에 이벤트 일관성에 대해 어떻게 처리할지 고민해야만 합니다. 일관성이라 함은 데이터 처리의 순서 또는 반드시 한번 처리(exactly-once)와 같은 내용이 포함됩니다.
이벤트 소싱과 이벤트 드리븐 아키텍처를 비교하기도 하는데 바라보는 아키텍처의 범위의 차이라고 보면 쉽습니다. 이벤트 소싱은 하나의 애플리케이션 또는 시스템 단위이고 이벤트 드리븐 아키텍처는 전체 시스템 또는 여러 애플리케이션을 연동하는 단위로 볼 수 있습니다.
CQRS 패턴
CQRS(Command and Query Responsibility Segregation)는 이벤트 소싱 패턴 구현과 매우 유사합니다. CQRS패턴은 개별 인터페이스를 사용해서 데이터를 읽는(조회) 작업과 업데이트(처리)하는 작업을 분리하는 것이 핵심입니다. 서비스 애플리케이션에서 CQRS패턴으로 개발을 진행함으로서 성능, 확장성, 보안을 최대화할 수 있습니다.
CQRS 패턴을 구현하는 방법중 하나로 별도의 읽기 및 쓰기 데이터베이스를 따로 사용하는 것을 예로 들 수 있습니다. 이 경우에는 구체화된 뷰(Materialized View)를 사용하여 읽기전용 데이터베이스에서는 작은 용량으로 데이터를 사용할 수 있습니다.
CQRS패턴을 구현하는데 이벤트 소싱이 반드시 필요한 것은 아니지만, 이벤트 소싱에는 CQRS패턴이 필수입니다.
카프카와 이벤트 소싱, CQRS
결론부터 말하자면 카프카는 이벤트 소싱 패턴과 CQRS 패턴을 적용한 애플리케이션에 적용 가능하고 효과적으로 동작합니다. 카프카 스트림즈 라이브러리를 사용하면 애플리케이션에서 이벤트 소싱 패턴과 CQRS 패턴을 구현할 수 있습니다. 카프카 스트림즈는 카프카 클러스터와 연동할 수 있는 자바 라이브러리로서 토픽의 데이터를 처리(프로세스)하고 다시 토픽으로 데이터를 저장하는데 특화되어 있습니다. 뿐만 아니라 토픽에 존재하는 스트림 데이터(또는 언바운디드 데이터, 끝이 없는 데이터)를 스트림단위, 테이블 단위로 조회하고 처리할 수 있습니다. 카프카의 내부 구조(파티션 단위 등)에 맞게 동작하기 때문에 높은 확장성, 고 가용성, 분산처리 등의 특징을 지니고 있습니다.
스트림즈를 구현하면 이벤트 소싱과 CQRS로 구현된 아키텍처를 카프카 기반으로 변경할 수 있다.
반면에 카프카를 이벤트 소싱, CQRS로 사용하는 것에 대해 의구심을 가지는 의견도 있다. 토픽이라는 단위는 이벤트의 고유한 ID기반으로 생성할 수 없으며 해당 ID의 종료에 대한 대응(특정 이벤트 삭제)한 기능이 없기 때문에 적합하지 않다고 한다.
관련 문서
- Event sourcing, CQRS, stream processing and Apache Kafka: What’s the connection?
- 나만 모르고 있던 CQRS & EventSourcing
- Event driven architectures vs event sourcing patterns
- Apache Kafka Is Not for Event Sourcing
'빅데이터 > Kafka' 카테고리의 다른 글
카프카 스트림즈 Exactly-once 설정하는 방법과 내부 동작 (0) | 2021.06.03 |
---|---|
카프카 스트림즈 All stream threads have died. 오류 해결 방안 (0) | 2021.05.27 |
ProducerRecord에 파티션 번호를 지정하면 어떻게 동작할까? (0) | 2021.05.05 |
confluent-kafka-go 컨슈머를 구현하는 5가지 방법 (0) | 2021.04.30 |
레디슈 큐(queue), 레디스 스트림(streams), 레디스 펍섭(pub/sub) 그리고 카프카와 비교 (0) | 2021.04.25 |
카프카 스트림즈의 commit.interval.ms옵션 (2) | 2021.04.15 |