运维
读模型重建手册
用 go-sequent 的 replay 流水线重建可丢弃的读模型:prepare、replay、catchup、optimize、golive,含库 API、CLI schema 阶段与运维提示。
读模型重建手册
Replay 流水线沿用 Sequent 8 的流程:prepare、replay、catchup、optimize、golive,另有可选的 abort。
账本与余额类 Projector(把事件写成查询用读模型,例如余额表)必须保持强一致,因此在线路径上仍是 SyncInTxn(在写事务里同步更新读模型)。重建用于可丢弃的读模型,或用历史数据填充一张新的读模型表。
库 API
pipe := &replay.Pipeline{
Name: "balances",
Source: eventSource, // 实现 StreamAll
Publisher: syncInTxnWithProjectorsOnly,
Schema: &replay.PostgresSchema{Pool: pool}, // 或 replay.NoopSchema{}
State: replay.NewMemoryState(), // 或你应用里基于数据库的 StateStore
ManagedTables: []string{"account_balances"},
}
if err := pipe.RunAll(ctx); err != nil {
return err
}
Pipeline 还提供 Prepare、Replay、Optimize、GoLive 与 Abort,可以逐阶段运行。其他字段有 ReplaySchema、ViewSchema 与 BatchSize。BatchSize 为 0 时,Replay 使用 1000。
Publisher 通过 PublishProjectorsOnly 重放,它不包含 Workflow,所以重建不会重新触发邮件、付款这类副作用。
State 是一个 StateStore。replay.NewMemoryState() 在进程退出后会丢失进度。如果重建需要跨重启存活,请使用持久化的存储。迁移创建的 projector_replay_states 表可用于此。
各阶段
| 阶段 | 动作 |
|---|---|
| prepare | 创建 replay_* schema,用 CREATE TABLE … (LIKE …) 创建受管表,并清空 |
| replay | 把历史事件流式投入重放用的 Projector 和表 |
| catchup | 在在线系统继续运行的同时,应用高水位之后追加的事件 |
| optimize | 执行 ANALYZE,按需添加索引 |
| golive | 短暂切换:把在线表移开,把重放表提升到 view schema |
| abort | DROP SCHEMA replay_* CASCADE |
CLI:只有 schema 阶段
CLI 负责重建中与 schema 相关的部分:
go run ./cmd/go-sequent migrate -dsn "$GO_SEQUENT_PG_DSN"
go run ./cmd/go-sequent replay -dsn "$GO_SEQUENT_PG_DSN" \
-projector balances -stage prepare -tables account_balances
# 之后按需:-stage optimize | golive | abort
CLI 接受 prepare、optimize、golive 与 abort 阶段。它无法流式读取事件,因为它不知道你注册了哪些 Projector。replay 与 catchup 阶段必须在你自己的应用二进制里,用上面的流水线运行。参见 Migrations 与 CLI。
运维提示
- 按事件量设置
BatchSize。批次大意味着往返少,但事务更长。 golive期间,如果你的切换不是无锁的,就暂停写入方,或短暂串行化。golive之后,余额的事实来源仍然是SyncInTxnProjector。- 通过
projector_replay_states或你自己的StateStore跟踪进度。 - 如果
golive前发现异常,执行abort。此时在线表尚未被动过。
相关
文档随 go-sequent 源码更新;若与 API 不一致,以源码为准。