现象(生产实测;租户信息已匿名)
一个生产租户库的 sys_notification_delivery:
| channel |
status |
行数 |
max(attempts) |
email |
dead |
2,876 |
1 |
inbox |
success |
2,876 |
1 |
零 pending。该租户没有配置邮件传输。
每条 notify(channels: ['inbox','email'])写 2 行投递,email 那行第一次尝试就死信。对象声明 lifecycle: { class: 'telemetry', retention: { maxAge: '90d' } } ⇒ 投递表在 90 天内线性增长,该库每天 +316 行。
为什么要紧
投递表是调度器每一跳都要查的热表(调度器空闲成本、驱动缺索引两张关联卡,编号见本卡评论)。这些死信行不再承载任何工作,却让每一次领取查询的代价随时间线性上涨。按目前速度,第 90 天该表约 2.8 万行。
需要裁决(附推荐)
- 推荐 A:fan-out 时解析渠道可用性。传输未配置的渠道不写投递行,在
sys_notification 上记录该渠道被抑制及原因。可审计,热表零成本
- B:照写,但直接落
suppressed(而非 dead),并为 dead / suppressed 这类终态行设更短的保留(例如 7d)
- C:只缩短终态行保留
A 最干净:热表只装有工作的行。B 保留逐条审计。C 治标不治本。
验收(按 A)
- 无邮件传输的租户:
notify 只写 inbox 投递行;notification 上可读到 email 被抑制的原因
- 有邮件传输的租户:行为不变
- 两种租户各有测试
现象(生产实测;租户信息已匿名)
一个生产租户库的
sys_notification_delivery:emaildeadinboxsuccess零 pending。该租户没有配置邮件传输。
每条
notify(channels: ['inbox','email'])写 2 行投递,email 那行第一次尝试就死信。对象声明lifecycle: { class: 'telemetry', retention: { maxAge: '90d' } }⇒ 投递表在 90 天内线性增长,该库每天 +316 行。为什么要紧
投递表是调度器每一跳都要查的热表(调度器空闲成本、驱动缺索引两张关联卡,编号见本卡评论)。这些死信行不再承载任何工作,却让每一次领取查询的代价随时间线性上涨。按目前速度,第 90 天该表约 2.8 万行。
需要裁决(附推荐)
sys_notification上记录该渠道被抑制及原因。可审计,热表零成本suppressed(而非dead),并为dead/suppressed这类终态行设更短的保留(例如 7d)A 最干净:热表只装有工作的行。B 保留逐条审计。C 治标不治本。
验收(按 A)
notify只写 inbox 投递行;notification 上可读到 email 被抑制的原因