跳到正文

运维

分区指南

在共享 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(多租户)。

推荐做法

  1. 通过命令、事件、聚合与读模型上的 tenant_id 保持逻辑多租户。
  2. 把 partition_key 设为 tenant_id,或租户加哈希,以获得流的局部性。
  3. 如有需要,把 events 转成分区父表。每个租户哈希桶一个分区;超大租户则一个租户一个分区。
  4. aggregate_unique_keys 在 schema 内保持全局。用 tenancy.UniqueScope 让唯一键作用域包含租户。
  5. 不要把每租户一个 schema 作为产品模型。

行级安全

基于 tenant_id 的行级安全(RLS)是可选的,可加深防御。仍然要在 Repository 与加载时强制检查租户匹配。见 Tenancy(多租户)。

与高可用和备份的关系

  • 分区裁剪对主库和从库都有帮助。重建 worker 应按分区范围过滤。
  • 备份仍然是集群级别,见 备份与恢复。

示例 SQL

仓库里的 docs/ops/sql/events_partition_by_tenant_hash.example.sql 演示了按租户哈希分区。它不会被自动应用。

相关

文档随 go-sequent 源码更新;若与 API 不一致,以源码为准。