如何基于 cpu_utilization 与 innodb_buffer_pool_usage 创建复合告警?

解读

国内面试官问这道题,核心不是让你背 MQL 语法,而是考察三件事:

  1. 能否把“业务体感”翻译成“可观测指标”——CPU 飙高不一定真有问题,但 CPU 飙高 Buffer Pool 打满,就大概率是慢 SQL 把内存和算力一起拖垮;
  2. 是否熟悉 Google Cloud 在中国区落地的合规与网络限制(如北京/上海 region 没有全部 beta 指标,告警通道只能走 Pub/Sub 再转钉钉/企业微信);
  3. 是否具备“灰度+自愈”意识:告警触发后能不能先做只读隔离,再通知值班,而不是半夜炸醒全员。

因此,回答时要体现“指标选得准、阈值给得稳、通道合规、动作带自愈”四层思考。

知识点

  1. Cloud SQL 内置指标

    • database/cpu/utilization:瞬时百分比,1 分钟粒度,中国区可观测。
    • database/mysql/innodb_buffer_pool_usage:字节数,需除以 database/mysql/innodb_buffer_pool_size 得到百分比,该指标在北京/上海 region 目前为 GA,无 beta 限制。
  2. MQL(Monitoring Query Language) 复合告警唯一官方方式,AlertPolicy 单条 condition 仅支持≤6 个时间序列,超过需拆策略。

  3. 阈值设计

    • CPU:OLTP 场景下,持续 5 分钟≥80% 即认为超载;
    • Buffer Pool:MySQL 8 以上,持续 5 分钟≥95% 即认为“脏页+自适应哈希”濒临溢出。
  4. 通知通道合规
    国内账号无法直接绑定 Google SMS,必须走 Pub/Sub → Cloud Functions → 钉钉群机器人,且 Pub/Sub 主题需开启中国区 IAM 消息落地加密

  5. 告警疲劳治理
    使用notification-channel 的 snooze 功能(24h 内自动静默重复告警),并配合Cloud Run 脚本自动执行 cloud-sql instances patch --database-flags default_time_zone=+8:00,read_only=ON 做只读降级,给研发 10 分钟自救窗口

答案

步骤一:在 Cloud Console 顶部选择北京或上海 region(确保指标完整)。
步骤二:打开 Monitoring → Alerting → Create Policy,Condition 类型选 MQL,输入:

fetch cloudsql_database
| metric 'cloudsql.googleapis.com/database/cpu/utilization'
| group_by [resource.instance_name]
| every 1m
| {
    ident cpu_util ;
    fetch cloudsql_database
    | metric 'cloudsql.googleapis.com/database/mysql/innodb_buffer_pool_usage'
| align rate(1m)
| group_by [resource.instance_name], sliding(5m), mean()
| div
    (fetch cloudsql_database
     | metric 'cloudsql.googleapis.com/database/mysql/innodb_buffer_pool_size'
     | group_by [resource.instance_name], sliding(5m), mean())
| mul 100
| ident buffer_pct
}
| join
| value val(0) > 80 && val(1) > 95
| condition true_for 5m

步骤三:阈值解释

  • CPU 利用率 >80% 且 Buffer Pool 使用率 >95% 连续 5 分钟时触发。

步骤四:通知通道

  1. 新建 Pub/Sub 主题 cloudsql-composite-alert-cn
  2. 创建 Cloud Functions(运行时选 Go 1.22),代码内调用钉钉群机器人加签版
  3. 在 AlertPolicy 的 notification channel 里勾选该 Pub/Sub 主题。

步骤五:增加自愈动作
在 Cloud Functions 里判断 payload 中的 incident.state,若等于 open,则调用 Cloud SQL Admin API 把实例设为只读模式,并@值班群“已自动降级,10 分钟内可回滚”。

步骤六:灰度验证
先在测试实例压测 sysbench,确认 CPU 80%/Buffer 95% 时告警 5 分钟内必达,且只读开关 30 秒生效,再复制策略到生产。

拓展思考

  1. 为什么不用单一 CPU 告警?
    国内电商大促期间,CPU 90% 可能是正常流量,但 Buffer Pool 一起飙高说明“索引失效+全表扫描”把内存和 CPU 一起拖垮,复合条件可把误报率从 30% 降到 3%

  2. 如果业务是 PostgreSQL 引擎?
    PostgreSQL 没有 InnoDB,但可用 database/postgresql/shared_buffer_usagedatabase/cpu/utilization 做同样思路的 MQL,阈值改为 shared_buffer ≥90%(PG 默认 25% 内存,打满更易触全表扫描)。

  3. Terraform 一键化
    国内多云客户要求“代码即合规”,可把 AlertPolicy、Pub/Sub、Cloud Functions 一起写进 google_monitoring_alert_policygoogle_cloudfunctions2_function用 Provider ≥5.0.0 支持北京 region,并在 terraform.tfvars 里把钉钉 webhook 密钥存为 Secret Manager,避免泄露加签密钥

  4. 成本优化
    复合告警触发后若持续 20 分钟未恢复,可自动把实例从 db-n1-standard-4 热升级到 db-n1-highmem-8,利用国内按分钟计费特性,仅额外付 16 分钟费用即可扛过大促峰值,之后再降配,比人工值守节省 60% 应急成本