이 품질 관리로 계속 돌아옵니다. 그리고 나는 기존의 답변이 충분히 미묘한 것을 찾지 못했기 때문에 이것을 추가하고 있습니다.
TL; DR. 이벤트 소싱 사용량에 따라 예 또는 아니요.
내가 알고있는 두 가지 주요 이벤트 소스 시스템이 있습니다.
다운 스트림 이벤트 프로세서 = 예
이런 종류의 시스템에서 이벤트는 실제 세계에서 발생하며 사실로 기록됩니다. 제품 팔레트를 추적하는 창고 시스템과 같은. 기본적으로 충돌하는 이벤트가 없습니다. 잘못 되었더라도 모든 일이 이미 일어났습니다 (즉, 팔레트 123456은 트럭 A에 장착되었지만 트럭 B에 예약되었습니다.) 그런 다음,보고 메커니즘을 통해 예외를 확인합니다. Kafka는 이러한 종류의 다운 스트림 이벤트 처리 응용 프로그램에 적합합니다.
이러한 맥락에서 Kafka 직원이이를 이벤트 소싱 솔루션으로 옹호하는 이유를 이해할 수 있습니다. 예를 들어 클릭 스트림과 같이 이미 사용 된 방식과 매우 유사하기 때문입니다. 그러나 이벤트 소싱 (스트림 처리와 반대)이라는 용어를 사용하는 사람들은 두 번째 사용법을 참조 할 가능성이 높습니다.
응용 프로그램 제어 진실 소스 = 아니오
이러한 종류의 응용 프로그램은 사용자 요청이 비즈니스 로직을 통과 한 결과로 자체 이벤트를 선언합니다. 이 경우 Kafka는 두 가지 주요 이유로 제대로 작동하지 않습니다.
엔터티 격리 부족
이 시나리오에는 특정 엔티티에 대한 이벤트 스트림을로드하는 기능이 필요합니다. 일반적인 이유는 비즈니스 로직이 요청을 처리하는 데 사용할 임시 쓰기 모델을 빌드하기 때문입니다. 이 작업은 Kafka에서 비실용적입니다. 엔터티 당 주제를 사용하면 수천 또는 수백만 엔터티가있을 수있는 스타터가 아닌 것을 제외하고는이를 허용 할 수 있습니다. 이것은 Kafka / Zookeeper의 기술적 한계 때문입니다.
이러한 방식으로 임시 쓰기 모델을 사용하는 주된 이유 중 하나는 비즈니스 논리 변경을 저렴하고 쉽게 배포 할 수 있도록하기위한 것입니다.
Kafka 대신 유형별 주제를 사용하는 것이 좋지만 단일 엔터티에 대한 이벤트를 가져 오려면 해당 유형의 모든 엔터티 에 대한 이벤트를로드해야합니다 . 어떤 이벤트가 어떤 엔티티에 속하는지 로그 위치로 알 수 없기 때문입니다. 알려진 로그 위치에서 시작하기 위해 스냅 샷 을 사용 하더라도이 이벤트는 상당히 많은 이벤트가 될 수 있습니다.
충돌 감지 부족
둘째, 사용자는 동일한 엔터티에 대한 동시 요청으로 인해 경쟁 조건을 만들 수 있습니다. 충돌 이벤트를 저장하고 사실 후에 해결하는 것은 바람직하지 않습니다. 따라서 충돌하는 이벤트를 방지 할 수 있어야합니다. 요청로드를 확장하기 위해 조건부 쓰기를 사용하여 쓰기 충돌을 방지하면서 상태 비 저장 서비스를 사용하는 것이 일반적입니다 (마지막 엔터티 이벤트가 #x 인 경우에만 쓰기). 일명 낙관적 동시성. Kafka는 낙관적 동시성을 지원하지 않습니다. 주제 수준에서 지원하더라도 효과적이려면 엔티티 수준까지 내려 가야합니다. Kafka를 사용하고 충돌하는 이벤트를 방지하려면 응용 프로그램 수준에서 상태 저장 직렬화 기록기를 사용해야합니다. 이것은 중요한 아키텍처 요구 사항 / 제한 사항입니다.
추가 정보
댓글 당 업데이트
댓글이 삭제되었지만 질문은 다음과 같습니다. 사람들이 이벤트 저장에 사용하는 것은 무엇입니까?
대부분의 사람들은 기존 데이터베이스를 기반으로 자체 이벤트 스토리지 구현을 수행하는 것으로 보입니다. 내부 백엔드 또는 독립형 제품과 같은 비 분산 시나리오의 경우 SQL 기반 이벤트 저장소를 작성하는 방법 이 잘 문서화 되어 있습니다. 그리고 다양한 종류의 데이터베이스 위에 사용 가능한 라이브러리가 있습니다. 이 목적을 위해 만들어진 EventStore 도 있습니다 .
분산 시나리오에서 몇 가지 다른 구현을 보았습니다. Jet의 Panther 프로젝트는 피드 변경 기능과 함께 Azure CosmosDB 를 사용하여 리스너에게 알립니다. AWS에서 들었던 또 다른 유사한 구현은 DynamoDB를 Streams 기능과 함께 사용하여 리스너에게 알리는 것입니다. 파티션 키는 아마도 최상의 데이터 분배를위한 스트림 ID 여야합니다 (과잉 프로비저닝 양을 줄이려면). 그러나 Dynamo의 스트림에서 전체 재생은 비용이 많이 듭니다 (읽기 및 비용 기준). 따라서이 impl은 Dynamo Streams가 이벤트를 S3에 덤프하도록 설정되었습니다. 새 리스너가 온라인 상태가되거나 기존 리스너가 전체 재생을 원하면 S3을 먼저 읽습니다.
현재 프로젝트는 다중 테넌트 시나리오이며 Postgres를 기반으로 프로젝트를 진행했습니다. Citus와 같은 것은 텐 턴트 + 스트림에 의한 파티션, 확장성에 적합한 것으로 보입니다.
Kafka는 여전히 분산 시나리오에서 매우 유용합니다. 각 서비스의 이벤트를 다른 서비스에 노출시키는 것은 사소한 문제가 아닙니다. 이벤트 저장소는 일반적으로 그러한 용도로 구축되지는 않지만 Kafka가 잘하는 것입니다. 각 서비스에는 자체 내부 소스가 있으며 (이벤트 저장 또는 기타 일 수 있음) "외부"에서 발생하는 상황을 파악하기 위해 Kafka를 경청합니다. 이 서비스는 Kafka에 이벤트를 게시하여 "외부"에 서비스가 수행 한 흥미로운 작업을 알릴 수 있습니다.