GH GambleHub

이벤트 소싱: 기본

이벤트 소싱이란 무엇입니까?

ES (Event Sourcing) 는 도메인 객체의 상태를 "현재 라인" 이 아니라 발생한 모든 것을 설명하는 변경할 수없는 이벤트 로그로 저장하는 방법입니다. 골재의 현재 상태는 이벤트를 롤업 (재생) 하여 얻을 수 있으며 모든 읽기보기는이 로그 위에 투영으로 구축됩니다.

주요 의미:
  • 역사는 "진리의 주요 원천" 이고 국가는 역사의 투영입니다.
  • 모든 상태를 복제, 점검 및 설명 할 수 있습니다 (감사).
  • 새로운보기와 분석을 추가하면 이전 "스냅 샷" 의 마이그레이션이 필요하지 않습니다. 이벤트를 잃기에 충분합니다.

기본 용어

집계 - 명확한 불변량과의 일관성 도메인 단위 (주문, 지불, UserBalance).
이벤트-과거에 발생한 변하지 않는 사실 ('지불. ',' 주문 승인. 배송 ').
이벤트 스토어는 장치 내 이벤트 순서를 제공하는 부록 전용 로그입니다.
집계 버전은 마지막으로 적용되는 이벤트의 수입니다 (낙관적 동시성).
스냅 샷-컨볼 루션 속도를 높이기위한 상태의주기적인 인상.
투영 (읽기 모델) - 읽기/검색/보고에 대한 구체화 된보기 (종종 비동기식).

작동 방식 (스레드 → 이벤트 → 투영)

1. 클라이언트는 명령 ('CapturePayment', 'PlaceOrder') 을 보냅니다.
2. 집계는 불변량을 검증하고 모두 괜찮은 경우 이벤트를 생성합니다.
3. 이벤트는 버전 검증 (낙관적 동시성) 과 함께 이벤트 스토어에 원자 적으로 추가됩니다.
4. 프로젝션 프로세서는 이벤트 흐름에 가입하고 읽기 모델을 업데이트합니다.
5. 다음 명령에 대한 집계가로드되면 상태가 스냅 샷 (있는 경우) → 스냅 샷 후 이벤트로 복원됩니다.

이벤트 디자인

필수 속성 (핵심)

json
{
"event_id": "uuid",
"event_type": "payment. authorized. v1",
"aggregate_type": "Payment",
"aggregate_id": "pay_123",
"aggregate_version": 5,
"occurred_at": "2025-10-31T10:42:03Z",
"payload": { "amount": 1000, "currency": "EUR", "method": "card" },
"meta": { "trace_id": "t-abc", "actor": "user_42" }
}
권장 사항:
  • 명명: '도메인. 행동. v {major} '.
  • 첨가제: 새로운 필드는 오래된 필드의 의미를 바꾸지 않고 선택 사항입니다.
  • 미니멀리즘: 쉽게 복구 할 수있는 데이터를 중복하지 않고 사실 만.

계약 및 체계

스키마 (Avro/JSON 스키마/프로토 타입) 를 수정하고 CI에서 호환성을 확인하십시오.
"파괴" 변경 사항-이벤트의 새로운 주요 버전 및 마이그레이션 기간 동안 병렬 게시물 'v1 '/' v2'.

경쟁 액세스: 낙관적 인 동시성

규칙: 새로운 이벤트는 '예상 _ 버전 = = 현재 _ 버전' 인 경우에만 작성할 수 있습니다.

의사 코드:
pseudo load: snapshot(state, version), then apply events > version new_events = aggregate. handle(command)
append_to_store(aggregate_id, expected_version=current_version, events=new_events)
//if someone has already written an event between load and append, the operation is rejected -> retray with reload

따라서 분산 거래없이 불변의 무결성을 보장합니다.

스냅 샷 (컨볼 루션 가속)

모든 N 이벤트 또는 타이머에 스냅 샷을 찍습니다

'snapt _ state', 'colligate _ id', 'version', 'producted _ at'.
스냅 샷 후 항상 이벤트를 확인하고 따라 잡으십시오 (캐스트를 믿지 마십시오).
로그에서 스냅 샷을 다시 만들 수 있도록 스냅 샷을 제거하십시오 ("매직" 필드를 저장하지 마십시오).

투영 및 CQRS

ES는 자연스럽게 CQRS와 결합됩니다

쓰기 모델 = 집계 + 이벤트 스토어.
모델 읽기 = 이벤트에 의해 업데이트 된 프로젝션 (Redis 카드, 검색을위한 OpenSearch, 보고를위한 ClickHouse/OLAP).
투영은 dempotent입니다. 동일한 '이벤트 _ id' 를 다시 처리해도 결과가 변경되지 않습니다.

회로 진화 및 호환성

첨가제 우선: 필드 추가; 유형/의미를 변경하지 마십시오.
복잡한 변경을 위해 새로운 이벤트 유형을 해제하고 투영 철새를 작성하십시오.
전환 기간 동안 이중 항목 ('v1' + 'v2') 을 유지하고 모든 프로젝션이 준비되면 'v1' 을 촬영하십시오.

안전, PII 및 "잊을 권리"

역사에는 종종 민감한 데이터가 포 접근 방식:
  • 이벤트에서 PII를 최소화하십시오 (데이터 대신 식별자, 보호 측면의 세부 사항).
  • 암호화 지우기: 필드를 암호화하고 삭제하라는 메시지가 표시되면 키가 파괴됩니다 (이벤트는 남아 있지만 데이터는 사용할 수 없음).
  • 개정 이벤트: '사용자. piiredacted. v1 '은 프로젝션에서 민감한 필드를 대체합니다 (기록은 편집 사실을 유지합니다).
  • 보존 정책: 일부 도메인의 경우 일부 이벤트를 WORM 스토리지에 보관 할 수 있습니다.

성능 및 규모

파티셔닝: 'agregate _ id' 로 파티션 인 골재 내부에서 순서가 중요합니다.
콜드 스타트: 스냅 샷 + 주기적 "압축" 컨볼 루션.
배치 부록-한 트랜잭션의 그룹 이벤트.
프로젝션 프로세서의 역압 및 DLQ; 지연 시간 (메시지 시간 및 수) 을 측정합니다.
이벤트 스토어 인덱싱: '(집계 _ 유형, 집계 _ id)' 및 시간별 빠른 액세스.

테스트

집계에 대한 사양 테스트- "명령 → 예상 이벤트" 시나리오.
프로젝션 테스트: 이벤트 흐름을 피드하고 구체화 된 상태/인덱스를 확인하십시오.
재생 가능성 테스트: 스탠드에서 처음부터 프로젝션을 재구성-결과가 일치하는지 확인하십시오.
혼돈/대기 시간: 지연과 테이크를 주입하고 demmpotence를 확인하십시오.

도메인의 예

1) 지불

이벤트: '지불. ',' 결제를 시작했습니다. ',' 결제 승인. ',' 를 캡처했습니다. 환불 '.
불변량: '승인 된' 없이는 '캡처' 할 수 없습니다. 양은 음이 아닙니다. 통화는 변경되지 않습니다.
프로젝션: "결제 카드" (KV), 트랜잭션 검색 (OpenSearch), 보고 (OLAP).

2) 주문 (전자 상거래)

이벤트: '주문. ',' 주문. ',' 주문을 지불했습니다. 포장 된 ',' 주문. ',' 주문했습니다. 배달되었습니다.
불변량: 상태 차트 상태 전환; '배송' 하기 전에 취소 할 수 있습니다.
프로젝션: 사용자 주문 목록, 상태 별 SLA 보드.

3) 대차 대조표 (금융/iGaming)

이벤트: '균형. ',' 균형이 기탁되었습니다. ',' 균형을 토론했습니다. 크레딧 ',' 균형. 조정 '.
하드 불변: 균형이 사라지지 않습니다 <0; 명령은 'operation _ id' 입니다.
중요한 연산은 집계 (엄격한 일관성), UI-투영 (최종) 에서 직접 읽습니다.

전형적인 이벤트 스토어 구조 (DB 변형)

이벤트

'이벤트 _ id (PK)', '집계 _ 유형', '집계 _ id', '버전', '발생 _ at', '이벤트 _ 유형', '페이로드', '메타'

색인: '(집계 _ 유형, 집계 _ id, 버전)'.

스냅 샷

'집계 _ 유형', '집계 _ id', '버전', '상태', '생성 된 _ at'

색인: '(집계 _ 유형, 집계 _ id)'.

소비자 _ 오프셋

'소비자 _ id', '이벤트 _ id '/' 위치', '업데이트 된 _ at' (프로젝션 및 소매 용).

자주 묻는 질문 (FAQ)

ES를 어디에서나 사용해야합니까?
아니요, 그렇지 않습니다. ES는 감사, 복잡한 불변량, 재현성 및 다른 데이터 표현이 중요 할 때 유용합니다. 간단한 CRUD의 경우 이것은 중복입니다.

"현재 상태" 요청은 어떻습니까?

프로젝션 (빠르게, 최종) 또는 장치 (더 비싸지 만 엄격하게) 에서 읽으십시오. 중요한 작업은 일반적으로 두 번째 경로를 사용합니다

카프카/스트림 브로커가 필요합니까?

이벤트 스토어-진실의 원천; 브로커는 이벤트를 프로젝터 및 외부 시스템에 배포하는 데 편리합니

"잊을 권리" 와 어떻게해야합니까?
PII를 최소화하고 민감한 필드를 암호화하며 투영에 암호화 소거/수정을 적용합니다.

오래된 데이터를 어떻게 마이그레이션

회고 적 이벤트 생성 ("다시 이야기") 을위한 스크립트를 작성하거나 "상태" 로 시작하여 새로운 변경 사항에 대해서만 이벤트를 게시하십시오.

안티 패턴

이벤트 소싱 "습관이 없음": 도메인 혜택없이 시스템을 복잡하게합니다.
뚱뚱한 이벤트: PII 및 복식이 포함 된 부풀어 오른 페이로드-브레이크 및 규정 준수 문제.
낙관적 인 동시성 부족: 경주 할 때 불변량의 손실.
재현 불가능한 프로젝션: 재생/스냅 샷 → 수동 수정 없음.
도메인 이벤트로서의 원시 CDC: 유출 된 DB 스키마 및 하드 연결.
내부 및 통합 이벤트 혼합: 외부에 안정화 된 "쇼케이스" 를 게시하십시오.

생산 체크리스트

  • 집계, 불변 및 이벤트 (제목, 버전, 스키마) 가 정의됩니다.
  • 이벤트 스토어는 집계 및 낙관적 동시성 내에서 주문을 제공합니다.
  • 스냅 샷과 재건 계획이 포함되어 있습니다.
  • 투영은 dempotent이며 DLQ 및 지연 메트릭이 있습니다.
  • 체계는 CI에서 검증되고 버전 정책은 문서화됩니다.
  • PII가 최소화되고 필드가 암호화되며 "잊어 버린" 전략이 있습니다.
  • 벤치에서 투사 재생을 확인했습니다. 재난 복구 계획이 있습니다.
  • 대시 보드: 앱 속도, 프로젝션 지연, 응용 프로그램 오류, 배송 비율.

합계

이벤트 소싱은 시스템의 역사를 일류 인공물로 만듭니다. 우리는 사실을 포착하고 상태를 재현하며 표현을 자유롭게 구축합니다. 이는 체계, 경쟁 제어 및 민감한 데이터를 이용한 유능한 작업에 대한 규율에 따라 분석의 감사, 변경 및 유연성에 대한 감사, 저항성을 제공합니다.

Contact

문의하기

질문이나 지원이 필요하시면 언제든지 연락하십시오.우리는 항상 도울 준비가 되어 있습니다!

통합 시작

Email — 필수. Telegram 또는 WhatsApp — 선택 사항.

이름 선택 사항
Email 선택 사항
제목 선택 사항
메시지 선택 사항
Telegram 선택 사항
@
Telegram을 입력하시면 Email과 함께 Telegram에서도 답변드립니다.
WhatsApp 선택 사항
형식: +국가 코드 + 번호 (예: +82XXXXXXXXX).

버튼을 클릭하면 데이터 처리에 동의하는 것으로 간주됩니다.