如何基于 Prometheus 采集 Cloud SQL 的自定义指标?

解读

在国内云原生面试中,这道题考察的是“全托管数据库”与“可观测性体系”的桥接能力。
面试官想确认:

  1. 你是否理解 Cloud SQL 作为 全托管服务 的观测边界——Google 只暴露它愿意暴露的指标,自定义指标必须自己“造”
  2. 你是否能把 Cloud SQL 的指标纳入国内最常用的 Prometheus 体系,同时兼顾 合规(跨境数据不可出境)安全(Private Service Connect/私网打通)成本(无公网出流量)
  3. 你是否具备 “指标语义设计” 能力,而不仅仅是“把数拉下来”。

一句话:不是“能不能采”,而是“怎么采得准、采得稳、采得便宜”

知识点

  1. Cloud SQL 指标来源

    • Google Cloud Monitoring API 提供的 Metric Descriptor,命名空间 cloudsql.googleapis.com,仅含 Google 预定义指标(CPU、QPS、磁盘 I/O 等),不支持自定义 SQL 级指标
    • 自建 Exporter 才是自定义指标唯一路径:通过 Cloud SQL Auth Proxy + 私网 IP 直连实例,执行 SQL 采集,再转成 Prometheus 格式。
  2. 国内网络合规

    • 跨境问题:Google Cloud Monitoring API 默认走 monitoring.googleapis.com,数据需经香港或新加坡,国内金融、政企场景直接否决
    • 解决方案
      – 在 国内 GCP 合作伙伴(如神州数码)VPC 内起 GKE Autopilot 集群,通过 Private Service Connect + Private Google Accessmonitoring.googleapis.com 解析到 国内边缘节点,流量不出境。
      – 若客户无 GCP 账号,可退而求其次:用 Cloudberry 出口节点HTTPS 反向代理,但需签 数据不出境承诺书
  3. 指标语义设计

    • 业务层orcl_order_delay_seconds{shard="db-order-0"} 由应用埋点,与 Cloud SQL 解耦,Prometheus 直接拉应用 /metrics
    • 数据库层cloudsql_custom_lock_wait_ratio 通过 Exporter 每秒执行
      SELECT count(*) FILTER (WHERE wait_event_type='Lock') / GREATEST(count(*),1) AS ratio
      FROM pg_stat_activity;
      
      返回 Gauge,标签带上 database、replica_role,方便 Sharding 场景下做 分片级告警
  4. 高可用与权限

    • 连接串:使用 Cloud SQL Auth ProxyUnix Socket 模式,避免把密码写进 Deployment,Sidecar 容器通过 Workload IdentityService Account Token最小权限仅授予 roles/cloudsql.client
    • 容灾:Exporter 以 DaemonSet 部署在 同 Region 不同 Zone 的节点,Prometheus 联邦 一层在 GKE 集群内,一层在 国内可观测性中台(如夜莺、Thanos Receive),实现 跨可用区双写
  5. 成本优化

    • 采样频率:自定义指标 15 s 拉一次 即可,不要 5 s,否则 Cloud SQL 连接数打满会触发 $0.015/小时 的额外费用
    • 指标基数:标签值必须 枚举可控,禁止把 user_id 做标签,单指标基数 < 1000,防止 Prometheus 内存 OOM

答案

分五步落地:

  1. 网络打通
    国内合作伙伴 VPC 创建 GKE Autopilot 集群,开启 Private Google Access,通过 Private Service Connectmonitoring.googleapis.com 解析到 国内边缘,确保 数据不出境

  2. 权限最小化
    Exporter 专用 Service Account 仅授予 roles/cloudsql.client禁用 Project Owner,并启用 VPC Service Controls 把 Cloud SQL 实例圈进 Perimeter,防止 数据被意外复制到境外

  3. Exporter 实现
    Go 写自定义 Exporter,逻辑:

    • 通过 Cloud SQL Auth Proxy Unix Socket 连接实例;
    • 每 15 s 执行 预定义 SQL 文件(放在 ConfigMap),把结果映射为 Prometheus Gauge/Counter;
    • SQL 示例
      SELECT datname,
             count(*) AS idle_in_txn,
             'gauge' AS type
      FROM pg_stat_activity
      WHERE state = 'idle in transaction'
      GROUP BY datname;
      
    • HTTP 端口只监听 ClusterIP不暴露公网
  4. Prometheus 集成
    GKE 集群内kube-prometheus-stack,通过 ServiceMonitor 选中 Exporter,relabel__meta_kubernetes_pod_annotation_cloudsql_instance 转成 instance_id 标签,方便与 Google 预定义指标联合查询

  5. 合规审计

    • 日志:Exporter 容器把 SQL 执行记录 打到 stdoutCloud Logging 通过 Log Router 转存到 国内合作伙伴 OSS Bucket保留 30 天
    • 巡检:每周跑 PromQL
      increase(prometheus_target_scrapes_exceeded_sample_limit_total[1w]) > 0
      
      若大于 0,立即 降低采样频率裁剪标签

一句话总结:“用私网 Auth Proxy 做连接,用自建 Exporter 做语义,用国内边缘节点做合规,用 Prometheus ServiceMonitor 做集成,用 VPC Service Controls 做审计。”

拓展思考

  1. Serverless 场景
    如果客户是 Cloud Run + Cloud SQL,实例 无公网 IP,Exporter 只能以 Sidecar 形式打包进 Cloud Run Revision,但 Cloud Run 最小实例数=0 时 Exporter 也会缩容到 0,导致指标断点
    解法:把 Exporter 拆成 Cloud Run Job每 1 min 触发一次,把指标 push 到国内 Prometheus Pushgateway(通过 VPC Connector)断点用 timestamp() 函数回填,保证 SLI 连续性

  2. 多云一致性
    国内部分业务在 阿里云 RDS,部分在 Cloud SQL,需要 统一 SLI
    方案

    • 定义 OpenMetrics 标准指标名db_transaction_duration_seconds{engine="postgres",cloud="gcp"}
    • Thanos Receive多写,**Router 层根据 {cloud=~"gcp|aliyun"}降采样与长期存储
    • Grafana 仪表板只依赖 标准标签底层云厂商差异对业务透明
  3. AI4DB 前沿
    把自定义指标 实时写入 BigQuery(国内边缘节点),用 Vertex AI Gemini异常检测预测锁等待飙升预测结果Prometheus 指标 形式 回写联邦层实现“AI 生成指标”闭环