<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cardinality on Tarragon</title><link>https://tarrragon.github.io/blog/tags/cardinality/</link><description>Recent content in Cardinality on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 22 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/cardinality/index.xml" rel="self" type="application/rss+xml"/><item><title>4.C14 觀測平台成本治理：從帳單驚嚇到可預測成本</title><link>https://tarrragon.github.io/blog/backend/04-observability/cases/observability-cost-governance-at-scale/</link><pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/04-observability/cases/observability-cost-governance-at-scale/</guid><description>&lt;p>觀測成本治理案例來自多家企業的共同經驗：觀測平台帳單每季成長 30%，管理層問「為什麼監控這麼貴」但沒人能歸因。問題的核心不是「花太多」而是「花在哪不知道」— 沒有 per-team cost attribution 的觀測平台，成本優化只能靠全域砍 retention 或降 sampling，兩者都會傷害觀測品質。&lt;/p>
&lt;h2 id="業務背景">業務背景&lt;/h2>
&lt;p>這個案例綜合三個組織的經驗模式：&lt;/p>
&lt;p>一家中型 SaaS 公司用 Datadog 做全端觀測（APM + logs + metrics + RUM）。月帳單從 $15K 成長到 $60K，兩年內四倍。CFO 問 CTO「這筆錢買到什麼」，CTO 轉問 platform team，platform team 說不出哪些團隊佔多少。&lt;/p>
&lt;p>一家金融科技公司自建 Grafana Stack（Prometheus + Loki + Tempo + Mimir）。自建沒有 SaaS 帳單，但 Kubernetes 節點跟 storage 的成本持續增加。infra team 知道 Mimir 的 storage 在成長，但不知道是哪些 metric label 造成的 cardinality 爆炸。&lt;/p>
&lt;p>一家遊戲公司用 CloudWatch 做 AWS 原生觀測。Logs 的 ingestion 費用佔帳單 70%，但追查後發現 90% 是 debug-level log，只在排錯時用到，平常沒人查。&lt;/p>
&lt;h2 id="技術挑戰">技術挑戰&lt;/h2>
&lt;h3 id="沒有-cost-attribution">沒有 cost attribution&lt;/h3>
&lt;p>觀測帳單通常是 organization-level 的一筆支出。SaaS 帳單按 hosts、custom metrics、log volume、APM spans 計費；自建平台按 compute 跟 storage 計費。兩種模式都缺少「這些費用是哪個 team / service 造成的」的歸因。&lt;/p>
&lt;p>沒有 attribution 的後果是所有優化都是全域操作 — 砍 retention 從 30 天到 7 天影響所有人，降 sampling 從 100% 到 10% 影響所有服務。需要觀測資料的團隊被平均到成本節省裡，不需要的團隊搭便車。&lt;/p>
&lt;h3 id="cardinality-爆炸">Cardinality 爆炸&lt;/h3>
&lt;p>Metrics 成本的主要 driver 是 cardinality — unique label combination 的數量。常見的 cardinality 爆炸來源：&lt;/p>
&lt;ul>
&lt;li>把 user ID 或 request ID 放進 metric label（每個 unique user 產生一組 series）&lt;/li>
&lt;li>動態的 endpoint path（&lt;code>/api/users/123&lt;/code> 每個 user ID 是一個 label value）&lt;/li>
&lt;li>多租戶 label 過細（tenant × region × service × endpoint 的笛卡兒積）&lt;/li>
&lt;/ul>
&lt;p>一個失控的 label 可以讓 series 數量從 10 萬跳到 1000 萬。SaaS 的計費是 per custom metric，自建的代價是 Prometheus / Mimir 的 memory 跟 storage。&lt;/p>
&lt;h3 id="log-volume-失控">Log volume 失控&lt;/h3>
&lt;p>Debug-level log 在開發階段有用，但 production 環境裡通常只在排錯時被查。全量 debug log 送進 hot tier（Elasticsearch、Loki、CloudWatch Logs）的 ingestion 跟 storage 成本是最大的 log 成本來源。&lt;/p>
&lt;p>問題是沒人敢降 debug log — 「萬一出事需要 debug log 怎麼辦」。恐懼驅動的 log level 設定讓 log volume 只升不降。&lt;/p></description><content:encoded><![CDATA[<p>觀測成本治理案例來自多家企業的共同經驗：觀測平台帳單每季成長 30%，管理層問「為什麼監控這麼貴」但沒人能歸因。問題的核心不是「花太多」而是「花在哪不知道」— 沒有 per-team cost attribution 的觀測平台，成本優化只能靠全域砍 retention 或降 sampling，兩者都會傷害觀測品質。</p>
<h2 id="業務背景">業務背景</h2>
<p>這個案例綜合三個組織的經驗模式：</p>
<p>一家中型 SaaS 公司用 Datadog 做全端觀測（APM + logs + metrics + RUM）。月帳單從 $15K 成長到 $60K，兩年內四倍。CFO 問 CTO「這筆錢買到什麼」，CTO 轉問 platform team，platform team 說不出哪些團隊佔多少。</p>
<p>一家金融科技公司自建 Grafana Stack（Prometheus + Loki + Tempo + Mimir）。自建沒有 SaaS 帳單，但 Kubernetes 節點跟 storage 的成本持續增加。infra team 知道 Mimir 的 storage 在成長，但不知道是哪些 metric label 造成的 cardinality 爆炸。</p>
<p>一家遊戲公司用 CloudWatch 做 AWS 原生觀測。Logs 的 ingestion 費用佔帳單 70%，但追查後發現 90% 是 debug-level log，只在排錯時用到，平常沒人查。</p>
<h2 id="技術挑戰">技術挑戰</h2>
<h3 id="沒有-cost-attribution">沒有 cost attribution</h3>
<p>觀測帳單通常是 organization-level 的一筆支出。SaaS 帳單按 hosts、custom metrics、log volume、APM spans 計費；自建平台按 compute 跟 storage 計費。兩種模式都缺少「這些費用是哪個 team / service 造成的」的歸因。</p>
<p>沒有 attribution 的後果是所有優化都是全域操作 — 砍 retention 從 30 天到 7 天影響所有人，降 sampling 從 100% 到 10% 影響所有服務。需要觀測資料的團隊被平均到成本節省裡，不需要的團隊搭便車。</p>
<h3 id="cardinality-爆炸">Cardinality 爆炸</h3>
<p>Metrics 成本的主要 driver 是 cardinality — unique label combination 的數量。常見的 cardinality 爆炸來源：</p>
<ul>
<li>把 user ID 或 request ID 放進 metric label（每個 unique user 產生一組 series）</li>
<li>動態的 endpoint path（<code>/api/users/123</code> 每個 user ID 是一個 label value）</li>
<li>多租戶 label 過細（tenant × region × service × endpoint 的笛卡兒積）</li>
</ul>
<p>一個失控的 label 可以讓 series 數量從 10 萬跳到 1000 萬。SaaS 的計費是 per custom metric，自建的代價是 Prometheus / Mimir 的 memory 跟 storage。</p>
<h3 id="log-volume-失控">Log volume 失控</h3>
<p>Debug-level log 在開發階段有用，但 production 環境裡通常只在排錯時被查。全量 debug log 送進 hot tier（Elasticsearch、Loki、CloudWatch Logs）的 ingestion 跟 storage 成本是最大的 log 成本來源。</p>
<p>問題是沒人敢降 debug log — 「萬一出事需要 debug log 怎麼辦」。恐懼驅動的 log level 設定讓 log volume 只升不降。</p>
<h3 id="trace-sampling-恐懼">Trace sampling 恐懼</h3>
<p>類似的恐懼存在於 trace sampling — 「如果剛好那筆有問題的 request 被 sample 掉怎麼辦」。100% tracing 的成本在中等規模（每秒數萬 request）就開始顯著。</p>
<h2 id="解法">解法</h2>
<h3 id="cost-attribution-by-team--service">Cost attribution by team / service</h3>
<p>第一步是讓成本可見，歸因先於優化。</p>
<p>SaaS 平台：用 Datadog 的 usage attribution 或 Grafana Cloud 的 usage reporting 把 ingestion 按 service tag / team tag 拆分。每個 team 看到自己的 metric series、log volume 跟 span 數量。</p>
<p>自建平台：在 Mimir / Loki 的 tenant 維度或 Prometheus 的 namespace 維度拆分 storage 跟 query cost。用 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">4.15 Cost Attribution</a> 的框架把 infra cost 按 service ownership 分配。</p>
<p>Attribution 本身就能驅動行為改變 — 當團隊看到自己佔了 40% 的 log volume、而且 95% 是 debug level 時，他們會主動調 log level。</p>
<h3 id="cardinality-budget-per-team">Cardinality budget per team</h3>
<p>Attribution 之後，為每個 team / service 設定 cardinality budget（active series 上限）。超出 budget 的 series 進入 review 流程 — team 決定哪些 label 可以 aggregate 或移除，而非由 platform 單方面 drop。</p>
<p>Budget 的設定依據是 baseline measurement + growth rate，不是拍腦袋。先觀察 3 個月的 cardinality 趨勢，把 budget 設在 baseline 的 1.5 倍，每季 review。</p>
<h3 id="log-tiering">Log tiering</h3>
<p>把 log 從「全部進 hot tier」改成分層：</p>
<table>
  <thead>
      <tr>
          <th>Log level</th>
          <th>目的地</th>
          <th>Retention</th>
          <th>查詢延遲</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Error / Warn</td>
          <td>Hot tier（Loki / Elasticsearch）</td>
          <td>30 天</td>
          <td>即時</td>
      </tr>
      <tr>
          <td>Info</td>
          <td>Warm tier（壓縮 + 延遲查詢）</td>
          <td>14 天</td>
          <td>秒到分鐘</td>
      </tr>
      <tr>
          <td>Debug</td>
          <td>Cold archive（object storage）</td>
          <td>7 天</td>
          <td>分鐘到小時</td>
      </tr>
  </tbody>
</table>
<p>Debug log 仍然保留，但不進昂貴的 hot tier。需要排錯時從 cold archive 拉回 — 多等幾分鐘的代價遠低於全量 hot tier 的持續成本。</p>
<h3 id="adaptive-sampling">Adaptive sampling</h3>
<p>Trace sampling 從 uniform 改成 adaptive：</p>
<ul>
<li>錯誤 request 100% 保留</li>
<li>高 latency request（&gt; p99）100% 保留</li>
<li>正常 request 依 traffic volume adaptive sampling（高流量 endpoint 低 sample rate、低流量 endpoint 高 sample rate）</li>
</ul>
<p>Adaptive sampling 保留了排錯最需要的 trace（error 跟 outlier），砍的是正常 request 的重複 trace。</p>
<h2 id="取捨">取捨</h2>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>不治理</th>
          <th>治理後</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>成本趨勢</td>
          <td>隨 traffic 超線性成長</td>
          <td>跟 traffic 線性成長或低於線性</td>
      </tr>
      <tr>
          <td>觀測覆蓋</td>
          <td>全量（但可能是低品質的全量）</td>
          <td>分層（high-value 資料保留全量、low-value 降級）</td>
      </tr>
      <tr>
          <td>Debug 體驗</td>
          <td>所有資料都在 hot tier、查得快</td>
          <td>部分資料要從 cold archive 拉、多等幾分鐘</td>
      </tr>
      <tr>
          <td>團隊自主性</td>
          <td>無限制（cardinality 跟 log level 隨意）</td>
          <td>有 budget 跟 policy 約束</td>
      </tr>
      <tr>
          <td>治理人力</td>
          <td>零（直到帳單爆炸才開始）</td>
          <td>需要 platform team 持續維護 attribution + budget + policy</td>
      </tr>
  </tbody>
</table>
<p>治理的最大風險是「砍過頭」— 在事故期間發現 debug log 被移到 cold archive 查不到、或 trace 被 sample 掉找不到問題 request。Adaptive sampling 跟 error retention 100% 是安全網，但安全網的設計本身需要定期 review（例如 error 的定義是否涵蓋了所有異常模式）。</p>
<h2 id="回寫教材的連結">回寫教材的連結</h2>
<ul>
<li><a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">4.15 Cost Attribution</a>：per-team cost visibility 是治理的起點。</li>
<li><a href="/blog/backend/04-observability/cardinality-cost-governance/" data-link-title="4.7 Cardinality 治理與成本邊界" data-link-desc="把 metric / log / trace 的 cardinality 與成本作為平台一級治理議題">4.7 Cardinality 治理</a>：cardinality budget 跟 label review 的操作流程。</li>
<li><a href="/blog/backend/04-observability/telemetry-pipeline/" data-link-title="4.11 Telemetry Pipeline 架構" data-link-desc="把 log / metric / trace 的 agent → collector → ingest → storage → query 分層治理">4.11 Telemetry Pipeline</a>：log tiering 跟 adaptive sampling 是 pipeline 的 routing 跟 processing 層配置。</li>
</ul>
<h2 id="判讀徵兆">判讀徵兆</h2>
<p>讀者在自己的系統看到以下訊號時，應該回讀本案例：</p>
<ul>
<li>觀測帳單每季成長 &gt; 20%，但服務的 request volume 成長遠小於此 — cardinality 或 log volume 可能在失控成長</li>
<li>管理層問「監控花多少錢、誰在用」但沒人能回答</li>
<li>曾經做過「全域降 retention」或「全域降 sampling」的成本優化，但幾個月後成本回升</li>
<li>Platform team 花大量時間處理「Prometheus OOM」或「Elasticsearch disk full」而非改善觀測品質</li>
<li>團隊的 debug log level 在 production 預設開著，理由是「不知道什麼時候需要」</li>
</ul>
]]></content:encoded></item></channel></rss>