GH GambleHub

Event Source - Basi

Cos'è Event Source

Event Source (ES) è un modo per memorizzare lo stato degli oggetti di dominio non come una stringa corrente, ma come un registro eventi immutabile che descrive tutto ciò che è accaduto. Lo stato corrente dell'aggregazione è rappresentato da una combinazione degli eventi e le viste di lettura vengono create come proiezioni sopra il registro.

Indagini chiave:
  • La storia è la fonte primaria della verità, la condizione è la proiezione della storia.
  • Qualsiasi stato può essere riprodotto, convalidato e spiegato.
  • L'aggiunta di nuove viste e analisi non richiede la migrazione di vecchie snapshot - basta perdere eventi.

Termini di base

L'aggregazione è un'unità di dominio con invarianti chiari (Order, Payment, UserBalance).
L'evento è un fatto non modificabile avvenuto in passato ('payment. authorized`, `order. shipped`).
Event Store è un registro di append che garantisce l'ordine degli eventi all'interno dell'unità.
La versione dell'unità è il numero dell'ultimo evento applicato (per ottimistico concertency).
Snapshot è un calco di stato periodico per accelerare la coagulazione.
Proiezione (modello read) - Vista materializzata per la lettura, la ricerca e il reporting (spesso asincrona).

Come funziona (flusso di comandi di eventi di proiezione )

1. Il cliente sta inviando una squadra.
2. L'aggregazione valuta gli invarianti e, se tutto va bene, genera eventi.
3. Gli eventi vengono aggiunti atomonicamente all'Event Store con la versione ottimistica.
4. I processori di proiezione sono iscritti al flusso di eventi e aggiornano i modelli read.
5. Durante il caricamento dell'aggregazione per il comando seguente, lo stato viene ripristinato (se disponibile) dopo il snap dell'evento.

Progettazione degli eventi

Attributi obbligatori (kernel)

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" }
}
Raccomandazioni:
  • La denominazione è «domain». action. v{major}`.
  • Additività: i nuovi campi sono opzionali, senza modificare il significato dei vecchi campi.
  • Minimalismo: solo fatti, senza duplicazioni di dati facilmente recuperabili.

Contratti e schemi

Fissare gli schemi (Avro/JSON Schema/Protobuf) e verificare la compatibilità con CI.
Per le modifiche "frammentarie", la nuova versione maggiore dell'evento e la pubblicazione parallela dì v1 "/" v2 "per il periodo di migrazione.

Accesso competitivo: ottimistica concurrency

Regola: è possibile scrivere nuovi eventi solo se 'expected _ variante = = current _ variante'.

Pseudocode:
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

In questo modo garantiamo l'integrità degli invarianti senza transazioni distribuite.

Snapshot (accelerazione della saldatura)

Fate un snap ogni n eventi o timer.
Храните `snapshot_state`, `aggregate_id`, `version`, `created_at`.
Controlla sempre e raggiungi gli eventi dopo il snapshot (non fidarti solo del calco).
Togliere i nastri in modo che possano essere ripiegati dal cavo (non memorizzare i campi magici).

Proiezioni e CQRS

ES si combina naturalmente con CQRS:
  • Modello Write = unità + Event Store.
  • Modelli read = proiezioni aggiornate da eventi (Redis schede, ricerca, per report).
  • Le proiezioni sono idipotenti: la riprogettazione dello stesso «event _ id» non cambia il risultato.

Evoluzione degli schemi e compatibilità

Additive-first - Aggiungere campi; Non cambiare i tipi/semantiche.
Per le modifiche complesse, rilasciare nuovi tipi di eventi e scrivere i migratori di proiezione.
Mantenere la doppia scrittura ('v1' + 'v2') per il periodo di transizione e filmare 'v1' quando tutte le proiezioni sono pronte.

Sicurezza, PII e diritto all'oblio

La storia contiene spesso dati sensibili. Approcci:
  • Ridurre al minimo il PII negli eventi (ID anziché dati, parti in lati protetti).
  • Crittografia - Cifrare i campi e eliminare la chiave quando si chiede l'eliminazione (l'evento rimane ma i dati non sono disponibili).
  • Eventi di redazione: 'user. piiredacted. v1 'sostituito da campi sensibili nelle proiezioni (cronologia conserva la modifica).
  • Criteri di rettificazione: per alcuni domini è possibile archiviare alcuni eventi nello storage WORM.

Prestazioni e scalabilità

Partizionamento: l'ordine è importante all'interno dell'unità - Partizionare per «aggregate _ id».
Partenza fredda: snapshot + compressione periodica.
Appended batch: raggruppa gli eventi con una singola transazione.
Backpressure e DLQ per i processori di proiezione misurare la lega (tempo e numero di messaggi).
Indice Event Store: accesso rapido per '(aggregate _ type, aggregate _ id)' e in base all'ora.

Test

Specification test per aggregati: script «comandi per gli eventi previsti».
Progection test: inserisci il flusso di eventi e controlla lo stato/gli indici materializzati.
Replayability test - Riarrangiare le proiezioni da zero nello stand. Assicurarsi che il risultato corrisponda.
Chaos/latency: inserisci ritardi e prese, controlla l'idempotenza.

Esempi di dominio

1) Pagamenti

Eventi dì payment ". initiated`, `payment. authorized`, `payment. captured`, `payment. refunded`.
Invarianti: non è possibile «capture» senza «authorized»; gli importi non sono costosi; la valuta è invariata.
Proiezioni: carta di pagamento (KV), ricerca transazioni (OpenSearch), report (OLAP).

2) Ordini (e-commerce)

Eventi: 'order. placed`, `order. paid`, `order. packed`, `order. shipped`, `order. delivered`.
Invarianti - Transizioni di stato in un grafico di stato può essere annullato fino a «shipped».
Proiezioni: elenco degli ordini dell'utente, SLA-dashboard per stato.

3) Bilanci (finanza/iGaming)

Eventi dì equilibrio. deposited`, `balance. debited`, `balance. credited`, `balance. adjusted`.
Invariante rigido: il bilanciamento non parte. <0 i comandi sono idonei a «operation _ id».
Le operazioni critiche vengono lette direttamente dall'aggregazione (coerenza rigorosa) e dall'UI dalla proiezione (avvenual).

Struttura standard Event Store (opzione database)

events

`event_id (PK)`, `aggregate_type`, `aggregate_id`, `version`, `occurred_at`, `event_type`, `payload`, `meta`

Indice: '(aggregate _ type, aggregate _ id, variante)'.

snapshots

`aggregate_type`, `aggregate_id`, `version`, `state`, `created_at`

Indice: '(aggregate _ type, aggregate _ id)'.

consumers_offsets

«consumer _ id», «event _ id »/« position», «updated _ at» (per proiezioni e retlay).

Domande frequenti (FAQ)

È necessario utilizzare ES ovunque?
No, no. ES è utile quando le verifiche, gli invarianti complessi, la riproduzione e le viste dei dati sono importanti. Per un CRUD semplice è eccessivo.

Come vanno le richieste di «stato attuale»?
O leggi dalla proiezione (veloce, avvenual) o dall'aggregazione (più costosa, ma rigorosa). Le operazioni critiche di solito utilizzano un secondo percorso.

Ha bisogno di Kafka/stream broker?
Event Store è la fonte della verità; il broker è facile da distribuire ai proiettori e ai sistemi esterni.

E il «diritto all'oblio»?
Minimizza il PII, crittografa i campi sensibili e applica la crittografia/revisione nelle proiezioni.

Come migrare i vecchi dati?
Scrivete uno script per generare eventi retrospettivi (re-highstory) o iniziate con lo stato-come-è e pubblicate eventi solo per nuove modifiche.

Antipattern

Event Source «abitudine»: rende il sistema più difficile senza vantaggi di dominio.
Fat events: payload gonfiati con PII e doppie - freni e problemi di compilazione.
Assenza di concurrency ottimistico: perdita di invarianti durante le corse.
Proiezioni impermeabili: nessuna replica/snapshot, fissaggio manuale.
CDC crudi come eventi di dominio: perdita di schemi di database e connettività rigida.
Miscelazione degli eventi interni e di integrazione: pubblicare una vetrina stabilizzata all'esterno.

Foglio di assegno per la produzione

  • Sono stati definiti aggregati, invarianti ed eventi (nomi, versioni, schemi).
  • Event Store fornisce l'ordine all'interno dell'unità e ottimistico concertency.
  • Sono inclusi i snapshot e il piano di rielaborazione.
  • Le proiezioni sono idipotenti, ci sono DLQ e metriche della laga.
  • Gli schemi sono validi su CI, il criterio di versione è documentato.
  • PII è stato minimizzato, i campi sono cifrati, c'è una strategia di dimenticanza.
  • Le repliche delle proiezioni sono state verificate nello stand; C'è un piano di disaster recovery.
  • Dashboard: velocità dell'appendice, gioco di proiezioni, errori di applicazione, quota di retrai.

Totale

Event Sorcing rende la storia del sistema un artefatto di prima classe, che cattura i fatti, riproduce lo stato e costruisce liberamente qualsiasi rappresentazione. Ciò consente di verificare, gestire i cambiamenti e la flessibilità degli analisti, con disciplina dei circuiti, controllo competitivo e gestione dei dati sensibili.

Contact

Mettiti in contatto

Scrivici per qualsiasi domanda o richiesta di supporto.Siamo sempre pronti ad aiutarti!

Avvia integrazione

L’Email è obbligatoria. Telegram o WhatsApp — opzionali.

Il tuo nome opzionale
Email opzionale
Oggetto opzionale
Messaggio opzionale
Telegram opzionale
@
Se indichi Telegram — ti risponderemo anche lì, oltre che via Email.
WhatsApp opzionale
Formato: +prefisso internazionale e numero (ad es. +39XXXXXXXXX).

Cliccando sul pulsante, acconsenti al trattamento dei dati.