3. 成本可视化与分摊

成本可视化不是把账单数字画成图表,而是把“谁花了钱、花在什么上、为什么花”这三件事同时说清楚。Cloud Billing 报表提供开箱即用的聚合视图,BigQuery 账单导出提供逐行明细与任意维度组合,Looker Studio 则把查询结果变成可共享、可下钻的看板。三者构成一条从原始账单到问责视图的链路:Cloud Billing 导出 → BigQuery 明细表 → 视图/查询 → Looker Studio 看板。理解这条链路,才能让看板上的每个数字都能追溯到具体资源。

一、先理解账单数据的粒度与维度

BigQuery 账单导出表(通常命名为 gcp_billing_export_v1_<BILLING_ACCOUNT_ID>)是成本分摊的事实表。每一行代表一个“资源 × 时间 × 费用类型”的组合,关键字段包括:

  • project.id、project.name:项目维度,用于按项目分摊。
  • service.description、sku.description:服务与 SKU 维度,用于识别 Compute Engine、Cloud Storage、BigQuery 等具体消耗。
  • labels(数组,含 key/value):标签维度,是自定义分摊的核心。
  • cost、usage.amount、usage.unit:金额与用量,注意 cost 已含折扣与信用额影响。
  • credits(数组):承诺使用折扣、促销、Sustained Use Discount 等抵扣明细。
  • usage_start_time、usage_end_time:时间维度,用于按天/月聚合。

需要特别说明:cost 是净额,credits 中的抵扣会以负值体现。若看板只展示 cost 而不拆分 credits,团队会误以为折扣没有生效。因此分摊视图通常同时输出“原始成本”和“抵扣后净成本”两列。

二、用 BigQuery 视图固化分摊逻辑

不要在每个看板里重复写 SQL,而是先建一个标准化视图,把项目、标签、服务、月份、净成本统一成稳定字段。下面是一个可直接参考的示例视图(示例参数,实际请替换为自己的账单项目与数据集):

CREATE OR REPLACE VIEW `finops.billing.cost_by_dimension` AS
SELECT
  invoice.month                                   AS billing_month,
  project.id                                      AS project_id,
  project.name                                    AS project_name,
  service.description                             AS service_name,
  sku.description                                 AS sku_name,
  IFNULL((SELECT value FROM UNNEST(labels)
          WHERE key = 'team'), 'unlabeled')       AS team_label,
  IFNULL((SELECT value FROM UNNEST(labels)
          WHERE key = 'env'), 'unlabeled')        AS env_label,
  SUM(cost)                                       AS gross_cost,
  SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS credit_amount,
  SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) c), 0)) AS net_cost
FROM `my-billing-project.billing_export.gcp_billing_export_v1_01A2B3`
GROUP BY 1,2,3,4,5,6,7;

这个视图做了三件关键事:把 labels 数组展开为 team、env 两个可分组字段;把 credits 单独汇总为 credit_amount;用 gross_cost + credit_amount 得到 net_cost。注意 credits 的 amount 本身为负,所以是相加而非相减。若某资源没有打标签,会归入 unlabeled,这正是后续治理的抓手。

标签是分摊的前提。建议在资源创建阶段就通过组织策略或 Terraform 强制注入 team、env、cost-center 三类标签,否则看板上会出现大量 unlabeled,分摊就失去意义。

三、Looker Studio 看板的结构设计

看板不应是一堆图表的堆砌,而应按“总览 → 下钻 → 异常”三层组织。第一层用记分卡展示本月净成本、环比变化、预算消耗率;第二层用时间序列看趋势,用条形图按项目/服务/标签排序;第三层用表格列出 Top 10 成本增长项,并允许点击下钻到 SKU 级别。Looker Studio 连接 BigQuery 时,建议直接使用上面的视图作为数据源,而不是连接原始导出表,这样字段语义清晰、查询量可控。

一个实用的做法是设置日期范围控件和维度筛选器(项目、team、env),让同一张看板既能给财务看全局,也能给团队看自己那一份。对于“按标签分摊”的诉求,用饼图或堆叠条形图展示各 team 的净成本占比,并保留 unlabeled 作为一个独立扇区——它的存在本身就是治理信号。

成本可视化与分摊链路:从账单明细到问责看板 Cloud Billing 导出 gcp_billing_export_v1 逐行:资源×时间×费用 含 cost / credits / labels BigQuery 明细表 project / service / sku labels 数组展开 credits 抵扣明细 标准化视图 cost_by_dimension gross_cost / credit_amount net_cost / team / env Looker Studio 看板 三个分摊维度在看板中的落点 按项目 project.id / project.name 回答:哪个项目在花钱 按标签 labels: team / env / cost-center 回答:哪个团队该负责 按服务 service / sku description 回答:钱花在什么资源上 看板三层结构 第一层:总览记分卡 净成本 / 环比 / 预算消耗率 第二层:趋势与排序 时间序列 + 项目/服务/标签条形图 第三层:异常下钻 Top 增长项 → SKU 级明细

四、从看板到问责:让数字可行动

看板的价值在于驱动行动。建议在看板中固定三个判断指标:unlabeled 成本占比(目标低于 5%)、预算消耗率(当月净成本 ÷ 月度预算)、环比增长率(本月 vs 上月净成本)。当 unlabeled 占比升高,说明新资源没有打标签,应回到资源创建流程修复;当某 team 的预算消耗率超过 100%,看板应能下钻到具体 service 和 sku,定位是 Compute Engine 实例规格过大,还是 Cloud Storage 存储类别不合理。

实操中一个常见问题是时区与账期不一致。BigQuery 中 usage_start_time 为 UTC,而财务账期可能按本地时间或自然月划分。若看板直接按 UTC 月份聚合,月末几小时的用量可能被计入下月,造成对账差异。解决方式是在视图中显式转换时区,例如 DATE(usage_start_time, "Asia/Shanghai"),并在看板标题中标注账期口径,确保财务与工程看到的是同一套数字。

不要用 Cloud Billing 报表的“按标签筛选”直接替代 BigQuery 分摊视图。Cloud Billing 报表对标签的支持有限,且无法自定义 credits 拆分逻辑;一旦需要按 team 分摊承诺使用折扣,仍必须回到 BigQuery 视图完成。

五、一个可复用的分摊检查清单

检查项判断标准不达标时的动作
标签覆盖率unlabeled 净成本占比 < 5%在资源创建模板中强制注入 team/env 标签
credits 拆分看板同时展示 gross_cost 与 net_cost在视图中单独汇总 credits.amount
账期口径看板月份与财务账期一致视图中统一转换为 Asia/Shanghai 时区
下钻路径可从项目下钻到 service 再到 sku在 Looker Studio 中配置层级维度
预算对照每个 team 有明确月度预算值建立预算表并与净成本视图关联

把上述视图、看板三层结构和检查清单落地后,成本分摊就从“月底财务发一张总账单”变成“每个团队随时能看到自己那份、并能定位到具体资源”的持续过程。这正是 FinOps 中“可视化 → 分摊 → 问责 → 优化”闭环的起点。