34.5 流量型止血动作
流量型止血的目标不是让所有请求都继续进入,而是让系统重新获得完成有价值工作的 能力。在过载区间里,少接收一些工作通常比全部接收、全部超时更可用。
34.5.1 限流、熔断、摘除非关键负载
越靠近来源,拒绝成本越低
client / edge
-> application admission
-> local pool
-> proxy / PgBouncer
-> PostgreSQL在应用 admission 拒绝一个尚未创建事务的请求,成本通常远低于让它拿到 database connection、执行一半、生成 WAL 后再取消。因此控制顺序优先:
- 阻止新的低优先级到达;
- 冻结无抖动重试、autoscaling 和批量 worker 扩张;
- 缩小 batch/report/migration pool;
- 对依赖数据库的非关键功能打开熔断或静态降级;
- 最后才在数据库内取消已经进入的 exact work。
限流、熔断、摘流回答不同问题
| 控制 | 回答 | 典型状态 |
|---|---|---|
| rate limit | 单位时间允许多少新工作 | token/leaky bucket |
| concurrency limit | 同时允许多少在途工作 | semaphore/pool |
| queue bound | 等待多少、等多久 | length + deadline |
| circuit breaker | 下游失败时是否继续尝试 | closed/open/half-open |
| load shedding | 哪类工作先被拒绝 | priority/admission class |
| route removal | 哪个后端不再接新流量 | health/maintenance state |
熔断打开不等于数据库恢复;它只是停止继续伤害下游。half-open probe 必须有很小并发, 否则所有实例同时探测会形成下一轮风暴。
按业务价值而不是技术便利舍弃
一个可执行的 shedding 顺序需要产品 owner 参与:
preserve:
- payment commit
- authentication write
- incident/admin probe
degrade:
- recommendation to cached response
- dashboard to stale snapshot
pause:
- ETL
- report export
- reindex/migration
reject:
- best-effort refresh“所有 SELECT 都是低价值”或“写都更重要”并不成立。某些 read 是支付授权前置条件, 某些 write 只是可重算的埋点。
34.5.2 取消查询、暂停批处理与只读降级
取消只命中已证明的工作集
安全筛选示例:
WITH target AS (
SELECT pid, backend_start
FROM pg_stat_activity
WHERE application_name LIKE 'report-worker:%'
AND state = 'active'
AND query_start < clock_timestamp() - interval '30 seconds'
AND pid <> pg_backend_pid()
)
SELECT pid,
backend_start,
pg_cancel_backend(pid) AS signaled
FROM target;生产中还应绑定数据库、role、query/job tag、变更单与 owner。LIKE 'report-worker:%'
只有在 application_name 受治理、不能被任意业务伪造时才够用。
取消后等待并验收,不要立即升级为 terminate:
target sessions disappear or become idle/aborted
root lock releases
waiters make progress
application does not recreate work
useful completion rate rises
rollback/recovery cost remains bounded暂停 producer 比逐条 cancel 更有效
batch 系统通常有 scheduler、queue consumer 或 worker deployment。先暂停 producer, 再处理 in-flight work;否则数据库每取消一条,调度器就补一条。暂停要记录:
queue name and partition
last acknowledged item/checkpoint
in-flight ownership
resume condition
duplicate/replay semantics
maximum backlog after pause如果任务没有 checkpoint 与幂等性,暂停本身可能产生业务不一致,需要应用 owner 决策。
只读降级有一致性前提
把读流量移到 replica 可以减少 primary 的部分 CPU/I/O,但必须回答:
can this operation tolerate replica lag?
does it require read-your-write or monotonic reads?
will long reads delay replay or create conflicts?
does replica share the same storage/CPU failure domain?
is offline/analytics capacity isolated?
what happens when no eligible replica exists?不要把写请求改成“返回成功但不落库”,除非业务明确设计了 durable queue/ledger 和补偿。 也不要把所有查询涌向一台 replica:这可能让 replay 落后,进一步破坏读语义和 HA 候选质量。
Pigsty 的 replica/offline 服务可以表达路由意图,不能替代这些语义判断。路由后用
pg_is_in_recovery()、transaction_read_only、replay lag 与业务 token 复核。
34.5.3 每个动作写清收益、代价、停止条件和回退
动作卡,而不是命令清单
action_id: FLOW-07
hypothesis:
report batch consumes the OLTP server pool
target:
application_name_prefix: "report-worker:"
pool: report
expected_benefit:
free_at_least_connections: 12
reduce_lock_waiters_below: 3
cost:
report_jobs_paused: true
duplicate_risk: reconciled-by-job-id
guard:
exclude_admin_and_oltp: true
stop_condition:
useful_tps_not_improved_after: 120s
rollback_io_exceeds_baseline_by: 2x
rollback:
restore_pool_limit: after 15m stable window
evidence:
before: ...
after: ...
owner: ...四个字段不可省:
- 收益:哪个指标应在多长时间内变化;
- 代价:谁被拒绝、延迟或需要补偿;
- 停止条件:什么证据说明假设错误或副作用更大;
- 回退:如何撤销临时配置、恢复任务并验证没有重放。
一次只改变可辨识的控制变量
同时扩容、重启、cancel、改 pool 和改路由,曲线即使恢复也无法知道哪个动作有效; 某个有害动作可能被另一个动作掩盖。事故很急时可以并行动作,但必须按独立目标分组, 记录精确时间和 owner:
T0 admission limit
T1 batch pause
T2 exact cancel
T3 service probe recovery
T4 queue below stop threshold涉及同一变量的相反动作不能并发,例如一个人缩 pool、另一个人扩大 max_connections。
止血成功的定义
至少同时满足:
user success and tail latency recover
queue/rejection trend is understood
database has resource headroom, not merely lower traffic
replicas/archive/backup remain healthy
no unknown large rollback or retention boundary remains
temporary controls have owner, expiry and rollback evidence服务恢复后不要马上取消全部限流。先保持观察窗口,逐级放量;每一级都验证完成率、 尾延迟、资源余量与重试量。一次把 backlog 全部释放,会制造第二次尖峰。
上一节:CPU、内存、I/O 与 OOM · 返回本章目录 · 下一节:保留型故障的安全路由 · 查看全书目录 · 查看索引中心