PAYATHON 2026

如何在 Snowflake 中按不同功能拆分 billing?

支付阿杰

结论

如果需要清楚核算并限制不同业务功能的计算费用,建议为每项功能分配独立的 virtual warehouse,再按需为各 warehouse 配置 resource monitor。

Snowflake 无法将 warehouse 的计算费用直接绑定到某个 database 或 schema。查询产生的计算消耗记在执行该查询的 warehouse 上,而不是数据对象所属的 database 或 schema 上。此外,一条查询可能同时访问多个 database 或 schema,无法直接按照对象边界拆分计算费用。

resource monitor 可以监控和限制 credit 消耗,但不会自动拆分 Snowflake 账单。实际核算通常需要结合以下方式:

  • 使用独立 warehouse,建立清晰的计算成本边界。
  • 使用 QUERY_TAG 标记业务、功能、团队或项目。
  • 通过 SNOWFLAKE.ACCOUNT_USAGE 生成内部成本报表。
  • 使用 object tags、budgets 等功能管理成本归属和预算。具体能否使用,取决于账户版本、授权情况以及 Snowflake 当前提供的功能。

推荐方案:按功能拆分 warehouse

可以让 ETL、BI 查询和数据科学工作负载分别使用不同的 warehouse:

CREATE WAREHOUSE ETL_WH
  WAREHOUSE_SIZE = 'MEDIUM'
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED = TRUE;

CREATE WAREHOUSE BI_WH
  WAREHOUSE_SIZE = 'SMALL'
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED = TRUE;

CREATE WAREHOUSE DS_WH
  WAREHOUSE_SIZE = 'LARGE'
  AUTO_SUSPEND = 300
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED = TRUE;

再通过角色权限控制各团队能够使用的 warehouse:

GRANT USAGE ON WAREHOUSE ETL_WH TO ROLE ETL_ROLE;
GRANT USAGE ON WAREHOUSE BI_WH TO ROLE BI_ROLE;
GRANT USAGE ON WAREHOUSE DS_WH TO ROLE DATA_SCIENCE_ROLE;

这样便可以根据 warehouse 的计量记录核算费用:

SELECT
    warehouse_name,
    SUM(credits_used_compute) AS compute_credits,
    SUM(credits_used_cloud_services) AS cloud_services_credits,
    SUM(credits_used) AS total_credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD('month', -1, CURRENT_TIMESTAMP())
GROUP BY warehouse_name
ORDER BY total_credits DESC;

ACCOUNT_USAGE 视图的数据可能有延迟,不适合用作完全实时的用量控制机制。

使用 resource monitor 控制额度

不同的 warehouse 可以设置各自的额度。例如,为 BI warehouse 设置每月 credit 配额:

CREATE RESOURCE MONITOR BI_MONTHLY_MONITOR
  WITH CREDIT_QUOTA = 500
  FREQUENCY = MONTHLY
  START_TIMESTAMP = IMMEDIATELY
  TRIGGERS
    ON 75 PERCENT DO NOTIFY
    ON 90 PERCENT DO SUSPEND
    ON 100 PERCENT DO SUSPEND_IMMEDIATE;

ALTER WAREHOUSE BI_WH
  SET RESOURCE_MONITOR = BI_MONTHLY_MONITOR;

resource monitor 主要用于用户管理的 virtual warehouse。Snowflake 的部分 serverless 功能、存储费用及其他平台服务,并不会全部受到同一配额限制。

SUSPEND 和 SUSPEND_IMMEDIATE 会影响正在运行或之后提交的工作负载。在生产环境中设置这些阈值时要格外谨慎,以免关键任务意外中断。

无法拆分 warehouse 时使用 QUERY_TAG

如果多个功能必须共用一个 warehouse,可以为会话或查询添加业务标签:

ALTER SESSION SET QUERY_TAG = 'function=finance_reporting';

SELECT *
FROM analytics.finance.monthly_report;

应用程序也可以在执行任务前设置标签:

ALTER SESSION SET QUERY_TAG = 'function=customer_sync;team=crm';

之后可以按标签统计查询活动:

SELECT
    query_tag,
    warehouse_name,
    COUNT(*) AS query_count,
    SUM(total_elapsed_time) / 1000 AS elapsed_seconds,
    SUM(bytes_scanned) AS bytes_scanned
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD('month', -1, CURRENT_TIMESTAMP())
GROUP BY query_tag, warehouse_name
ORDER BY elapsed_seconds DESC;

不过,QUERY_HISTORY 中的运行时间和扫描字节数等指标,并不等于精确的 credit 消耗。warehouse 的费用取决于运行时间和规格,多个查询还可能并发执行。如果要在共享 warehouse 内部分摊成本,需要提前制定内部规则,例如按照查询执行时间、负载时间或扫描量进行分配。由此得到的是成本估算,并非 Snowflake 原生账单明细。

database 和 schema 能做什么

database 和 schema 适合划分以下内容:

  • 数据所有权;
  • 访问权限;
  • 生命周期和保留策略;
  • 存储量统计;
  • 对象标签与成本归属元数据。

但它们无法直接限制 warehouse 上运行的查询所消耗的 credits。例如,查询 SALES_DB 中的数据时,计算费用仍会计入当前使用的 warehouse:

USE WAREHOUSE BI_WH;
USE DATABASE SALES_DB;
USE SCHEMA REPORTING;

SELECT * FROM MONTHLY_SALES;

这次查询的计算消耗属于 BI_WH,不会自动记到 SALES_DB 或 REPORTING schema 名下。

存储成本可以根据 database 或 schema 中对象的占用量另行分析,但还要考虑 Time Travel、Fail-safe、克隆、暂存区和数据共享等因素。计算成本与存储成本应分别核算。

还需要单独考虑的费用

只按 warehouse 拆分,无法覆盖 Snowflake 的全部费用。完整的成本模型通常还要包括:

  • 数据存储;
  • cloud services;
  • serverless 功能;
  • automatic clustering;
  • Snowpipe;
  • materialized view maintenance;
  • search optimization;
  • replication 和跨区域数据传输。

这些项目对应的用量来源和计量视图各不相同,也不一定受 resource monitor 控制。如果某项功能由多个团队共用,可以借助相应的 usage view、对象标签或事先约定的规则分摊费用。

实际使用时,可以采用两层方案:先用独立 warehouse 建立可审计的计算成本边界,再用 QUERY_TAG 标记具体应用或任务。database 和 schema 更适合数据治理及存储归属,不应作为拆分 warehouse 计算费用的主要依据。

备注:内容仅供参考。