GH GambleHub

活动来源:基本知识

什么是Event Sourcing

Event Sourcing (ES)是将域对象的状态存储为"当前字符串"而不是描述发生的任何事物的不可变事件日志的一种方式。聚合的当前状态是通过其事件的卷积(复制)获得的,并且任何要读取的视图都构造为该日志顶部的投影。

主要调查结果:
  • 故事是"真理的主要来源",状态是故事的投影。
  • 任何状态都可以重新复制、验证和解释(审核)。
  • 添加新的视图和分析不需要迁移旧的"快照"-只需输掉事件即可。

基本术语

聚合是具有明确不变量(秩序,支付,用户平衡)的一致性域单位。

该事件是过去发生的不变事实('payment。authorized`, `order.shipped`).

Event Store是一个append-only日志,在集合中提供事件顺序。
聚合版本是应用的最后一个事件的编号(用于优化顺序)。
Snapshot是一种周期性的状态铸件,用于加速卷积。
投影(读取模型)是用于阅读/搜索/报告(通常是异步的)的实例化视图。

如何工作(命令流→事件→投影)

1.客户端发送命令("CapturePayment","PlaceOrder")。
2.聚合物验证不变量,如果所有,则产生事件。
3.事件通过版本验证(optimistic concurrency)原子添加到Event Store中。
4.投影处理器订阅事件流并更新读取模型。
5.加载以下命令的单元时,状态会恢复:snapshot(如果有)→ snapshot后的事件。

活动设计

强制属性(内核)

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" }
}
建议:
  • 命名:"域。action.v{major}`.
  • 可加性:新字段-可选,不改变旧字段的含义。
  • 极简主义:只有事实,不重复容易恢复的数据。

合同和计划

捕获电路(Avro/JSON Schema/Protobuf)并检查CI上的兼容性。
对于"中断"更改,是事件的新主要版本,并且在迁移期间并行发布"v1"/"v2"。

竞争性访问: 优化兼容

规则:只有在'expected_version==current_version'时才能记录新事件。

伪代码:
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

因此,我们保证了不分布式事务的不变量的完整性。

Snapshots(卷积加速)

每N事件或计时器进行一次狙击。

Храните `snapshot_state`, `aggregate_id`, `version`, `created_at`.

在snapshot之后总是检查和追赶事件(不要只相信演员)。
移除snapshots,以便可以将其从日志中重新放置(不要存储"魔术"字段)。

投影和CQRS

ES自然与CQRS配合:
  • Write模型=聚合+活动商店。
  • 阅读模型=事件更新的投影(Redis卡,OpenSearch用于搜索,ClickHouse/OLAP用于报告)。
  • 投影是偶然的:相同的"event_id"的重新处理不会改变结果。

电路的演变和互操作性

Additive-first:添加字段;不要改变类型/语义。
对于复杂的更改:发布新的事件类型并编写投影迁移器。
支持过渡期的双重录音("v1"+"v2"),并在所有投影准备就绪时拍摄"v1"。

安全,PII和"遗忘权"

历史通常包含敏感数据。方法:
  • 最小化事件中的PII(标识符而不是数据,部件在受保护的侧面)。
  • 加密擦除:加密字段,并在请求删除时销毁密钥(事件仍然存在,但数据不可用)。
  • 修订事件:'user。piiredacted.v1'替换投影中的敏感字段(历史记录保留了编辑事实)。
  • 转义策略:对于某些域,可以将某些事件存档到WORM存储中。

性能和扩展

分党:分组内的顺序很重要-通过"aggregate_id"分党。
冷启动:snapshots+周期性的"密封"卷积。
Batch-append:将事件分组为一个事务。
用于投影处理器的背景和DLQ;测量差值(消息的时间和数量)。
事件商店索引:通过"(aggregate_type,aggregate_id)"和时间快速访问。

测试

集合的规范测试:"命令→预期事件"脚本。
Projection tests:提交事件流并检查实例化状态/索引。
Replayability tests:从头开始重新包装展位上的投影-确保总数匹配。
Chaos/Latency:注入延迟和双击,检查等效性。

域示例

1)付款

事件: '支付。initiated`, `payment.authorized`, `payment.captured`, `payment.refunded`.

不变式:没有"授权"就无法进行"捕获";金额为非负数;货币不变。
投影:"支付卡"(KV),交易搜索(OpenSearch),报告(OLAP)。

2)订单(电子商务)

事件: 'order。placed`, `order.paid`, `order.packed`, `order.shipped`, `order.delivered`.

不变量:状态图中的状态过渡;在"shipped"之前可以取消。
投影:用户订单列表,按状态排列的SLA-dashbords。

3)资产负债表(财务/iGaming)

事件: 'balance。deposited`, `balance.debited`, `balance.credited`, `balance.adjusted`.

刚性不变性:平衡不会消失<0;根据"operation_id"命令是相等的。
关键操作直接从单元(严格的一致性)读取,UI从投影(事件)读取。

活动商店的类型结构(DB变体)

events

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

索引:"(aggregate_type,aggregate_id,版本)"。

snapshots

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

索引:"(aggregate_type,aggregate_id)"。

consumers_offsets

"consumer_id","event_id"/"position","updated_at"(用于投影和转发)。

常见问题(FAQ)

是否必须在任何地方使用ES?
没有。当审计,复杂的不变性,可重复性和不同的数据表示很重要时,ES很有用。对于简单的CRUD,这是多余的。

如何处理"最新状态"查询?

要么从投影中阅读(快速,事件),要么从集合中阅读(更贵,但严格)。关键操作通常使用第二种方法。

需要一个Kafka/流经纪人吗?

事件商店是真理的来源;经纪人方便将事件分发给投影仪和外部系统。

如何处理"遗忘权"?
最小化PII,加密敏感字段并在投影中应用加密擦除/修订。

如何迁移旧数据?

编写回顾性事件生成脚本("re-highstori")或从"状态不变"开始,仅发布新更改的事件。

反模式

Event Sourcing"按习惯":使系统复杂化,没有域收益。
Fat events:带有PII和双打的肿胀的薪水-制动器和合规性问题。
缺乏优化顺应性:赛车中不变量的丧失。
不可制作的投影:没有反射/snapshot →手持小玩意。
原始CDC作为域事件:DB方案泄漏和刚性连通性。
融合内部和整合事件:向外发布稳定的"展示柜"。

生产的支票清单

  • 定义聚合、不变量和事件(名称、版本、模式)。
  • Event Store在聚合和优化匹配中提供顺序。
  • 包括snapshots和重新构建它们的计划。
  • 投影是幂等的,有DLQ和滞后度量。
  • 方案在CI上验证,版本策略-记录在案。
  • PII最小化,字段加密,存在"遗忘"策略。
  • 在展台上检查投影的倒置;有一个灾难恢复计划。
  • Dashbords:上游速度,投影时差,应用错误,后退比例。

底线

Event Sourcing使系统的历史成为一流的人工制品:我们捕捉事实,从中复制状态并自由构建任何表示形式。这提供了审计,对变化的抵抗力和分析灵活性-受制于计划,竞争控制和对敏感数据的熟练处理。

Contact

联系我们

如需任何咨询或支持,请随时联系我们。我们随时准备提供帮助!

开始集成

Email — 必填。Telegram 或 WhatsApp — 可选

您的姓名 可选
Email 可选
主题 可选
消息内容 可选
Telegram 可选
@
如果填写 Telegram,我们也会在 Telegram 回复您。
WhatsApp 可选
格式:+国家代码 + 号码(例如:+86XXXXXXXXX)。

点击按钮即表示您同意数据处理。