运维
分区指南
在共享 schema + tenant_id 模型内,何时以及如何对 go-sequent 事件库做分区:partition_key、触发条件、推荐步骤、可选 RLS 与示例 SQL。
分区指南
**模型:**一个共享 schema,带 tenant_id 列与钩子。不是每租户一个 schema,也不是每租户一个数据库。
物理分区是可选的,并且停留在这个共享 schema 之内。迁移创建的是未分区的表。仓库里 docs/ops/sql/ 下的 SQL 仅作参考,请在容量评估之后有意识地应用。store.Migrate 与 go-sequent migrate 永远不会执行它。
何时分区
| 症状 | 候选方案 |
|---|---|
events 远超几十 GB,或 vacuum 压力大 |
按 partition_key 分区,通常是 tenant_id 或 tenant_id:shard |
commands 非常大 |
按时间做 range 分区,或按 id 做 hash 分区 |
| 很少跨租户扫描 | 优先选择与加载过滤条件一致、利于裁剪的键 |
go-sequent 已经保存 events.partition_key 与 aggregates.events_partition_key。用 tenancy.PartitionKey 或 tenancy.PartitionKeyHashed 设置分区键:
key := tenancy.PartitionKey(tenantID) // tenantID 是 uuid.UUID
// 或者把一个大租户分散到多个桶,再传入一个 shard 字符串:
hashed := tenancy.PartitionKeyHashed(tenantID, shard)
其他辅助函数见 Tenancy(多租户)。
推荐做法
- 通过命令、事件、聚合与读模型上的
tenant_id保持逻辑多租户。 - 把
partition_key设为tenant_id,或租户加哈希,以获得流的局部性。 - 如有需要,把
events转成分区父表。每个租户哈希桶一个分区;超大租户则一个租户一个分区。 aggregate_unique_keys在 schema 内保持全局。用tenancy.UniqueScope让唯一键作用域包含租户。- 不要把每租户一个 schema 作为产品模型。
行级安全
基于 tenant_id 的行级安全(RLS)是可选的,可加深防御。仍然要在 Repository 与加载时强制检查租户匹配。见 Tenancy(多租户)。
与高可用和备份的关系
- 分区裁剪对主库和从库都有帮助。重建 worker 应按分区范围过滤。
- 备份仍然是集群级别,见 备份与恢复。
示例 SQL
仓库里的 docs/ops/sql/events_partition_by_tenant_hash.example.sql 演示了按租户哈希分区。它不会被自动应用。
相关
文档随 go-sequent 源码更新;若与 API 不一致,以源码为准。