<?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>Capacity on Tarragon</title><link>https://tarrragon.github.io/blog/tags/capacity/</link><description>Recent content in Capacity 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/capacity/index.xml" rel="self" type="application/rss+xml"/><item><title>k6</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/</guid><description>&lt;p>k6 的核心責任是把 workload model 轉成可重跑、可版本化、可接到 CI 的壓測 scenario。它適合 API、HTTP、gRPC、WebSocket 與 browser-style flow 的負載驗證，重點在用程式化腳本描述使用者行為、負載階段、threshold 與結果輸出。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>k6 是 Grafana Labs 旗下的 scriptable load testing 工具、2021 年被 Grafana 收購。產品線分兩層：&lt;em>k6 OSS&lt;/em>（Go 寫的 engine + JS API 描述 scenario、CLI 為主、output 可丟 Prometheus / InfluxDB / JSON / CSV）跟 &lt;em>Grafana Cloud k6&lt;/em>（前 k6 Cloud、SaaS 多 region runner + 結果保存 + 跟 Grafana Cloud dashboard / Loki / Tempo 同 plane）。底層 engine 是 Go、不是 JS — JS 只是 scenario 描述層、runtime 由 Go 跑、所以單機 VU 容量比 Python-based 工具高出一個量級。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a> 比、k6 走 &lt;em>code-first + CI-friendly&lt;/em>、JMeter 走 &lt;em>XML / GUI + plugin ecosystem&lt;/em>；JMeter 在 protocol 廣度（JDBC / LDAP / JMS / FTP）跟非工程團隊操作勝出、k6 在版控、PR review、artifact pipeline 勝出。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust&lt;/a> 比、k6 用 JS、Locust 用 Python；Locust 對 Python team 自然、但 Python GIL 讓單機 VU 容量受限、需多 worker、k6 單機可跑數千 VU。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling&lt;/a> 比、Gatling 走 JVM + Scala/Java/Kotlin DSL、適合 JVM-heavy 團隊；k6 的 threshold + Grafana ecosystem 整合在 release gate 場景更直接。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>k6 適合把壓測納入工程流程。當團隊已經能描述 traffic shape、endpoint mix、arrival rate、think time 與 stop condition，k6 可以把這些模型寫成腳本，讓每次 release、capacity review 或 peak-event readiness 都能重跑同一組驗證。&lt;/p>
&lt;p>這個定位讓 k6 接到三個主章。它從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 接收流量模型，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a> 接收 ramp-up 與 knee point 判讀，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> 接收 canary、dark launch 或 production-like load test 的安全邊界。&lt;/p></description><content:encoded><![CDATA[<p>k6 的核心責任是把 workload model 轉成可重跑、可版本化、可接到 CI 的壓測 scenario。它適合 API、HTTP、gRPC、WebSocket 與 browser-style flow 的負載驗證，重點在用程式化腳本描述使用者行為、負載階段、threshold 與結果輸出。</p>
<h2 id="服務定位">服務定位</h2>
<p>k6 是 Grafana Labs 旗下的 scriptable load testing 工具、2021 年被 Grafana 收購。產品線分兩層：<em>k6 OSS</em>（Go 寫的 engine + JS API 描述 scenario、CLI 為主、output 可丟 Prometheus / InfluxDB / JSON / CSV）跟 <em>Grafana Cloud k6</em>（前 k6 Cloud、SaaS 多 region runner + 結果保存 + 跟 Grafana Cloud dashboard / Loki / Tempo 同 plane）。底層 engine 是 Go、不是 JS — JS 只是 scenario 描述層、runtime 由 Go 跑、所以單機 VU 容量比 Python-based 工具高出一個量級。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a> 比、k6 走 <em>code-first + CI-friendly</em>、JMeter 走 <em>XML / GUI + plugin ecosystem</em>；JMeter 在 protocol 廣度（JDBC / LDAP / JMS / FTP）跟非工程團隊操作勝出、k6 在版控、PR review、artifact pipeline 勝出。跟 <a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a> 比、k6 用 JS、Locust 用 Python；Locust 對 Python team 自然、但 Python GIL 讓單機 VU 容量受限、需多 worker、k6 單機可跑數千 VU。跟 <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a> 比、Gatling 走 JVM + Scala/Java/Kotlin DSL、適合 JVM-heavy 團隊；k6 的 threshold + Grafana ecosystem 整合在 release gate 場景更直接。</p>
<h2 id="定位">定位</h2>
<p>k6 適合把壓測納入工程流程。當團隊已經能描述 traffic shape、endpoint mix、arrival rate、think time 與 stop condition，k6 可以把這些模型寫成腳本，讓每次 release、capacity review 或 peak-event readiness 都能重跑同一組驗證。</p>
<p>這個定位讓 k6 接到三個主章。它從 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 接收流量模型，從 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 接收 ramp-up 與 knee point 判讀，從 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 接收 canary、dark launch 或 production-like load test 的安全邊界。</p>
<h2 id="適用場景">適用場景</h2>
<p>API 壓測是 k6 最穩定的入口。Checkout、login、search、order query、payment callback mock 與 internal API 都可以用 scenario 表達，並用 threshold 把 latency、error rate 與 throughput 轉成 pass / fail 訊號。</p>
<p>CI performance gate 是 k6 的常見價值。團隊可以在 merge、nightly、pre-release 或 game day 前跑固定 baseline，觀察 p95 / p99、error rate、throughput 與 regression trend，再把結果交給 <a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a>。</p>
<p>Peak readiness rehearsal 適合用 k6 表達階段式負載。活動前可以用 ramping arrival rate 模擬 T-90、T-30、T-7、T-1 與 T-0 的負載階段，並把結果回寫到 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a>。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 k6 deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Scenario design</strong>：用 <code>executor: ramping-arrival-rate</code> 而非 <code>constant-vus</code>、把 RPS / arrival rate 設成 first-class、VU 由 engine 自動算；scenario 描述跟 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 的 endpoint mix、think time、cohort 對得起來</li>
<li><strong>Threshold gate</strong>：<code>thresholds</code> 區塊明確寫 p95 / p99 / error rate / throughput、CI fail 條件清楚、不靠人眼看 summary 判斷 pass / fail</li>
<li><strong>Output 進 observability stack</strong>：<code>--out experimental-prometheus-rw</code> 把 metric remote-write 到 Prometheus、Grafana dashboard 接 k6 同 datasource、結果跟 target service 的 saturation metric 在同一張圖上看</li>
<li><strong>k6 Cloud vs CLI 邊界</strong>：本地 CLI 跑 baseline + CI、Grafana Cloud k6 跑跨 region / 大規模 / 結果 retention；不要把 CI gate 放 Cloud（成本 + 時間不對）、也不要本地單機硬跑 100k VU（runner 自身瓶頸假象）</li>
</ul>
<p>四件事任一缺失、就是 scenario 已經寫得不完整、threshold gate 失效、或 runner 觀測缺失。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>k6 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>腳本化</td>
          <td>scenario、threshold、setup / teardown 可版本化</td>
          <td>production traffic 抽樣與模型校正</td>
      </tr>
      <tr>
          <td>CI 友善</td>
          <td>CLI 與 artifact 容易接 pipeline</td>
          <td>長期趨勢儲存與 release gate 語意</td>
      </tr>
      <tr>
          <td>API 導向</td>
          <td>HTTP / gRPC / WebSocket 等常見 API 場景清楚</td>
          <td>複雜瀏覽器互動與端到端資料準備</td>
      </tr>
      <tr>
          <td>團隊學習成本</td>
          <td>JavaScript 腳本容易被多數 backend 團隊接手</td>
          <td>大型分散式 runner 與測試資料治理</td>
      </tr>
  </tbody>
</table>
<p>腳本化價值來自可重跑。一次性的壓測只能回答當天配置能撐多少；可版本化 scenario 可以回答 release 後容量曲線有沒有漂移，並讓退化調查回到同一份 workload model。</p>
<p>CI 友善價值來自交接成本低。壓測結果要能轉成 artifact、threshold、trend 與 gate decision，才會從「工程師手動跑工具」變成 release 流程的一部分。</p>
<p>API 導向價值來自後端路徑明確。k6 很適合 checkout API、search API、internal API 與 webhook receiver；如果主要問題是完整 browser UX、第三方真實支付或多裝置同步，文章要把資料準備、side effect 與環境隔離另外寫清楚。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>k6 和 JMeter 的主要差異是工作方式。k6 偏程式化腳本、CLI、CI artifact 與工程流程；JMeter 偏 GUI、protocol plugin、既有企業測試流程與非工程團隊協作。</p>
<p>k6 和 Gatling 的主要差異是生態與語言。k6 使用 JavaScript-style 腳本，Gatling 偏 JVM / Scala / Java / Kotlin 生態；團隊語言能力與既有 pipeline 會影響維護成本。</p>
<p>k6 和 Locust 的主要差異是團隊技能與模型表達。Locust 使用 Python，對 Python 團隊與 custom user behavior 很自然；k6 的 threshold、CLI 與雲端 / Grafana 生態讓 release gate 整合更直接。</p>
<p>k6 和 Vegeta 的主要差異是場景複雜度。Vegeta 適合簡單 HTTP load、CLI workflow 與快速 saturation 探測；k6 適合較完整的 multi-step scenario、threshold 與長期 baseline。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>k6</th>
          <th><a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a></th>
          <th><a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></th>
          <th><a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Scenario 語言</td>
          <td>JavaScript（ES6+）</td>
          <td>XML（GUI 編輯）/ Groovy</td>
          <td>Python</td>
          <td>Scala / Java / Kotlin DSL</td>
      </tr>
      <tr>
          <td>Engine runtime</td>
          <td>Go</td>
          <td>JVM</td>
          <td>Python（gevent）</td>
          <td>JVM（Akka）</td>
      </tr>
      <tr>
          <td>單機 VU 容量</td>
          <td>高（thousands+）</td>
          <td>中（JVM heap-bound）</td>
          <td>中低（GIL、需 multi-worker）</td>
          <td>高（Akka actor）</td>
      </tr>
      <tr>
          <td>CI 友善度</td>
          <td>強 — CLI + threshold + JSON / Prometheus</td>
          <td>中 — 需 plugin / Jenkins integration</td>
          <td>中 — CLI 友善但 result reporting 較弱</td>
          <td>強 — CLI + HTML report + Maven/Gradle plugin</td>
      </tr>
      <tr>
          <td>Protocol 廣度</td>
          <td>HTTP / gRPC / WebSocket / Browser</td>
          <td>最廣（JDBC / LDAP / JMS / FTP / SMTP）</td>
          <td>HTTP 為主、其他靠 custom client</td>
          <td>HTTP / WebSocket / JMS / MQTT</td>
      </tr>
      <tr>
          <td>Browser test</td>
          <td>k6 Browser（Playwright-based）</td>
          <td>無原生（Selenium plugin）</td>
          <td>無原生</td>
          <td>無原生</td>
      </tr>
      <tr>
          <td>Distributed</td>
          <td>k6 Cloud / k6 Operator on k8s</td>
          <td>Master / Slave（運維重）</td>
          <td>Master / Worker</td>
          <td>Gatling Enterprise / FrontLine</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>API-first + CI gate + Grafana ecosystem</td>
          <td>企業 + protocol 多 + 非工程團隊</td>
          <td>Python team + custom user behavior</td>
          <td>JVM team + DSL 表達力</td>
      </tr>
  </tbody>
</table>
<p>選 k6 的核心訴求：API-first scenario + CI gate + Grafana / Prometheus ecosystem 已用、且團隊接受 JS DSL。Protocol 廣度需求大、走 JMeter；Python team、走 Locust；JVM-heavy、走 Gatling。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>k6 Browser</strong>：基於 Chromium + Playwright API、跑在 k6 同 scenario 內、可混 protocol-level 跟 browser-level load（前段 API call、後段真實 browser flow）。意義是「pure API load 跟 real user UX 在同一份 scenario」、不用維護兩套工具。但 browser VU 比 protocol VU 重幾十倍、runner cost 要重新算。</p>
<p><strong>xk6 extensions</strong>：用 Go 寫 k6 extension、補 protocol（Kafka / Redis / SQL / AMQP）或 output（custom backend）。<code>xk6 build</code> 生出客製 binary、organization 可維護自家 extension。意義是 k6 不只跑 HTTP — Kafka producer load / Redis hot-key probe 都能用同一個 scenario harness。</p>
<p><strong>Grafana Cloud k6（前 k6 Cloud）</strong>：SaaS 跑 multi-region runner、結果保存、跟 Grafana Cloud dashboard / Loki / Tempo / Prometheus 同 plane。適合 <em>跨 region 真實延遲驗證</em>、<em>大規模 distributed run</em>、<em>結果 retention + team share</em>。跟 Grafana Cloud 已用的團隊 ecosystem 一致；只用 OSS 的團隊走 k6 Operator on k8s。</p>
<p><strong>Distributed execution</strong>：自管 distributed 走 <a href="https://github.com/grafana/k6-operator">k6 Operator</a> on Kubernetes、scenario 拆 instance、結果 aggregate 到 output。意義是不需要 k6 Cloud 也能跑跨機器 load、但 runner pool 自管成本 + 結果 aggregation 自己處理。</p>
<p><strong>Output integration</strong>：<code>--out experimental-prometheus-rw</code> 直接 remote-write 到 Prometheus、Grafana dashboard 一張圖看 k6 client metric + target service saturation；<code>--out cloud</code> 上 Grafana Cloud k6；<code>--out json=...</code> 落地檔案給 CI artifact；<code>--out influxdb</code> 接 InfluxDB（legacy）。Loki 用來接 k6 console log、Tempo 用來接 k6 trace（若 scenario 帶 W3C trace context）。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>VU 跑不上去 / runner CPU 滿</strong>：scenario 寫了重 JS 邏輯（big JSON parse、複雜 regex、crypto）— 把 setup-once 邏輯搬 <code>setup()</code>、不要每 VU iteration 重算</li>
<li><strong>Resource throttling 假象</strong>：runner 機器 CPU / network bandwidth / file descriptor 自身瓶頸、target service 還沒到 saturation — 換大機 / 多 runner / 看 runner 自身 saturation metric 排除</li>
<li><strong>Threshold 設過嚴 / CI 一直 red</strong>：threshold 抄 production SLO 不留 budget — staging tenant 跑 5-10 次抓 baseline distribution、threshold 設 baseline + buffer、不是 SLO 直接搬</li>
<li><strong>p95 看起來好但 user 抱怨慢</strong>：scenario endpoint mix 跟 production traffic shape 不符 — 補 production endpoint distribution、按 weight 配 scenario、跟 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 對齊</li>
<li><strong>Script logic 太重 / VU iteration 不穩</strong>：在 scenario 內做 token refresh / large payload 處理、iteration 時間漂移 — 用 <code>executor: ramping-arrival-rate</code> 鎖 RPS 而非 VU count、iteration 時間漂移由 engine 吸收</li>
<li><strong>結果無法回放 / 找不到 baseline</strong>：output 沒落 artifact、Grafana dashboard 沒存 time range — 每次 run 強制 <code>--out json</code> + tag scenario version + push 到 evidence package</li>
</ul>
<h2 id="操作成本">操作成本</h2>
<p>k6 的主要成本是 workload model 維護。腳本本身容易寫，真正的成本在 production endpoint mix、資料分布、tenant / region / user cohort、think time 與 peak shape 的持續校正。</p>
<p>Runner 成本會隨負載規模上升。單機 runner 適合小型 API baseline；跨 region、數十萬 RPS 或長時間 soak test 需要分散式 runner、網路成本、目標服務隔離與觀測儲存。</p>
<p>測試資料治理是高風險成本。Checkout、payment、order、email、notification 與 webhook 路徑都可能產生 side effect，因此 scenario 要明確定義 test tenant、idempotency key、mock boundary、cleanup 與 stop condition。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>k6 結果應回寫到 evidence package。最小欄位包括 scenario version、target environment、time range、VUs / arrival rate、threshold、p95 / p99、error rate、throughput、target service saturation metric、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>k6 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>k6 summary、JSON output、dashboard link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>Grafana / Prometheus / APM 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>scenario coverage、test data freshness</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>production similarity、runner capacity</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 endpoint、未模擬第三方、資料偏差</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 release gate 能判斷。k6 的 threshold pass 只是其中一個訊號；gate 還要看 target service 的 CPU、connection、DB latency、cache hit rate、queue lag 與 cloud cost。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>k6 目前在 09 案例庫中主要作為工具類承接點，案例主角仍是負載形狀與驗證節奏。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 售票壓測</a> 的 pre-event load test 判讀、<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day readiness</a> 的 staged validation、<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 雙峰 workload</a> 的多模型壓測需求、<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech FIFA World Cup readiness</a> 的 54000 TPS @ 25ms p95 驗證、以及 <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft 8x peak</a> 跨 100+ 微服務的獨立 threshold 設計。</p>
<p>這些案例提供的是負載形狀與工程節奏。k6 頁引用案例時，要把 case 轉成 workload model、ramp-up、threshold、runner 規模與 stop condition，並讓工具回到可替換的承載選項 — 例如 GR8 Tech 25ms p95 是 threshold pass / fail 的硬目標、Lyft 的「8x 是特定服務、不是全部 8x」要拆成 per-service scenario。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></li>
<li>跨模組：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a></li>
<li>官方：<a href="https://grafana.com/docs/k6/latest/">Grafana k6 documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.1 壓測理論與系統行為</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-theory/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-theory/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>壓測理論的角色是讓「加機器能不能解決」這個問題從直覺變成可推導。沒有理論基礎時、容量決策容易陷入「跑壓測 → 看數字 → 加機器」的盲試循環；有理論之後、可以從「現在的延遲 / 吞吐 / 並發量」反推「瓶頸在哪個資源、加什麼有效」。&lt;/p>
&lt;p>本章是 9.2-9.12 的共同基礎。後續章節的 workload modeling、saturation discovery、capacity planning、SLO 都會回引本章的數學工具。讀者可以把這章當作「容量規劃的最小詞彙表」、其他章節是這些詞彙的應用情境。&lt;/p>
&lt;p>本章不深入推導公式、聚焦在 &lt;em>工程意義&lt;/em>。讀完之後讀者能回答：為什麼系統在 80% utilization 就該擴、為什麼加機器會邊際效益遞減、為什麼 sub-ms 延遲需求會反推架構選擇。&lt;/p>
&lt;h2 id="littles-law穩態系統的最小數學工具">Little&amp;rsquo;s Law：穩態系統的最小數學工具&lt;/h2>
&lt;p>Little&amp;rsquo;s Law 用一條等式 L = λW 把三個變數綁在一起：L 是系統內平均並發數、λ 是請求到達率、W 是請求平均逗留時間。這個關係在 &lt;em>穩態&lt;/em>（流量已穩定、不在 warmup 階段）必然成立、不需要假設特定分布或服務模式。&lt;/p>
&lt;p>工程上最有價值的用法是「反推」。給定預期 RPS λ = 1000 跟 SLO latency 上限 W = 200ms、能算出系統最大穩態並發 L = 1000 × 0.2 = 200。這個 200 直接對應「connection pool size」「thread pool size」「async worker count」這類容量參數 — 訂得比 200 小、系統撐不住預期流量；訂得比 200 大太多、資源浪費。&lt;/p>
&lt;p>反向也成立。當 connection pool 卡死在某個 size L、latency budget W 已訂、能算出可支撐的 RPS。這個算法在 capacity planning 階段比 ramp-up 壓測更快、可以先用 Little&amp;rsquo;s Law 篩掉明顯撐不住的配置、再用壓測驗證剩下的候選。&lt;/p>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &amp;#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase sub-ms&lt;/a> 把 W 訂在 sub-millisecond、所有架構選擇都從這個 W 反推；&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">Tubi ML p99 &amp;lt; 10ms&lt;/a> 從 W 反推 feature lookup 必須 cache hit 路徑、不能回到持久 store。&lt;/p>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/little-law/" data-link-title="Little&amp;#39;s Law" data-link-desc="說明系統內並發數、到達率與逗留時間三者的數學關係">Little&amp;rsquo;s Law 卡片&lt;/a>。&lt;/p>
&lt;h2 id="queueing-theory為什麼-80-利用率就是-knee">Queueing Theory：為什麼 80% 利用率就是 knee&lt;/h2>
&lt;p>排隊論（M/M/c 模型）解釋了一個常見直覺：「系統在 50% utilization 看似還很閒、80% 就該擴、90% 已經太晚」。這個直覺不是經驗法則、是 &lt;em>數學必然&lt;/em>。&lt;/p>
&lt;p>M/M/c 系統的平均 queue length 跟 utilization 之間是非線性關係。當 utilization 從 50% 漲到 70%、queue length 約增加 2-3 倍；從 70% 漲到 90%、queue length 增加 10 倍以上。latency 跟 queue length 成正比（Little&amp;rsquo;s Law 又出現）、所以 latency 也呈現同樣的指數成長。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>壓測理論的角色是讓「加機器能不能解決」這個問題從直覺變成可推導。沒有理論基礎時、容量決策容易陷入「跑壓測 → 看數字 → 加機器」的盲試循環；有理論之後、可以從「現在的延遲 / 吞吐 / 並發量」反推「瓶頸在哪個資源、加什麼有效」。</p>
<p>本章是 9.2-9.12 的共同基礎。後續章節的 workload modeling、saturation discovery、capacity planning、SLO 都會回引本章的數學工具。讀者可以把這章當作「容量規劃的最小詞彙表」、其他章節是這些詞彙的應用情境。</p>
<p>本章不深入推導公式、聚焦在 <em>工程意義</em>。讀完之後讀者能回答：為什麼系統在 80% utilization 就該擴、為什麼加機器會邊際效益遞減、為什麼 sub-ms 延遲需求會反推架構選擇。</p>
<h2 id="littles-law穩態系統的最小數學工具">Little&rsquo;s Law：穩態系統的最小數學工具</h2>
<p>Little&rsquo;s Law 用一條等式 L = λW 把三個變數綁在一起：L 是系統內平均並發數、λ 是請求到達率、W 是請求平均逗留時間。這個關係在 <em>穩態</em>（流量已穩定、不在 warmup 階段）必然成立、不需要假設特定分布或服務模式。</p>
<p>工程上最有價值的用法是「反推」。給定預期 RPS λ = 1000 跟 SLO latency 上限 W = 200ms、能算出系統最大穩態並發 L = 1000 × 0.2 = 200。這個 200 直接對應「connection pool size」「thread pool size」「async worker count」這類容量參數 — 訂得比 200 小、系統撐不住預期流量；訂得比 200 大太多、資源浪費。</p>
<p>反向也成立。當 connection pool 卡死在某個 size L、latency budget W 已訂、能算出可支撐的 RPS。這個算法在 capacity planning 階段比 ramp-up 壓測更快、可以先用 Little&rsquo;s Law 篩掉明顯撐不住的配置、再用壓測驗證剩下的候選。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase sub-ms</a> 把 W 訂在 sub-millisecond、所有架構選擇都從這個 W 反推；<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">Tubi ML p99 &lt; 10ms</a> 從 W 反推 feature lookup 必須 cache hit 路徑、不能回到持久 store。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/little-law/" data-link-title="Little&#39;s Law" data-link-desc="說明系統內並發數、到達率與逗留時間三者的數學關係">Little&rsquo;s Law 卡片</a>。</p>
<h2 id="queueing-theory為什麼-80-利用率就是-knee">Queueing Theory：為什麼 80% 利用率就是 knee</h2>
<p>排隊論（M/M/c 模型）解釋了一個常見直覺：「系統在 50% utilization 看似還很閒、80% 就該擴、90% 已經太晚」。這個直覺不是經驗法則、是 <em>數學必然</em>。</p>
<p>M/M/c 系統的平均 queue length 跟 utilization 之間是非線性關係。當 utilization 從 50% 漲到 70%、queue length 約增加 2-3 倍；從 70% 漲到 90%、queue length 增加 10 倍以上。latency 跟 queue length 成正比（Little&rsquo;s Law 又出現）、所以 latency 也呈現同樣的指數成長。</p>
<p>工程意義：健康系統運轉在 50-70% utilization、超過 80% 就接近 knee、超過 90% 進入不可預測區。「為什麼明明還沒滿就 saturate」的答案就在這條曲線。autoscaler 的 target metric 通常訂在 60-70%、是 queueing theory 推導出的安全邊界、不是工程師憑感覺。</p>
<p>多 server 模型（M/M/c）比單 server（M/M/1）有顯著容量優勢：c 個 server 的有效容量遠超 1 個 server 容量 × c。這也解釋了為什麼水平擴容（多開幾個 instance）通常比垂直擴容（單機加 CPU）划算 — 不只是規模、是 queue 行為的本質差異。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech 25ms p95</a> 把 p95 維持在 25ms 同時撐 54K TPS、靠的是 <em>永遠不讓系統進入 knee</em>、AI 預測讓擴容窗口縮短到 reaction time 內。</p>
<h2 id="universal-scalability-law擴容會邊際失效">Universal Scalability Law：擴容會邊際失效</h2>
<p>USL（Neil Gunther 提出）的公式 throughput(N) = N / (1 + α(N-1) + βN(N-1)) 解釋了「為什麼加機器到某個點之後 throughput 反而下降」。兩個常數 α 跟 β 描述系統的擴展限制：</p>
<ul>
<li>α 是必須序列化的部分（Amdahl&rsquo;s Law 的對應）。distributed lock、coordinator、單一 leader DB 都是 α 來源。α 越大、線性擴容越早 plateau。</li>
<li>β 是節點間互相通訊的成本（crosstalk）。cache invalidation broadcast、consensus <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a>、cross-region replication 都是 β。β 比 α 更危險、會讓 throughput 在 N 大到某點後 <em>反向下降</em>。</li>
</ul>
<p>工程上 α 比較好處理 — 把序列化部分拆細、用 partition 切分、用 sharded coordinator。β 比較難 — 通訊本質就需要協調、降低 β 通常要重新設計分散式協議（例如 Spanner 用 TrueTime 把跨節點交易的協調成本降低）。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">Spanner 線性擴展到 10 億 req/sec</a> — TrueTime API 讓跨地區交易的 β 降到可接受、達成傳統 OLTP 做不到的線性；<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase RAFT consensus</a> — RAFT 的 quorum 通訊讓 β 不可降、所以 <em>選擇不橫向擴</em>、改用 z1d + Cluster Placement Group 榨單機。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/universal-scalability-law/" data-link-title="Universal Scalability Law (USL)" data-link-desc="說明系統擴容到一定規模後吞吐反而下降的數學模型">USL 卡片</a>。</p>
<h2 id="saturation-curvelinear--knee--cliff">Saturation Curve：linear → knee → cliff</h2>
<p>實際系統的 latency vs throughput 曲線分三段。第一段是 linear region — utilization 低、latency 平穩、加流量幾乎不影響 latency。第二段是 knee — utilization 接近 80%、latency 開始指數成長、再加流量會明顯變慢。第三段是 cliff — 系統進入不穩定區、latency 不可預測、可能 timeout、可能 cascade failure。</p>
<p>容量規劃的關鍵概念是 <em>knee point = 設計容量上限</em>。健康系統運轉在 knee 以下 50-70%、留出 headroom 應付 burst 跟 forecast 誤差。沒有量過 knee 的系統等於「不知道距離崩潰多遠」 — 平日看起來穩、實際隨時可能因為一個小 spike 進入 cliff。</p>
<p>不同 system 的 knee 位置差異很大。stateless service 通常 knee 在 80% CPU；DB 因為 lock contention、knee 可能在 60% utilization；broker / queue 因為 disk I/O bottleneck、knee 可能在 50%。容量規劃時不能一概而論、必須個別量測。</p>
<p>每次重大改動後必須 re-test knee。新增功能、改 ORM、升級 library、調 GC tuning、改 cache 策略 — 任何一個都可能讓 knee 往不好的方向移。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft DynamoDB IOPS 20 → 135K</a> — partition 設計均勻時 saturation point 可以推到極遠（6750x 擴展）；<a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">Amazon Ads 9000 萬 RPS</a> — 線性擴展靠 partition key 均勻、不靠 vendor 神話。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point 卡片</a>。</p>
<h2 id="反推從業務-kpi-到系統參數">反推：從業務 KPI 到系統參數</h2>
<p>理論工具的真正價值在「反推」 — 不是先設計系統再量測 saturate 多少、是 <em>先訂業務目標再反推系統參數</em>。這層思維把容量規劃從 reactive（撐到撐不住才擴）變成 proactive（按業務需求預先配置）。</p>
<p>反推流程通常從 latency budget 開始（詳見 <a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a>）：</p>
<ol>
<li>從 user-perceived end-to-end latency（例如 p99 500ms）開始</li>
<li>拆到每個 stage（網路、CDN、application、cache、DB、第三方）的 latency 配額</li>
<li>配額決定每個 stage 的設計選擇 — DB 配 50ms → 不能跨 region、application 配 100ms → 不能多層 microservice hop</li>
<li>配額 + 預期 RPS → Little&rsquo;s Law 算每個 stage 的並發</li>
<li>並發 → 每個 stage 的容量需求 → 實例數 / connection pool size / cache size</li>
</ol>
<p>反推失敗的常見徵兆：算出來的某個 stage 容量超過 vendor 提供的上限（例如「需要 50 萬 DynamoDB RCU」可能超過單一 table partition 上限）、或某個 stage latency 配額過短（例如 cross-AZ 網路至少 1-2ms、配 0.5ms 不可能達成）。這時要回頭調整 SLO 或重新設計架構。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget 卡片</a>。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a></td>
          <td>sub-ms latency 反推所有架構選擇</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></td>
          <td>TrueTime 降低 β 達成線性擴展</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a></td>
          <td>ML p99 &lt; 10ms 的 stage latency 配額</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></td>
          <td>線性擴展靠 partition 均勻、不靠魔法</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>下游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a>（把模型量化成 production traffic）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>（實測 knee point）</li>
<li>跨章節：<a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a>（latency budget 拆解）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/little-law/" data-link-title="Little&#39;s Law" data-link-desc="說明系統內並發數、到達率與逗留時間三者的數學關係">Little&rsquo;s Law</a></li>
<li><a href="/blog/backend/knowledge-cards/universal-scalability-law/" data-link-title="Universal Scalability Law (USL)" data-link-desc="說明系統擴容到一定規模後吞吐反而下降的數學模型">Universal Scalability Law</a></li>
<li><a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point</a></li>
<li><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget</a></li>
<li><a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency</a></li>
</ul>
]]></content:encoded></item><item><title>9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/</guid><description>&lt;p>這個案例的核心責任是提供「極端可預期峰值」的容量設計參考點。Prime Day 是 Amazon 每年最大的單一行銷事件、發生時間提前數月公告、所有相依服務都能進入準備階段、是最接近「教科書版本的容量規劃」的真實場景。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>2025 年 Prime Day 期間 AWS 主要服務的峰值數字（引自 &lt;a href="https://aws.amazon.com/blogs/aws/aws-services-scale-to-new-heights-for-prime-day-2025-key-metrics-and-milestones/">AWS News Blog&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>服務&lt;/th>
 &lt;th>峰值&lt;/th>
 &lt;th>年增率&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Amazon SQS&lt;/td>
 &lt;td>1.66 億訊息 / 秒（新紀錄）&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AWS Lambda&lt;/td>
 &lt;td>每日 1.7 兆次呼叫&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon API Gateway&lt;/td>
 &lt;td>1 兆次內部請求&lt;/td>
 &lt;td>+30%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon DynamoDB&lt;/td>
 &lt;td>1.51 億 RPS、毫秒級回應&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon ElastiCache&lt;/td>
 &lt;td>每日 1.5 quadrillion 請求&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon CloudFront&lt;/td>
 &lt;td>3 兆次 HTTP 請求&lt;/td>
 &lt;td>+43%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon Kinesis Streams&lt;/td>
 &lt;td>8.07 億 records / 秒峰值&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon EBS&lt;/td>
 &lt;td>20.3 兆次 I/O&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon Aurora&lt;/td>
 &lt;td>5000 億次 transaction&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon SageMaker AI&lt;/td>
 &lt;td>6260 億次推論請求&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Amazon ECS on Fargate&lt;/td>
 &lt;td>每日 1840 萬個 task&lt;/td>
 &lt;td>+77%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AWS FIS（混沌實驗）&lt;/td>
 &lt;td>6800+ 次彈性測試&lt;/td>
 &lt;td>8 倍於 2024&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>基礎設施層面：AWS Graviton 處理器承擔超過 40% 的 EC2 compute、部署超過 87,000 顆 Inferentia / Trainium AI 晶片、AWS Outposts 對機器人下達 5.24 億條指令（年增 160%）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Prime Day 是「可預期極端峰值」的標竿。它的容量問題不是「會不會撐住」、而是「準備到什麼程度才划算」。對應主章問題節點：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Capacity Planning&lt;/strong>（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6&lt;/a>）：年度活動的容量計算可以用歷史 baseline × 預期成長 × headroom 三項相乘、但 Prime Day 規模下、每一項的不確定性放大都會變成數百萬美金成本差異。Amazon 公開的年增率（API Gateway +30%、CloudFront +43%、ECS on Fargate +77%）顯示連 Amazon 自己每年的成長預測都不能直線外推。&lt;/li>
&lt;li>&lt;strong>Performance Observability&lt;/strong>（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8&lt;/a>）：DynamoDB 「1.51 億 RPS、毫秒級回應」這種敘述同時包含吞吐與延遲、是 production-grade 容量地圖的最小單位。只說吞吐不說延伸分布、容量資訊不完整。&lt;/li>
&lt;li>&lt;strong>Improvement Loop&lt;/strong>（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9&lt;/a>）：FIS 混沌實驗 8 倍於 2024 顯示 Amazon 把「在 Prime Day 之前主動製造失敗」當成必修課、不是事後檢討。這層投資跟容量規劃同等重要。&lt;/li>
&lt;/ol>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>這個案例可以抽出三個跨平台可重用的工程做法。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>把可預期峰值寫進服務級 SLO&lt;/strong>：Prime Day 在 SQS / Lambda / DynamoDB / Aurora 都建立了內部 SLO baseline、平日跑在 baseline 之下、峰值是擴張到「設計容量」而不是「實驗容量」。這跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 直接對齊。&lt;/li>
&lt;li>&lt;strong>pre-scaling + scheduled capacity&lt;/strong>：CloudFront 43%、API Gateway 30% 的年增率都是 &lt;em>提前算進&lt;/em> 容量計畫、不是當天 reactive 擴容。對應 EC2 Auto Scaling 的 &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-predictive-scaling.html">predictive / scheduled scaling&lt;/a> 模式。&lt;/li>
&lt;li>&lt;strong>事前主動製造失敗、不靠當天 reactive&lt;/strong>：FIS 8x 成長代表「在 Prime Day 之前 6800 次 chaos test」、把驗證成本前置到容量規劃階段。這條跟 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/chaos-testing/" data-link-title="6.4 chaos testing" data-link-desc="把故障注入從工具操作升級成可驗證流程：先定義穩態，再按依賴類型設計注入、控制 blast radius 與收集證據">06.4 Chaos Testing&lt;/a> 形成閉環 — 06 講失敗模式驗證、09 講容量地圖、兩者在 Prime Day 級別的事件上必須一起做。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP 的 Compute Engine MIG + Predictive Autoscaler、Azure 的 VM Scale Sets + Predictive Autoscale、Kubernetes 生態的 KEDA + Karpenter 都可以實作同樣的 pre-scaling 策略。差異是 vendor 整合度、不是工程概念。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供「極端可預期峰值」的容量設計參考點。Prime Day 是 Amazon 每年最大的單一行銷事件、發生時間提前數月公告、所有相依服務都能進入準備階段、是最接近「教科書版本的容量規劃」的真實場景。</p>
<h2 id="觀察">觀察</h2>
<p>2025 年 Prime Day 期間 AWS 主要服務的峰值數字（引自 <a href="https://aws.amazon.com/blogs/aws/aws-services-scale-to-new-heights-for-prime-day-2025-key-metrics-and-milestones/">AWS News Blog</a>）：</p>
<table>
  <thead>
      <tr>
          <th>服務</th>
          <th>峰值</th>
          <th>年增率</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Amazon SQS</td>
          <td>1.66 億訊息 / 秒（新紀錄）</td>
          <td>-</td>
      </tr>
      <tr>
          <td>AWS Lambda</td>
          <td>每日 1.7 兆次呼叫</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon API Gateway</td>
          <td>1 兆次內部請求</td>
          <td>+30%</td>
      </tr>
      <tr>
          <td>Amazon DynamoDB</td>
          <td>1.51 億 RPS、毫秒級回應</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon ElastiCache</td>
          <td>每日 1.5 quadrillion 請求</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon CloudFront</td>
          <td>3 兆次 HTTP 請求</td>
          <td>+43%</td>
      </tr>
      <tr>
          <td>Amazon Kinesis Streams</td>
          <td>8.07 億 records / 秒峰值</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon EBS</td>
          <td>20.3 兆次 I/O</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon Aurora</td>
          <td>5000 億次 transaction</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon SageMaker AI</td>
          <td>6260 億次推論請求</td>
          <td>-</td>
      </tr>
      <tr>
          <td>Amazon ECS on Fargate</td>
          <td>每日 1840 萬個 task</td>
          <td>+77%</td>
      </tr>
      <tr>
          <td>AWS FIS（混沌實驗）</td>
          <td>6800+ 次彈性測試</td>
          <td>8 倍於 2024</td>
      </tr>
  </tbody>
</table>
<p>基礎設施層面：AWS Graviton 處理器承擔超過 40% 的 EC2 compute、部署超過 87,000 顆 Inferentia / Trainium AI 晶片、AWS Outposts 對機器人下達 5.24 億條指令（年增 160%）。</p>
<h2 id="判讀">判讀</h2>
<p>Prime Day 是「可預期極端峰值」的標竿。它的容量問題不是「會不會撐住」、而是「準備到什麼程度才划算」。對應主章問題節點：</p>
<ol>
<li><strong>Capacity Planning</strong>（<a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6</a>）：年度活動的容量計算可以用歷史 baseline × 預期成長 × headroom 三項相乘、但 Prime Day 規模下、每一項的不確定性放大都會變成數百萬美金成本差異。Amazon 公開的年增率（API Gateway +30%、CloudFront +43%、ECS on Fargate +77%）顯示連 Amazon 自己每年的成長預測都不能直線外推。</li>
<li><strong>Performance Observability</strong>（<a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8</a>）：DynamoDB 「1.51 億 RPS、毫秒級回應」這種敘述同時包含吞吐與延遲、是 production-grade 容量地圖的最小單位。只說吞吐不說延伸分布、容量資訊不完整。</li>
<li><strong>Improvement Loop</strong>（<a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9</a>）：FIS 混沌實驗 8 倍於 2024 顯示 Amazon 把「在 Prime Day 之前主動製造失敗」當成必修課、不是事後檢討。這層投資跟容量規劃同等重要。</li>
</ol>
<h2 id="策略">策略</h2>
<p>這個案例可以抽出三個跨平台可重用的工程做法。</p>
<ol>
<li><strong>把可預期峰值寫進服務級 SLO</strong>：Prime Day 在 SQS / Lambda / DynamoDB / Aurora 都建立了內部 SLO baseline、平日跑在 baseline 之下、峰值是擴張到「設計容量」而不是「實驗容量」。這跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 直接對齊。</li>
<li><strong>pre-scaling + scheduled capacity</strong>：CloudFront 43%、API Gateway 30% 的年增率都是 <em>提前算進</em> 容量計畫、不是當天 reactive 擴容。對應 EC2 Auto Scaling 的 <a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-predictive-scaling.html">predictive / scheduled scaling</a> 模式。</li>
<li><strong>事前主動製造失敗、不靠當天 reactive</strong>：FIS 8x 成長代表「在 Prime Day 之前 6800 次 chaos test」、把驗證成本前置到容量規劃階段。這條跟 <a href="/blog/backend/06-reliability/chaos-testing/" data-link-title="6.4 chaos testing" data-link-desc="把故障注入從工具操作升級成可驗證流程：先定義穩態，再按依賴類型設計注入、控制 blast radius 與收集證據">06.4 Chaos Testing</a> 形成閉環 — 06 講失敗模式驗證、09 講容量地圖、兩者在 Prime Day 級別的事件上必須一起做。</li>
</ol>
<p>跨平台等效：GCP 的 Compute Engine MIG + Predictive Autoscaler、Azure 的 VM Scale Sets + Predictive Autoscale、Kubernetes 生態的 KEDA + Karpenter 都可以實作同樣的 pre-scaling 策略。差異是 vendor 整合度、不是工程概念。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃年度活動容量 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a></li>
<li>想設計可預期峰值的 SLO → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO 與 Error Budget 政策</a></li>
<li>想做事前混沌驗證 → <a href="/blog/backend/06-reliability/chaos-testing/" data-link-title="6.4 chaos testing" data-link-desc="把故障注入從工具操作升級成可驗證流程：先定義穩態，再按依賴類型設計注入、控制 blast radius 與收集證據">06.4 Chaos Testing</a> + <a href="/blog/backend/06-reliability/steady-state-definition/" data-link-title="6.22 Steady State Definition" data-link-desc="在 chaos 與 failover 前先定義系統應維持的穩定狀態與可接受退化">06.22 Steady State Definition</a></li>
<li>對照不同形狀的峰值 → <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a>（事件型不可預期峰值）/ <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a>（無峰值低延遲）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/aws/aws-services-scale-to-new-heights-for-prime-day-2025-key-metrics-and-milestones/">AWS services scale to new heights for Prime Day 2025: key metrics and milestones</a></li>
<li><a href="https://aws.amazon.com/blogs/industries/conquering-peak-retail-events-with-aws/">Conquering Peak Retail Events with AWS</a></li>
<li><a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-predictive-scaling.html">Predictive scaling for Amazon EC2 Auto Scaling</a></li>
</ul>
]]></content:encoded></item><item><title>Apache JMeter</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/</guid><description>&lt;p>JMeter 的核心責任是把多 protocol 測試與既有企業測試資產轉成可重跑的負載驗證。它適合 GUI 驅動、plugin 生態成熟、HTTP 之外還需要 JDBC、JMS、FTP、mail 或 legacy protocol 的團隊，重點在把測試流程保留成可審查、可交接、可在 non-GUI mode 跑的 artifact。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>JMeter 是 Apache Software Foundation 的 OSS load testing tool、Java 寫、用 XML 描述 thread group / sampler / listener 組成的 test plan（&lt;code>.jmx&lt;/code> 檔）、支援 GUI 與 CLI（non-GUI / headless）雙模式。它是業界最老牌、protocol 覆蓋最廣的壓測工具 — sampler 直接覆蓋 HTTP、JDBC、JMS、SOAP、FTP、SMTP、IMAP、TCP、JUnit、OS process 等。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a> 比、JMeter 走 &lt;em>GUI-driven + protocol 廣&lt;/em>、k6 走 &lt;em>code-first（JavaScript）+ HTTP 為主&lt;/em>；JMeter 適合 QA 團隊維護、k6 適合 dev / SRE 寫進 CI。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust&lt;/a> 比、JMeter 用 XML + plugin、Locust 用純 Python class、custom client 彈性 Locust 強但 protocol 內建支援 JMeter 廣。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling&lt;/a> 比、JMeter 偏 GUI / 多 protocol、Gatling 偏 JVM DSL（Scala / Java / Kotlin）+ async runtime、單機 throughput Gatling 較高但 protocol 廣度與既有資產承接 JMeter 勝。&lt;/p>
&lt;p>關鍵張力：&lt;em>GUI / protocol 廣度&lt;/em> ↔ &lt;em>單機 throughput / CI 友善度&lt;/em> 是選 JMeter 的根本取捨。GUI 適合 QA 團隊與跨角色協作、&lt;code>.jmx&lt;/code> 又有 plugin 生態與十多年累積；代價是 XML diff 難 review、GUI listener 吃記憶體、CI 整合相比 k6 / Gatling 多一層 packaging。&lt;/p>
&lt;p>JMeter 適合測試資產已經存在的組織。當團隊有大量 &lt;code>.jmx&lt;/code> 測試計畫、QA 團隊用 GUI 維護 scenario、或壓測需要跨 HTTP、JDBC、JMS 與其他 plugin protocol，JMeter 的價值在於承接組織流程，而不只是產生 HTTP 負載。這個定位讓 JMeter 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a>。它能支援 production-like test 的多系統 dependency，但 evidence package 要補上測試計畫版本、plugin 版本、runner 配置與結果保存方式。&lt;/p></description><content:encoded><![CDATA[<p>JMeter 的核心責任是把多 protocol 測試與既有企業測試資產轉成可重跑的負載驗證。它適合 GUI 驅動、plugin 生態成熟、HTTP 之外還需要 JDBC、JMS、FTP、mail 或 legacy protocol 的團隊，重點在把測試流程保留成可審查、可交接、可在 non-GUI mode 跑的 artifact。</p>
<h2 id="服務定位">服務定位</h2>
<p>JMeter 是 Apache Software Foundation 的 OSS load testing tool、Java 寫、用 XML 描述 thread group / sampler / listener 組成的 test plan（<code>.jmx</code> 檔）、支援 GUI 與 CLI（non-GUI / headless）雙模式。它是業界最老牌、protocol 覆蓋最廣的壓測工具 — sampler 直接覆蓋 HTTP、JDBC、JMS、SOAP、FTP、SMTP、IMAP、TCP、JUnit、OS process 等。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> 比、JMeter 走 <em>GUI-driven + protocol 廣</em>、k6 走 <em>code-first（JavaScript）+ HTTP 為主</em>；JMeter 適合 QA 團隊維護、k6 適合 dev / SRE 寫進 CI。跟 <a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a> 比、JMeter 用 XML + plugin、Locust 用純 Python class、custom client 彈性 Locust 強但 protocol 內建支援 JMeter 廣。跟 <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a> 比、JMeter 偏 GUI / 多 protocol、Gatling 偏 JVM DSL（Scala / Java / Kotlin）+ async runtime、單機 throughput Gatling 較高但 protocol 廣度與既有資產承接 JMeter 勝。</p>
<p>關鍵張力：<em>GUI / protocol 廣度</em> ↔ <em>單機 throughput / CI 友善度</em> 是選 JMeter 的根本取捨。GUI 適合 QA 團隊與跨角色協作、<code>.jmx</code> 又有 plugin 生態與十多年累積；代價是 XML diff 難 review、GUI listener 吃記憶體、CI 整合相比 k6 / Gatling 多一層 packaging。</p>
<p>JMeter 適合測試資產已經存在的組織。當團隊有大量 <code>.jmx</code> 測試計畫、QA 團隊用 GUI 維護 scenario、或壓測需要跨 HTTP、JDBC、JMS 與其他 plugin protocol，JMeter 的價值在於承接組織流程，而不只是產生 HTTP 負載。這個定位讓 JMeter 接到 <a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a> 與 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a>。它能支援 production-like test 的多系統 dependency，但 evidence package 要補上測試計畫版本、plugin 版本、runner 配置與結果保存方式。</p>
<h2 id="適用場景">適用場景</h2>
<p>多 protocol 壓測是 JMeter 的主要入口。企業服務常同時需要測 HTTP API、JDBC query、JMS queue、FTP 或 mail flow，JMeter 的 sampler 與 plugin 生態能讓同一份測試計畫覆蓋多種 dependency。</p>
<p>GUI 協作適合非純工程團隊。QA、測試中心或受監管環境常需要可視化測試設計、審核與交接，JMeter 的 GUI 能降低跨角色溝通成本。</p>
<p>Legacy 測試資產適合保留 JMeter。既有 <code>.jmx</code> 檔案、listener、plugin 與報表流程如果已經運作多年，重寫到 k6、Gatling 或 Locust 的機會成本要用維護收益抵銷。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 JMeter deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Thread group 設計</strong>：thread count / ramp-up / loop count / duration 是否反映真實流量模型、有沒有用 <em>Stepping Thread Group</em>（plugin）或 <em>Concurrency Thread Group</em> 控制 arrival rate、不是把 thread 當「user」直接綁</li>
<li><strong>Listener 配置</strong>：GUI listener（View Results Tree / Aggregate Report / Graph）只在 design / debug 階段開、正式跑必須改 <em>Simple Data Writer</em> 輸出 JTL、結果分析交給離線 HTML report 或外部 Grafana</li>
<li><strong>Distributed mode 設定</strong>：單機 thread 上限約 3000-5000（受 JVM heap 與 thread context switch 限制）、超過要走 <em>master + slave</em>（remote engine）；slave 機器 plugin / JMeter version / JVM 參數要跟 master 一致、否則結果不可信</li>
<li><strong>GUI vs CLI 模式區分</strong>：GUI 是 design / debug only、production load 一律走 <code>jmeter -n -t plan.jmx -l result.jtl</code>；GUI 跑大規模測試會把 listener 拉爆記憶體、結果反而失真</li>
</ul>
<p>四件事任一缺、就是 <a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a> 邊界的待補項目。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>JMeter 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多 protocol</td>
          <td>sampler 與 plugin 覆蓋廣</td>
          <td>plugin 版本治理與測試環境一致性</td>
      </tr>
      <tr>
          <td>GUI 協作</td>
          <td>非工程角色可讀可改</td>
          <td>code review、diff 與版本控制紀律</td>
      </tr>
      <tr>
          <td>既有資產</td>
          <td><code>.jmx</code>、listener、報表可延續</td>
          <td>scenario cleanup 與 artifact 標準化</td>
      </tr>
      <tr>
          <td>分散式執行</td>
          <td>remote engine 可擴負載</td>
          <td>runner sizing、網路瓶頸與結果合併</td>
      </tr>
  </tbody>
</table>
<p>多 protocol 價值來自 dependency coverage。當 workload model 包含 database、queue、file transfer 或 legacy endpoint，JMeter 可以把不同 dependency 的壓力放在同一個測試計畫中觀察。</p>
<p>GUI 協作價值來自跨角色可見性。這個優點會帶來版本控制成本，因為 XML diff 不容易 review；團隊要補上 naming、folder structure、parameterization 與 review checklist。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>JMeter 和 k6 的主要差異是 workflow。JMeter 偏 GUI、plugin 與既有企業流程；k6 偏 code-first、CLI、threshold 與 CI artifact。</p>
<p>JMeter 和 Gatling 的主要差異是 scenario 表達。JMeter 用 test plan、thread group、sampler 與 listener 組裝；Gatling 用 JVM DSL 描述 simulation，較適合工程團隊維護複雜 flow。</p>
<p>JMeter 和 Locust 的主要差異是自訂能力。JMeter 依賴 plugin 與 sampler，Locust 可以直接用 Python library 實作 custom client；如果 protocol 特別特殊，Python 團隊可能更適合 Locust。</p>
<p>JMeter 和 Vegeta 的主要差異是複雜度。Vegeta 適合快速 HTTP saturation probe；JMeter 適合多步驟、多 dependency 與可交接測試計畫。</p>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>JMeter</th>
          <th>k6</th>
          <th>Locust</th>
          <th>Gatling</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>描述語言</td>
          <td>XML（<code>.jmx</code>）+ GUI</td>
          <td>JavaScript</td>
          <td>Python（class-based）</td>
          <td>Scala / Java / Kotlin DSL</td>
      </tr>
      <tr>
          <td>Protocol 覆蓋</td>
          <td>HTTP/JDBC/JMS/SOAP/FTP/SMTP/TCP</td>
          <td>HTTP/WebSocket/gRPC</td>
          <td>HTTP + 任何 Python lib custom</td>
          <td>HTTP/JMS/MQTT</td>
      </tr>
      <tr>
          <td>單機 throughput</td>
          <td>中（thread-per-user）</td>
          <td>高（Go goroutine）</td>
          <td>中（gevent / async）</td>
          <td>高（Akka async）</td>
      </tr>
      <tr>
          <td>Runtime model</td>
          <td>JVM thread</td>
          <td>Go runtime</td>
          <td>Python gevent</td>
          <td>JVM async actor</td>
      </tr>
      <tr>
          <td>CI 友善度</td>
          <td>需 packaging <code>.jmx</code> + plugin</td>
          <td>強 — 單一 JS file + CLI</td>
          <td>強 — pip + Python file</td>
          <td>強 — sbt / Maven + Scala file</td>
      </tr>
      <tr>
          <td>GUI</td>
          <td>完整 GUI（design / debug）</td>
          <td>無（CLI only）</td>
          <td>Web UI（runtime monitoring）</td>
          <td>無（HTML report only）</td>
      </tr>
      <tr>
          <td>Distributed</td>
          <td>Master + Slave（remote engine）</td>
          <td>k6 Cloud / Operator</td>
          <td>Master + Worker</td>
          <td>Gatling Enterprise / FrontLine</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Enterprise QA + 多 protocol</td>
          <td>Dev / SRE + HTTP-heavy + CI</td>
          <td>Python 團隊 + custom protocol</td>
          <td>JVM 團隊 + 複雜 scenario</td>
      </tr>
  </tbody>
</table>
<h2 id="操作成本">操作成本</h2>
<p>JMeter 的主要成本是測試計畫治理。<code>.jmx</code> 檔案可以累積大量 listener、debug sampler、hard-coded variable 與過期 assertion，長期不整理會讓壓測結果失去可追溯性。</p>
<p>Runner 成本來自 JVM 與 listener。GUI listener 適合開發階段觀察，不適合大規模壓測；正式測試要使用 non-GUI mode，把結果輸出成 JTL、HTML report 或外部 metrics。</p>
<p>Plugin 成本來自版本漂移。不同 runner、不同工程師機器或 CI image 的 plugin 版本如果不一致，同一份測試計畫可能產生不同結果，因此要把 plugin 清單、JMeter 版本與 container image 固定下來。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>JMeter 結果應回寫到 evidence package。最小欄位包括 test plan version、JMeter version、plugin list、runner topology、thread group 設定、ramp-up、duration、p95 / p99、error rate、throughput、target saturation metric 與 known gap。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>JMeter 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td><code>.jmx</code>、JTL、HTML report、dashboard link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / Prometheus / DB / queue 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>test plan version、plugin version</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>runner topology、production similarity</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 protocol、資料偏差、listener overhead</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓結果可審查。JMeter 測試計畫常由多人維護，gate decision 要能追到哪一版 <code>.jmx</code>、哪一組 runner、哪一批測試資料與哪一個目標環境。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>JMeter Plugins 生態</strong>：<a href="https://jmeter-plugins.org/">jmeter-plugins.org</a> 社群維護的 plugin 集合補齊原版 JMeter 的不足 — <em>Custom Thread Groups</em>（Stepping / Ultimate / Concurrency / Arrivals）讓 thread schedule 反映真實 arrival rate、<em>PerfMon</em> 抓 remote server CPU / memory、<em>Throughput Shaping Timer</em> 直接以 RPS 為目標而非 thread count、<em>Dummy Sampler</em> 拿來 mock dependency。Plugin Manager 統一安裝、CI image 要把 plugin 清單固定（<code>PluginsManagerCMD.sh install &lt;plugins&gt;</code>）避免漂移。</p>
<p><strong>BlazeMeter Cloud / Distributed execution</strong>：自建 distributed mode（master + slave 跨多 VM）成本高 — slave 機器要同 JMeter 版本、同 plugin、同 JVM 參數、RMI port 開通、結果回傳網路足夠。<a href="https://www.blazemeter.com/">BlazeMeter</a>（Perforce / 前 CA）是 JMeter SaaS、直接吃 <code>.jmx</code> 跑 cloud-scale 壓測、附 geo-distributed runner、適合短期 spike 測試不想自建 distributed cluster 的團隊。trade-off 是 vendor lock-in 跟 per-test 計費 — 長期高頻測試自建較划算。</p>
<p><strong>Distributed mode 細節</strong>：master 機器發 control plane（thread group 配置、test plan 分發）、slave 跑 thread 並回傳 sample 結果。瓶頸常出在 <em>master 收結果</em>（RMI / 自訂 protocol），不是 slave 跑不動 — 大規模測試應該關掉 GUI listener、用 <em>Backend Listener</em> 把 metric 即時推到外部時序資料庫、master 只收彙整指標而非每個 sample。同步要點：所有 slave 用同一份 <code>.jmx</code> 與 test data CSV，CSV 不能依賴 master local path。</p>
<p><strong>Backend Listener + Grafana 整合</strong>：JMeter 原生 <em>Backend Listener</em> 支援 InfluxDB / Graphite / Elasticsearch、把 active thread / response time / hit / error 即時推出去、Grafana 配 <a href="https://grafana.com/grafana/dashboards/5496-apache-jmeter-dashboard/">official JMeter dashboard</a> 即時看 throughput / latency curve。這個組合取代 GUI listener、是 distributed mode 的標準觀測方式 — listener overhead 從 master 移到外部時序系統、master 不再被 GUI 拉爆。配合 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">4 observability</a> 的時序資料庫已有時、JMeter metric 進同一個 Grafana、跟 application 端的 latency / error 並列、加速 <a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a> 的對照判讀。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>GUI 模式吃記憶體爆 / OOM</strong>：GUI listener（View Results Tree / Graph）會把所有 sample 留在 heap、跑大規模就 OutOfMemoryError — 設計階段才開 GUI、正式跑切 <code>jmeter -n</code> non-GUI、listener 用 Simple Data Writer 寫 JTL 而非 in-memory aggregate</li>
<li><strong>Listener 拖累 throughput / 結果失真</strong>：太多 listener 同時開、每個 sample 都被多個 listener 處理、JMeter 自身成為瓶頸 — 正式測試只留 Simple Data Writer + Backend Listener、結果分析離線跑 <code>jmeter -g result.jtl -o report/</code> 產 HTML</li>
<li><strong>Thread group 計算錯 / 真實流量對不上</strong>：把 thread 當「user」直接設、忽略 think time + ramp-up、結果壓出來的是 thread 全速跑而非業務流量 — 改用 Concurrency Thread Group 或 Throughput Shaping Timer 直接以 RPS 為目標、配 Constant Timer 模擬 think time</li>
<li><strong>Distributed mode 結果跟單機對不上</strong>：slave 機器 plugin / JMeter version / JVM heap 不一致、或 CSV 路徑只存在 master — 把 slave 環境 container 化（同 Docker image）、CSV 隨 <code>.jmx</code> 一起分發、<code>--remote-start</code> 統一啟動</li>
<li><strong><code>.jmx</code> XML diff 不可 review / merge conflict 多</strong>：多人同時改測試計畫、GUI 改完 XML 結構大變 — 拆 fragment（Test Fragment + Module Controller）、scenario 分檔、parameterization 走外部 CSV / properties、PR review 看截圖 + 跑結果而非 raw XML diff</li>
<li><strong>Plugin 版本漂移 / CI 結果不可重現</strong>：dev 機器 plugin 跟 CI image 不同版 — 固定 plugin manifest、CI image 用 <code>PluginsManagerCMD.sh install-for-jmx plan.jmx</code> 從 plan 自動安裝、版本鎖到 image tag</li>
<li><strong>HTTPS / TLS 連線數爆炸</strong>：JMeter 預設每 thread 一個 TLS handshake、large thread count 把 server TLS 拖垮、結果反而測到 TLS 不是 app — 開 <em>HTTP Cache Manager</em> 跟 <em>KeepAlive</em>、必要時調 <code>httpclient4.idletimeout</code></li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>JMeter 在 09 案例庫中適合作為 enterprise load test 承接點。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 售票壓測</a> 的 pre-event validation、<a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow ticketing</a> 的售票流量模型、<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day readiness</a> 的 staged validation、<a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL 1860 萬同時觀看</a> 的全球直播 pre-event rehearsal、以及 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 跨 7 個受監管市場的 Aurora 4000 TPS 容量驗證。</p>
<p>這些案例提供的是複雜業務流程與活動前驗證節奏。JMeter 頁引用案例時，要把 case 轉成 thread group、ramp-up、data set、dependency sampler 與 result artifact，並讓負載數字回到業務流程判讀 — 例如 Hotstar 的「集中地理區 CDN 壓力」要在 JMeter 用 per-region thread group 模擬、不是把全球流量塞進單一 runner。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>、<a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>、<a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></li>
<li>跨模組：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a></li>
<li>官方：<a href="https://jmeter.apache.org/usermanual/index.html">Apache JMeter documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.2 Workload Modeling</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>Workload modeling 的角色是讓壓測結果有意義。如果壓測模型跟 production traffic shape 不一致、壓測通過不代表 production 撐得住。這一層的工作不是「製造大量請求」、而是「製造跟 production 一樣形狀的請求」。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&amp;#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論&lt;/a> 的關係：9.1 提供推導工具、9.2 把工具的輸入（流量參數）量化。沒有 workload model、Little&amp;rsquo;s Law 的 λ 跟 W 都是猜。&lt;/p>
&lt;p>本章的核心問題：production traffic 不是「N RPS」這麼簡單。它有時間分布、地理分布、操作分布、cohort 分布、burst pattern。每個維度都會影響系統行為。一個只測「總 RPS」的壓測通過了、production 還是可能因為某個 cohort 集中或某個 burst pattern 出事。&lt;/p>
&lt;h2 id="traffic-shape-的五個維度">Traffic shape 的五個維度&lt;/h2>
&lt;p>Production traffic shape 至少要量五個維度才算 model 完整。&lt;/p>
&lt;p>&lt;strong>平均吞吐 vs 峰值&lt;/strong>：peak/avg ratio 是工程意義最大的單一指標。1.5x 的 peak/avg 代表流量相對平緩、容量規劃可以接近 average peak；3-5x 的 peak/avg 代表 bursty 流量、必須按 peak 規劃、平日大幅 over-provision。對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">ASOS Black Friday 24h 1.67 億 / 峰值 3500 RPS&lt;/a> 峰均比約 1.81x 屬於相對溫和；&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">Tixcraft 5 分鐘賣完&lt;/a> 是另一極端。&lt;/p>
&lt;p>&lt;strong>時間分布&lt;/strong>：日內（早晚通勤）、週內（週末活躍）、月內（月初發薪）、季內（節慶）、年內（活動）。不同尺度的週期都要記錄、用於 forecast 跟 pre-scaling 決策。&lt;/p>
&lt;p>&lt;strong>用戶分布&lt;/strong>：geographic（哪個 region 多）、device（mobile vs desktop）、tier（free / paid / VIP）。同樣 RPS、不同分布可能造成完全不同系統行為 — VIP 用戶可能跑更複雜 query、mobile 用戶可能更多 retry、跨 region 用戶可能更多 cross-zone latency。&lt;/p>
&lt;p>&lt;strong>操作分布&lt;/strong>：read vs write 比、不同 endpoint 的 mix。一個系統 90% read 跟 50% read 的容量設計完全不同 — read-heavy 可以 cache、write-heavy 必須關注 storage IOPS。&lt;/p>
&lt;p>&lt;strong>Cohort 與 burst pattern&lt;/strong>：同一秒的請求不一定均勻 — bursty arrival 比 Poisson arrival 對系統更殘酷。突發 burst 來源：promo 推播、KOL 推廣、新片發布、新聞事件。&lt;/p>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &amp;#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech 賽事高潮 burst&lt;/a> — 賽事「進球瞬間」 burst 比平均流量高 10-50 倍；&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&amp;#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&amp;#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">Disney+ 新片發布&lt;/a> — 同片瞬間集中、cohort 高度集中。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>Workload modeling 的角色是讓壓測結果有意義。如果壓測模型跟 production traffic shape 不一致、壓測通過不代表 production 撐得住。這一層的工作不是「製造大量請求」、而是「製造跟 production 一樣形狀的請求」。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論</a> 的關係：9.1 提供推導工具、9.2 把工具的輸入（流量參數）量化。沒有 workload model、Little&rsquo;s Law 的 λ 跟 W 都是猜。</p>
<p>本章的核心問題：production traffic 不是「N RPS」這麼簡單。它有時間分布、地理分布、操作分布、cohort 分布、burst pattern。每個維度都會影響系統行為。一個只測「總 RPS」的壓測通過了、production 還是可能因為某個 cohort 集中或某個 burst pattern 出事。</p>
<h2 id="traffic-shape-的五個維度">Traffic shape 的五個維度</h2>
<p>Production traffic shape 至少要量五個維度才算 model 完整。</p>
<p><strong>平均吞吐 vs 峰值</strong>：peak/avg ratio 是工程意義最大的單一指標。1.5x 的 peak/avg 代表流量相對平緩、容量規劃可以接近 average peak；3-5x 的 peak/avg 代表 bursty 流量、必須按 peak 規劃、平日大幅 over-provision。對應案例：<a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">ASOS Black Friday 24h 1.67 億 / 峰值 3500 RPS</a> 峰均比約 1.81x 屬於相對溫和；<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 5 分鐘賣完</a> 是另一極端。</p>
<p><strong>時間分布</strong>：日內（早晚通勤）、週內（週末活躍）、月內（月初發薪）、季內（節慶）、年內（活動）。不同尺度的週期都要記錄、用於 forecast 跟 pre-scaling 決策。</p>
<p><strong>用戶分布</strong>：geographic（哪個 region 多）、device（mobile vs desktop）、tier（free / paid / VIP）。同樣 RPS、不同分布可能造成完全不同系統行為 — VIP 用戶可能跑更複雜 query、mobile 用戶可能更多 retry、跨 region 用戶可能更多 cross-zone latency。</p>
<p><strong>操作分布</strong>：read vs write 比、不同 endpoint 的 mix。一個系統 90% read 跟 50% read 的容量設計完全不同 — read-heavy 可以 cache、write-heavy 必須關注 storage IOPS。</p>
<p><strong>Cohort 與 burst pattern</strong>：同一秒的請求不一定均勻 — bursty arrival 比 Poisson arrival 對系統更殘酷。突發 burst 來源：promo 推播、KOL 推廣、新片發布、新聞事件。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech 賽事高潮 burst</a> — 賽事「進球瞬間」 burst 比平均流量高 10-50 倍；<a href="/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">Disney+ 新片發布</a> — 同片瞬間集中、cohort 高度集中。</p>
<h2 id="從-production-log-抽-workload-model">從 production log 抽 workload model</h2>
<p>實務上 workload model 不能憑空寫、要從 production data 抽。流程通常分四步：</p>
<p><strong>第一步：data 蒐集</strong>。從 access log、APM trace、metric 系統取得 production traffic 樣本。要 sampling（不是全量）、避免影響 production；要包含 <em>至少一個完整 weekly cycle</em>（含週末、含峰谷）；要按 endpoint / per-tenant 分組。</p>
<p><strong>第二步：分組統計</strong>。對每組（per endpoint、per tier、per region）計算 percentile（p50 / p95 / p99）、arrival pattern（Poisson、bursty、scheduled）、payload size 分布。輸出是「workload profile」 — 比單一數字更接近 reality。</p>
<p><strong>第三步：序列重播</strong>。複製一段 production traffic 的時間序列、保留 inter-arrival timing（不只是 RPS 平均、是 <em>每秒幾個</em>）。這層讓 burst 在壓測重現、不只是「平均壓力均勻分布」。</p>
<p><strong>第四步：脫敏處理</strong>。PII（user_id、phone、address）必須匿名化或替換 — 否則壓測環境變成 PII 洩漏點。常見做法：hash + salt + 確保結果 cardinality 跟 production 一致。</p>
<p>production log 通常缺寫入 payload（log 只記 metadata、不記 request body）、要從 application metric 或 schema sample 補。schema sample 用「distinct value 抽樣」、不是「random」 — 確保壓測涵蓋常見 value pattern。</p>
<h2 id="synthetic-load-vs-production-replay">Synthetic load vs production replay</h2>
<p>兩種主要壓測方式各有取捨。</p>
<p><strong>Synthetic load</strong>：手寫腳本、明確控制每個請求的 shape。優點是好複現、可以針對特定情境設計（例如「測登入失敗 retry」）；缺點是容易脫離 production reality、寫腳本的人會無意識套用自己的偏見。</p>
<p><strong>Production traffic replay</strong>：用 GoReplay、Istio mirror、AWS VPC Traffic Mirroring 等工具把 production traffic 複製到測試環境。優點是 <em>最貼近真實</em>、自動帶上 burst 跟 cohort；缺點是消耗 production 下游資源（要算進容量規劃）、PII / 合規處理複雜、replay 環境的下游 mock 不容易做。</p>
<p><strong>混合模式</strong>：常態壓測用 synthetic（cheap、可控）、release candidate 驗證用 production replay（真實）、debug 特定 incident 用 <em>特定時段</em> 的 replay。三種工具在不同階段用、不是二選一。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">FanDuel 雙峰需要兩個 workload model 並行</a> — 直播 model（CDN heavy、長 session）跟投注 model（低延遲、burst at goal）必須分開壓測、不能合成一個。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/workload-model/" data-link-title="Workload Model" data-link-desc="描述 production traffic 形狀的可重播模型 — 容量規劃跟壓測的共同輸入">Workload Model 卡片</a> 跟 <a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic 卡片</a>。</p>
<h2 id="模型驗證怎麼知道模型像-production">模型驗證：怎麼知道模型像 production</h2>
<p>寫了 workload model 之後、怎麼驗證它真的「像 production」？方法是 <em>跑壓測 同時 對比 production metrics</em>。</p>
<p>驗證指標包含：throughput pattern（總 RPS、各 endpoint mix）、latency 分布（p50 / p95 / p99 對比）、resource utilization（CPU / memory / network 行為）、error rate 與 retry pattern。</p>
<p>兩個可能的偏差結果：</p>
<ul>
<li><strong>模型撐不住但 production 撐得住</strong> → 模型太苛刻、可能高估了流量或操作複雜度。usually fine、調整模型參數即可。</li>
<li><strong>模型撐得住但 production 撐不住</strong> → 模型不足、漏了某個維度。dangerous、需要回到 data 蒐集階段找漏掉的 pattern。</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">Zoom 30x COVID surge</a> — 之前的 workload model 完全不能用、必須 reset baseline 重新從 post-COVID 流量抽 model；<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 10K t2.micro 壓測</a> — 用實際售票場景重播驗證、不是 synthetic 數字。</p>
<h2 id="模型維護定期-review">模型維護：定期 review</h2>
<p>Workload model 不是一次抽完就永久有效。業務變化會讓模型過時、過時的模型導出的容量規劃會失準。</p>
<p>需要 re-抽 model 的訊號：</p>
<ul>
<li>新功能上線改變 user journey（例如新增 video upload、user 行為變寫多）</li>
<li>新市場進入改變 cohort 分布（例如進入印度市場、mobile share 大幅增加）</li>
<li>行銷活動改變 burst pattern（例如新增 push notification、burst 集中度上升）</li>
<li>用戶習慣轉變（例如 work-from-home 讓週末跟平日流量比變化）</li>
</ul>
<p>維護節奏建議每季 review 一次、重大產品改動立即 re-抽。每次 re-抽要 <em>跟前一版對比</em>、量化變化幅度、決定哪些容量計畫要重新評估。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS Black Friday</a></td>
          <td>持續高峰型 workload（峰均比 1.81x）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
          <td>flash-sale 形狀（5 分鐘賣完）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft</a></td>
          <td>100+ 微服務各自 workload model（不能用單一）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay</a></td>
          <td>3 億 / 天的峰均比預估</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a></td>
          <td>雙峰必須兩個 model 並行</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a>（用什麼工具實作 model）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>（用 model 跑 ramp-up）</li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a>（production log 來源）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/workload-model/" data-link-title="Workload Model" data-link-desc="描述 production traffic 形狀的可重播模型 — 容量規劃跟壓測的共同輸入">Workload Model</a></li>
<li><a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
<li><a href="/blog/backend/knowledge-cards/growth-curve/" data-link-title="Growth Curve" data-link-desc="說明用戶 / 流量隨時間成長的五種典型形狀、影響容量規劃方法">Growth Curve</a></li>
<li><a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast</a></li>
</ul>
]]></content:encoded></item><item><title>9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/</guid><description>&lt;p>這個案例的核心責任是說明「事件型不可預期峰值」的工程做法。體育博彩流量的形狀跟 Prime Day 不同 — 峰值會在賽事的特定瞬間（進球、最後一分鐘）爆量、單一賽事內可能有多次脈衝、跨賽事的時間點難以提前數月排程。GR8 Tech 在 2022 FIFA World Cup 期間達到零停機營運、是這類負載形狀的有效參考。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>GR8 Tech 從本地基礎設施遷移到 AWS、重建為微服務架構後的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/gr8-tech-case-study/">GR8 Tech case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>遷移前狀況&lt;/th>
 &lt;th>遷移後峰值&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>投注延遲&lt;/td>
 &lt;td>賽事高峰期額外延遲 2-3 秒&lt;/td>
 &lt;td>25 ms p95&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>結算吞吐&lt;/td>
 &lt;td>（未公開）&lt;/td>
 &lt;td>每分鐘 100 萬次投注結算&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>交易吞吐&lt;/td>
 &lt;td>（未公開）&lt;/td>
 &lt;td>54000 TPS @ 25ms p95&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>同時在線&lt;/td>
 &lt;td>-&lt;/td>
 &lt;td>200,000+ 同時使用者&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>投注吞吐&lt;/td>
 &lt;td>-&lt;/td>
 &lt;td>每分鐘 80,000 次體育投注&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性&lt;/td>
 &lt;td>-&lt;/td>
 &lt;td>99.95% uptime&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本彈性&lt;/td>
 &lt;td>固定預配置&lt;/td>
 &lt;td>需求降低時成本下降 25%&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Amazon EKS（Kubernetes 容器編排、跨雲端與本地）、Amazon EC2（compute）、Amazon S3 與 Amazon EBS（儲存）、AWS Auto Scaling 結合 &lt;strong>GR8 Tech 自家 AI 預測模型&lt;/strong>、AWS Infrastructure Event Management（重大賽事支援）。&lt;/p>
&lt;p>擴展範圍：「Scaled to 15 markets using AWS」。事件覆蓋：2022 FIFA World Cup 期間零停機。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>GR8 Tech 的工程做法揭露三個事件型峰值的判讀重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>不可預期 ≠ 不可預測&lt;/strong>：賽事「何時開打」是已知的（schedule 提前公告）、「賽事內何時爆量」是未知的（進球、加時、最後一分鐘）。AI 預測模型不是預測「會不會有峰值」、而是預測「峰值在 60 秒內可能多大」、把擴容窗口縮短到反應時間之內。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的「預測時間尺度」軸。&lt;/li>
&lt;li>&lt;strong>延遲是業務指標、不是技術指標&lt;/strong>：「2-3 秒額外延遲」直接造成「投注失敗、客戶流失」。25ms p95 是收入 KPI 而不是 SLO 漂亮數字。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性&lt;/a> 把 latency 翻成業務 metric 的責任。&lt;/li>
&lt;li>&lt;strong>微服務 + 容器編排是擴容粒度的前置&lt;/strong>：遷移前的單體系統「擴容」只能複製整套系統、成本曲線陡峭。EKS 拆解後可以針對熱點服務（投注引擎、結算引擎）獨立擴容、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 的逐層定位直接對齊。&lt;/li>
&lt;/ol>
&lt;p>需要警惕的判讀盲點：54000 TPS @ 25ms 是 &lt;em>公開的成功數字&lt;/em>、不是「永遠都這樣」的承諾。AI 預測模型必然有預測誤差、AWS Infrastructure Event Management 也是事件型服務、不是平台預設。這類案例適合作為「目標可達性」的存在證明、不適合直接套用為自家服務的容量假設。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>把賽事 schedule 灌進 capacity forecast&lt;/strong>：在事件已知的條件下、預先把 baseline 拉高、避免 AI 模型在零起跑時擴容。對應 EC2 Auto Scaling 的 &lt;a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html">scheduled scaling&lt;/a> + predictive scaling 雙模。&lt;/li>
&lt;li>&lt;strong>AI 模型輸入要包含領域訊號&lt;/strong>：通用 ML autoscaler 用 CPU / latency 預測、領域 autoscaler 還會用 &lt;em>賽事重要性&lt;/em>、&lt;em>投注量歷史曲線&lt;/em>、&lt;em>下注玩家集中度&lt;/em> 等業務訊號。這層讓擴容時機從反應式變成預測式。&lt;/li>
&lt;li>&lt;strong>熱點服務獨立擴容、不是整體擴容&lt;/strong>：投注引擎跟結算引擎的峰值時間不一致（投注集中在賽前 + 比賽中、結算集中在賽後）、單獨擴容比整體擴容省 25%+ 成本。&lt;/li>
&lt;li>&lt;strong>AWS Infrastructure Event Management 等廠商支援服務&lt;/strong>：在年度重大事件可以申請（World Cup、Olympic、Black Friday 等）、提供 pre-scaling 與專屬監控通道。這在 GCP / Azure 也有對等服務（GCP Customer Care Premium、Azure Event Management Support）。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP GKE + Vertical Pod Autoscaler + 自家 ML 預測、Azure AKS + KEDA + Azure ML 預測、自建 Kubernetes + Karpenter + Prometheus 推導模型都可以實作同樣的「預測 + 擴容」模式。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「事件型不可預期峰值」的工程做法。體育博彩流量的形狀跟 Prime Day 不同 — 峰值會在賽事的特定瞬間（進球、最後一分鐘）爆量、單一賽事內可能有多次脈衝、跨賽事的時間點難以提前數月排程。GR8 Tech 在 2022 FIFA World Cup 期間達到零停機營運、是這類負載形狀的有效參考。</p>
<h2 id="觀察">觀察</h2>
<p>GR8 Tech 從本地基礎設施遷移到 AWS、重建為微服務架構後的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/gr8-tech-case-study/">GR8 Tech case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>遷移前狀況</th>
          <th>遷移後峰值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>投注延遲</td>
          <td>賽事高峰期額外延遲 2-3 秒</td>
          <td>25 ms p95</td>
      </tr>
      <tr>
          <td>結算吞吐</td>
          <td>（未公開）</td>
          <td>每分鐘 100 萬次投注結算</td>
      </tr>
      <tr>
          <td>交易吞吐</td>
          <td>（未公開）</td>
          <td>54000 TPS @ 25ms p95</td>
      </tr>
      <tr>
          <td>同時在線</td>
          <td>-</td>
          <td>200,000+ 同時使用者</td>
      </tr>
      <tr>
          <td>投注吞吐</td>
          <td>-</td>
          <td>每分鐘 80,000 次體育投注</td>
      </tr>
      <tr>
          <td>可用性</td>
          <td>-</td>
          <td>99.95% uptime</td>
      </tr>
      <tr>
          <td>成本彈性</td>
          <td>固定預配置</td>
          <td>需求降低時成本下降 25%</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Amazon EKS（Kubernetes 容器編排、跨雲端與本地）、Amazon EC2（compute）、Amazon S3 與 Amazon EBS（儲存）、AWS Auto Scaling 結合 <strong>GR8 Tech 自家 AI 預測模型</strong>、AWS Infrastructure Event Management（重大賽事支援）。</p>
<p>擴展範圍：「Scaled to 15 markets using AWS」。事件覆蓋：2022 FIFA World Cup 期間零停機。</p>
<h2 id="判讀">判讀</h2>
<p>GR8 Tech 的工程做法揭露三個事件型峰值的判讀重點。</p>
<ol>
<li><strong>不可預期 ≠ 不可預測</strong>：賽事「何時開打」是已知的（schedule 提前公告）、「賽事內何時爆量」是未知的（進球、加時、最後一分鐘）。AI 預測模型不是預測「會不會有峰值」、而是預測「峰值在 60 秒內可能多大」、把擴容窗口縮短到反應時間之內。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的「預測時間尺度」軸。</li>
<li><strong>延遲是業務指標、不是技術指標</strong>：「2-3 秒額外延遲」直接造成「投注失敗、客戶流失」。25ms p95 是收入 KPI 而不是 SLO 漂亮數字。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性</a> 把 latency 翻成業務 metric 的責任。</li>
<li><strong>微服務 + 容器編排是擴容粒度的前置</strong>：遷移前的單體系統「擴容」只能複製整套系統、成本曲線陡峭。EKS 拆解後可以針對熱點服務（投注引擎、結算引擎）獨立擴容、跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的逐層定位直接對齊。</li>
</ol>
<p>需要警惕的判讀盲點：54000 TPS @ 25ms 是 <em>公開的成功數字</em>、不是「永遠都這樣」的承諾。AI 預測模型必然有預測誤差、AWS Infrastructure Event Management 也是事件型服務、不是平台預設。這類案例適合作為「目標可達性」的存在證明、不適合直接套用為自家服務的容量假設。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>把賽事 schedule 灌進 capacity forecast</strong>：在事件已知的條件下、預先把 baseline 拉高、避免 AI 模型在零起跑時擴容。對應 EC2 Auto Scaling 的 <a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html">scheduled scaling</a> + predictive scaling 雙模。</li>
<li><strong>AI 模型輸入要包含領域訊號</strong>：通用 ML autoscaler 用 CPU / latency 預測、領域 autoscaler 還會用 <em>賽事重要性</em>、<em>投注量歷史曲線</em>、<em>下注玩家集中度</em> 等業務訊號。這層讓擴容時機從反應式變成預測式。</li>
<li><strong>熱點服務獨立擴容、不是整體擴容</strong>：投注引擎跟結算引擎的峰值時間不一致（投注集中在賽前 + 比賽中、結算集中在賽後）、單獨擴容比整體擴容省 25%+ 成本。</li>
<li><strong>AWS Infrastructure Event Management 等廠商支援服務</strong>：在年度重大事件可以申請（World Cup、Olympic、Black Friday 等）、提供 pre-scaling 與專屬監控通道。這在 GCP / Azure 也有對等服務（GCP Customer Care Premium、Azure Event Management Support）。</li>
</ol>
<p>跨平台等效：GCP GKE + Vertical Pod Autoscaler + 自家 ML 預測、Azure AKS + KEDA + Azure ML 預測、自建 Kubernetes + Karpenter + Prometheus 推導模型都可以實作同樣的「預測 + 擴容」模式。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想做事件型峰值的容量預測 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想用 AI / ML 做預測式擴容 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9 Performance Improvement Loop</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性</a></li>
<li>想拆解微服務以便獨立擴容 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a></li>
<li>對照不同形狀的峰值 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a>（可預期極端峰值）/ <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a>（無峰值低延遲）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/gr8-tech-case-study/">GR8 Tech Achieves High Performance and Scalability with Data Center Migration to AWS</a></li>
<li><a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-predictive-scaling.html">Predictive scaling for Amazon EC2 Auto Scaling</a></li>
<li><a href="https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html">Scheduled scaling for Amazon EC2 Auto Scaling</a></li>
</ul>
]]></content:encoded></item><item><title>Gatling</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/</guid><description>&lt;p>Gatling 的核心責任是把複雜使用者流程寫成可維護的 JVM simulation。它適合 JVM 生態團隊、強型別 DSL、HTTP / WebSocket / JMS / MQTT 等 scenario，以及需要把 injection profile、assertion、report 與 CI pipeline 綁在一起的壓測流程。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Gatling 是 &lt;em>Scala-origin / 現以 Java DSL 為主流&lt;/em> 的 load testing 工具、跑在 JVM、async / non-blocking engine（基於 Akka / Netty）讓單一 injector node 就能驅動高 RPS。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust&lt;/a> 的核心差異在 &lt;em>語言生態 + engine efficiency + scenario 表達力&lt;/em>、壓出負載的能力都具備：&lt;/p>
&lt;ul>
&lt;li>vs k6 — k6 走 Go runtime + JavaScript scripting、CLI / Grafana 生態友善；Gatling 走 JVM + Java/Scala/Kotlin DSL、適合既有 JVM 工具鏈與強型別 review&lt;/li>
&lt;li>vs JMeter — JMeter 走 GUI / XML test plan、適合非工程角色協作；Gatling 走 code-first、適合 PR / build pipeline / refactor 工作流&lt;/li>
&lt;li>vs Locust — Locust 走 Python coroutine、scripting 自由度高；Gatling 走 DSL + injection profile、scenario 結構化程度更高&lt;/li>
&lt;li>engine efficiency — async / non-blocking model 讓 Gatling 在單機可推到數萬 RPS、JMeter thread-per-user 在同等資源下 throughput 較低&lt;/li>
&lt;/ul>
&lt;p>產品線分兩層：&lt;em>Gatling OSS&lt;/em>（開源 simulation runner + HTML report）與 &lt;em>Gatling Enterprise&lt;/em>（前身 FrontLine、加上 distributed injector、cluster orchestration、live monitoring、long-term result storage、role-based access）。OSS 適合單機 baseline / CI smoke、Enterprise 適合 cross-region distributed / 大型活動前壓測 / 結果長期治理。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Gatling 在壓測流程裡是否健康、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Scala DSL vs Java DSL 版本&lt;/strong>：Gatling 3.7+（2022）正式加 Java DSL、2024 後新專案多走 Java DSL；舊 Scala simulation 仍可跑、但團隊要決定 &lt;em>維持 Scala 還是漸進改寫 Java&lt;/em>、避免雙語言治理&lt;/li>
&lt;li>&lt;strong>Injection profile 設計&lt;/strong>：simulation 是否明確區分 &lt;em>open model&lt;/em>（&lt;code>rampUsersPerSec&lt;/code> / &lt;code>constantUsersPerSec&lt;/code>、模擬真實 arrival）vs &lt;em>closed model&lt;/em>（&lt;code>atOnceUsers&lt;/code> / &lt;code>rampUsers&lt;/code>、模擬 fixed user pool），對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 的 traffic shape&lt;/li>
&lt;li>&lt;strong>Assertion gate&lt;/strong>：simulation 是否有 &lt;code>assertions { global.responseTime.percentile3.lt(500) }&lt;/code> 這類 hard gate、CI 跑完直接 fail build；沒 assertion 的 simulation 只是壓測、不是 release gate&lt;/li>
&lt;li>&lt;strong>Enterprise vs OSS 邊界&lt;/strong>：是否清楚知道哪些能力只 Enterprise 有（distributed injector / multi-region / long-term result storage / live dashboard）、避免用 OSS 拼湊 Enterprise 級需求&lt;/li>
&lt;/ul>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>Gatling 適合 code-first 且 JVM 能力強的團隊。當 workload model 需要多步驟 flow、資料 feeder、條件分支、session state 與明確 injection profile，Gatling 能用 simulation 把這些行為寫成工程 artifact。&lt;/p></description><content:encoded><![CDATA[<p>Gatling 的核心責任是把複雜使用者流程寫成可維護的 JVM simulation。它適合 JVM 生態團隊、強型別 DSL、HTTP / WebSocket / JMS / MQTT 等 scenario，以及需要把 injection profile、assertion、report 與 CI pipeline 綁在一起的壓測流程。</p>
<h2 id="服務定位">服務定位</h2>
<p>Gatling 是 <em>Scala-origin / 現以 Java DSL 為主流</em> 的 load testing 工具、跑在 JVM、async / non-blocking engine（基於 Akka / Netty）讓單一 injector node 就能驅動高 RPS。它跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> / <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a> / <a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a> 的核心差異在 <em>語言生態 + engine efficiency + scenario 表達力</em>、壓出負載的能力都具備：</p>
<ul>
<li>vs k6 — k6 走 Go runtime + JavaScript scripting、CLI / Grafana 生態友善；Gatling 走 JVM + Java/Scala/Kotlin DSL、適合既有 JVM 工具鏈與強型別 review</li>
<li>vs JMeter — JMeter 走 GUI / XML test plan、適合非工程角色協作；Gatling 走 code-first、適合 PR / build pipeline / refactor 工作流</li>
<li>vs Locust — Locust 走 Python coroutine、scripting 自由度高；Gatling 走 DSL + injection profile、scenario 結構化程度更高</li>
<li>engine efficiency — async / non-blocking model 讓 Gatling 在單機可推到數萬 RPS、JMeter thread-per-user 在同等資源下 throughput 較低</li>
</ul>
<p>產品線分兩層：<em>Gatling OSS</em>（開源 simulation runner + HTML report）與 <em>Gatling Enterprise</em>（前身 FrontLine、加上 distributed injector、cluster orchestration、live monitoring、long-term result storage、role-based access）。OSS 適合單機 baseline / CI smoke、Enterprise 適合 cross-region distributed / 大型活動前壓測 / 結果長期治理。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Gatling 在壓測流程裡是否健康、最少看四件事：</p>
<ul>
<li><strong>Scala DSL vs Java DSL 版本</strong>：Gatling 3.7+（2022）正式加 Java DSL、2024 後新專案多走 Java DSL；舊 Scala simulation 仍可跑、但團隊要決定 <em>維持 Scala 還是漸進改寫 Java</em>、避免雙語言治理</li>
<li><strong>Injection profile 設計</strong>：simulation 是否明確區分 <em>open model</em>（<code>rampUsersPerSec</code> / <code>constantUsersPerSec</code>、模擬真實 arrival）vs <em>closed model</em>（<code>atOnceUsers</code> / <code>rampUsers</code>、模擬 fixed user pool），對應 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 的 traffic shape</li>
<li><strong>Assertion gate</strong>：simulation 是否有 <code>assertions { global.responseTime.percentile3.lt(500) }</code> 這類 hard gate、CI 跑完直接 fail build；沒 assertion 的 simulation 只是壓測、不是 release gate</li>
<li><strong>Enterprise vs OSS 邊界</strong>：是否清楚知道哪些能力只 Enterprise 有（distributed injector / multi-region / long-term result storage / live dashboard）、避免用 OSS 拼湊 Enterprise 級需求</li>
</ul>
<h2 id="定位">定位</h2>
<p>Gatling 適合 code-first 且 JVM 能力強的團隊。當 workload model 需要多步驟 flow、資料 feeder、條件分支、session state 與明確 injection profile，Gatling 能用 simulation 把這些行為寫成工程 artifact。</p>
<p>這個定位讓 Gatling 接到 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 與 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>。它的價值在於把 traffic shape 寫進 injection profile，讓 ramp-up、constant users、stress peak 與 soak test 都能被版本化。</p>
<h2 id="適用場景">適用場景</h2>
<p>JVM 團隊適合用 Gatling 承接壓測。Java、Scala 或 Kotlin 團隊能把 simulation 當成一般程式碼 review，並用既有 build、dependency、CI 與 artifact 流程維護。</p>
<p>複雜 scenario 適合用 Gatling 表達。登入、搜尋、加入購物車、checkout、payment mock、order query 這類 multi-step flow 可以用 session 與 feeder 管理資料。</p>
<p>高品質 report 適合 release review。Gatling 的 report 能幫 reviewer 看到 response time distribution、request group、error 與 injection profile，適合在 release gate 中保留可讀證據。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Gatling 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>JVM DSL</td>
          <td>simulation 可 code review</td>
          <td>Scala / Java / Kotlin 維護能力</td>
      </tr>
      <tr>
          <td>Injection profile</td>
          <td>負載階段可精準表達</td>
          <td>production traffic shape 校正</td>
      </tr>
      <tr>
          <td>Session / feeder</td>
          <td>多步驟資料與狀態容易管理</td>
          <td>測試資料治理與敏感資料遮罩</td>
      </tr>
      <tr>
          <td>Report</td>
          <td>release review 可讀性高</td>
          <td>長期趨勢儲存與 cross-run comparison</td>
      </tr>
  </tbody>
</table>
<p>JVM DSL 價值來自可維護性。壓測 scenario 如果需要被長期 review、重構、抽 helper 或接 build pipeline，Gatling 的 code-first workflow 會比 GUI test plan 更適合工程團隊。</p>
<p>Injection profile 價值來自負載形狀精準。團隊可以把 steady load、spike、ramp、open model 與 closed model 放到 simulation 中，讓 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 的 knee point 判讀更可重現。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Gatling 和 k6 的主要差異是語言與生態。Gatling 適合 JVM 團隊與強型別 simulation；k6 適合 JavaScript-style scripting、CLI workflow 與 Grafana 生態。</p>
<p>Gatling 和 JMeter 的主要差異是維護模式。Gatling 偏 code review、build pipeline 與 simulation abstraction；JMeter 偏 GUI、plugin 與跨角色測試資產。</p>
<p>Gatling 和 Locust 的主要差異是自訂語言。Locust 適合 Python 團隊與任意 Python client；Gatling 適合 JVM 團隊與 report / injection profile 的結構化壓測。</p>
<p>Gatling 和 Vegeta 的主要差異是 scenario 深度。Vegeta 適合快速 HTTP pressure test；Gatling 適合需要 session、feeder、assertion 與多 request group 的長期測試。</p>
<h2 id="操作成本">操作成本</h2>
<p>Gatling 的主要成本是 JVM 團隊能力。非 JVM 團隊要承擔語言、build tool、dependency 與 simulation pattern 的學習成本；這個成本只有在 scenario 複雜度夠高時才划算。</p>
<p>測試資料成本來自 feeder 與 session。多步驟 flow 需要 account、cart、order、token、region 與 tenant 資料，資料過期或分布偏差會讓壓測結果失真。</p>
<p>Enterprise / distributed 成本要提前評估。單機 Gatling 適合中小型 baseline；跨 region、大型活動前驗證或長時間 soak test 需要 runner topology、結果集中與雲端成本治理。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Gatling 結果應回寫到 evidence package。最小欄位包括 simulation version、injection profile、feeder source、target environment、assertion、response time distribution、error rate、throughput、target service saturation metric、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Gatling 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>simulation code、HTML report、dashboard link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / logs 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>feeder freshness、scenario coverage</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>production similarity、runner capacity</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 flow、資料偏差、下游 mock 限制</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 simulation 可回放。Reviewer 要能從 report 回到 injection profile、scenario code、feeder 與目標環境，才有辦法判斷一次壓測是容量訊號還是測試設計偏差。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Gatling</th>
          <th>k6</th>
          <th>JMeter</th>
          <th>Locust</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>語言 / DSL</td>
          <td>Java / Kotlin / Scala DSL（JVM）</td>
          <td>JavaScript（Go runtime）</td>
          <td>GUI / XML test plan（JVM）</td>
          <td>Python（coroutine / gevent）</td>
      </tr>
      <tr>
          <td>Engine model</td>
          <td>Async / non-blocking（Akka + Netty）</td>
          <td>Async（Go goroutine）</td>
          <td>Thread-per-user（同步）</td>
          <td>Async coroutine</td>
      </tr>
      <tr>
          <td>單機 RPS 上限</td>
          <td>高（數萬 RPS）</td>
          <td>高（數萬 RPS）</td>
          <td>中（thread overhead）</td>
          <td>中（GIL + coroutine）</td>
      </tr>
      <tr>
          <td>Scenario 表達力</td>
          <td>強（session / feeder / 條件分支內建）</td>
          <td>中（JS function 自寫）</td>
          <td>中（GUI 拖拉 + listener）</td>
          <td>中（Python class + task）</td>
      </tr>
      <tr>
          <td>Report quality</td>
          <td>高（HTML report 內建、distribution / group 詳細）</td>
          <td>中（CLI 摘要 + Grafana 串接）</td>
          <td>中（GUI listener、不適合 headless）</td>
          <td>中（web UI 即時、無 historical）</td>
      </tr>
      <tr>
          <td>CI integration</td>
          <td>強（Maven / Gradle / sbt + assertion gate）</td>
          <td>強（CLI + JSON output）</td>
          <td>中（CLI mode 可、但 GUI-first）</td>
          <td>強（CLI + Python ecosystem）</td>
      </tr>
      <tr>
          <td>Distributed</td>
          <td>OSS 自建 / Enterprise 內建</td>
          <td>k6 Cloud / OSS 自建</td>
          <td>自建（master-slave）</td>
          <td>自建（master-worker）</td>
      </tr>
      <tr>
          <td>商業版本</td>
          <td>Gatling Enterprise（前 FrontLine）</td>
          <td>Grafana Cloud k6</td>
          <td>無（純 OSS）</td>
          <td>無（純 OSS）</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>JVM 團隊、複雜 scenario、release gate、高 RPS efficiency</td>
          <td>全棧團隊、CLI workflow、Grafana 生態</td>
          <td>跨角色團隊、legacy test plan、protocol 多樣</td>
          <td>Python 團隊、自訂 client、輕量 setup</td>
      </tr>
  </tbody>
</table>
<p>選 Gatling 的核心訴求：<em>JVM 團隊 + 複雜 scenario（session / feeder / 多 group）+ 高 RPS 單機效率 + HTML report 作為 release gate 證據</em>。Java DSL 在 2024 後降低了 Scala 學習門檻、讓 Java/Kotlin 後端團隊不必再為了壓測導入 Scala。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Gatling Enterprise（前 FrontLine）</strong>：商業版加 <em>distributed injector cluster</em>（跨 region / 跨 cloud 推大型負載）、<em>live monitoring dashboard</em>（real-time RPS / response time 趨勢、不用等 simulation 結束看 HTML）、<em>long-term result storage</em>（cross-run comparison、retention policy）、<em>role-based access</em>（QA / dev / SRE 不同權限）。對只跑單機 baseline 的團隊 OSS 已夠；要跑黑五 / 春晚級活動前壓測或多 region 同時施壓、需要 Enterprise 或自建 distributed topology。</p>
<p><strong>Java DSL 取代 Scala 成主流（2022-2024）</strong>：Gatling 3.7（2022）正式釋出 Java DSL、3.9+ 文件 Java / Kotlin / Scala 三語並列、2024 後新教學多以 Java 為主。對 Java 後端團隊降低 onboarding 成本、但要注意 <em>Gatling 2.x → 3.x</em> 的 Scala syntax 不向後相容（<code>scenario</code> builder、<code>http</code> config、<code>feed</code> 用法都改寫）— 舊 simulation 升級時等於改寫一遍。</p>
<p><strong>Distributed execution（OSS）</strong>：OSS 沒有內建 cluster orchestration、要靠 <em>multiple injector + result aggregation</em>：每台 injector 跑同一份 simulation（按 user count 切割）、結束後把 <code>simulation.log</code> 蒐集到一處用 <code>gatling.sh</code> 重跑 report stage。常見補位是用 Kubernetes Job + 共享 PVC、或直接走 Gatling Enterprise。</p>
<p><strong>HTML report 與 release gate</strong>：simulation 跑完自動產 HTML report、含 <em>response time percentile distribution</em>（mean / p50 / p95 / p99 / max）、<em>per-request-group breakdown</em>、<em>active users over time</em>、<em>error log</em>。release gate 的標準做法是：CI job 跑 simulation → assertion gate fail 直接 break build → HTML report 存成 build artifact 供 reviewer 翻查、配合 <a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">Evidence Package</a> 治理。</p>
<p><strong>CI integration 模式</strong>：Jenkins / GitLab CI / GitHub Actions 都靠 <code>mvn gatling:test</code> / <code>gradle gatlingRun</code> / <code>sbt gatling:test</code> 入口、CI 設定 <em>baseline simulation</em>（每 PR 跑、catch regression）+ <em>release simulation</em>（release branch / nightly 跑、長時間 soak）。staging environment 跑壓測時要隔離噪音來源（其他 QA 流量 / cron job）、否則 RPS 數字會被污染。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Scala learning curve 拖累進度</strong>：團隊沒人會 Scala、被 implicit / case class / pattern match 卡住 — 改用 Java DSL（3.7+）或 Kotlin DSL、保留 Gatling 表達力但去除 Scala 學習成本</li>
<li><strong>Gatling 2.x → 3.x 升級 simulation 全紅</strong>：<code>bootstrap</code> import path / <code>scenario</code> builder API / <code>feed</code> 語法都變了 — 走 <em>新專案直接 3.x、舊專案維持 2.x</em> 雙軌、或安排專門 sprint 改寫、避免邊跑邊踩雷</li>
<li><strong>JVM heap OOM / GC pause 拖慢 RPS</strong>：高 RPS 下 default heap 不夠、Young Gen GC 頻繁 — 調 <code>-Xmx4G -Xms4G</code>、用 G1GC / ZGC、監控 injector 的 GC log 跟 CPU、不是只看 target service</li>
<li><strong>Injection profile 設計錯導致誤判 saturation</strong>：用 <code>atOnceUsers(1000)</code> 壓 closed model 但實際 traffic 是 open arrival、結果 knee point 找錯 — 看 production traffic shape、open model 用 <code>constantUsersPerSec</code> / <code>rampUsersPerSec</code>、closed model 才用 <code>atOnceUsers</code></li>
<li><strong>Single injector node 撞 client-side bottleneck</strong>：injector CPU / network / file descriptor / source port 用滿、看起來 target saturate 其實是 injector saturate — 監控 injector resource、scale out 成 distributed 或走 Enterprise</li>
<li><strong>Feeder data 過期 / 分布偏差</strong>：用同一份 <code>users.csv</code> 反覆壓、cache hit rate 失真、production 看不到的 cache miss 路徑沒被測 — feeder 走 <code>random</code> / <code>shuffle</code>、定期 regenerate、覆蓋 long-tail key</li>
<li><strong>HTML report 看起來綠但 production 出事</strong>：assertion gate 只設 average response time、p99 / error rate 沒設、release 後尖峰時段才爆 — assertion 要明確設 p95 / p99 + error rate threshold、不只看 mean</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Gatling 適合回寫多步驟與多負載模型案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 雙峰 workload</a> 的直播與投注雙模型、<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 token / admission flow、<a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow ticketing</a> 的售票流程壓力、<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora 金融帳本</a> 的「比賽期讀爆量 + payout 時寫爆量」雙峰錯位，以及 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> 的「投注 / 結算 / 賠率更新」三類請求 group 的 injection profile。</p>
<p>這些案例的重點是 scenario 與 injection profile。Gatling 頁引用案例時，要把業務流程拆成 request group、session state、feeder、assertion 與 stop condition — 例如 DraftKings 雙峰錯位要寫成兩個 scenario 平行注入、各自有獨立 assertion budget。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>、<a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>、<a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></li>
<li>官方：<a href="https://docs.gatling.io/">Gatling documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.3 壓測工具選型</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/load-test-tooling/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/load-test-tooling/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>壓測工具選型的核心不是「哪個工具最強」、是「哪個工具最貼合本團隊的 workload model 表達能力跟 CI 整合需求」。沒有絕對最好的工具、只有最匹配當前場景的工具。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 的關係：9.2 定義 workload 長什麼樣、9.3 找能複製這個樣子的工具。工具選對、壓測結果可信；工具選錯、壓測結果誤導。&lt;/p>
&lt;p>本章不是工具教學、是 &lt;em>選型維度&lt;/em> + 主流工具的 &lt;em>適用情境&lt;/em>。讀者讀完後能回答「我現在這個 workload 該用哪個工具」、而不是「哪個工具最快」。&lt;/p>
&lt;h2 id="六個選型維度">六個選型維度&lt;/h2>
&lt;p>選工具時要按六個維度評估、不能只看「能不能跑 HTTP GET」。&lt;/p>
&lt;p>&lt;strong>腳本表達能力&lt;/strong>：能不能寫複雜 user journey（登入 → 瀏覽 → 加購物車 → 結帳）、不只是單一 HTTP request。複雜系統的壓測通常是 user journey 級別、單一 endpoint 壓測只能找絕對極限、找不到 cross-endpoint contention。&lt;/p>
&lt;p>&lt;strong>協議支援&lt;/strong>：HTTP / WebSocket / gRPC / TCP / 自家二進位協議。WebSocket 跟 gRPC 是現代後端常見、傳統工具（JMeter、wrk）可能要 plugin 補。&lt;/p>
&lt;p>&lt;strong>規模能力&lt;/strong>：單機可以發多少 RPS、能不能分散式擴容。本機 wrk 可發 10K-50K RPS；分散式 Locust 可發 1M+ RPS。決定因素：CPU 效率、async I/O 模型、是否單機 bound。&lt;/p>
&lt;p>&lt;strong>CI 整合&lt;/strong>：能不能在 PR 上跑 lightweight perf check、結果能不能機器可讀（JSON / Prometheus exposition）、能不能跟 baseline diff。沒有 CI 整合的工具只能做「事件型壓測」、無法做 continuous perf governance。&lt;/p>
&lt;p>&lt;strong>結果分析&lt;/strong>：原生 dashboard（k6 Cloud、Gatling Enterprise）/ Prometheus + Grafana 整合 / 純文字輸出。要看結果分發、團隊成員能不能輕鬆查詢歷史。&lt;/p>
&lt;p>&lt;strong>學習曲線&lt;/strong>：腳本語言（JavaScript / Scala / Python / Go）、團隊熟悉度。工具好但團隊不會用、會變成 1-2 個工程師的孤島技能、流失時整套廢掉。&lt;/p>
&lt;h2 id="主流開源工具對照">主流開源工具對照&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>工具&lt;/th>
 &lt;th>腳本&lt;/th>
 &lt;th>規模&lt;/th>
 &lt;th>學習曲線&lt;/th>
 &lt;th>適用情境&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>k6&lt;/td>
 &lt;td>JS&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>低-中&lt;/td>
 &lt;td>複雜 user journey + CI 整合、現代工具首選&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>JMeter&lt;/td>
 &lt;td>XML/GUI&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>中-高&lt;/td>
 &lt;td>企業已有流程、protocol 廣、reluctant 改&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gatling&lt;/td>
 &lt;td>Scala&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>報表精美、Scala 學習門檻&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Locust&lt;/td>
 &lt;td>Python&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>複雜邏輯、Python 生態、單機 throughput 受限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Vegeta&lt;/td>
 &lt;td>CLI&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>低&lt;/td>
 &lt;td>CLI driven、quick HTTP 壓測&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>wrk/wrk2&lt;/td>
 &lt;td>C&lt;/td>
 &lt;td>高&lt;/td>
 &lt;td>低&lt;/td>
 &lt;td>單機極限 RPS、saturation discovery 用&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>k6&lt;/strong> 是過去 5 年崛起的綜合首選。JavaScript 腳本（前端工程師也能寫）、原生 dashboard、Prometheus exposition、CI 友善。Grafana 收購後生態加速。缺點：複雜 stateful 場景（DB connection pool 共享）需要繞 workaround。&lt;/p>
&lt;p>&lt;strong>JMeter&lt;/strong> 是企業常見的 incumbent。協議支援廣（含 LDAP、JDBC、JMS）、有 GUI 編輯器。缺點：腳本是 XML、版本控制困難；GUI 主要用來生成腳本、實際跑壓測還是要 headless。已經在用的團隊建議繼續、新團隊不必特意選它。&lt;/p>
&lt;p>&lt;strong>Gatling&lt;/strong> 高 throughput 純 async、性能優秀、報表精美。缺點：Scala / Kotlin DSL 學習曲線陡、新版本（11+）改了 DSL 不向後相容。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>壓測工具選型的核心不是「哪個工具最強」、是「哪個工具最貼合本團隊的 workload model 表達能力跟 CI 整合需求」。沒有絕對最好的工具、只有最匹配當前場景的工具。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 的關係：9.2 定義 workload 長什麼樣、9.3 找能複製這個樣子的工具。工具選對、壓測結果可信；工具選錯、壓測結果誤導。</p>
<p>本章不是工具教學、是 <em>選型維度</em> + 主流工具的 <em>適用情境</em>。讀者讀完後能回答「我現在這個 workload 該用哪個工具」、而不是「哪個工具最快」。</p>
<h2 id="六個選型維度">六個選型維度</h2>
<p>選工具時要按六個維度評估、不能只看「能不能跑 HTTP GET」。</p>
<p><strong>腳本表達能力</strong>：能不能寫複雜 user journey（登入 → 瀏覽 → 加購物車 → 結帳）、不只是單一 HTTP request。複雜系統的壓測通常是 user journey 級別、單一 endpoint 壓測只能找絕對極限、找不到 cross-endpoint contention。</p>
<p><strong>協議支援</strong>：HTTP / WebSocket / gRPC / TCP / 自家二進位協議。WebSocket 跟 gRPC 是現代後端常見、傳統工具（JMeter、wrk）可能要 plugin 補。</p>
<p><strong>規模能力</strong>：單機可以發多少 RPS、能不能分散式擴容。本機 wrk 可發 10K-50K RPS；分散式 Locust 可發 1M+ RPS。決定因素：CPU 效率、async I/O 模型、是否單機 bound。</p>
<p><strong>CI 整合</strong>：能不能在 PR 上跑 lightweight perf check、結果能不能機器可讀（JSON / Prometheus exposition）、能不能跟 baseline diff。沒有 CI 整合的工具只能做「事件型壓測」、無法做 continuous perf governance。</p>
<p><strong>結果分析</strong>：原生 dashboard（k6 Cloud、Gatling Enterprise）/ Prometheus + Grafana 整合 / 純文字輸出。要看結果分發、團隊成員能不能輕鬆查詢歷史。</p>
<p><strong>學習曲線</strong>：腳本語言（JavaScript / Scala / Python / Go）、團隊熟悉度。工具好但團隊不會用、會變成 1-2 個工程師的孤島技能、流失時整套廢掉。</p>
<h2 id="主流開源工具對照">主流開源工具對照</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>腳本</th>
          <th>規模</th>
          <th>學習曲線</th>
          <th>適用情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>k6</td>
          <td>JS</td>
          <td>中</td>
          <td>低-中</td>
          <td>複雜 user journey + CI 整合、現代工具首選</td>
      </tr>
      <tr>
          <td>JMeter</td>
          <td>XML/GUI</td>
          <td>中</td>
          <td>中-高</td>
          <td>企業已有流程、protocol 廣、reluctant 改</td>
      </tr>
      <tr>
          <td>Gatling</td>
          <td>Scala</td>
          <td>高</td>
          <td>高</td>
          <td>報表精美、Scala 學習門檻</td>
      </tr>
      <tr>
          <td>Locust</td>
          <td>Python</td>
          <td>高</td>
          <td>中</td>
          <td>複雜邏輯、Python 生態、單機 throughput 受限</td>
      </tr>
      <tr>
          <td>Vegeta</td>
          <td>CLI</td>
          <td>中</td>
          <td>低</td>
          <td>CLI driven、quick HTTP 壓測</td>
      </tr>
      <tr>
          <td>wrk/wrk2</td>
          <td>C</td>
          <td>高</td>
          <td>低</td>
          <td>單機極限 RPS、saturation discovery 用</td>
      </tr>
  </tbody>
</table>
<p><strong>k6</strong> 是過去 5 年崛起的綜合首選。JavaScript 腳本（前端工程師也能寫）、原生 dashboard、Prometheus exposition、CI 友善。Grafana 收購後生態加速。缺點：複雜 stateful 場景（DB connection pool 共享）需要繞 workaround。</p>
<p><strong>JMeter</strong> 是企業常見的 incumbent。協議支援廣（含 LDAP、JDBC、JMS）、有 GUI 編輯器。缺點：腳本是 XML、版本控制困難；GUI 主要用來生成腳本、實際跑壓測還是要 headless。已經在用的團隊建議繼續、新團隊不必特意選它。</p>
<p><strong>Gatling</strong> 高 throughput 純 async、性能優秀、報表精美。缺點：Scala / Kotlin DSL 學習曲線陡、新版本（11+）改了 DSL 不向後相容。</p>
<p><strong>Locust</strong> 是 Python 生態的選擇、特別適合複雜業務邏輯（用 Python 寫 user journey 自然）。分散式部署原生支援。缺點：Python 單線程 throughput 受限、要靠分散式擴容。</p>
<p><strong>Vegeta</strong> 跟 <strong>wrk</strong> 是「quick check」工具、用於單一 endpoint 的極限測試。不適合複雜場景、適合 saturation discovery 第一輪「找這個服務的天花板」。</p>
<h2 id="production-traffic-replay-工具">Production traffic replay 工具</h2>
<p>當需要複製 <em>真實 production traffic</em> 的壓測場景時、需要另一類工具。</p>
<p><strong>GoReplay</strong> 是最常用的開源 traffic replay 工具。在 production server 上 tcpdump-based 捕獲 HTTP traffic、可以 store 到 file 或 stream 到 staging 環境。優點：開源、無 vendor lock-in；缺點：HTTP only、加密流量要拿到 key 才能用。</p>
<p><strong>Service mesh shadow（Istio / Linkerd mirror）</strong>：mesh 層 mirror traffic 到 staging service。優點：mesh 已部署的話 zero infra cost、加密 traffic 也能 mirror。缺點：需要 service mesh 已落地。</p>
<p><strong>AWS VPC Traffic Mirroring</strong>：底層網路層 mirror、application 完全無感。優點：最低 invasion；缺點：AWS only、加密 traffic 要另外處理。</p>
<p><strong>Diffy（Twitter / X 開源、已 deprecated 但概念仍有效）</strong>：dual-write 同時打到舊 / 新版本、比對結果。適合驗證「新版本是否邏輯正確」、不是純壓測。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 10K t2.micro 壓測</a> — 用分散式 EC2 跑 synthetic load 模擬 100K 同時搶票；<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">SeatGeek Virtual Waiting Room</a> — token 配發邏輯通常用 dual-write 驗證新舊版本一致。</p>
<h2 id="雲端-managed-壓測服務">雲端 managed 壓測服務</h2>
<p>當不想養 load test infrastructure、想 ad-hoc 跑大規模壓測時、用 managed service。</p>
<p><strong>AWS Distributed Load Testing</strong>：CloudFormation 起 Fargate cluster 跑 JMeter 或 Taurus、報表寫到 S3。優點：一鍵部署、Fargate 計費；缺點：JMeter-based、不是現代 k6 風格。</p>
<p><strong>Grafana k6 Cloud</strong>：託管 k6、跨地理 distributed 壓測（從多個 region 同時發流量）。優點：地理分散原生、跟 Grafana 整合無縫；缺點：vendor cost。</p>
<p><strong>Azure Load Testing</strong>：Azure 原生、整合 Application Insights。優點：Azure 用戶無縫；缺點：相對較新、生態還在補。</p>
<p><strong>GCP 沒有 first-party managed load testing</strong>：要靠 Marketplace 方案或自管 Locust on GKE。</p>
<h2 id="工具選型決策樹">工具選型決策樹</h2>
<p>落地時的快速決策：</p>
<ul>
<li>想快速驗證單一 API 極限 → wrk / Vegeta</li>
<li>想寫複雜 user journey + CI 整合 + JavaScript 團隊 → <strong>k6</strong>（新項目首選）</li>
<li>企業已有 JMeter 流程、不想換 → JMeter（接受 XML / GUI 複雜度）</li>
<li>大規模分散式 + Python 生態 → Locust</li>
<li>報表給管理層看、Scala 團隊 → Gatling</li>
<li>想複製真實 production traffic → GoReplay 或 service mesh shadow</li>
<li>想 ad-hoc 雲端大規模壓測 → 對應雲商的 managed load test</li>
</ul>
<h2 id="常見反模式">常見反模式</h2>
<ul>
<li><strong>只測單一 API、不測 user journey</strong>：找不到 cross-endpoint contention、找不到 session state 累積</li>
<li><strong>壓測機跟被測機在同一網段</strong>：網路延遲被低估、p99 比 production 樂觀</li>
<li><strong>壓測時 throttle 自己的工具</strong>：結果不是被測系統的極限、是工具自己的極限</li>
<li><strong>結果報表只看平均</strong>：<a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">tail latency</a> 看不到、p99 退化被掩蓋</li>
<li><strong>壓測環境跟 production hardware 不一致</strong>：CPU 型號、network、disk IOPS 差很大、結果不可外推</li>
<li><strong>沒驗證 model</strong>：跑了壓測但沒對比 production metrics、不知道 model 是否貼近 reality</li>
</ul>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
          <td>10,000 台 t2.micro 跑分散式壓測（$130 / 小時）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a></td>
          <td>ML p99 &lt; 10ms 壓測必須帶 latency distribution</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>（用工具找 knee）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a>（CI 整合）</li>
<li>跨模組：<a href="/blog/backend/06-reliability/ci-pipeline/" data-link-title="6.1 CI pipeline" data-link-desc="CI pipeline 的分層策略、artifact 管理、flaky 治理與 release gate 輸入">06.1 CI Pipeline</a>（壓測在 CI 的位置）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">Load Test</a></li>
<li><a href="/blog/backend/knowledge-cards/workload-model/" data-link-title="Workload Model" data-link-desc="描述 production traffic 形狀的可重播模型 — 容量規劃跟壓測的共同輸入">Workload Model</a></li>
<li><a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
<li><a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point</a></li>
</ul>
]]></content:encoded></item><item><title>9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/</guid><description>&lt;p>這個案例的核心責任是揭示「無明顯峰值但延遲就是收入」這類負載的容量設計、跟前兩個案例形成對照。金融交易不靠峰值定義成敗、靠每個交易的延遲穩定性 — 多 1ms 延遲在套利策略下可能直接吃掉整筆交易的利潤。Coinbase International Exchange 為這類負載做了一系列「反主流」的取捨：固定佈署、不啟用自動擴容、強制節點實體靠近。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Coinbase 在 2023-05 推出國際交易所、上線後關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/coinbase-cryptocurrency-exchange-case-study/">Coinbase Case Study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>吞吐量&lt;/td>
 &lt;td>100,000 messages/sec（擴容後）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>延遲目標&lt;/td>
 &lt;td>sub-millisecond（次毫秒級）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>累計交易額&lt;/td>
 &lt;td>上線以來超過 150 億美元&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性&lt;/td>
 &lt;td>24/7、受監管的交易平台&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Amazon EC2 z1d 實例&lt;/strong>：高頻 CPU + NVMe 本地儲存、針對單執行緒效能最佳化&lt;/li>
&lt;li>&lt;strong>EC2 Cluster Placement Groups&lt;/strong>：強制把節點集中到單一機架附近、最小化 node-to-node 網路延遲&lt;/li>
&lt;li>&lt;strong>Amazon Aurora&lt;/strong>：高速 transaction lookup 的關聯式資料庫&lt;/li>
&lt;li>「Built from the ground up, using Cloud Native principles」（沒有複用既有交易所程式碼）&lt;/li>
&lt;li>內部使用 &lt;strong>RAFT consensus&lt;/strong> 維持交易順序&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>這個案例最值得讀的地方、是它「沒有做」的事比「做了」的事更有教學價值。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>沒有用 Auto Scaling&lt;/strong>：交易撮合引擎用 RAFT consensus 維持嚴格順序、節點數量是 consensus 一部分、不能臨時增加。容量規劃完全是 &lt;em>pre-provision&lt;/em>、不是 reactive。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 必須區分「可水平擴容服務」跟「不可水平擴容服務」、後者的容量公式只有 headroom × peak、沒有 elastic 補救。&lt;/li>
&lt;li>&lt;strong>沒有用通用 EC2 實例&lt;/strong>：z1d 是 AWS 針對「高頻 CPU + NVMe」設計的特化實例、犧牲了通用性換取單核效能。這層選擇隱含一個容量規劃決策：&lt;em>單機效能上限&lt;/em> 直接決定 &lt;em>系統理論吞吐上限&lt;/em>、橫向擴容不能超過 RAFT 節點數限制、那麼縱向就必須榨乾。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 必須先判斷瓶頸屬「可分散」還是「不可分散」。&lt;/li>
&lt;li>&lt;strong>沒有用多區域分散&lt;/strong>：Cluster Placement Group 把節點壓到同一可用區內、犧牲了 region failover 速度、換取 node-to-node 網路延遲。這跟「高可用性」的常見直覺相反、是「延遲敏感型負載的容量設計優先於可靠性設計」的一個範例。&lt;/li>
&lt;li>&lt;strong>延遲是設計輸入、不是設計結果&lt;/strong>：sub-millisecond 是先訂目標、再反推所有架構選擇的結果、壓測只是驗證手段。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為&lt;/a> 中 Little&amp;rsquo;s Law 的反向應用 — 給定延遲目標 + 吞吐目標、反推 concurrency 上限 + 每個 stage 的 latency budget。&lt;/li>
&lt;/ol>
&lt;p>需要警惕的判讀盲點：「sub-millisecond latency 達成」這類陳述通常指 &lt;em>p50 或 p90&lt;/em>、不一定是 p99 或 p999。長尾延遲在 RAFT 系統下可能比平均高一個數量級（leader election、replication lag）。讀案例時要注意延遲分布 vs 平均值的差別。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>延遲敏感型服務先做 latency budget 反推&lt;/strong>：給每個 stage（網路、CPU、磁碟、序列化、共識）一個 latency 配額、總和等於 SLO 上限。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a>。&lt;/li>
&lt;li>&lt;strong>單機效能榨乾優先於橫向擴容&lt;/strong>：當 consensus / ordered processing 限制了水平擴容時、單機選型（CPU 頻率、NUMA locality、NVMe）變成主要槓桿。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 把 saturation 點推得越遠。&lt;/li>
&lt;li>&lt;strong>拓樸感知的部署策略&lt;/strong>：Cluster Placement Group 是 AWS 名稱、概念是「網路拓樸感知的工作負載放置」。GCP 有 Compact Placement Policy、Azure 有 Proximity Placement Groups、自建 Kubernetes 有 Pod Topology Spread Constraints + Node Affinity。&lt;/li>
&lt;li>&lt;strong>接受「不可彈性」是有意識決策、不是失敗&lt;/strong>：很多服務不該全部都自動擴容。設計時要區分「需要 elastic 的 stateless 邊緣」跟「必須 pre-provision 的有狀態核心」、容量規劃也要兩條腿。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：所有主流雲端都有對應的高頻 CPU 實例（GCP C2 / Azure HBv 系列）、placement policy 與本地 NVMe 儲存。自建環境可以用 SR-IOV + RDMA + NUMA pinning 達成更極致的版本。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是揭示「無明顯峰值但延遲就是收入」這類負載的容量設計、跟前兩個案例形成對照。金融交易不靠峰值定義成敗、靠每個交易的延遲穩定性 — 多 1ms 延遲在套利策略下可能直接吃掉整筆交易的利潤。Coinbase International Exchange 為這類負載做了一系列「反主流」的取捨：固定佈署、不啟用自動擴容、強制節點實體靠近。</p>
<h2 id="觀察">觀察</h2>
<p>Coinbase 在 2023-05 推出國際交易所、上線後關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/coinbase-cryptocurrency-exchange-case-study/">Coinbase Case Study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>吞吐量</td>
          <td>100,000 messages/sec（擴容後）</td>
      </tr>
      <tr>
          <td>延遲目標</td>
          <td>sub-millisecond（次毫秒級）</td>
      </tr>
      <tr>
          <td>累計交易額</td>
          <td>上線以來超過 150 億美元</td>
      </tr>
      <tr>
          <td>可用性</td>
          <td>24/7、受監管的交易平台</td>
      </tr>
  </tbody>
</table>
<p>服務組合：</p>
<ul>
<li><strong>Amazon EC2 z1d 實例</strong>：高頻 CPU + NVMe 本地儲存、針對單執行緒效能最佳化</li>
<li><strong>EC2 Cluster Placement Groups</strong>：強制把節點集中到單一機架附近、最小化 node-to-node 網路延遲</li>
<li><strong>Amazon Aurora</strong>：高速 transaction lookup 的關聯式資料庫</li>
<li>「Built from the ground up, using Cloud Native principles」（沒有複用既有交易所程式碼）</li>
<li>內部使用 <strong>RAFT consensus</strong> 維持交易順序</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>這個案例最值得讀的地方、是它「沒有做」的事比「做了」的事更有教學價值。</p>
<ol>
<li><strong>沒有用 Auto Scaling</strong>：交易撮合引擎用 RAFT consensus 維持嚴格順序、節點數量是 consensus 一部分、不能臨時增加。容量規劃完全是 <em>pre-provision</em>、不是 reactive。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 必須區分「可水平擴容服務」跟「不可水平擴容服務」、後者的容量公式只有 headroom × peak、沒有 elastic 補救。</li>
<li><strong>沒有用通用 EC2 實例</strong>：z1d 是 AWS 針對「高頻 CPU + NVMe」設計的特化實例、犧牲了通用性換取單核效能。這層選擇隱含一個容量規劃決策：<em>單機效能上限</em> 直接決定 <em>系統理論吞吐上限</em>、橫向擴容不能超過 RAFT 節點數限制、那麼縱向就必須榨乾。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 必須先判斷瓶頸屬「可分散」還是「不可分散」。</li>
<li><strong>沒有用多區域分散</strong>：Cluster Placement Group 把節點壓到同一可用區內、犧牲了 region failover 速度、換取 node-to-node 網路延遲。這跟「高可用性」的常見直覺相反、是「延遲敏感型負載的容量設計優先於可靠性設計」的一個範例。</li>
<li><strong>延遲是設計輸入、不是設計結果</strong>：sub-millisecond 是先訂目標、再反推所有架構選擇的結果、壓測只是驗證手段。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為</a> 中 Little&rsquo;s Law 的反向應用 — 給定延遲目標 + 吞吐目標、反推 concurrency 上限 + 每個 stage 的 latency budget。</li>
</ol>
<p>需要警惕的判讀盲點：「sub-millisecond latency 達成」這類陳述通常指 <em>p50 或 p90</em>、不一定是 p99 或 p999。長尾延遲在 RAFT 系統下可能比平均高一個數量級（leader election、replication lag）。讀案例時要注意延遲分布 vs 平均值的差別。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>延遲敏感型服務先做 latency budget 反推</strong>：給每個 stage（網路、CPU、磁碟、序列化、共識）一個 latency 配額、總和等於 SLO 上限。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a>。</li>
<li><strong>單機效能榨乾優先於橫向擴容</strong>：當 consensus / ordered processing 限制了水平擴容時、單機選型（CPU 頻率、NUMA locality、NVMe）變成主要槓桿。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 把 saturation 點推得越遠。</li>
<li><strong>拓樸感知的部署策略</strong>：Cluster Placement Group 是 AWS 名稱、概念是「網路拓樸感知的工作負載放置」。GCP 有 Compact Placement Policy、Azure 有 Proximity Placement Groups、自建 Kubernetes 有 Pod Topology Spread Constraints + Node Affinity。</li>
<li><strong>接受「不可彈性」是有意識決策、不是失敗</strong>：很多服務不該全部都自動擴容。設計時要區分「需要 elastic 的 stateless 邊緣」跟「必須 pre-provision 的有狀態核心」、容量規劃也要兩條腿。</li>
</ol>
<p>跨平台等效：所有主流雲端都有對應的高頻 CPU 實例（GCP C2 / Azure HBv 系列）、placement policy 與本地 NVMe 儲存。自建環境可以用 SR-IOV + RDMA + NUMA pinning 達成更極致的版本。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計延遲敏感型服務的容量地圖 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想搞清楚哪些服務該水平擴容、哪些不該 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a></li>
<li>想做 latency budget 反推 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號</a></li>
<li>對照不同形狀的負載 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a>（可預期極端峰值）/ <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a>（事件型不可預期峰值）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/coinbase-cryptocurrency-exchange-case-study/">Coinbase Launches an Ultra-Low-Latency Cryptocurrency Exchange on AWS</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/coinbase-migration-case-study/">Coinbase Scales 50% Faster, Cuts Costs 62% with AWS</a></li>
<li><a href="https://aws.amazon.com/video/watch/a413043e5cb/">Ultra-Low-Latency Crypto Exchange on AWS（video）</a></li>
</ul>
]]></content:encoded></item><item><title>Locust</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/</guid><description>&lt;p>Locust 的核心責任是用 Python 表達高度自訂的使用者行為與 protocol client。它適合 Python 團隊、需要自訂 client、需要 distributed worker、或 scenario 邏輯比工具內建 sampler 更複雜的壓測流程。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Locust 適合把壓測寫成一般 Python 程式。當 workload model 需要呼叫 internal SDK、特殊 protocol、複雜資料準備、狀態機、隨機行為或自訂 client、Locust 可以直接使用 Python 生態來表達。底層架構是 &lt;em>master + worker&lt;/em> 分散式 swarm、worker 之間用 Gevent green-thread（非 OS thread）模擬大量並發 user、master 負責 spawn rate、aggregation 跟 Web UI。&lt;/p>
&lt;p>這個定位讓 Locust 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程&lt;/a>。它能把特殊 client 與下游 dependency 放進同一個 user behavior、但也要求團隊處理 runner、資料與可重現性。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a>（JS / Go runtime）比、Locust 用 Python 換到 &lt;em>自訂能力與生態相容&lt;/em>、但代價是單 worker capacity 低、CPU bound 容易先打到自己。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a>（GUI / XML）比、Locust 偏 &lt;em>code-first 工程團隊&lt;/em>、scenario 直接走 Git review、不靠 GUI plugin 拼裝。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling&lt;/a>（Scala DSL）比、Locust 換到 &lt;em>Python team 友善 + 既有 domain library 重用&lt;/em>、但失去 JVM injection profile 的精細度與報表內建。&lt;/p>
&lt;p>關鍵張力：&lt;em>Python 表達力&lt;/em> ↔ &lt;em>runner 效能上限&lt;/em>。Python team 想 reuse domain library、staging fixture、API client 寫壓測腳本時 Locust 是首選；但要心裡有數 &lt;em>單 worker RPS 上限不高&lt;/em>、超過幾千 RPS 就要靠 worker scale-out、不是調 Locust 本身。&lt;/p>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>Python 團隊適合用 Locust 長期維護壓測。既有 domain library、API client、fixture、資料產生器與驗證 helper 都可以被壓測腳本重用。&lt;/p>
&lt;p>自訂 protocol 適合用 Locust。HTTP 之外、如果服務需要 gRPC、WebSocket、binary protocol、message broker client 或自家 SDK、Locust 可以直接接 Python library。&lt;/p>
&lt;p>Distributed load 適合用 Locust worker 擴展。當單機 Python runner 遇到 CPU 或 connection bottleneck、可以用 master / worker 拆開負載產生能力。&lt;/p></description><content:encoded><![CDATA[<p>Locust 的核心責任是用 Python 表達高度自訂的使用者行為與 protocol client。它適合 Python 團隊、需要自訂 client、需要 distributed worker、或 scenario 邏輯比工具內建 sampler 更複雜的壓測流程。</p>
<h2 id="服務定位">服務定位</h2>
<p>Locust 適合把壓測寫成一般 Python 程式。當 workload model 需要呼叫 internal SDK、特殊 protocol、複雜資料準備、狀態機、隨機行為或自訂 client、Locust 可以直接使用 Python 生態來表達。底層架構是 <em>master + worker</em> 分散式 swarm、worker 之間用 Gevent green-thread（非 OS thread）模擬大量並發 user、master 負責 spawn rate、aggregation 跟 Web UI。</p>
<p>這個定位讓 Locust 接到 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 與 <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>。它能把特殊 client 與下游 dependency 放進同一個 user behavior、但也要求團隊處理 runner、資料與可重現性。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>（JS / Go runtime）比、Locust 用 Python 換到 <em>自訂能力與生態相容</em>、但代價是單 worker capacity 低、CPU bound 容易先打到自己。跟 <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>（GUI / XML）比、Locust 偏 <em>code-first 工程團隊</em>、scenario 直接走 Git review、不靠 GUI plugin 拼裝。跟 <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>（Scala DSL）比、Locust 換到 <em>Python team 友善 + 既有 domain library 重用</em>、但失去 JVM injection profile 的精細度與報表內建。</p>
<p>關鍵張力：<em>Python 表達力</em> ↔ <em>runner 效能上限</em>。Python team 想 reuse domain library、staging fixture、API client 寫壓測腳本時 Locust 是首選；但要心裡有數 <em>單 worker RPS 上限不高</em>、超過幾千 RPS 就要靠 worker scale-out、不是調 Locust 本身。</p>
<h2 id="適用場景">適用場景</h2>
<p>Python 團隊適合用 Locust 長期維護壓測。既有 domain library、API client、fixture、資料產生器與驗證 helper 都可以被壓測腳本重用。</p>
<p>自訂 protocol 適合用 Locust。HTTP 之外、如果服務需要 gRPC、WebSocket、binary protocol、message broker client 或自家 SDK、Locust 可以直接接 Python library。</p>
<p>Distributed load 適合用 Locust worker 擴展。當單機 Python runner 遇到 CPU 或 connection bottleneck、可以用 master / worker 拆開負載產生能力。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>Locust 在壓測 stack 中承擔哪一段（user behavior modeling / load generation / distributed swarm）、哪些要外接（<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Prometheus / Grafana</a> 觀測 worker 自身、APM 看目標 saturation）</li>
<li>User class / task weight / on_start lifecycle 的 ownership 設計（誰寫 locustfile、誰 review、誰調 spawn rate）</li>
<li>Distributed master-worker 部署的容量規劃（單 worker user 上限、worker 數量計算、target RPS 對應 worker count）</li>
<li>何時用 Locust、何時走 k6 / JMeter / Gatling 的取捨</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Locust 壓測是否健康、最少看四件事：</p>
<ul>
<li><strong>User class 設計</strong>：每個 <code>HttpUser</code> / <code>User</code> subclass 是不是一個明確的 <em>persona</em>（mobile user / API client / admin user）、<code>wait_time</code> 是否反映真實使用者間隔（不是 0 拼最大 RPS、是 <code>between(1, 5)</code> 模擬 think time）、user state 是否在 instance 內封閉</li>
<li><strong>Task 比例</strong>：<code>@task(weight)</code> 數字是否對應 production traffic mix（80% read / 15% write / 5% admin、不是每個 endpoint 等比例）、weight 是否走版控 review</li>
<li><strong>on_start lifecycle</strong>：login / token fetch / session bootstrap 是否寫在 <code>on_start</code>（每個 user 一次）、不是寫在 <code>@task</code> 裡（每個 request 都重做）— 寫錯位置會讓 auth endpoint 變成主要 traffic</li>
<li><strong>Distributed master-worker</strong>：worker 數量是否夠（單 worker 跑幾千 user 後 CPU 會先打死、不是目標服務先死）、master 是否獨立機器（master 也跑 user 時 aggregation 跟 Web UI 會卡）、<code>--expect-workers</code> 是否設、worker sync drift 是否觀察</li>
</ul>
<p>四件事任一缺失、就是壓測證據可信度的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>locustfile 結構</strong>：locustfile.py 是 Python module、定義 <code>User</code> / <code>HttpUser</code> subclass、每個 user 有 <code>wait_time</code>、若干 <code>@task(weight)</code> method、<code>on_start</code> / <code>on_stop</code> lifecycle hook。執行用 <code>locust -f locustfile.py --host=https://target</code> 起 Web UI、或 <code>locust --headless -u 1000 -r 100 -t 10m</code> 在 CI 跑無 UI 模式。locustfile 應該走 Git review、不是 GUI 改完就跑。</p>
<p><strong>Task weight / wait_time 設計</strong>：weight 是 <em>相對權重</em>、不是百分比 —<code>@task(8)</code> + <code>@task(2)</code> 等於 80% / 20%。<code>wait_time = between(1, 5)</code> 在每個 task 之間等 1-5 秒、模擬 think time；若要拚最大 RPS 用 <code>constant(0)</code>、但同時要意識到這就不是 user behavior 模型、是 <em>throughput probe</em>。</p>
<p><strong>on_start vs @task 的邊界</strong>：<code>on_start(self)</code> 每個 user instance 啟動時跑一次、適合做 login、token fetch、cache warm、fixture lookup；<code>@task</code> 是 user 行為主迴圈、每次選一個 task 跑。把 login 寫在 <code>@task</code> 是常見錯誤、會讓 IdP 變成主壓力來源、不是目標 API。</p>
<p><strong>Gevent-based concurrency</strong>：Locust 用 <a href="https://www.gevent.org/">gevent</a> 的 green-thread 模擬大量 concurrent user、不是 OS thread。意義是單 worker 可以跑幾千個 <em>user</em>、但 CPU bound 工作（JSON serialization、加密、本地計算）會 <em>blocking</em> 整個 worker 的 event loop。<code>gevent.monkey.patch_all()</code> 要在 import 第一行、否則 socket / time / ssl 不會被 patch、blocking call 會卡死 swarm。</p>
<p><strong>Distributed master-worker</strong>：單機到極限時開 distributed — <code>locust --master</code> 起 master、<code>locust --worker --master-host=master.example.com</code> 起 worker。Master 負責 Web UI、spawn rate 控制、result aggregation、stat 收集；worker 負責跑 user。Master 不該跑 user（會跟 aggregation 搶 CPU、stat 失真）。worker 數量計算：先單 worker 拉到 CPU 80% 看能撐多少 user、目標 user 數除這個值 + 20% buffer。</p>
<p><strong>Custom load shape</strong>：除了固定 <code>-u 1000</code>、Locust 支援 <code>LoadTestShape</code> subclass 寫 <em>時間軸負載曲線</em> — spike test（瞬間 0 → 5000 user）、ramp test（線性爬升）、wave test（週期性高低交替）、step test（階梯式增加）。<code>tick()</code> method 每秒回傳 <code>(user_count, spawn_rate)</code>。用 custom shape 才能模擬 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 那種 ticket drop 瞬間衝擊。</p>
<p><strong>Prometheus exporter / 觀測</strong>：Locust 內建 stat 只是 in-memory 的 p50 / p95 / p99 / RPS、結束就消失。長期觀測接 <a href="https://github.com/ContainerSolutions/locust_exporter">locust-prometheus-exporter</a>（或 <code>--csv result.csv</code> 自己抓）、把 metric 推到 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Prometheus</a> + Grafana。<strong>worker 自身的 CPU / memory / network</strong> 一定要同時觀測、不然分不出是目標 saturation 還是 worker 已死。</p>
<p><strong>Locust Cloud（managed SaaS）</strong>：2024 後 Locust 推官方 <a href="https://docs.locust.cloud/">Locust Cloud</a>、託管 master + worker + result storage、付費換 ops 成本。自管 master-worker 對 CI / staging 是合理的；production 等級的 scale test（10k+ concurrent user）跑一次要拉幾十台 worker、用 Cloud 省 infra ops 是合理 trade-off。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Locust</th>
          <th>k6</th>
          <th>JMeter</th>
          <th>Gatling</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>腳本語言</td>
          <td>Python（generic）</td>
          <td>JavaScript (k6 runtime)</td>
          <td>XML / GUI / Groovy</td>
          <td>Scala DSL（也支援 Java / Kotlin）</td>
      </tr>
      <tr>
          <td>Runtime</td>
          <td>Python + Gevent green-thread</td>
          <td>Go-based、單 binary、低 overhead</td>
          <td>JVM、heavy</td>
          <td>JVM、async actor model</td>
      </tr>
      <tr>
          <td>單 worker capacity</td>
          <td>中低（Python overhead、千級 user）</td>
          <td>高（Go runtime、萬級 VU 單機）</td>
          <td>中（JVM tuning 後可用）</td>
          <td>高（Akka actor、效能好）</td>
      </tr>
      <tr>
          <td>Distributed mode</td>
          <td>內建 master-worker</td>
          <td>內建 k6 Cloud / k6 Operator</td>
          <td>內建 master-slave</td>
          <td>Gatling Enterprise（前 FrontLine）</td>
      </tr>
      <tr>
          <td>User behavior 彈性</td>
          <td>高 — 一般 Python、任意 library</td>
          <td>中 — JS 但 k6 runtime 受限</td>
          <td>中 — GUI 拼裝 + plugin</td>
          <td>中高 — Scala DSL 表達 simulation</td>
      </tr>
      <tr>
          <td>Custom protocol</td>
          <td>強 — 接任何 Python library</td>
          <td>強 — 有 gRPC / WS / Kafka extension</td>
          <td>強但繁瑣 — plugin 生態廣</td>
          <td>中 — 主要 HTTP / WS</td>
      </tr>
      <tr>
          <td>CI / headless</td>
          <td><code>--headless</code> 支援</td>
          <td>CI-first design</td>
          <td>non-GUI mode 支援</td>
          <td>內建支援</td>
      </tr>
      <tr>
          <td>Report / UI</td>
          <td>Web UI 即時 + CSV 匯出</td>
          <td>k6 Cloud / Grafana / 簡 stdout</td>
          <td>GUI listener / HTML report</td>
          <td>HTML report 內建、視覺豐富</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>緩（Python team）/ 陡（非 Python）</td>
          <td>中 — JS-style scripting</td>
          <td>緩（GUI）/ 陡（深度 tuning）</td>
          <td>陡 — Scala 語法</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Python team + 自訂 behavior / client</td>
          <td>DevOps + CI / 標準 HTTP / 高 RPS 單機</td>
          <td>非工程角色協作 / legacy enterprise</td>
          <td>JVM team + 精細 injection profile</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>低 — Python 腳本可移植</td>
          <td>中 — k6 runtime 綁定</td>
          <td>中 — XML jmx 不易他移</td>
          <td>中 — Scala DSL 綁定</td>
      </tr>
  </tbody>
</table>
<p>選 Locust 的核心訴求：<em>Python team + custom user behavior + 既有 domain library 重用</em>、且能投入 worker scale-out 預算（單 worker capacity 低、要靠分散式補）+ scenario 走 Git review 不靠 GUI。標準 HTTP 高 RPS 單機壓測直接走 k6 更快、非工程角色協作壓測走 JMeter、JVM team 精細模擬走 Gatling。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Distributed Locust 的 master-worker swarm</strong>：production scale test 通常需要 10-100 個 worker。實作要點：worker 之間 <em>不要</em> 共享 state、shared resource 由 master 統一發（用 <a href="https://zeromq.org/">zeromq</a> message bus）；worker 加入 / 離開時 user 會 redistribute、避免 user index 當 unique key；worker 跨 region 跑時 <em>latency 來自 worker → target 不只是 target 內部</em>、要在 worker 本身的 region 對齊。</p>
<p><strong>Custom load shape（spike / wave / step）</strong>：<code>LoadTestShape.tick(self)</code> return <code>(user_count, spawn_rate)</code> tuple 每秒被叫一次。Spike test：前 60 秒 0 user、第 61 秒瞬間衝 5000、模擬 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 admission storm。Wave test：sine wave 在 1000-3000 user 之間振盪、測 autoscaling 反應速度。Step test：每 5 分鐘加 1000 user、觀察哪一階開始降級。custom shape 是 Locust 比 k6 強的點之一。</p>
<p><strong>跟 Prometheus exporter 整合</strong>：locust-prometheus-exporter 把 Locust stat 推到 Prometheus / Grafana、做長期 baseline、跨 test 比較、p99 退化偵測。實務上要在 dashboard 同時放 <em>Locust 內部 stat</em> + <em>worker host metric</em> + <em>目標服務 APM</em>、三層 stack 起來才能判讀是 runner 還是目標 saturation。</p>
<p><strong>Locust Cloud（managed SaaS）</strong>：2024+ 官方 SaaS、託管 master + worker + result + dashboard。trade-off：自管適合 CI / staging / 內網壓測（target 跑在內網時 Cloud 連不到）；Cloud 適合大規模一次性 scale test（拉 50 worker 跑 2 小時、跑完即停、不想自己 infra ops）。</p>
<h2 id="操作成本">操作成本</h2>
<p>Locust 的主要成本是 runner overhead 與分散式治理。Python runner 的效能上限要用 worker scale-out 解決；壓測結論要同時檢查目標服務 saturation 與 worker 本身 CPU、connection、network 是否已成瓶頸。</p>
<p>腳本工程成本來自自由度。Python 可以很快寫出複雜行為、也容易把測試資料、randomness、side effect、sleep 與 exception handling 寫散；團隊要維持 scenario structure、fixture、logging 與 artifact 標準。</p>
<p>自訂 client 成本來自校正。使用 SDK 或 custom protocol client 時、要確認 client retry、timeout、connection pool 與 serialization 行為是否接近 production、避免 runner 模擬出不存在的壓力形狀。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Worker CPU 100% 但目標服務閒</strong>：Python runner 先死、不是 target saturation — 加 worker 數量、或檢查 task 裡有沒有 CPU bound 的本地計算（大 JSON parse、加密、本地 fixture 生成）擠掉 event loop</li>
<li><strong>Gevent monkey-patch gotcha</strong>：<code>requests</code> / <code>psycopg2</code> / 自家 SDK 在第三方 library 內部 blocking call、整個 worker 卡住 — <code>gevent.monkey.patch_all()</code> 一定要寫在 import 第一行；無法 patch 的 C extension（如 native MySQL driver）改用 gevent-friendly client</li>
<li><strong>RPS 達不到目標 / 看起來像 target 慢</strong>：實際是 worker connection pool 耗盡、或 worker 本身網卡飽和 — 觀測 worker 本身的 TCP socket 數、netstat ESTABLISHED、network throughput；不要直接 blame target</li>
<li><strong>Distributed sync drift</strong>：worker 之間 user count 不平均、aggregation 顯示 RPS 抖動 — <code>--expect-workers=N</code> 確認 master 等所有 worker join 才開測；worker 跨 region 時 message bus latency 也會影響 sync</li>
<li><strong>on_start 在 @task 裡跑</strong>：壓測啟動瞬間打爆 auth endpoint、看到 IdP latency 飆高以為是 target — 把 login / token fetch 移到 <code>on_start</code>、每個 user 只做一次</li>
<li><strong>wait_time = 0 拼最大 RPS 結果結論奇怪</strong>：這已經不是 user behavior 是 throughput probe、p99 跟 production 對不上 — 改成 <code>between(1, 5)</code> 模擬 think time 或寫 custom shape</li>
<li><strong>Web UI 卡 / master CPU 100%</strong>：master 同時在跑 user + aggregation — <code>locust --master</code> 跟 worker 拆機器、master 不跑 user</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>標準 HTTP / 高 RPS 單機 / CI-first</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a></td>
      </tr>
      <tr>
          <td>非工程角色協作 / GUI 拼裝</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a></td>
      </tr>
      <tr>
          <td>JVM team / 精細 injection profile</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a></td>
      </tr>
      <tr>
          <td>極簡 HTTP probe / 命令列 one-shot</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a></td>
      </tr>
      <tr>
          <td>Production traffic replay / shadow</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a> / <a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a></td>
      </tr>
      <tr>
          <td>壓測結果回寫到效能工程 lifecycle</td>
          <td><a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>、<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>locustfile 完整語法 reference、<code>User</code> 跟 <code>HttpUser</code> 的 attribute 細節</li>
<li>Locust Cloud 計費跟 quota 細節（看官方 docs）</li>
<li>gevent 跟 asyncio 的取捨（Locust 選了 gevent、不在本頁討論替代）</li>
<li>壓測證據怎麼歸檔（看 <a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">9.7 evidence package</a> 通則）</li>
</ul>
<h2 id="evidence-package">Evidence Package</h2>
<p>Locust 結果應回寫到 evidence package。最小欄位包括 locustfile version、user class、task weight、spawn rate、worker count、client library version、target environment、p95 / p99、error rate、throughput、target saturation metric、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Locust 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>locustfile、CSV / JSON result、dashboard link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / logs 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>user behavior coverage、fixture freshness</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>worker capacity、client realism</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>worker bottleneck、custom client 偏差、資料偏差</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是區分目標瓶頸與 runner 瓶頸。Locust 分散式測試要同時保存 worker 數量、worker 資源、spawn rate 與 client behavior、讓 reviewer 知道壓力是否真的打到目標服務。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>Locust 適合回寫需要高度自訂 user behavior 的案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 雙峰 workload</a> 的投注行為模型、<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 admission / token flow、<a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay mobile payment messaging</a> 的外部推送與下游 quota 模擬、<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Niantic Pokémon GO 50x surge</a> 的玩家移動 + 互動混合行為、以及 <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom COVID 30x surge</a> 的會議建立 / 加入 / 離開行為混合。</p>
<p>這些案例的重點是 domain behavior。Locust 頁引用案例時、要把 case 轉成 user class、task weight、custom client、downstream mock 與 worker capacity、再把總 RPS 放回這些行為條件下判讀 — 例如 Pokémon GO 玩家行為跟一般 web user 完全不同（持續 GPS 上報 + 偶發互動）、不能直接用 HTTP RPS 衡量；SeatGeek waiting room 要寫 <code>LoadTestShape</code> 模擬 ticket drop 瞬間衝擊、不是穩態 RPS。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>、<a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>、<a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>、<a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a></li>
<li>跨類：<a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a>（production traffic replay 替代 synthetic load）</li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">4 Observability</a>（worker 自身 + 目標 APM 雙觀測）</li>
<li>官方：<a href="https://docs.locust.io/">Locust documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.4 Saturation Discovery</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>Saturation discovery 的責任是把「系統能撐多少」這個問題變成可量化答案。沒有 saturation 量測時、容量規劃只能猜；有 saturation 量測之後、能說「在當前配置下、p99 &amp;lt; 100ms 的條件下、能撐 X RPS、headroom Y%」。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&amp;#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論&lt;/a> 的關係：9.1 預測 saturation curve 的形狀（linear → knee → cliff）、9.4 用實測找出 &lt;em>本服務&lt;/em> 的曲線具體位置。理論告訴我們 knee 存在、實測告訴我們它在哪裡。&lt;/p>
&lt;p>本章不深入工具操作（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3&lt;/a> 處理工具）、聚焦在 &lt;em>方法論&lt;/em> — 怎麼設計 ramp-up、怎麼判斷 knee、怎麼把結果文件化讓後續決策可用。&lt;/p>
&lt;h2 id="saturation-的精確定義">Saturation 的精確定義&lt;/h2>
&lt;p>容量規劃裡 saturation 不是「系統當機」、是「系統 &lt;em>進入 latency 指數成長區&lt;/em>」。這個區分很重要 — 系統 &lt;em>看起來&lt;/em> 還在跑、其實已經不可預測。&lt;/p>
&lt;p>技術上 saturation 對應 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">queueing theory 的 knee point&lt;/a>：utilization 超過某個臨界（M/M/c 通常 70-80%）、平均 queue length 從線性轉成指數成長。latency 是 queue length 的線性函數、所以也跟著指數成長。&lt;/p>
&lt;p>實務上把 saturation 分三段：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>linear region&lt;/strong>（utilization &amp;lt; 50%）：latency 平穩、加流量幾乎不影響&lt;/li>
&lt;li>&lt;strong>knee region&lt;/strong>（utilization 50-80%）：latency 開始上升、但還可接受&lt;/li>
&lt;li>&lt;strong>cliff region&lt;/strong>（utilization &amp;gt; 80%）：latency 不可預測、可能 timeout / cascade failure&lt;/li>
&lt;/ul>
&lt;p>健康系統運轉在 linear 後半段或 knee 前段（utilization 50-70%）、留出 headroom 應付 burst。autoscaler 的 target metric 通常訂在 60-70%、是這條曲線推導出的安全位置。&lt;/p>
&lt;h2 id="ramp-up-測試方法">Ramp-up 測試方法&lt;/h2>
&lt;p>要找出 saturation 點、必須跑 &lt;em>ramp-up 測試&lt;/em> — 不能固定一個壓力值。&lt;/p>
&lt;p>&lt;strong>單點壓測的問題&lt;/strong>：跑「2000 RPS 連續 10 分鐘」、看 latency 100ms、結論「能撐 2000 RPS」 — 但不知道 1500 跟 2500 RPS 是什麼樣。可能 1500 也是 100ms（離 knee 還很遠）、可能 2500 直接崩（已經在 cliff）。&lt;/p>
&lt;p>&lt;strong>Ramp-up 流程&lt;/strong>：從基線開始、按倍數加壓（1x / 2x / 4x / 8x &amp;hellip;）。每個壓力 level 維持 5-10 分鐘、觀察 latency / throughput / resource utilization 的穩態（不是 transient）。紀錄每個 level 的 percentile 分布。&lt;/p>
&lt;p>&lt;strong>Knee 出現的訊號&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>throughput 從線性成長轉成 sub-linear（加壓但 throughput 不再等比成長）&lt;/li>
&lt;li>latency p50 還算穩、但 p99 / p999 開始飆&lt;/li>
&lt;li>resource saturation queue 開始堆積（不只 utilization 上升）&lt;/li>
&lt;li>error rate 仍接近 0（cliff 才會 error 飆）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Cliff 出現的訊號&lt;/strong>：throughput 開始下降（加壓反而越來越慢）、latency p99 變成 timeout、error rate 飆升、retry storm 出現。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>Saturation discovery 的責任是把「系統能撐多少」這個問題變成可量化答案。沒有 saturation 量測時、容量規劃只能猜；有 saturation 量測之後、能說「在當前配置下、p99 &lt; 100ms 的條件下、能撐 X RPS、headroom Y%」。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論</a> 的關係：9.1 預測 saturation curve 的形狀（linear → knee → cliff）、9.4 用實測找出 <em>本服務</em> 的曲線具體位置。理論告訴我們 knee 存在、實測告訴我們它在哪裡。</p>
<p>本章不深入工具操作（<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3</a> 處理工具）、聚焦在 <em>方法論</em> — 怎麼設計 ramp-up、怎麼判斷 knee、怎麼把結果文件化讓後續決策可用。</p>
<h2 id="saturation-的精確定義">Saturation 的精確定義</h2>
<p>容量規劃裡 saturation 不是「系統當機」、是「系統 <em>進入 latency 指數成長區</em>」。這個區分很重要 — 系統 <em>看起來</em> 還在跑、其實已經不可預測。</p>
<p>技術上 saturation 對應 <a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">queueing theory 的 knee point</a>：utilization 超過某個臨界（M/M/c 通常 70-80%）、平均 queue length 從線性轉成指數成長。latency 是 queue length 的線性函數、所以也跟著指數成長。</p>
<p>實務上把 saturation 分三段：</p>
<ul>
<li><strong>linear region</strong>（utilization &lt; 50%）：latency 平穩、加流量幾乎不影響</li>
<li><strong>knee region</strong>（utilization 50-80%）：latency 開始上升、但還可接受</li>
<li><strong>cliff region</strong>（utilization &gt; 80%）：latency 不可預測、可能 timeout / cascade failure</li>
</ul>
<p>健康系統運轉在 linear 後半段或 knee 前段（utilization 50-70%）、留出 headroom 應付 burst。autoscaler 的 target metric 通常訂在 60-70%、是這條曲線推導出的安全位置。</p>
<h2 id="ramp-up-測試方法">Ramp-up 測試方法</h2>
<p>要找出 saturation 點、必須跑 <em>ramp-up 測試</em> — 不能固定一個壓力值。</p>
<p><strong>單點壓測的問題</strong>：跑「2000 RPS 連續 10 分鐘」、看 latency 100ms、結論「能撐 2000 RPS」 — 但不知道 1500 跟 2500 RPS 是什麼樣。可能 1500 也是 100ms（離 knee 還很遠）、可能 2500 直接崩（已經在 cliff）。</p>
<p><strong>Ramp-up 流程</strong>：從基線開始、按倍數加壓（1x / 2x / 4x / 8x &hellip;）。每個壓力 level 維持 5-10 分鐘、觀察 latency / throughput / resource utilization 的穩態（不是 transient）。紀錄每個 level 的 percentile 分布。</p>
<p><strong>Knee 出現的訊號</strong>：</p>
<ul>
<li>throughput 從線性成長轉成 sub-linear（加壓但 throughput 不再等比成長）</li>
<li>latency p50 還算穩、但 p99 / p999 開始飆</li>
<li>resource saturation queue 開始堆積（不只 utilization 上升）</li>
<li>error rate 仍接近 0（cliff 才會 error 飆）</li>
</ul>
<p><strong>Cliff 出現的訊號</strong>：throughput 開始下降（加壓反而越來越慢）、latency p99 變成 timeout、error rate 飆升、retry storm 出現。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 用 10K t2.micro 壓測</a> 找 DynamoDB 從 20 IOPS 到 135K 的擴展曲線、知道 knee 在哪。</p>
<h2 id="resource-saturation-的六個維度">Resource saturation 的六個維度</h2>
<p>每次 ramp-up 都要同時觀察六個維度的 resource saturation、找出哪個 <em>先 saturate</em>。</p>
<p><strong>CPU</strong>：utilization 100% <em>不一定</em> 等於 saturation。要看 load average 跟 run queue。utilization 80% 但 run queue 不斷增長 → 已 saturate；utilization 100% 但 run queue 空 → 還能撐（單純 CPU bound）。</p>
<p><strong>Memory</strong>：not OOM 即可？不夠。GC pause（Java、Go）、swap（Linux）、cache eviction 都是隱性 saturation。記憶體不直接 OOM 但 GC 飆 → 已影響 <a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">tail latency</a>。</p>
<p><strong>Disk I/O</strong>：要看三個維度：throughput（MB/s）、IOPS（operations/sec）、queue depth。雲端 SSD 通常先 IOPS bound、不是 throughput；本機 NVMe 可能先 throughput bound。</p>
<p><strong>Network</strong>：bandwidth（Gbps）、packets per second、connection count。雲端 instance 通常有 PPS limit、超過會 silent drop、不是顯式錯誤。</p>
<p><strong>Connection pool</strong>：DB / cache / external API 的連線數。這是 <em>最常見的隱性 bottleneck</em>。pool size 訂 100、實際在用 95 → utilization 看似還好、其實已經 saturate（剩下的 request 在等 connection）。</p>
<p><strong>External API quota</strong>：第三方 rate limit（Stripe、Twilio、Slack API）。這個維度的 saturation 看不到 <em>本系統</em> 的訊號、要看 <em>對方 API 的 429 error rate</em>。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">Lemino RDB connection limit</a> — connection 是 RDB 的 saturation 點、CPU 跟 RAM 都還沒到。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method 卡片</a>。</p>
<h2 id="hot-partition-的隱性-saturation">Hot partition 的隱性 saturation</h2>
<p>對分散式 KV / OLTP（DynamoDB、Cosmos DB、Bigtable、Cassandra）、saturation 還有另一個維度：<a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">hot partition</a>。</p>
<p>名義容量 = 每 partition 上限 × partition 數量。partition key 分布不均 → 名義容量達不到。整體 utilization 看起來 20% → 系統還能撐？不一定。最熱 partition 已經 100%、其他 partition 0%、整體平均才 20%、但加流量會打在最熱 partition、立即 throttle。</p>
<p><strong>識別 hot partition 的訊號</strong>：</p>
<ul>
<li>throughput 上不去、但 average resource utilization 低</li>
<li>某些 key 的 request latency 飆、其他 key 正常</li>
<li>DynamoDB throttling event 出現（即使 capacity 還沒滿）</li>
</ul>
<p><strong>處理方法</strong>：</p>
<ul>
<li>composite key（event_id + user_id_hash）</li>
<li>write sharding（event_id + random_suffix）</li>
<li>time-bucket（event_id + minute）</li>
<li>用 cache 吸收 hot key（DAX、ElastiCache）</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">Amazon Ads 9000 萬 RPS</a> — partition 設計均勻時可以撐 sustained 高吞吐；<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 售票</a> — 同一場演唱會（event_id）天然容易 hot、必須用 composite key 分散。</p>
<h2 id="long-tail-latency-的-saturation">Long-tail latency 的 saturation</h2>
<p>p50 / p95 / p99 / p999 在 saturate 時表現可能完全不同。</p>
<p>p50（中位數）對 GC pause、retry storm、tail latency 不敏感 — 大部分 request 沒事、p50 看不到。
p99（百分之 1）對 connection contention 開始敏感、能早期看到 saturation。
p999（千分之 1）對 GC stop-the-world、leader election、retry storm 敏感、是長尾的最強訊號。</p>
<p>純看 average / p50 會誤判 saturation 還沒到。SLO 通常訂 p99（讓 99% 用戶體驗良好）、internal critical 系統可訂 p99.9（5 個 9 的可用性對應 5 個 9 的 latency 期待）。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">Tubi p99 &lt; 10ms</a> — ML 系統的 user-perceived latency 是 <em>最後完成的 inference</em>、p50 快沒用；<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase sub-ms</a> — RAFT 系統的 p999 通常比 p99 高一個量級。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency 卡片</a>。</p>
<h2 id="saturation-文件化容量地圖">Saturation 文件化：容量地圖</h2>
<p>Saturation discovery 跑完之後、產出 <em>容量地圖</em> — 不是一個數字、是一張表。</p>
<p>容量地圖至少要回答：</p>
<ul>
<li>在 X 配置下（instance count、type、network）</li>
<li>SLO 條件 Y 下（p99 &lt; N ms、error rate &lt; M%）</li>
<li>能撐 Z RPS（含分解到不同 endpoint）</li>
<li>knee 在哪（什麼條件下進入 cliff）</li>
<li>第一個 saturate 的 resource 是什麼</li>
</ul>
<p>紀錄 <em>測試時間</em> 跟 <em>軟硬體版本</em>：硬體 / 軟體版本變動後、saturation 點可能位移、舊地圖不能套用。</p>
<p>加入 release gate：每次重大改動後 re-test、確認 knee 沒往不好的方向移。這層自動化跟 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a> 對接。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
          <td>DynamoDB IOPS 20 → 135K 的擴展曲線量測</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></td>
          <td>partition 均勻時的線性擴展</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a></td>
          <td>connection limit 是 RDB 的 saturation 點</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a></td>
          <td>p99 &lt; 10ms saturation 條件比平均嚴格</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論</a> / <a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>（找到 knee 之後、定位是哪個 resource）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>（用 knee 算 headroom）</li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a>（量測訊號）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point</a></li>
<li><a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method</a></li>
<li><a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency</a></li>
<li><a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">Hot Partition</a></li>
</ul>
]]></content:encoded></item><item><title>9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/</guid><description>&lt;p>這個案例的核心責任是說明「transactional 金融系統」如何在不可預期峰值下維持低延遲。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &amp;#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech&lt;/a> 對比 — GR8 Tech 走「微服務 + AI 預測擴容」、DraftKings 走「Aurora 單一資料庫服務支撐多 DB cluster」、兩條路徑都解決同類業務問題。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>DraftKings 帳本系統的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/draftkings-aurora-case-study/">DraftKings case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>客戶數&lt;/td>
 &lt;td>310 萬 unique customers / month (Q2 2024)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>峰值操作&lt;/td>
 &lt;td>100 萬 ops / 分鐘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀延遲&lt;/td>
 &lt;td>&amp;lt; 1 ms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫延遲&lt;/td>
 &lt;td>6 ms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Replication lag&lt;/td>
 &lt;td>從 30 秒降到 10-30 ms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Database 數量&lt;/td>
 &lt;td>200 個 individual databases&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Super Bowl 流量&lt;/td>
 &lt;td>比賽季開幕高 +50%&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Amazon Aurora MySQL-Compatible、Aurora Replicas（讀寫分流）、Aurora I/O-Optimized（2023-05 推出）、Aurora Database Cloning（測試環境）、跨三個 AZ 儲存複製。&lt;/p>
&lt;p>關鍵負載形狀：「write workloads spike up significantly around payout events, but opening the app during the game also activates a lot of balance queries」— 比賽進行時是讀爆量、payout event 時是寫爆量、雙峰錯位。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>DraftKings 的工程選擇揭露三個 OLTP 容量設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>200 個獨立資料庫 = sharding 預先做好&lt;/strong>：按業務切 200 個 cluster、用巨型 cluster 撐全部在這個規模行不通。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 把「單機極限」改成「shard 極限」、每個 shard 的容量規劃變成獨立問題。&lt;/li>
&lt;li>&lt;strong>Replication lag 30 秒 → 10-30 ms&lt;/strong>：這個改善不只是「快」、而是讓 read-after-write 變得可預測。Aurora 的 storage layer 多 AZ 複製是這個 lag 改善的主因。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 replication lag 影響 transaction boundary 設計。&lt;/li>
&lt;li>&lt;strong>Super Bowl +50% 「no sweat」&lt;/strong>：這句話的工程意義是 &lt;em>提前做好容量規劃&lt;/em>、不是「Aurora 神奇」。寫 workload 預期可能 + 50%、整個 system headroom 預留至少 50%、加上 read replica 動態加減、才能讓 50% 增幅變成「不流汗」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的 headroom budget 與 event-driven scheduled scaling。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：100 萬 ops / 分鐘 = ~17K ops / 秒、跨 200 個 databases 平均下來每個 DB 約 80 ops / 秒。這不是「單一 DB 撐 100 萬 ops」、而是「200 shard 加總 100 萬」。讀案例時要看「峰值是分散到多少 shard」、不只看總數。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「transactional 金融系統」如何在不可預期峰值下維持低延遲。跟 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> 對比 — GR8 Tech 走「微服務 + AI 預測擴容」、DraftKings 走「Aurora 單一資料庫服務支撐多 DB cluster」、兩條路徑都解決同類業務問題。</p>
<h2 id="觀察">觀察</h2>
<p>DraftKings 帳本系統的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/draftkings-aurora-case-study/">DraftKings case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>客戶數</td>
          <td>310 萬 unique customers / month (Q2 2024)</td>
      </tr>
      <tr>
          <td>峰值操作</td>
          <td>100 萬 ops / 分鐘</td>
      </tr>
      <tr>
          <td>讀延遲</td>
          <td>&lt; 1 ms</td>
      </tr>
      <tr>
          <td>寫延遲</td>
          <td>6 ms</td>
      </tr>
      <tr>
          <td>Replication lag</td>
          <td>從 30 秒降到 10-30 ms</td>
      </tr>
      <tr>
          <td>Database 數量</td>
          <td>200 個 individual databases</td>
      </tr>
      <tr>
          <td>Super Bowl 流量</td>
          <td>比賽季開幕高 +50%</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Amazon Aurora MySQL-Compatible、Aurora Replicas（讀寫分流）、Aurora I/O-Optimized（2023-05 推出）、Aurora Database Cloning（測試環境）、跨三個 AZ 儲存複製。</p>
<p>關鍵負載形狀：「write workloads spike up significantly around payout events, but opening the app during the game also activates a lot of balance queries」— 比賽進行時是讀爆量、payout event 時是寫爆量、雙峰錯位。</p>
<h2 id="判讀">判讀</h2>
<p>DraftKings 的工程選擇揭露三個 OLTP 容量設計重點。</p>
<ol>
<li><strong>200 個獨立資料庫 = sharding 預先做好</strong>：按業務切 200 個 cluster、用巨型 cluster 撐全部在這個規模行不通。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 把「單機極限」改成「shard 極限」、每個 shard 的容量規劃變成獨立問題。</li>
<li><strong>Replication lag 30 秒 → 10-30 ms</strong>：這個改善不只是「快」、而是讓 read-after-write 變得可預測。Aurora 的 storage layer 多 AZ 複製是這個 lag 改善的主因。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 replication lag 影響 transaction boundary 設計。</li>
<li><strong>Super Bowl +50% 「no sweat」</strong>：這句話的工程意義是 <em>提前做好容量規劃</em>、不是「Aurora 神奇」。寫 workload 預期可能 + 50%、整個 system headroom 預留至少 50%、加上 read replica 動態加減、才能讓 50% 增幅變成「不流汗」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的 headroom budget 與 event-driven scheduled scaling。</li>
</ol>
<p>需要警惕：100 萬 ops / 分鐘 = ~17K ops / 秒、跨 200 個 databases 平均下來每個 DB 約 80 ops / 秒。這不是「單一 DB 撐 100 萬 ops」、而是「200 shard 加總 100 萬」。讀案例時要看「峰值是分散到多少 shard」、不只看總數。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>按業務切 OLTP cluster、不要一個 DB 撐全部</strong>：DraftKings 200 個 databases 顯示「業務切片」是 OLTP 擴容的前置。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema design 與 partition 決策。</li>
<li><strong>讀寫分流是 OLTP 容量規劃的基線</strong>：6ms 寫 vs &lt;1ms 讀的差距、加上 read replica、是 OLTP 擴容最基本的兩個槓桿。</li>
<li><strong>事件型峰值預測寫進 baseline</strong>：Super Bowl 是已知事件、+50% 是歷史經驗、所以可以提前 pre-scale。事件未知（突發新聞、KOL 推廣）的情況才需要 AI 預測（對照 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a>）。</li>
</ol>
<p>跨平台等效：GCP Cloud SQL + read replica / Spanner、Azure Database for PostgreSQL + read replica、自建 PostgreSQL + Patroni + pgbouncer 都可以實作對等架構。Aurora 的差異是 storage layer 對 replica 的 lag 改善。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 OLTP 高峰容量 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想搞清楚事件型 vs 突發型峰值 → <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> 對照</li>
<li>想做 read replica 容量設計 → <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a></li>
<li>想理解 replication lag 對 transaction boundary 的影響 → <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a></li>
<li>想理解 6 寫 / 4 讀 quorum 跟 200 cluster fleet 治理 → <a href="/blog/backend/01-database/vendors/aurora/storage-architecture/" data-link-title="Aurora Storage Architecture：quorum-based 分散式 log 與韌性即性能設計" data-link-desc="Aurora storage / compute 分離、6-way 跨 AZ replication、4-of-6 write / 3-of-6 read quorum、韌性投資自動 amortize 成 read 性能、DraftKings 6ms 寫 / &lt;1ms 讀 production reference">Aurora 儲存層架構</a></li>
<li>想規劃 read replica scaling 與 reader endpoint 路由 → <a href="/blog/backend/01-database/vendors/aurora/read-replica-scaling/" data-link-title="Aurora Read Replica Scaling：15 replica 上限、lag profile、headroom 預留與 fleet 治理" data-link-desc="Aurora 15 replica 上限、共享 storage 為什麼能養大量 replica、事件型容量分級表、DraftKings headroom 預留判讀、FanDuel 雙 SLO 並行、fleet 治理 3 條 driver（business sharding / microservice / 合規）">Aurora read replica scaling</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/draftkings-aurora-case-study/">DraftKings Scales Its Financial Ledger with Amazon Aurora</a></li>
<li><a href="https://aws.amazon.com/blogs/database/amazon-aurora-i-o-optimized-database-storage-configuration/">Aurora I/O-Optimized announcement</a></li>
</ul>
]]></content:encoded></item><item><title>Vegeta</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vegeta/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vegeta/</guid><description>&lt;p>Vegeta 的核心責任是用簡潔 CLI 對 HTTP endpoint 產生固定 rate 負載，快速探測 latency、throughput、error rate 與 saturation。它適合單一 endpoint、少量 header / body 變化、快速 baseline、incident 後驗證與工程師本機或 CI 中的輕量壓測。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Vegeta 是 Go 寫的 HTTP load testing CLI，核心模型是 &lt;em>constant rate attack&lt;/em>：指定「每秒 N 個 request」就持續打 N rps、不會因 server 變慢就降速，跟「fire-and-wait」型工具（hey / wrk 預設 closed-loop）行為差異很大。constant rate 是 &lt;em>open-loop&lt;/em> 模型 — 模擬真實流量「不會因服務慢而減少」的行為、所以 saturation 點才會明確浮現。&lt;/p>
&lt;p>Vegeta 是 Unix philosophy CLI：targets 從 stdin 讀（可以 pipe 進複雜 generator）、binary report 從 stdout 出（可以 pipe 進 &lt;code>vegeta report&lt;/code> / &lt;code>vegeta plot&lt;/code> / &lt;code>vegeta encode&lt;/code>）。這個設計讓 Vegeta 容易跟 shell pipeline / CI script 接合、但同時也決定它不適合表達多步驟 session。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a> 比、Vegeta 走 &lt;em>CLI-first + open-loop constant rate&lt;/em>、k6 走 &lt;em>JS scenario + threshold + CI artifact&lt;/em>。Vegeta 適合「我要對這個 URL 打 200 rps 60 秒」的一次性壓測、k6 適合「我有 3 種 user journey、各占 40/30/30%、跑 ramp-up profile」的可維護 scenario。跟 hey 比、Vegeta 的 constant rate 是真的 open-loop、hey 的 &lt;code>-q&lt;/code> 是 per-worker rate（worker 變慢整體就降速）— 探測 saturation 時 Vegeta 比較誠實。跟 wrk / wrk2 比、Vegeta 沒有 LuaJIT 那麼極致的單機壓測效能、但 binary report + &lt;code>vegeta plot&lt;/code> + targets pipe 對日常工程師工作流更友善。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>何時用 Vegeta、何時走 k6 / hey / wrk / Gatling / Locust 的取捨&lt;/li>
&lt;li>constant rate attack 的設計意涵（open-loop vs closed-loop、為什麼這對 saturation discovery 重要）&lt;/li>
&lt;li>target file / rate / duration / report 四件套的 baseline workflow 跟 evidence package 對應&lt;/li>
&lt;li>排錯時的常見陷阱：runner 端 TCP socket exhaust、open file limit、constant rate 跟 target server 限速 disconnect&lt;/li>
&lt;/ol>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>Vegeta 適合快速回答「這個 endpoint 在某個 rate 下表現如何」。當團隊需要先找出大概 knee point、驗證一個修補是否降低 latency、或在 CI 裡跑小型 performance smoke test，Vegeta 的 CLI workflow 很直接。&lt;/p></description><content:encoded><![CDATA[<p>Vegeta 的核心責任是用簡潔 CLI 對 HTTP endpoint 產生固定 rate 負載，快速探測 latency、throughput、error rate 與 saturation。它適合單一 endpoint、少量 header / body 變化、快速 baseline、incident 後驗證與工程師本機或 CI 中的輕量壓測。</p>
<h2 id="服務定位">服務定位</h2>
<p>Vegeta 是 Go 寫的 HTTP load testing CLI，核心模型是 <em>constant rate attack</em>：指定「每秒 N 個 request」就持續打 N rps、不會因 server 變慢就降速，跟「fire-and-wait」型工具（hey / wrk 預設 closed-loop）行為差異很大。constant rate 是 <em>open-loop</em> 模型 — 模擬真實流量「不會因服務慢而減少」的行為、所以 saturation 點才會明確浮現。</p>
<p>Vegeta 是 Unix philosophy CLI：targets 從 stdin 讀（可以 pipe 進複雜 generator）、binary report 從 stdout 出（可以 pipe 進 <code>vegeta report</code> / <code>vegeta plot</code> / <code>vegeta encode</code>）。這個設計讓 Vegeta 容易跟 shell pipeline / CI script 接合、但同時也決定它不適合表達多步驟 session。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> 比、Vegeta 走 <em>CLI-first + open-loop constant rate</em>、k6 走 <em>JS scenario + threshold + CI artifact</em>。Vegeta 適合「我要對這個 URL 打 200 rps 60 秒」的一次性壓測、k6 適合「我有 3 種 user journey、各占 40/30/30%、跑 ramp-up profile」的可維護 scenario。跟 hey 比、Vegeta 的 constant rate 是真的 open-loop、hey 的 <code>-q</code> 是 per-worker rate（worker 變慢整體就降速）— 探測 saturation 時 Vegeta 比較誠實。跟 wrk / wrk2 比、Vegeta 沒有 LuaJIT 那麼極致的單機壓測效能、但 binary report + <code>vegeta plot</code> + targets pipe 對日常工程師工作流更友善。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>何時用 Vegeta、何時走 k6 / hey / wrk / Gatling / Locust 的取捨</li>
<li>constant rate attack 的設計意涵（open-loop vs closed-loop、為什麼這對 saturation discovery 重要）</li>
<li>target file / rate / duration / report 四件套的 baseline workflow 跟 evidence package 對應</li>
<li>排錯時的常見陷阱：runner 端 TCP socket exhaust、open file limit、constant rate 跟 target server 限速 disconnect</li>
</ol>
<h2 id="定位">定位</h2>
<p>Vegeta 適合快速回答「這個 endpoint 在某個 rate 下表現如何」。當團隊需要先找出大概 knee point、驗證一個修補是否降低 latency、或在 CI 裡跑小型 performance smoke test，Vegeta 的 CLI workflow 很直接。</p>
<p>這個定位讓 Vegeta 接到 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 與 <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>。它提供的是快速壓力探針，後續若要表達複雜 workload model，通常要轉向 k6、Gatling、Locust 或 JMeter。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一次 Vegeta 壓測是否有效、最少看四件事：</p>
<ul>
<li><strong>Target 描述完整性</strong>：targets file 是否包含 method / URL / headers / body、是否反映真實 request shape（含 auth header、content-type、representative payload size），缺一就會讓壓測結果偏離正式環境</li>
<li><strong>Rate model 設計</strong>：選的是 constant rate（<code>-rate=200/s</code>）還是 ramp（用多段 attack pipe），constant rate 適合 saturation probe、ramp-up 要 wrap script 自己 stage、Vegeta 沒有原生 ramp profile</li>
<li><strong>Report 解讀</strong>：<code>vegeta report</code> 給 mean / p50 / p95 / p99 / max latency + success rate + throughput，重點看 <em>p99 跟 max 的距離</em> 與 <em>requested rate vs actual throughput</em> 是否 disconnect — disconnect 表示 server / runner 端有人在限速</li>
<li><strong>Duration vs warm-up</strong>：短 duration（&lt; 30s）容易吃到 JIT / cache / connection pool warm-up 噪音，baseline 壓測 duration 至少 60s、且第一段 result 要 discard，否則 p99 會被前 5s 拉高</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p>單 endpoint saturation probe 是 Vegeta 的主要入口。工程師可以對 login、search、read API、feature flag endpoint 或 internal health-like endpoint 施加固定 rate，觀察 p95 / p99 與 error rate 何時開始上升。</p>
<p>Regression smoke test 適合用 Vegeta。CI 或 pre-release 可以用短時間固定 rate 測試，確認 hot path 沒有明顯退化，再把更完整的 scenario 交給 k6、Gatling 或 Locust。</p>
<p>Incident 後修補驗證適合用 Vegeta。當事故根因是某個 endpoint 的 query、cache miss、lock contention 或 timeout，修補後可以用相同 request set 重跑，快速比較 latency distribution。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Vegeta 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CLI 簡潔</td>
          <td>本機、CI、shell workflow 容易接</td>
          <td>長期報表與 artifact 標準化</td>
      </tr>
      <tr>
          <td>固定 rate</td>
          <td>探測 rate / latency 關係清楚</td>
          <td>複雜使用者行為與 arrival pattern</td>
      </tr>
      <tr>
          <td>HTTP 導向</td>
          <td>API hot path 快速驗證</td>
          <td>非 HTTP protocol 與 multi-step flow</td>
      </tr>
      <tr>
          <td>快速 probe</td>
          <td>適合 smoke test 與修補驗證</td>
          <td>完整 workload model 與資料治理</td>
      </tr>
  </tbody>
</table>
<p>CLI 簡潔價值來自低摩擦。當問題還在定位階段，工程師可以很快產生可重跑 command 與 target file，先取得 baseline，再決定是否需要完整壓測平台。</p>
<p>固定 rate 價值來自可比較。用相同 request set、rate、duration 與 target environment 重跑，可以讓修補前後的 latency distribution 有清楚對照。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Vegeta 和 k6 的主要差異是 scenario 深度。Vegeta 適合固定 rate HTTP probe；k6 適合多步驟 scenario、threshold、CI artifact 與 browser-style flow。</p>
<p>Vegeta 和 JMeter 的主要差異是工具重量。Vegeta 適合快速 CLI；JMeter 適合 GUI、多 protocol、plugin 與企業測試資產。</p>
<p>Vegeta 和 Gatling 的主要差異是長期維護模式。Vegeta 用 command / target file 保持簡單；Gatling 用 simulation 維護複雜 flow 與 injection profile。</p>
<p>Vegeta 和 Locust 的主要差異是自訂能力。Locust 適合 Python user behavior 與 custom client；Vegeta 適合 HTTP endpoint 的直接壓力測量。</p>
<h2 id="操作成本">操作成本</h2>
<p>Vegeta 的主要成本是 workload coverage 有限。它能快速測 endpoint，但多步驟 session、資料依賴、payment mock、queue side effect 與 realistic user journey 需要額外工具或腳本補上。</p>
<p>Artifact 成本來自命令可追溯性。每次測試要保存 rate、duration、targets、headers、body、環境、版本與結果檔；否則快速 probe 很容易變成不可比較的一次性觀察。</p>
<p>Runner 成本通常較低，但仍要檢查本機瓶頸。高 rate 測試時，產生負載的機器也可能先被 CPU、network、file descriptor 或 connection limit 卡住。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Vegeta 結果應回寫到 evidence package。最小欄位包括 command、target file hash、rate、duration、workers、target environment、p95 / p99、max latency、error rate、throughput、target saturation metric、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Vegeta 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>command、targets file、binary result、report</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>test start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / logs 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>target set freshness、header / body correctness</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>runner capacity、endpoint representativeness</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋多步驟 flow、資料偏差、runner limit</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓快速測試可以比較。Vegeta 的結果通常很短，反而更需要保存 command 與 target set，讓下一次修補驗證能跑同一組條件。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Vegeta</th>
          <th>k6</th>
          <th>hey</th>
          <th>wrk / wrk2</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>負載模型</td>
          <td>Open-loop constant rate（rps 不隨 latency 降）</td>
          <td>Open-loop（k6 default）/ closed-loop（VU mode）</td>
          <td>Per-worker rate（closed-loop 傾向）</td>
          <td>wrk closed-loop / wrk2 open-loop</td>
      </tr>
      <tr>
          <td>Scenario 深度</td>
          <td>單 endpoint pipe target、多 endpoint 需 script</td>
          <td>JS script、多步驟、staging / threshold / SLO 內建</td>
          <td>單一 URL CLI flag</td>
          <td>Lua script 可寫複雜邏輯但 idiom 較陡</td>
      </tr>
      <tr>
          <td>輸出形式</td>
          <td>Binary stream + <code>vegeta report/plot/encode</code></td>
          <td>stdout summary + JSON + 內建 dashboard</td>
          <td>stdout 文字 summary</td>
          <td>stdout 文字 summary、HdrHistogram</td>
      </tr>
      <tr>
          <td>CI 整合</td>
          <td>用 shell 包、自寫 threshold gate</td>
          <td>內建 threshold / exit code、CI artifact 標準化</td>
          <td>簡單 smoke、無 threshold</td>
          <td>需自寫 wrapper</td>
      </tr>
      <tr>
          <td>學習成本</td>
          <td>低 — 幾個 flag 就上手</td>
          <td>中 — 要寫 JS scenario</td>
          <td>極低 — 一行 CLI</td>
          <td>中 — Lua 加 HdrHistogram 概念</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>修補驗證、CI smoke、saturation probe</td>
          <td>完整壓測平台、SLO gate、多 scenario</td>
          <td>一次性 ad-hoc 探測</td>
          <td>極致單機壓測效能、低 overhead 量測</td>
      </tr>
  </tbody>
</table>
<p>選 Vegeta 的核心訴求：<em>工程師本機 / CI smoke / 修補驗證 / saturation probe</em> 都要快速可重跑、且結果要可以保存比較；不需要完整 scenario 模型也不需要 GUI 報表。若團隊需要完整 user journey、threshold / SLO gate、長期 trend dashboard，直接走 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> 或 <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Reporting 多輸出 format</strong>：<code>vegeta report</code> 預設 text summary、加 <code>-type=hist[0,10ms,50ms,100ms,500ms]</code> 給 latency bucket histogram、<code>-type=json</code> 給機器可讀 result、<code>vegeta plot</code> 出 HTML latency chart、<code>vegeta encode -to=csv</code> 轉成可進 spreadsheet / dashboard 的 CSV。binary result 檔可重複 decode 成不同 format，不用重跑壓測。修補驗證的標準作法是保留 <code>results.bin</code>、之後可隨時 re-render report。</p>
<p><strong>Pipe attack workflow</strong>：Vegeta 的 stdin/stdout 都是 stream — 可以用 shell pipe 串接 <code>jq</code> 動態產 targets（<code>jq -r '.urls[] | &quot;GET &quot; + .'</code>）、用 <code>vegeta attack | tee results.bin | vegeta report</code> 同時寫檔跟即時看 summary、用 <code>cat results-old.bin results-new.bin | vegeta report</code> 比較兩次結果。這個設計讓 Vegeta 跟 incident drill / chaos test script 容易接合 — 修補 deploy 完跑一次 attack、result 直接 commit 進 git 當 evidence。</p>
<p><strong>CI integration pattern</strong>：CI 裡 Vegeta 沒有 k6 那種內建 threshold，要自寫 gate — <code>vegeta report -type=json results.bin | jq '.latencies.p99'</code> 出 p99、bash 比較 budget、超標 exit 非零。把 <code>targets.txt</code> + <code>attack.sh</code> + <code>expected-budget.json</code> commit 進 repo、CI artifact 上傳 <code>results.bin</code> + <code>plot.html</code>，下次 regression 時可以 diff。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Requested rate 跟 actual throughput disconnect（要 200rps 實際只跑 80rps）</strong>：runner 端先飽和、不是 server 飽和 — 看 <code>vegeta attack</code> stderr 是否報 <code>socket: too many open files</code>、檢查 <code>ulimit -n</code>（生產壓測 runner 至少設 65535）；或 server 端有限速 / rate limit / connection cap 把 request reject 在 TCP 層、Vegeta 看不到完整 response 就被卡</li>
<li><strong>TCP socket exhaust（runner 端）</strong>：constant rate 模型下、若 server 回應慢、connection 會堆積、<code>TIME_WAIT</code> socket 爆 ephemeral port range — 用 <code>-keepalive=true</code>（預設）並調 <code>net.ipv4.tcp_tw_reuse=1</code>、或加 <code>-connections=N</code> 限制 connection pool 上限避免無限堆 socket</li>
<li><strong>p99 / max latency 異常高、但 server-side metrics 看不到</strong>：runner 端 GC pause / CPU steal / network jitter 把 latency 量測污染 — 把 runner 移到跟 target 同 placement group / same AZ、確認 runner CPU 沒被其他 process 搶、duration 拉長到 5min 讓 outlier 變稀釋</li>
<li><strong>Success rate 100% 但 server 已經爆</strong>：targets 沒帶 auth header / 打到 LB 而非 backend、所有 request 在前面就 200 / cache hit、server 根本沒收到壓力 — 檢查 target server access log 的 request count 跟 Vegeta requested rate 是否對得上</li>
<li><strong>短時間壓測結果不穩定（同 command 跑兩次差很多）</strong>：duration 太短（&lt; 30s）、warm-up 噪音占比太高 — 至少 60s、第一段 5-10s discard、若 endpoint 有 lazy initialization（cache / connection pool / JIT compile）先跑一段 warm-up attack 再正式量</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Vegeta 適合回寫單 endpoint hot path 與修補驗證案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase ultra-low latency</a> 的 sub-millisecond latency distribution 判讀、<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi feature store</a> 的 p99 &lt; 10ms lookup 驗證、<a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino connection limit</a> 的 RDB bottleneck 探測、<a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder ElastiCache</a> 的次毫秒 cache lookup 驗證，以及 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB</a> 的 hot partition 探測。</p>
<p>這些案例的重點是快速定位與比較。Vegeta 頁引用案例時，要把 case 轉成 endpoint、rate、duration、latency budget、target saturation metric 與 runner limit — 例如 Coinbase 的 sub-ms 目標要求 Vegeta runner 必須跟 target 同 placement group、否則 runner 自身的網路 jitter 會吃掉觀測精度。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>、<a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>、<a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></li>
<li>跨模組：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a></li>
<li>官方：<a href="https://github.com/tsenart/vegeta">Vegeta documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.5 瓶頸定位流程</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/bottleneck-localization/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/bottleneck-localization/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>瓶頸定位的責任是回答「為什麼擴 app 沒用」這類問題。當 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a> 找到 knee point 之後、下一步是知道 &lt;em>哪個 resource&lt;/em> 先 saturate。沒有定位、容量規劃只能 &lt;em>全部翻倍&lt;/em>；有定位、可以 &lt;em>精準加在瓶頸層&lt;/em>。&lt;/p>
&lt;p>跟其他章節的關係：跟 9.4 是姊妹章（9.4 找出 knee、9.5 定位 knee 的成因）、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性&lt;/a> 互補（9.8 訊號治理、9.5 用訊號做定位）。&lt;/p>
&lt;p>本章不深入工具操作、聚焦在 &lt;em>方法論&lt;/em> — 怎麼按層次定位、怎麼避免常見誤判、怎麼區分可分散 vs 不可分散瓶頸。&lt;/p>
&lt;h2 id="use-methodresource-oriented-觀察">USE method：resource-oriented 觀察&lt;/h2>
&lt;p>Brendan Gregg 的 USE method 提供逐層定位的最小框架：對每個資源、量三個維度。&lt;/p>
&lt;p>&lt;strong>Utilization&lt;/strong>：資源使用率 0-100%。CPU 70%、memory 60%、disk 40% 這類數字。
&lt;strong>Saturation&lt;/strong>：資源排隊量（queue depth）。CPU run queue length、memory swap rate、disk I/O wait queue、connection pool wait count。
&lt;strong>Errors&lt;/strong>：資源層錯誤。CPU page fault、memory OOM、disk I/O error、network packet drop、connection refused。&lt;/p>
&lt;p>對每個資源（CPU / RAM / disk / network / DB connection / cache connection / file descriptor）逐一檢查。&lt;em>第一個出現 saturation 上升的資源是 bottleneck&lt;/em>、不是 utilization 最高的那個。&lt;/p>
&lt;p>USE 跟 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED method&lt;/a>（rate / errors / duration）互補：USE 看「哪個資源頂不住」、RED 看「哪個 endpoint 表現變差」。容量規劃通常先用 USE 找瓶頸、再用 RED 看影響面。&lt;/p>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method 卡片&lt;/a>。&lt;/p>
&lt;h2 id="逐層定位流程">逐層定位流程&lt;/h2>
&lt;p>從 application 層往下查、按依賴鏈逐層檢查。多數 bottleneck 在 application 跟 DB 兩層、但不能跳過其他層 — 偶爾真的在意外位置。&lt;/p>
&lt;p>&lt;strong>1. 應用層（application）&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>thread / coroutine pool 使用率：是否已飽和&lt;/li>
&lt;li>event loop lag（Node.js、async runtime）：&amp;gt; 50ms 是警訊&lt;/li>
&lt;li>GC pause 頻率與時長：影響 p99 / p999&lt;/li>
&lt;li>request queue（accept queue、application internal queue）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. DB 層&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>connection pool 使用率（最常見隱性 bottleneck）&lt;/li>
&lt;li>slow query frequency&lt;/li>
&lt;li>replication lag&lt;/li>
&lt;li>lock contention（row lock、table lock）&lt;/li>
&lt;li>transaction queue depth&lt;/li>
&lt;/ul>
&lt;p>定位到 DB 層瓶頸時、優先檢查 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&amp;#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式&lt;/a> 清單 — 多數 DB 層瓶頸的根因是「應用程式發給 DB 的 query 寫法」、不是 DB 規格不夠。N+1 query 放大 connection 占用、long-running transaction 放大 lock contention、缺索引讓 slow query frequency 升高、&lt;code>SELECT *&lt;/code> 放大 transaction queue。這層判讀走完、再考慮 DB 規格升級或加 replica。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>瓶頸定位的責任是回答「為什麼擴 app 沒用」這類問題。當 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 找到 knee point 之後、下一步是知道 <em>哪個 resource</em> 先 saturate。沒有定位、容量規劃只能 <em>全部翻倍</em>；有定位、可以 <em>精準加在瓶頸層</em>。</p>
<p>跟其他章節的關係：跟 9.4 是姊妹章（9.4 找出 knee、9.5 定位 knee 的成因）、跟 <a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a> 互補（9.8 訊號治理、9.5 用訊號做定位）。</p>
<p>本章不深入工具操作、聚焦在 <em>方法論</em> — 怎麼按層次定位、怎麼避免常見誤判、怎麼區分可分散 vs 不可分散瓶頸。</p>
<h2 id="use-methodresource-oriented-觀察">USE method：resource-oriented 觀察</h2>
<p>Brendan Gregg 的 USE method 提供逐層定位的最小框架：對每個資源、量三個維度。</p>
<p><strong>Utilization</strong>：資源使用率 0-100%。CPU 70%、memory 60%、disk 40% 這類數字。
<strong>Saturation</strong>：資源排隊量（queue depth）。CPU run queue length、memory swap rate、disk I/O wait queue、connection pool wait count。
<strong>Errors</strong>：資源層錯誤。CPU page fault、memory OOM、disk I/O error、network packet drop、connection refused。</p>
<p>對每個資源（CPU / RAM / disk / network / DB connection / cache connection / file descriptor）逐一檢查。<em>第一個出現 saturation 上升的資源是 bottleneck</em>、不是 utilization 最高的那個。</p>
<p>USE 跟 <a href="/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED method</a>（rate / errors / duration）互補：USE 看「哪個資源頂不住」、RED 看「哪個 endpoint 表現變差」。容量規劃通常先用 USE 找瓶頸、再用 RED 看影響面。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method 卡片</a>。</p>
<h2 id="逐層定位流程">逐層定位流程</h2>
<p>從 application 層往下查、按依賴鏈逐層檢查。多數 bottleneck 在 application 跟 DB 兩層、但不能跳過其他層 — 偶爾真的在意外位置。</p>
<p><strong>1. 應用層（application）</strong>：</p>
<ul>
<li>thread / coroutine pool 使用率：是否已飽和</li>
<li>event loop lag（Node.js、async runtime）：&gt; 50ms 是警訊</li>
<li>GC pause 頻率與時長：影響 p99 / p999</li>
<li>request queue（accept queue、application internal queue）</li>
</ul>
<p><strong>2. DB 層</strong>：</p>
<ul>
<li>connection pool 使用率（最常見隱性 bottleneck）</li>
<li>slow query frequency</li>
<li>replication lag</li>
<li>lock contention（row lock、table lock）</li>
<li>transaction queue depth</li>
</ul>
<p>定位到 DB 層瓶頸時、優先檢查 <a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式</a> 清單 — 多數 DB 層瓶頸的根因是「應用程式發給 DB 的 query 寫法」、不是 DB 規格不夠。N+1 query 放大 connection 占用、long-running transaction 放大 lock contention、缺索引讓 slow query frequency 升高、<code>SELECT *</code> 放大 transaction queue。這層判讀走完、再考慮 DB 規格升級或加 replica。</p>
<p><strong>3. Cache 層</strong>：</p>
<ul>
<li>hit rate（突然下降是訊號）</li>
<li>eviction rate</li>
<li>connection 飽和（cache pool 也會耗盡）</li>
<li>memory utilization</li>
</ul>
<p><strong>4. Broker / queue 層</strong>：</p>
<ul>
<li>consumer lag（最重要的單一指標）</li>
<li>queue depth</li>
<li>dead-letter rate</li>
<li>broker connection count</li>
</ul>
<p><strong>5. 外部 API / 第三方 quota</strong>：</p>
<ul>
<li>rate limit 觸發頻率</li>
<li>retry storm（自家 retry 把對方 quota 打爆）</li>
<li>circuit breaker trip</li>
<li>timeout rate</li>
</ul>
<p><strong>6. 網路層</strong>：</p>
<ul>
<li>bandwidth utilization</li>
<li>packets per second（PPS limit）</li>
<li>socket count（file descriptor limit）</li>
<li>跨 region / 跨 AZ latency</li>
</ul>
<p><strong>7. DNS / load balancer</strong>：</p>
<ul>
<li>DNS resolution latency</li>
<li>LB connection establishment time</li>
<li>TLS handshake duration</li>
<li>backend health check failure</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">Lemino</a> RDB connection limit 是隱性 bottleneck、CPU / RAM 都還行；<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 付款層獨立</a> — 把高頻搶票流量跟低頻付款流量分離、避免一層拖累另一層。</p>
<h2 id="profile-工具鏈">Profile 工具鏈</h2>
<p>USE 找出哪一層 saturate 之後、profile 工具找出 <em>該層的哪段 code</em> 拖累。</p>
<p><strong>Continuous profiling</strong>：Datadog Continuous Profiler、Pyroscope（開源 + Grafana 整合）、Parca（CNCF）、GCP Cloud Profiler、Azure Application Insights Profiler、AWS CodeGuru Profiler。production 持續取樣 CPU / heap / lock、overhead 通常 &lt; 1%。</p>
<p><strong>Distributed tracing</strong>：OpenTelemetry、Jaeger、Tempo、AWS X-Ray、GCP Cloud Trace、Azure Application Insights。記錄 request 在每個 service / 每個 stage 花了多少時間、找跨服務的 latency 累積。</p>
<p><strong>Flame graph</strong>：profile 結果視覺化的標準。從寬度可以看到「哪段 code 佔 CPU 最多」。學會看 flame graph 是 SRE 的基本功。</p>
<p><strong>Profile diff</strong>：壓測 baseline 跟 release candidate 比 stack 差異。看 <em>相對變化</em> 而非絕對值。詳見 <a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">Profile Diff 卡片</a>。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix Aurora storage / compute 分離</a> — DB 統一後 application profile 變單純、退化來源更容易識別。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous Profiling 卡片</a>。</p>
<h2 id="跨層依賴鏈">跨層依賴鏈</h2>
<p>瓶頸不一定在 <em>本服務</em>、可能在 <em>下游服務</em>。這層判斷常被忽略。</p>
<p><strong>第三方 API quota</strong> 是常見隱性瓶頸。Twilio SMS、Stripe API、Slack webhook、Sendgrid email、Google Maps API 都有 rate limit。自家服務看起來健康、實際是 <em>對方 throttle</em>、自家 retry 再讓對方更慢。</p>
<p><strong>跨 region / 跨 zone 網路延遲</strong> 是累積的。一個 user request 經過 5 個 service、每個 service 跨 AZ 一次、累積 10-20ms cross-AZ latency。看起來每個 service 都很快、但 end-to-end 慢。</p>
<p><strong>Downstream cache</strong> 也是依賴。app 看起來健康、但其實是 cache 在擋；cache 突然 cold start（restart、eviction storm）、application 直接被打爆。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">PayPay 行動支付</a> — DynamoDB 寫入可以撐 3K msg/sec、但 APNs / FCM 一天的 quota 有限、推送下游才是瓶頸。</p>
<h2 id="可分散-vs-不可分散瓶頸">可分散 vs 不可分散瓶頸</h2>
<p>定位完瓶頸後、要判斷它 <em>可不可以橫向擴</em>。這個判斷決定能不能用「加機器」解決。</p>
<p><strong>可分散瓶頸</strong>：</p>
<ul>
<li>stateless app server → 加機器有用</li>
<li>partitioned KV / OLTP（partition key 均勻時）→ 加 partition 有用</li>
<li>read replica（read-heavy workload）→ 加 replica 有用</li>
<li>worker pool → 加 worker 有用</li>
</ul>
<p><strong>不可分散瓶頸</strong>：</p>
<ul>
<li>consensus DB（RAFT / Paxos）→ 加節點不一定快（<a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a> overhead）</li>
<li>single leader DB（master 寫）→ 必須垂直擴</li>
<li>中央 coordinator → 必須拆解或垂直擴</li>
<li>共享 cache（hot key）→ 必須改 partition key 或加 local cache</li>
</ul>
<p>判斷不可分散的關鍵是「協調成本」。一個操作必須 <em>跟所有 / 多數節點協調</em> 才能完成、就不可水平擴。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase RAFT consensus</a> — consensus 不可水平擴、所以 <em>選擇不擴</em>、改用單機極致；<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">Spanner TrueTime</a> — TrueTime 把協調成本 amortize 到 hardware（GPS + 原子鐘）、讓 OLTP 可水平擴。</p>
<h2 id="常見定位陷阱">常見定位陷阱</h2>
<p><strong>看單一指標就下結論</strong>：CPU 100% 不一定是 bottleneck（可能 saturation queue 空）；CPU 50% 不一定健康（可能 saturation queue 已滿）。always 看 USE 三個維度。</p>
<p><strong>平均看 OK、p99 看不出來</strong>：average latency 50ms 看起來健康、p99 500ms 已經出事。用 percentile、不用 average。</p>
<p><strong>Observer effect</strong>：profile / tracing 本身有 overhead、量測會輕微影響系統。critical path 上的 instrumentation 要 sampled 不要 100%。</p>
<p><strong>跨 release 比較 baseline 沒對齊</strong>：上週的 baseline 對應 v1.2、這週的 candidate 對應 v1.3、但 v1.2 跟 v1.3 之間還有 schema migration / hardware 變化、baseline 已經漂移。重新建 baseline 再 diff。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a></td>
          <td>connection limit 是 RDB 隱性 bottleneck</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 付款層獨立</a></td>
          <td>關鍵路徑切分避免 cross contamination</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase RAFT consensus</a></td>
          <td>不可分散 bottleneck</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay</a></td>
          <td>下游 APNs / FCM quota 瓶頸</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>（針對 bottleneck 規劃）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a>（用 profile diff 改進）</li>
<li>下游：<a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算</a>（DB 層 bottleneck 多半在 query 寫法）</li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> / <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method</a></li>
<li><a href="/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED Method</a></li>
<li><a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous Profiling</a></li>
<li><a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">Profile Diff</a></li>
<li><a href="/blog/backend/knowledge-cards/universal-scalability-law/" data-link-title="Universal Scalability Law (USL)" data-link-desc="說明系統擴容到一定規模後吞吐反而下降的數學模型">Universal Scalability Law</a></li>
</ul>
]]></content:encoded></item><item><title>9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/</guid><description>&lt;p>這個案例的核心責任是提供「key-value 持續高吞吐」的極限參考點。廣告事件量測屬 &lt;em>write-heavy + read-heavy 同時存在&lt;/em> 的負載 — 每個曝光都要寫進度、每個曝光也都要查 metadata。這類負載沒有明顯峰谷、是長期 sustained growth、跟事件型峰值的容量設計邏輯不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Amazon Ads 在 DynamoDB 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>讀吞吐&lt;/td>
 &lt;td>9000 萬 reads / 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>寫吞吐&lt;/td>
 &lt;td>500 萬 writes / 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性&lt;/td>
 &lt;td>99.999%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>用途&lt;/td>
 &lt;td>廣告事件量測&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>讀寫比約 18:1。這個比例反映「曝光發生 1 次、後續查詢可能發生 18 次」的廣告計費邏輯。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>這個案例最重要的不是「DynamoDB 能撐多少」、而是「為什麼可以這樣設計」。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>單表分散到上千個 partition&lt;/strong>：DynamoDB 把每個 table 拆成多個 partition、每個 partition 內部還可以再分散。9000 萬 reads / 秒 是上千個 partition 加總的結果、單一節點達不到這個量級。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 的 sharding 邊界、跟 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 partition 設計。&lt;/li>
&lt;li>&lt;strong>partition key 選擇直接決定容量上限&lt;/strong>：DynamoDB 的容量是「每 partition 上限 × partition 數量」。partition key 不均勻會出現 hot partition、實際容量遠低於名義容量。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 saturation 不一定是整體 saturation、而是 &lt;em>最熱的 partition&lt;/em> saturation。&lt;/li>
&lt;li>&lt;strong>99.999% availability ≈ 5 分鐘 / 年的容錯&lt;/strong>：廣告計費 1 分鐘斷線可能損失幾百萬美金廣告收入。這個 SLO 不是行銷數字、是真實的營收邊界。對應 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「9000 萬 reads / 秒」這種敘述通常是 &lt;em>年度峰值的最高一秒&lt;/em>、不是平均值。容量規劃要區分「最大瞬時」、「99 百分位平均」、「常態流量」三個不同口徑。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>partition key 設計是 KV 容量的第一決策&lt;/strong>：均勻分散、避免 hot partition、必要時加 random suffix 強制分散。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 schema design 章節。&lt;/li>
&lt;li>&lt;strong>read-heavy 跟 write-heavy 比例變化是容量警訊&lt;/strong>：當業務邏輯改變（例如新增即時報表）、讀寫比可能跳一個量級、原本的容量規劃會失效。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性&lt;/a> 持續監控比例變化。&lt;/li>
&lt;li>&lt;strong>on-demand vs provisioned 是成本 vs 反應速度的取捨&lt;/strong>：on-demand 自動擴容但成本高、provisioned 便宜但需要預測。Amazon Ads 這種 sustained workload 通常用 provisioned + auto scaling、不用 on-demand。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP Cloud Bigtable + 良好 row key 設計、Azure Cosmos DB partition key 設計都是對等概念。差異是 DynamoDB 的 partition 透明度（你看不到 partition 數量）vs Bigtable 的明確 tablet 模型。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供「key-value 持續高吞吐」的極限參考點。廣告事件量測屬 <em>write-heavy + read-heavy 同時存在</em> 的負載 — 每個曝光都要寫進度、每個曝光也都要查 metadata。這類負載沒有明顯峰谷、是長期 sustained growth、跟事件型峰值的容量設計邏輯不同。</p>
<h2 id="觀察">觀察</h2>
<p>Amazon Ads 在 DynamoDB 的關鍵數字（引自 <a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>讀吞吐</td>
          <td>9000 萬 reads / 秒</td>
      </tr>
      <tr>
          <td>寫吞吐</td>
          <td>500 萬 writes / 秒</td>
      </tr>
      <tr>
          <td>可用性</td>
          <td>99.999%</td>
      </tr>
      <tr>
          <td>用途</td>
          <td>廣告事件量測</td>
      </tr>
  </tbody>
</table>
<p>讀寫比約 18:1。這個比例反映「曝光發生 1 次、後續查詢可能發生 18 次」的廣告計費邏輯。</p>
<h2 id="判讀">判讀</h2>
<p>這個案例最重要的不是「DynamoDB 能撐多少」、而是「為什麼可以這樣設計」。</p>
<ol>
<li><strong>單表分散到上千個 partition</strong>：DynamoDB 把每個 table 拆成多個 partition、每個 partition 內部還可以再分散。9000 萬 reads / 秒 是上千個 partition 加總的結果、單一節點達不到這個量級。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的 sharding 邊界、跟 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 partition 設計。</li>
<li><strong>partition key 選擇直接決定容量上限</strong>：DynamoDB 的容量是「每 partition 上限 × partition 數量」。partition key 不均勻會出現 hot partition、實際容量遠低於名義容量。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 saturation 不一定是整體 saturation、而是 <em>最熱的 partition</em> saturation。</li>
<li><strong>99.999% availability ≈ 5 分鐘 / 年的容錯</strong>：廣告計費 1 分鐘斷線可能損失幾百萬美金廣告收入。這個 SLO 不是行銷數字、是真實的營收邊界。對應 <a href="/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號</a> 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a>。</li>
</ol>
<p>需要警惕：「9000 萬 reads / 秒」這種敘述通常是 <em>年度峰值的最高一秒</em>、不是平均值。容量規劃要區分「最大瞬時」、「99 百分位平均」、「常態流量」三個不同口徑。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>partition key 設計是 KV 容量的第一決策</strong>：均勻分散、避免 hot partition、必要時加 random suffix 強制分散。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema design 章節。</li>
<li><strong>read-heavy 跟 write-heavy 比例變化是容量警訊</strong>：當業務邏輯改變（例如新增即時報表）、讀寫比可能跳一個量級、原本的容量規劃會失效。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性</a> 持續監控比例變化。</li>
<li><strong>on-demand vs provisioned 是成本 vs 反應速度的取捨</strong>：on-demand 自動擴容但成本高、provisioned 便宜但需要預測。Amazon Ads 這種 sustained workload 通常用 provisioned + auto scaling、不用 on-demand。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
</ol>
<p>跨平台等效：GCP Cloud Bigtable + 良好 row key 設計、Azure Cosmos DB partition key 設計都是對等概念。差異是 DynamoDB 的 partition 透明度（你看不到 partition 數量）vs Bigtable 的明確 tablet 模型。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 KV 高吞吐架構 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想避免 hot partition → <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a></li>
<li>想對照其他 KV 案例 → <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth Cosmos DB</a>（Azure 全球分散）</li>
<li>想深入 DynamoDB hot partition 反模式 → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a></li>
<li>想拆 access pattern 對應的 single-table design → <a href="/blog/backend/01-database/vendors/dynamodb/single-table-design-pattern/" data-link-title="DynamoDB Single-Table Design：從適用度前置判讀到 access pattern 反推 PK/SK" data-link-desc="DynamoDB single-table 設計不是「資料表越少越好」，而是 access pattern 反推 PK/SK 跟 GSI；本文先做 DynamoDB 適用度 4 軸前置判讀（PK 天然均勻 / control plane vs data plane / consistency / access pattern 穩定），再展開設計流程、failure modes 與 durable queue 正向用例">DynamoDB single-table design</a></li>
<li>想評估 on-demand vs provisioned 切換時機 → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
<li><a href="https://aws.amazon.com/blogs/database/handle-traffic-spikes-with-amazon-dynamodb-provisioned-capacity/">Handle traffic spikes with Amazon DynamoDB provisioned capacity</a></li>
<li><a href="https://aws.amazon.com/blogs/database/demystifying-amazon-dynamodb-on-demand-capacity-mode/">Demystifying Amazon DynamoDB on-demand capacity mode</a></li>
</ul>
]]></content:encoded></item><item><title>9.6 容量規劃模型</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>容量規劃的責任是把「未來 N 個月可能多大」翻成「現在該訂多少 capacity」。這層工作不純靠歷史外推、要結合業務 forecast、事件型成長、頂部風險 buffer。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a> 的關係：9.4 提供「當前配置能撐多少」、9.6 用這個數字加上 forecast 推「該規劃多少」。沒有 9.4 的 baseline、9.6 只是猜；沒有 9.6 的 forecast、9.4 的 baseline 只是 snapshot。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸&lt;/a> 的關係：9.13 先決定「沿哪條軸擴」（垂直 / 水平 / Y 軸拆服務 / Z 軸 partition），9.6 才能算出「該擴多少」。同樣是「處理 10 倍流量」、選垂直擴展要算單機規格上限、選水平擴展要算協調成本跟連線池放大、選 Y 軸拆服務要算跨服務 latency budget — 三條軸的容量公式參數完全不同。沒先做 9.13、9.6 的數字會落到錯誤的擴展軸上。&lt;/p>
&lt;p>本章是「規劃決策」的章節、不是執行手冊。讀完後讀者能回答：peak 怎麼預測、headroom 訂多少、autoscaler 怎麼配、不可水平擴的服務怎麼處理。&lt;/p>
&lt;h2 id="容量公式三項">容量公式三項&lt;/h2>
&lt;p>容量規劃的核心公式可以濃縮成三項相乘：&lt;code>容量 = 預期峰值 × (1 + headroom) / 可擴容速度&lt;/code>。每一項都需要獨立分析：&lt;/p>
&lt;p>&lt;strong>預期峰值（peak forecast）&lt;/strong>：歷史 baseline × 預期成長 × 事件因子。三項中最影響整體準度。詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast 卡片&lt;/a>。&lt;/p>
&lt;p>&lt;strong>Headroom budget&lt;/strong>：通常 30-50%、為了應付異常 burst + AZ 故障 + forecast 誤差。不同工作負載 headroom 不同。詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &amp;#43; AZ 故障 &amp;#43; forecast 誤差的安全餘量">Headroom Budget 卡片&lt;/a>。&lt;/p>
&lt;p>&lt;strong>可擴容速度（reactive vs predictive）&lt;/strong>：autoscaler 反應時間 vs 流量上升速度。如果流量上升比 autoscaler 快、必須 &lt;em>提前&lt;/em> pre-scale、不能等 reactive 反應。&lt;/p>
&lt;p>這個公式的另一個寫法是「容量 = peak × 安全係數」、安全係數 = (1 + headroom) / 可擴容速度。預測準 + 擴容快 → 安全係數小、容量緊湊；預測差 + 擴容慢 → 安全係數大、成本高。&lt;/p>
&lt;h2 id="peak-forecast-方法">Peak forecast 方法&lt;/h2>
&lt;p>Forecast 方法分三層、按業務型態選用。&lt;/p>
&lt;p>&lt;strong>歷史線性外推&lt;/strong>：拿過去 N 個月的趨勢、按斜率外推到下 N 個月。適合 sustained growth（B2B SaaS 月增 X%）；不適合 event peak（年度活動）跟 surge（產品爆紅）。&lt;/p>
&lt;p>&lt;strong>季節性分解（STL：Seasonal-Trend decomposition using Loess）&lt;/strong>：把長期趨勢、週期成分、殘差分開預測。適合電商（雙 11 / Black Friday）、串流（IPL / Super Bowl）、零售（聖誕節）。需要 &lt;em>至少兩個完整 cycle&lt;/em> 的歷史資料。&lt;/p>
&lt;p>&lt;strong>業務 ML 模型&lt;/strong>：結合 marketing pipeline（廣告投入）、新用戶獲取（acquisition rate）、留存率、產品變化等多 feature。最精準但成本高、需要 ML team。&lt;/p>
&lt;p>&lt;strong>最常見錯誤是「拿去年同期 × (1 + 預期成長 %)」&lt;/strong>：忽略產品改動 + 行銷投入變化 + 外部事件。Prime Day 2025 vs 2024 不只是 +30% — 是 AI shopping assistant 上線、是 ad spend 變化、是新國家上線。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>容量規劃的責任是把「未來 N 個月可能多大」翻成「現在該訂多少 capacity」。這層工作不純靠歷史外推、要結合業務 forecast、事件型成長、頂部風險 buffer。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 的關係：9.4 提供「當前配置能撐多少」、9.6 用這個數字加上 forecast 推「該規劃多少」。沒有 9.4 的 baseline、9.6 只是猜；沒有 9.6 的 forecast、9.4 的 baseline 只是 snapshot。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸</a> 的關係：9.13 先決定「沿哪條軸擴」（垂直 / 水平 / Y 軸拆服務 / Z 軸 partition），9.6 才能算出「該擴多少」。同樣是「處理 10 倍流量」、選垂直擴展要算單機規格上限、選水平擴展要算協調成本跟連線池放大、選 Y 軸拆服務要算跨服務 latency budget — 三條軸的容量公式參數完全不同。沒先做 9.13、9.6 的數字會落到錯誤的擴展軸上。</p>
<p>本章是「規劃決策」的章節、不是執行手冊。讀完後讀者能回答：peak 怎麼預測、headroom 訂多少、autoscaler 怎麼配、不可水平擴的服務怎麼處理。</p>
<h2 id="容量公式三項">容量公式三項</h2>
<p>容量規劃的核心公式可以濃縮成三項相乘：<code>容量 = 預期峰值 × (1 + headroom) / 可擴容速度</code>。每一項都需要獨立分析：</p>
<p><strong>預期峰值（peak forecast）</strong>：歷史 baseline × 預期成長 × 事件因子。三項中最影響整體準度。詳見 <a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast 卡片</a>。</p>
<p><strong>Headroom budget</strong>：通常 30-50%、為了應付異常 burst + AZ 故障 + forecast 誤差。不同工作負載 headroom 不同。詳見 <a href="/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &#43; AZ 故障 &#43; forecast 誤差的安全餘量">Headroom Budget 卡片</a>。</p>
<p><strong>可擴容速度（reactive vs predictive）</strong>：autoscaler 反應時間 vs 流量上升速度。如果流量上升比 autoscaler 快、必須 <em>提前</em> pre-scale、不能等 reactive 反應。</p>
<p>這個公式的另一個寫法是「容量 = peak × 安全係數」、安全係數 = (1 + headroom) / 可擴容速度。預測準 + 擴容快 → 安全係數小、容量緊湊；預測差 + 擴容慢 → 安全係數大、成本高。</p>
<h2 id="peak-forecast-方法">Peak forecast 方法</h2>
<p>Forecast 方法分三層、按業務型態選用。</p>
<p><strong>歷史線性外推</strong>：拿過去 N 個月的趨勢、按斜率外推到下 N 個月。適合 sustained growth（B2B SaaS 月增 X%）；不適合 event peak（年度活動）跟 surge（產品爆紅）。</p>
<p><strong>季節性分解（STL：Seasonal-Trend decomposition using Loess）</strong>：把長期趨勢、週期成分、殘差分開預測。適合電商（雙 11 / Black Friday）、串流（IPL / Super Bowl）、零售（聖誕節）。需要 <em>至少兩個完整 cycle</em> 的歷史資料。</p>
<p><strong>業務 ML 模型</strong>：結合 marketing pipeline（廣告投入）、新用戶獲取（acquisition rate）、留存率、產品變化等多 feature。最精準但成本高、需要 ML team。</p>
<p><strong>最常見錯誤是「拿去年同期 × (1 + 預期成長 %)」</strong>：忽略產品改動 + 行銷投入變化 + 外部事件。Prime Day 2025 vs 2024 不只是 +30% — 是 AI shopping assistant 上線、是 ad spend 變化、是新國家上線。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day 年增率 +30% ~ +77%</a> — 連 Amazon 自家每年成長都不能線性外推；<a href="/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">Disney+ 新片發布</a> — 事件型 forecast、按過去新片 metric 預估。</p>
<p>Forecast 必須有 <em>誤差範圍</em>、不能單一數字。給上下界（最壞 / 預期 / 最好）、容量規劃才能用 worst-case 訂 baseline。</p>
<h2 id="headroom-budget-設計">Headroom budget 設計</h2>
<p>Headroom 不是 over-provisioning 浪費、是容量規劃的安全邊界。常見比例 30-50%、按 saturation 行為跟工作負載敏感度調整。</p>
<p><strong>為什麼是 30-50% 而不是 10%</strong>：</p>
<ul>
<li>forecast 誤差：預測準度通常 ±20-30%</li>
<li>burst pattern：瞬間 spike 超過 average peak、需要短時間吸收</li>
<li>AZ / region failover：一個 AZ 掛、剩下兩個要承擔全部（多 33% 容量）</li>
<li>系統老化 / drift：軟硬體升級後 saturation 點可能位移</li>
</ul>
<p><strong>不同工作負載不同 headroom</strong>：</p>
<ul>
<li>stateless service：30%（autoscaler 反應快、headroom 可以薄）</li>
<li>DB：50%（不易擴容、要備援足夠空間）</li>
<li>broker / queue：60%（consumer 落後恢復時要瞬間吃下積壓）</li>
<li>consensus DB：80%+（完全不能 reactive 擴）</li>
</ul>
<p><strong>headroom 太低 → 出事</strong>：peak 期間進 cliff、用戶體驗變差。
<strong>headroom 太高 → 浪費錢</strong>：平日成本拉高、CFO 質疑。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech AI 預測</a> — 預測準了可以降 headroom 比例；預測不準必須拉高 headroom 補回安全邊界。</p>
<h2 id="growth-curve-形狀分類">Growth curve 形狀分類</h2>
<p>不同 growth curve 形狀對應不同 forecast 方法跟 review 節奏。</p>
<p><strong>Linear growth</strong>：用戶月增 X%。B2B SaaS 最常見。forecast 線性外推、每季 review、headroom 可以薄（成長可預測）。</p>
<p><strong>Step growth</strong>：每次行銷 / 活動跳一階、之間 plateau。需要 event tier 規劃、每個事件單獨 forecast、headroom 跟 event 強度連動。</p>
<p><strong>Exponential growth</strong>：早期初創、病毒擴散。forecast 容易低估、傳統線性外推會大幅低估；headroom 必須拉到 100%+、不能省。</p>
<p><strong>S-curve growth</strong>：成熟產品、會 saturate。Forecast 初期像 exponential、中期 plateau、晚期 mature。需要識別 inflection point、過了就調 forecast 方法。</p>
<p><strong>Cyclical</strong>：電商季節性。每年 Black Friday / Cyber Monday / Christmas / Chinese New Year 都重複、forecast 用 STL 季節性分解。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">Zoom 30x COVID</a> — step growth、外部衝擊讓 baseline 永久上移；<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">Pokemon GO 50x surge</a> — exponential（早期）+ 之後 S-curve；<a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">ASOS Black Friday</a> — cyclical。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/growth-curve/" data-link-title="Growth Curve" data-link-desc="說明用戶 / 流量隨時間成長的五種典型形狀、影響容量規劃方法">Growth Curve 卡片</a>。</p>
<h2 id="autoscaling-sizing">Autoscaling sizing</h2>
<p>訂好 capacity 之後、要設計 autoscaler 把這個容量 <em>動態使用</em>。</p>
<p><strong>min / max / target metric 三個參數</strong>：</p>
<ul>
<li>min 太低 → cold start 風險（流量上來時還在 boot）</li>
<li>min 太高 → 平日浪費</li>
<li>max 太低 → 限流（peak 時 autoscaler 不能再擴）</li>
<li>max 太高 → 月底炸帳單（autoscaler 不受控、過 peak 不會主動降）</li>
<li>target 太高 → autoscale 啟動太晚、進 knee 才反應</li>
<li>target 太低 → autoscale 太敏感、頻繁 scale up / down 浪費</li>
</ul>
<p><strong>Predictive vs reactive</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/predictive-scaling/" data-link-title="Predictive Scaling" data-link-desc="說明用歷史模式或 ML 模型預測流量、提前擴容的 autoscaler 模式">predictive scaling</a>：根據歷史 pattern 或 ML 模型提前擴</li>
<li>reactive scaling：根據當下指標擴</li>
<li>兩者組合最穩：predictive 處理已知 pattern、reactive 處理 unexpected burst</li>
</ul>
<p><strong>Scheduled vs metric-based</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">scheduled scaling</a>：時段觸發（年度活動、daily peak）</li>
<li>metric-based：根據 utilization / queue depth 觸發</li>
<li>三層組合（scheduled + predictive + reactive）最穩</li>
</ul>
<p><strong>不同層的 autoscaler 各自設計</strong>：</p>
<ul>
<li>EC2 Auto Scaling Group：infrastructure 層</li>
<li>Kubernetes HPA / VPA：pod 層</li>
<li>Karpenter：node 層</li>
<li>DynamoDB auto-scaling：DB capacity 層</li>
<li>CloudFront：CDN 層</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 30 分鐘擴 130 倍</a> — 6 台 → 800 台靠 ASG + AMI prebuild + ELB warmup；<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day predictive</a> — pre-scaling 30-77% 年增率提前算進容量。</p>
<h2 id="不可水平擴容服務的容量規劃">不可水平擴容服務的容量規劃</h2>
<p>部分服務不能用「加機器」解決容量問題。這類服務的容量規劃有獨立邏輯。</p>
<p><strong>典型不可水平擴</strong>：</p>
<ul>
<li>consensus DB（RAFT / Paxos）：節點數量是 consensus 一部分、不能臨時增減</li>
<li>single leader DB（PostgreSQL primary、MySQL master）：寫只有一個 leader</li>
<li>中央 coordinator：必須拆解才可擴</li>
</ul>
<p><strong>容量公式變成</strong>：單機極限 × headroom、沒有 elastic 救援。
<strong>設計重點</strong>：</p>
<ul>
<li>預先 provision 到能撐 peak、不依賴 reactive 擴</li>
<li>垂直擴容（更大 instance）為主、不是橫向</li>
<li>留更高 headroom（80%+）、出事沒有第二招</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase pre-provision</a> — RAFT 限制下完全 pre-provision、不 autoscale；<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">Spanner 節點即容量單位</a> — 雖然全球可擴、但每個 region 內節點數要預先規劃。</p>
<h2 id="跨地理--跨-region-容量規劃">跨地理 / 跨 region 容量規劃</h2>
<p>跨 region 服務不能用 <em>全球總量</em> 平攤、每個 region 獨立規劃。</p>
<p><strong>為什麼不能聚合</strong>：</p>
<ul>
<li>用戶在哪、流量就在哪、不會自動 spread</li>
<li>跨 region 切流量有延遲（DNS TTL、用戶習慣）、不能即時 rebalance</li>
<li>資料駐留合規可能強制各 region 獨立</li>
</ul>
<p><strong>規劃方法</strong>：</p>
<ul>
<li>每個 region 抽各自的 workload model</li>
<li>各自跑 saturation discovery</li>
<li>各自訂 headroom（區域峰值 + 區域 AZ failover）</li>
<li>跨 region failover plan：哪個 region 掛了、流量去哪、目標 region 要留多少 headroom 接</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">Standard Chartered 7 個受監管市場</a> — 跨市場獨立容量規劃；<a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">Genesys 15 region</a> — 15 主 region + 5 衛星 region 各自規劃；<a href="/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &#43; 1.5 億商品、用 GCP Vertex AI Search &#43; BigQuery 提供近即時搜尋與分析">Mercado Libre 18 國</a> — 每國獨立 cycle。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day</a></td>
          <td>可預期峰值的 forecast + pre-scaling</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a></td>
          <td>AI 預測式擴容、縮短反應時間</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a></td>
          <td>30x surge 後 baseline 永久上移</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></td>
          <td>跨市場獨立容量規劃</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a></td>
          <td>不可水平擴的 pre-provision</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> / <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a>（先選軸再算數量、不可水平擴容服務的判讀基底）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a>（容量翻成成本）</li>
<li>下游：<a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a></li>
<li>跨模組：<a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> autoscaler 實作</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast</a></li>
<li><a href="/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &#43; AZ 故障 &#43; forecast 誤差的安全餘量">Headroom Budget</a></li>
<li><a href="/blog/backend/knowledge-cards/growth-curve/" data-link-title="Growth Curve" data-link-desc="說明用戶 / 流量隨時間成長的五種典型形狀、影響容量規劃方法">Growth Curve</a></li>
<li><a href="/blog/backend/knowledge-cards/predictive-scaling/" data-link-title="Predictive Scaling" data-link-desc="說明用歷史模式或 ML 模型預測流量、提前擴容的 autoscaler 模式">Predictive Scaling</a></li>
<li><a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling</a></li>
</ul>
]]></content:encoded></item><item><title>9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/</guid><description>&lt;p>這個案例的核心責任是說明「cache layer 在持續成長服務」的角色 — 不是峰值問題、是延遲 SLA 與成本曲線同時拉緊的長期工程議題。Tinder 的配對引擎需要在每次滑動都查多個快取（用戶 profile、距離、偏好過濾、推薦池），單次互動的延遲就是 UX 本身。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Tinder 在 ElastiCache for Valkey 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/elasticache/customers/">ElastiCache customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>月活用戶&lt;/td>
 &lt;td>約 4700 萬 MAU (2025)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>配對累計&lt;/td>
 &lt;td>超過 10 億次配對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>地理覆蓋&lt;/td>
 &lt;td>190 個國家&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務年數&lt;/td>
 &lt;td>自 2012 年起&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>延遲特性&lt;/td>
 &lt;td>sub-millisecond latency&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>ElastiCache for Redis 7.1 在 r7g.4xlarge 上可達單節點 100 萬 RPS、單 cluster 5 億 RPS（引自 &lt;a href="https://aws.amazon.com/blogs/database/achieve-over-500-million-requests-per-second-per-cluster-with-amazon-elasticache-for-redis-7-1/">AWS Database Blog&lt;/a>）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Tinder 案例值得讀的是「快取在 long-running 服務的角色變化」。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>快取不是 DB 的補救、是主要服務面&lt;/strong>：配對引擎每次互動讀 cache 不讀 DB、cache miss 是 &lt;em>邊緣案例&lt;/em>。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 cache-as-source-of-truth 與 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary&lt;/a> 設計。&lt;/li>
&lt;li>&lt;strong>次毫秒延遲是業務 KPI、不只是技術指標&lt;/strong>：手指滑動之後 250ms 內必須給結果、否則「卡頓」。中間整個 chain（網路、cache、序列化）的 latency budget 必須緊。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 latency budget 反推。&lt;/li>
&lt;li>&lt;strong>長期 sustained growth 的容量曲線是成本曲線&lt;/strong>：47M MAU 沒有明顯峰谷、容量規劃變成「每月線性擴容 X%」的長期決策、不是峰值規劃。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的長期成本工程。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：Tinder 的「configurable matching」業務邏輯複雜、快取資料的 schema 變化頻繁。一個 schema 變更可能讓既有 cache 全部 invalid、引發 cache stampede。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-migration-stampede-rollback/" data-link-title="2.9 Cache Migration 與 Stampede Rollback（實作示範）" data-link-desc="以商品詳情與價格快取示範 cache migration 如何交付 evidence package、release gate 與 incident decision log。">02.6 cache migration stampede rollback&lt;/a>。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>cache layer 容量規劃跟 DB 容量規劃要分開&lt;/strong>：cache 容量受 working set size 影響、DB 容量受 total dataset 影響、兩者擴容邏輯不一樣。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 cache sizing。&lt;/li>
&lt;li>&lt;strong>cache 命中率變化是業務變化的訊號&lt;/strong>：突然命中率掉、可能是新功能影響 access pattern、不一定是 cache 容量問題。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性&lt;/a> 的訊號治理。&lt;/li>
&lt;li>&lt;strong>Valkey vs Redis OSS vs MemoryDB 是不同 trade-off&lt;/strong>：Valkey（社群分支、AWS 主推）、Redis OSS（受授權變化影響）、MemoryDB（持久化）三者選擇影響長期 vendor lock-in。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP Memorystore for Redis / Valkey、Azure Cache for Redis、自建 Redis Cluster + Sentinel 都可以實作對等架構。差異是 vendor 的 patch cadence 與容量擴張流程。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「cache layer 在持續成長服務」的角色 — 不是峰值問題、是延遲 SLA 與成本曲線同時拉緊的長期工程議題。Tinder 的配對引擎需要在每次滑動都查多個快取（用戶 profile、距離、偏好過濾、推薦池），單次互動的延遲就是 UX 本身。</p>
<h2 id="觀察">觀察</h2>
<p>Tinder 在 ElastiCache for Valkey 的關鍵數字（引自 <a href="https://aws.amazon.com/elasticache/customers/">ElastiCache customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>月活用戶</td>
          <td>約 4700 萬 MAU (2025)</td>
      </tr>
      <tr>
          <td>配對累計</td>
          <td>超過 10 億次配對</td>
      </tr>
      <tr>
          <td>地理覆蓋</td>
          <td>190 個國家</td>
      </tr>
      <tr>
          <td>服務年數</td>
          <td>自 2012 年起</td>
      </tr>
      <tr>
          <td>延遲特性</td>
          <td>sub-millisecond latency</td>
      </tr>
  </tbody>
</table>
<p>ElastiCache for Redis 7.1 在 r7g.4xlarge 上可達單節點 100 萬 RPS、單 cluster 5 億 RPS（引自 <a href="https://aws.amazon.com/blogs/database/achieve-over-500-million-requests-per-second-per-cluster-with-amazon-elasticache-for-redis-7-1/">AWS Database Blog</a>）。</p>
<h2 id="判讀">判讀</h2>
<p>Tinder 案例值得讀的是「快取在 long-running 服務的角色變化」。</p>
<ol>
<li><strong>快取不是 DB 的補救、是主要服務面</strong>：配對引擎每次互動讀 cache 不讀 DB、cache miss 是 <em>邊緣案例</em>。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 cache-as-source-of-truth 與 <a href="/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary</a> 設計。</li>
<li><strong>次毫秒延遲是業務 KPI、不只是技術指標</strong>：手指滑動之後 250ms 內必須給結果、否則「卡頓」。中間整個 chain（網路、cache、序列化）的 latency budget 必須緊。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 latency budget 反推。</li>
<li><strong>長期 sustained growth 的容量曲線是成本曲線</strong>：47M MAU 沒有明顯峰谷、容量規劃變成「每月線性擴容 X%」的長期決策、不是峰值規劃。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的長期成本工程。</li>
</ol>
<p>需要警惕：Tinder 的「configurable matching」業務邏輯複雜、快取資料的 schema 變化頻繁。一個 schema 變更可能讓既有 cache 全部 invalid、引發 cache stampede。對應 <a href="/blog/backend/02-cache-redis/cache-migration-stampede-rollback/" data-link-title="2.9 Cache Migration 與 Stampede Rollback（實作示範）" data-link-desc="以商品詳情與價格快取示範 cache migration 如何交付 evidence package、release gate 與 incident decision log。">02.6 cache migration stampede rollback</a>。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>cache layer 容量規劃跟 DB 容量規劃要分開</strong>：cache 容量受 working set size 影響、DB 容量受 total dataset 影響、兩者擴容邏輯不一樣。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 cache sizing。</li>
<li><strong>cache 命中率變化是業務變化的訊號</strong>：突然命中率掉、可能是新功能影響 access pattern、不一定是 cache 容量問題。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.8 效能可觀測性</a> 的訊號治理。</li>
<li><strong>Valkey vs Redis OSS vs MemoryDB 是不同 trade-off</strong>：Valkey（社群分支、AWS 主推）、Redis OSS（受授權變化影響）、MemoryDB（持久化）三者選擇影響長期 vendor lock-in。</li>
</ol>
<p>跨平台等效：GCP Memorystore for Redis / Valkey、Azure Cache for Redis、自建 Redis Cluster + Sentinel 都可以實作對等架構。差異是 vendor 的 patch cadence 與容量擴張流程。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計 cache layer 容量 → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a></li>
<li>想做 latency budget 反推 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為</a></li>
<li>想理解 cache stampede 風險 → <a href="/blog/backend/02-cache-redis/cache-migration-stampede-rollback/" data-link-title="2.9 Cache Migration 與 Stampede Rollback（實作示範）" data-link-desc="以商品詳情與價格快取示範 cache migration 如何交付 evidence package、release gate 與 incident decision log。">02.6 cache migration stampede rollback</a></li>
<li>對照其他 cache 案例 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB</a>（KV 高吞吐）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/elasticache/customers/">Amazon ElastiCache Customers</a></li>
<li><a href="https://aws.amazon.com/blogs/database/achieve-over-500-million-requests-per-second-per-cluster-with-amazon-elasticache-for-redis-7-1/">Achieve over 500 million requests per second per cluster with ElastiCache for Redis 7.1</a></li>
<li><a href="https://aws.amazon.com/blogs/database/optimize-redis-client-performance-for-amazon-elasticache/">Optimize Redis Client Performance for ElastiCache and MemoryDB</a></li>
</ul>
]]></content:encoded></item><item><title>9.7 成本邊界與 efficiency</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>成本工程的責任是讓容量決策有經濟邊界。沒有成本意識時、容量規劃會「保險起見全部擴」、最終帳單炸裂；有成本意識之後、能 &lt;em>在每一個容量決策點&lt;/em> 把「多保險」跟「多省錢」一起評估。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型&lt;/a> 的關係：9.6 算「該訂多少容量」、9.7 算「這樣訂值不值得」。兩者必須一起做、不能先決定容量再算成本。&lt;/p>
&lt;p>本章從 cost per request 這個 unit economics 開始、推到 cost curve、TCO、降級成本、人力成本工程化、FinOps 整合。讀完後讀者能回答「容量設計的成本邊界在哪、什麼時候該降級而非擴容」。&lt;/p>
&lt;h2 id="cost-per-request-模型">Cost per request 模型&lt;/h2>
&lt;p>雲端帳單從月度視角看是黑箱、從 cost per request 視角看可拆解。&lt;/p>
&lt;p>&lt;strong>基本公式&lt;/strong>：月帳單總額 / 月總 RPS = cost per request。但這只是平均、不同 endpoint 成本差很大。
&lt;strong>分 stage 拆解&lt;/strong>：app compute + DB read + DB write + cache + network egress + 第三方 API。每個 stage 自己有 unit cost。
&lt;strong>分 endpoint 拆解&lt;/strong>：登入請求可能 $0.0001、結帳請求可能 $0.001（10x 差距）。原因：結帳走更多 stage、可能跨 region、可能呼叫第三方支付。&lt;/p>
&lt;p>&lt;strong>對齊業務 metric&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>cost per active user：總成本 / MAU&lt;/li>
&lt;li>cost per transaction：總成本 / 完成的訂單數&lt;/li>
&lt;li>cost per ML inference：總成本 / inference 次數&lt;/li>
&lt;/ul>
&lt;p>業務 metric 級別的 cost 才能跟收入對比、才能算 unit economics。&lt;/p>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">Zomato 50% 成本下降&lt;/a> — 算出每筆計費事件的 cost per request 後、發現 TiDB over-provision 拖累、遷移 DynamoDB 後減半；&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix Aurora 28% 成本降&lt;/a> — DB consolidation 把多套 DB 的 cost 統一到 Aurora、Aurora 自己的 cost per request 更便宜。&lt;/p>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request 卡片&lt;/a>。&lt;/p>
&lt;h2 id="cost-curve-形狀">Cost curve 形狀&lt;/h2>
&lt;p>不同 pricing 模式的 cost curve 形狀不同、組合起來才能最佳化。&lt;/p>
&lt;p>&lt;strong>On-demand（pay-per-use）&lt;/strong>：流量上升、成本同步上升。線性 cost curve。優點：彈性、不用承諾；缺點：單位成本最貴。
&lt;strong>Reserved instances（RI）/ Savings Plans&lt;/strong>：承諾 1-3 年用量、單位成本降 30-60%。階梯 cost curve。優點：便宜；缺點：承諾期內如果用量低、浪費。
&lt;strong>Spot instances&lt;/strong>：用 cloud 閒置 capacity、單位成本降 70-90%。可被中斷。優點：最便宜；缺點：可能突然被收回。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>成本工程的責任是讓容量決策有經濟邊界。沒有成本意識時、容量規劃會「保險起見全部擴」、最終帳單炸裂；有成本意識之後、能 <em>在每一個容量決策點</em> 把「多保險」跟「多省錢」一起評估。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 的關係：9.6 算「該訂多少容量」、9.7 算「這樣訂值不值得」。兩者必須一起做、不能先決定容量再算成本。</p>
<p>本章從 cost per request 這個 unit economics 開始、推到 cost curve、TCO、降級成本、人力成本工程化、FinOps 整合。讀完後讀者能回答「容量設計的成本邊界在哪、什麼時候該降級而非擴容」。</p>
<h2 id="cost-per-request-模型">Cost per request 模型</h2>
<p>雲端帳單從月度視角看是黑箱、從 cost per request 視角看可拆解。</p>
<p><strong>基本公式</strong>：月帳單總額 / 月總 RPS = cost per request。但這只是平均、不同 endpoint 成本差很大。
<strong>分 stage 拆解</strong>：app compute + DB read + DB write + cache + network egress + 第三方 API。每個 stage 自己有 unit cost。
<strong>分 endpoint 拆解</strong>：登入請求可能 $0.0001、結帳請求可能 $0.001（10x 差距）。原因：結帳走更多 stage、可能跨 region、可能呼叫第三方支付。</p>
<p><strong>對齊業務 metric</strong>：</p>
<ul>
<li>cost per active user：總成本 / MAU</li>
<li>cost per transaction：總成本 / 完成的訂單數</li>
<li>cost per ML inference：總成本 / inference 次數</li>
</ul>
<p>業務 metric 級別的 cost 才能跟收入對比、才能算 unit economics。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">Zomato 50% 成本下降</a> — 算出每筆計費事件的 cost per request 後、發現 TiDB over-provision 拖累、遷移 DynamoDB 後減半；<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix Aurora 28% 成本降</a> — DB consolidation 把多套 DB 的 cost 統一到 Aurora、Aurora 自己的 cost per request 更便宜。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request 卡片</a>。</p>
<h2 id="cost-curve-形狀">Cost curve 形狀</h2>
<p>不同 pricing 模式的 cost curve 形狀不同、組合起來才能最佳化。</p>
<p><strong>On-demand（pay-per-use）</strong>：流量上升、成本同步上升。線性 cost curve。優點：彈性、不用承諾；缺點：單位成本最貴。
<strong>Reserved instances（RI）/ Savings Plans</strong>：承諾 1-3 年用量、單位成本降 30-60%。階梯 cost curve。優點：便宜；缺點：承諾期內如果用量低、浪費。
<strong>Spot instances</strong>：用 cloud 閒置 capacity、單位成本降 70-90%。可被中斷。優點：最便宜；缺點：可能突然被收回。</p>
<p><strong>最佳組合通常是「Reserved baseline + On-demand spike + Spot batch」</strong>：</p>
<ul>
<li>Reserved 覆蓋 baseline 容量（永遠用得到）</li>
<li>On-demand 處理 peak 跟 unpredicted burst</li>
<li>Spot 跑 batch 工作（不在 critical path、可被中斷）</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">Riot Games 年省 1000 萬</a> — 從自管 Mesos 遷到 EKS、降的不只是 instance cost、是 cluster 管理人力 + ops 簡化；<a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">Capcom 30% 成本下降</a> — DynamoDB + EKS 取代自管、釋放 DBA 人力。</p>
<h2 id="over-provisioning-vs-under-provisioning-取捨">Over-provisioning vs under-provisioning 取捨</h2>
<p>容量決策的核心經濟學問題：訂多大容量才是最划算？</p>
<p><strong>Over-provisioning 成本</strong>：每月多付 $X 雲端費。這個數字直接看帳單。
<strong>Under-provisioning 成本</strong>：sigma 機率 × downtime × revenue per minute。這個數字更難算 — 需要 historical incident rate + downtime impact analysis。</p>
<p><strong>兩個成本平衡點 = 經濟最佳 headroom</strong>。但實務上 under-provisioning 成本不容易量化、保守做法是把 sigma 機率拉高（用 worst-case 估）、headroom 訂寬一點。</p>
<p><strong>Critical workload</strong>（金融、醫療、付款）：under-provisioning 成本極高（合約違約 + 客戶流失 + 法規）、寧可 over-provisioning 30-50%。
<strong>Non-critical workload</strong>（內部工具、分析、batch）：under-provisioning 成本低、可以更貼近 minimum capacity。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">Zomato TiDB 必須 over-provision</a> — 為了應付 spike、TiDB 必須長期 over-provision；DynamoDB on-demand 不必、pay-per-use 自然處理。</p>
<h2 id="降級的成本邊界">降級的成本邊界</h2>
<p>「降級 vs 擴容」是常見容量決策、但常被當成「技術問題」而非「成本問題」。</p>
<p><strong>降級不是免費</strong>：</p>
<ul>
<li>流失轉換：UI 顯示「系統忙碌」、用戶可能放棄</li>
<li>客訴成本：客服處理客訴的 OpEx</li>
<li>品牌損失：社群媒體負面評論、口碑下降</li>
<li>合約違約：B2B 客戶可能基於 SLA 求償</li>
</ul>
<p><strong>算「降級 vs 擴容」哪個成本低</strong>：</p>
<ul>
<li>擴容成本：peak 時段多付的 cloud 費用</li>
<li>降級成本：上述四項合計</li>
<li>哪邊低就選哪邊</li>
</ul>
<p><strong>降級觸發條件</strong>通常按負載門檻 / 成本門檻 / SLA 觸發：</p>
<ul>
<li>負載門檻：utilization &gt; 85% → 啟動降級</li>
<li>成本門檻：本月雲端費已超預算 X% → 啟動降級</li>
<li>SLA 觸發：<a href="/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">error budget</a> 快用完 → 啟動降級保 SLA</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">Pokemon GO 50x surge</a> — surge 期間無法等比擴容、必須降級保住核心遊戲機制、犧牲附加功能。</p>
<h2 id="人力成本工程化">人力成本工程化</h2>
<p>雲端帳單是顯性成本、但 <em>人力成本</em> 是常被忽略的隱性容量成本。</p>
<p><strong>自建 vs managed 的人力成本對比</strong>：</p>
<ul>
<li>自建 Kafka / PostgreSQL / Redis：需要 DBA / SRE 持續維護 + 升級 + 故障處理</li>
<li>Managed 服務（MSK、Aurora、ElastiCache）：vendor 負責 patch、backup、failover</li>
<li>差距通常 <em>3-10 倍</em> 人力成本</li>
</ul>
<p><strong>DBA / SRE / network engineer 都是隱性容量成本</strong>：</p>
<ul>
<li>一個資深 DBA 在美國年薪 $200K+、台灣 NTD 200-400 萬</li>
<li>工程師時間是有上限的、自管系統佔的時間就是 <em>無法投入產品開發</em> 的機會成本</li>
</ul>
<p><strong>「90% 工程工時下降」是管理 ROI 的關鍵</strong>：重點是把工程資源從 <em>維持</em> 轉移到 <em>建構</em>、不是拿來吹噓技術。這條自建 vs managed 的人力成本對比、是 <a href="/blog/backend/00-service-selection/capability-buy-vs-build/" data-link-title="0.22 能力級買 vs 建：feature-as-a-service 與 BaaS bundle 選型" data-link-desc="在交付形態決定整個系統要不要自建之後、逐能力判斷該外包還是自建：辨識 managed 基礎設施、feature SaaS 與 BaaS bundle 三種外包深度、no-code 到 dev-tool 的服務光譜、買 vs 建判準與權重浮動、整合接縫與遷出代價">0.22 能力級買 vs 建</a> 裡「計費隨規模成長、自建 TCO 出現交叉點」那條 tripwire 的算法側 — 選型方向在 0.22 判、成本量化在這裡做。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">Spotify Kafka → Pub/Sub</a> — 不是因為 Pub/Sub 便宜、是因為 Spotify 規模下自管 Kafka 的人力成本不划算；<a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">Lemino 90% 工程工時降</a> — managed 路線讓電信商級新串流服務只用 5-10 個工程師 launch；<a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">Capcom DBA 釋放</a> — 把 DBA 時間從 patching 轉到遊戲品質。</p>
<h2 id="finops-跟容量規劃的整合">FinOps 跟容量規劃的整合</h2>
<p>FinOps 是 <em>財務跟工程的協作框架</em>、把成本決策從事後對帳變成事前規劃。</p>
<p><strong>Showback / chargeback</strong>：把雲端成本攤到團隊 / 服務 / feature。每個團隊看得到自己的成本、自然開始 optimize。chargeback（實際扣預算）比 showback（純展示）更有效但組織複雜度高。</p>
<p><strong>每月 cost review 變成容量 review 的一部分</strong>：</p>
<ul>
<li>對比預算 vs 實際</li>
<li>找出 top 5 cost driver</li>
<li>對比上月趨勢、看是否有 anomaly</li>
<li>跟 capacity team 一起討論 right-sizing</li>
</ul>
<p><strong>Spot diversification</strong>：spot 中斷風險可以靠 <em>多 instance type 跟多 AZ</em> 分散。例如：spot pool 同時包含 m5.large + m5a.large + m5n.large、各 AZ 都有、單一 type pool 撤回時其他 type 還在。</p>
<p><strong>Right-sizing</strong>：定期 review instance type 是否最適。常見浪費：訂太大 instance（CPU / RAM 用 30%）、過時 instance generation（用 c5 沒升到 c7）、reserved 過剩。</p>
<h2 id="反模式">反模式</h2>
<p>容量成本的常見錯誤模式：</p>
<p><strong>Autoscaling max 設無限大</strong>：流量爆衝時 autoscaler 跟著爆衝、月底帳單炸裂。max 必須訂、是 financial circuit breaker。</p>
<p><strong>全部用 on-demand、沒談 reserved / savings plan</strong>：cloud spending &gt; $10K/月 已經值得跟雲商 talk discount、savings plan 通常 30-60% off。</p>
<p><strong>沒成本 monitoring、直到帳單來才知道</strong>：要建 daily cost dashboard、anomaly 即時 alert、不要等月帳單。</p>
<p><strong>降級用人工觸發、出事時來不及</strong>：降級邏輯要 <em>自動化</em>、按 metric 觸發、不是 oncall 工程師看到 dashboard 才下指令。</p>
<p><strong>忘了人力成本</strong>：算 build vs buy 只算 cloud 費、忘了 SRE / DBA 時間、結果發現「省的 cloud 費 &lt; 多花的人力」。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a></td>
          <td>50% 成本下降（從 over-provision 解放）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a></td>
          <td>年省 1000 萬（EKS 替代 Mesos）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></td>
          <td>28% 成本下降（DB consolidation）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a></td>
          <td>90% 工程工時降（managed 路線）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a></td>
          <td>30% 成本下降（DBA 釋放到遊戲品質）</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a>（cost attribution）</li>
<li>跨模組：<a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04.14 cost attribution</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request</a></li>
<li><a href="/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &#43; AZ 故障 &#43; forecast 誤差的安全餘量">Headroom Budget</a></li>
</ul>
]]></content:encoded></item><item><title>9.C7 Lyft：100+ 微服務在 8 倍峰值下的 Auto Scaling</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/</guid><description>&lt;p>這個案例的核心責任是說明「微服務架構在事件型峰值下的容量治理」。共乘服務的負載形狀獨特 — 平日早晚通勤雙峰、週末晚間爆量、特殊事件（演唱會、球賽結束、機場）瞬間爆量、每個城市跟每個時段都不同。100+ 個微服務各自有不同的峰值時段、需要獨立擴容策略。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Lyft 在 AWS 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/lyft/">Lyft case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>峰值倍數&lt;/td>
 &lt;td>8x 平日基線&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>微服務數&lt;/td>
 &lt;td>100+ 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>月均搭乘&lt;/td>
 &lt;td>1400 萬 / 月&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務城市&lt;/td>
 &lt;td>200+&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Amazon DynamoDB（搭乘追蹤、GPS 座標）、Amazon Redshift（客戶洞察）、Amazon Kinesis（即時事件串流）、AWS Auto Scaling、Amazon EC2 Container Registry。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Lyft 的工程做法揭露三個微服務容量治理重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>微服務不是「全部 8x」、是「特定服務 8x」&lt;/strong>：8x 是 &lt;em>某些核心服務&lt;/em> 在週末爆量時刻的擴容比、不是 100 個服務全部 8x。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 必須先做「哪個服務是熱點」的層次定位。&lt;/li>
&lt;li>&lt;strong>微服務粒度 = 擴容粒度&lt;/strong>：把 ride matching、payment、driver tracking、notification 切成獨立服務、每個服務的 autoscaling policy 可以獨立設計。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的服務邊界。&lt;/li>
&lt;li>&lt;strong>GPS 座標寫入 DynamoDB 是高頻 sustained workload&lt;/strong>：每個 driver 每秒寫 1-2 次位置、200+ 城市 × 每個城市數萬司機 = 巨量持續寫入、跟峰值無關。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 的 KV 高吞吐設計同類。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「8x 峰值」是 &lt;em>峰值倍數&lt;/em>、不是 &lt;em>尖峰持續時間&lt;/em>。週末晚間的尖峰可能持續 3-4 小時、機場特殊事件可能持續 30 分鐘、演唱會結束可能只有 10 分鐘瞬間。容量策略要按持續時間區分。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>微服務粒度切到「同性質擴容單位」&lt;/strong>：同步 vs async、stateful vs stateless、CPU-bound vs I/O-bound 不該混在同一服務、否則擴容邏輯互相衝突。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 service decomposition。&lt;/li>
&lt;li>&lt;strong>預測式 + 反應式擴容混用&lt;/strong>：可預測（早晚通勤）用 scheduled scaling、不可預測（演唱會散場）用 reactive autoscaling、兩者組合。&lt;/li>
&lt;li>&lt;strong>GPS 類持續寫入適合 KV / time-series store&lt;/strong>：不適合放 OLTP DB、會佔用 transaction 資源。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 storage choice。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP GKE + HPA / VPA / Karpenter、Azure AKS + KEDA、自建 Kubernetes + Cluster Autoscaler 都可以實作對等架構。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>想做微服務容量治理 → &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a>&lt;/li>
&lt;li>想規劃事件型峰值 → &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &amp;#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech&lt;/a>&lt;/li>
&lt;li>想設計高頻 sustained workload → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://aws.amazon.com/solutions/case-studies/lyft/">Lyft Case Study&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「微服務架構在事件型峰值下的容量治理」。共乘服務的負載形狀獨特 — 平日早晚通勤雙峰、週末晚間爆量、特殊事件（演唱會、球賽結束、機場）瞬間爆量、每個城市跟每個時段都不同。100+ 個微服務各自有不同的峰值時段、需要獨立擴容策略。</p>
<h2 id="觀察">觀察</h2>
<p>Lyft 在 AWS 的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/lyft/">Lyft case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>峰值倍數</td>
          <td>8x 平日基線</td>
      </tr>
      <tr>
          <td>微服務數</td>
          <td>100+ 個</td>
      </tr>
      <tr>
          <td>月均搭乘</td>
          <td>1400 萬 / 月</td>
      </tr>
      <tr>
          <td>服務城市</td>
          <td>200+</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Amazon DynamoDB（搭乘追蹤、GPS 座標）、Amazon Redshift（客戶洞察）、Amazon Kinesis（即時事件串流）、AWS Auto Scaling、Amazon EC2 Container Registry。</p>
<h2 id="判讀">判讀</h2>
<p>Lyft 的工程做法揭露三個微服務容量治理重點。</p>
<ol>
<li><strong>微服務不是「全部 8x」、是「特定服務 8x」</strong>：8x 是 <em>某些核心服務</em> 在週末爆量時刻的擴容比、不是 100 個服務全部 8x。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 必須先做「哪個服務是熱點」的層次定位。</li>
<li><strong>微服務粒度 = 擴容粒度</strong>：把 ride matching、payment、driver tracking、notification 切成獨立服務、每個服務的 autoscaling policy 可以獨立設計。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 跟 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的服務邊界。</li>
<li><strong>GPS 座標寫入 DynamoDB 是高頻 sustained workload</strong>：每個 driver 每秒寫 1-2 次位置、200+ 城市 × 每個城市數萬司機 = 巨量持續寫入、跟峰值無關。對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 的 KV 高吞吐設計同類。</li>
</ol>
<p>需要警惕：「8x 峰值」是 <em>峰值倍數</em>、不是 <em>尖峰持續時間</em>。週末晚間的尖峰可能持續 3-4 小時、機場特殊事件可能持續 30 分鐘、演唱會結束可能只有 10 分鐘瞬間。容量策略要按持續時間區分。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>微服務粒度切到「同性質擴容單位」</strong>：同步 vs async、stateful vs stateless、CPU-bound vs I/O-bound 不該混在同一服務、否則擴容邏輯互相衝突。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 service decomposition。</li>
<li><strong>預測式 + 反應式擴容混用</strong>：可預測（早晚通勤）用 scheduled scaling、不可預測（演唱會散場）用 reactive autoscaling、兩者組合。</li>
<li><strong>GPS 類持續寫入適合 KV / time-series store</strong>：不適合放 OLTP DB、會佔用 transaction 資源。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 storage choice。</li>
</ol>
<p>跨平台等效：GCP GKE + HPA / VPA / Karpenter、Azure AKS + KEDA、自建 Kubernetes + Cluster Autoscaler 都可以實作對等架構。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想做微服務容量治理 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想規劃事件型峰值 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a></li>
<li>想設計高頻 sustained workload → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/lyft/">Lyft Case Study</a></li>
<li><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers</a></li>
</ul>
]]></content:encoded></item><item><title>9.8 效能可觀測性</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-observability/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-observability/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>效能可觀測性的責任是讓容量決策有訊號基礎。沒有適當訊號時、就算有壓測結果跟容量計畫、也看不到「現在實際距離 saturation 多遠」、無法做即時調整。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a> 的關係：9.4 找到 saturation 點、9.8 定義持續監控這個點的訊號跟 dashboard。跟 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組&lt;/a> 是 sibling — 04 處理通用觀測、9.8 處理 &lt;em>容量規劃用&lt;/em> 的觀測。&lt;/p>
&lt;p>本章不重複 04 的訊號治理基礎、聚焦在 &lt;em>容量 / 效能 / 成本三條觀測線怎麼整合&lt;/em>。讀完後讀者能設計一個「容量 dashboard」、回答「現在距離 saturation 還有多遠、什麼時候該擴」。&lt;/p>
&lt;h2 id="use-method-在-production-持續監控">USE method 在 production 持續監控&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE method&lt;/a> 不只是壓測時用、production 也要持續監控。&lt;/p>
&lt;p>對每個資源（CPU / RAM / disk / network / DB connection / cache pool / file descriptor）量三個維度：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Utilization&lt;/strong>（使用率 0-100%）：直觀但會誤判&lt;/li>
&lt;li>&lt;strong>Saturation&lt;/strong>（queue depth）：早期警訊&lt;/li>
&lt;li>&lt;strong>Errors&lt;/strong>（資源層錯誤）：已經出事的訊號&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>為什麼不能只看 utilization&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>CPU 100% 但 run queue 空 → 還能撐（單純 CPU bound）&lt;/li>
&lt;li>CPU 80% 但 run queue 不斷增長 → 已 saturate（saturation 比 utilization 領先）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Saturation metric 是 capacity warning 的最早訊號&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>queue depth（每個 queue / pool）&lt;/li>
&lt;li>connection pool 使用率（最常見隱性 bottleneck）&lt;/li>
&lt;li>thread pool / coroutine count&lt;/li>
&lt;li>event loop lag（Node.js、async runtime）&lt;/li>
&lt;li>GC pause time / frequency&lt;/li>
&lt;li>cache hit rate / eviction rate&lt;/li>
&lt;li>replication lag&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Dashboard 設計&lt;/strong>：每個關鍵資源獨立 panel、同時顯示 utilization 跟 saturation。alert 在 &lt;em>saturation 起飛&lt;/em> 時觸發、不是 utilization 滿。&lt;/p>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &amp;#43; AWS Media Services 撐 30 channels live &amp;#43; 5M MAU、工程工時下降 90%">Lemino connection limit&lt;/a> — connection saturation 是 RDB 的真正 bottleneck、不是 CPU；&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">Zomato latency 降 90%&lt;/a> — 從 TiDB 換到 DynamoDB、saturation 行為完全不同、observability 也要跟著改。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>效能可觀測性的責任是讓容量決策有訊號基礎。沒有適當訊號時、就算有壓測結果跟容量計畫、也看不到「現在實際距離 saturation 多遠」、無法做即時調整。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 的關係：9.4 找到 saturation 點、9.8 定義持續監控這個點的訊號跟 dashboard。跟 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 是 sibling — 04 處理通用觀測、9.8 處理 <em>容量規劃用</em> 的觀測。</p>
<p>本章不重複 04 的訊號治理基礎、聚焦在 <em>容量 / 效能 / 成本三條觀測線怎麼整合</em>。讀完後讀者能設計一個「容量 dashboard」、回答「現在距離 saturation 還有多遠、什麼時候該擴」。</p>
<h2 id="use-method-在-production-持續監控">USE method 在 production 持續監控</h2>
<p><a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE method</a> 不只是壓測時用、production 也要持續監控。</p>
<p>對每個資源（CPU / RAM / disk / network / DB connection / cache pool / file descriptor）量三個維度：</p>
<ul>
<li><strong>Utilization</strong>（使用率 0-100%）：直觀但會誤判</li>
<li><strong>Saturation</strong>（queue depth）：早期警訊</li>
<li><strong>Errors</strong>（資源層錯誤）：已經出事的訊號</li>
</ul>
<p><strong>為什麼不能只看 utilization</strong>：</p>
<ul>
<li>CPU 100% 但 run queue 空 → 還能撐（單純 CPU bound）</li>
<li>CPU 80% 但 run queue 不斷增長 → 已 saturate（saturation 比 utilization 領先）</li>
</ul>
<p><strong>Saturation metric 是 capacity warning 的最早訊號</strong>：</p>
<ul>
<li>queue depth（每個 queue / pool）</li>
<li>connection pool 使用率（最常見隱性 bottleneck）</li>
<li>thread pool / coroutine count</li>
<li>event loop lag（Node.js、async runtime）</li>
<li>GC pause time / frequency</li>
<li>cache hit rate / eviction rate</li>
<li>replication lag</li>
</ul>
<p><strong>Dashboard 設計</strong>：每個關鍵資源獨立 panel、同時顯示 utilization 跟 saturation。alert 在 <em>saturation 起飛</em> 時觸發、不是 utilization 滿。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">Lemino connection limit</a> — connection saturation 是 RDB 的真正 bottleneck、不是 CPU；<a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">Zomato latency 降 90%</a> — 從 TiDB 換到 DynamoDB、saturation 行為完全不同、observability 也要跟著改。</p>
<h2 id="red-method請求層的容量訊號">RED method：請求層的容量訊號</h2>
<p><a href="/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED method</a> 跟 USE 互補、從請求層看容量。</p>
<ul>
<li><strong>Rate</strong>：requests per second（每個 service / endpoint）</li>
<li><strong>Errors</strong>：error rate</li>
<li><strong>Duration</strong>：latency distribution（histogram、不是單一 percentile）</li>
</ul>
<p><strong>Duration 比 Errors 早</strong>：duration p99 飆通常先於 error rate 上升、是 saturation 的早期警訊。</p>
<p><strong>每個 endpoint 都要有 RED</strong>：不能只看全站 average、要分 endpoint。登入 endpoint 跟結帳 endpoint 的 saturation 行為不同、混在一起看不到 issue。</p>
<p><strong>Histogram 是必須、不是 nice-to-have</strong>：</p>
<ul>
<li>只記 p99 → 看不到 p999、看不到 distribution shape</li>
<li>記 histogram → 可以隨時算任何 percentile、可以做 long-tail 分析</li>
<li>Prometheus histogram、OpenMetrics histogram 是現代標準</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech 25ms p95</a> — p95 是業務 KPI、不是技術指標、每個 endpoint 都有獨立 SLO。</p>
<h2 id="p50--p95--p99--p999-的取捨">p50 / p95 / p99 / p999 的取捨</h2>
<p>不同 percentile 反映不同問題、選錯 percentile 會錯失 issue。</p>
<ul>
<li><strong>p50（中位數）</strong>：整體狀況、感覺正常的指標、對長尾不敏感</li>
<li><strong>p95</strong>：日常 user-perceived experience、大多數用戶感受到的延遲</li>
<li><strong>p99</strong>：minority but critical 用戶體驗、SLO 常訂在這</li>
<li><strong>p999</strong>：極端長尾、受 GC pause / leader election / retry storm 影響、internal critical 系統訂在這</li>
</ul>
<p><strong>業務 SLO 通常訂 p99</strong>：「99% 用戶 request &lt; 500ms」是常見承諾、合約 SLA 也通常基於 p99。
<strong>Internal critical 系統訂 p99.9</strong>：金融交易、即時配對、客服 SaaS（5 個 9 可用性對應 5 個 9 latency 期待）。</p>
<p><strong>紀錄分布、不只紀錄 percentile</strong>：</p>
<ul>
<li>gauge p99 → 看不到 distribution shape、看不到 multimodal 分布</li>
<li>histogram → 可以重新計算任何 percentile、可以對比 distribution、可以找 anomaly</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">Tubi p99 &lt; 10ms</a> — ML inference 在 p99 才能控制用戶體驗、p50 沒意義；<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase sub-ms</a> — 必須關注 p999、RAFT 系統長尾顯著。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency 卡片</a>。</p>
<h2 id="cost-dashboard">Cost dashboard</h2>
<p>成本訊號跟容量訊號要 <em>並列顯示</em>、不要分開看。</p>
<p><strong>Per-service / per-endpoint cost attribution</strong>：</p>
<ul>
<li>每個 service 自己的雲端成本</li>
<li>拆到每個 endpoint</li>
<li>跟 RPS / latency 並列、看「成本上升是因為流量還是低效」</li>
</ul>
<p><strong>Cost per request 的時序變化</strong>：</p>
<ul>
<li>突然上升通常是 <em>退化</em> 訊號（新版本沒效率）</li>
<li>緩慢上升通常是 <em>規模</em> 訊號（用戶增加但 efficiency 沒變）</li>
</ul>
<p><strong>成本異常告警（vs 容量異常告警）</strong>：</p>
<ul>
<li>容量告警：utilization &gt; X% → 擴容</li>
<li>成本告警：cost spike &gt; X% → review</li>
<li>兩者可能同時觸發（autoscaler 擴容也擴 cost）、要區分</li>
</ul>
<p><strong>跟業務 metric 對齊</strong>：cost per active user、cost per transaction、cost per ML inference。業務 metric 級別的 cost 才能 review unit economics。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">Lyft 100+ 微服務各自 cost</a> — 微服務粒度的 cost attribution、找出哪個 service 過貴；對應 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04.14 cost attribution</a>。</p>
<h2 id="continuous-profiling">Continuous profiling</h2>
<p><a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous profiling</a> 是現代效能 observability 的關鍵環節 — production 持續取 profile（CPU / heap / lock）、隨時可以做 diff 跟 root cause。</p>
<p><strong>工具生態</strong>：</p>
<ul>
<li>Datadog Continuous Profiler、Pyroscope（開源 + Grafana 整合）、Parca（CNCF）</li>
<li>GCP Cloud Profiler、Azure Application Insights Profiler、AWS CodeGuru Profiler</li>
<li>Overhead 通常 &lt; 1% CPU、放心開在 production</li>
</ul>
<p><strong>跟 distributed tracing 整合</strong>：trace → span → profile。一個 slow request 點下去、能看到對應 span、再下去看 profile。</p>
<p><strong>Profile diff 是 release gate 的核心訊號</strong>：每次 deploy 後自動對比 baseline、退化幅度過門檻 trigger alert。詳見 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a> 跟 <a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">Profile Diff 卡片</a>。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix 多 DB 統一後 profile 變單純</a> — DB 統一 → application 層 profile 噪音降低 → 退化定位更快。</p>
<h2 id="cardinality-cost-governance">Cardinality cost governance</h2>
<p>效能 observability 的成本經常爆炸、源頭通常是 high cardinality metric。</p>
<p><strong>高 cardinality 來源</strong>：</p>
<ul>
<li>per-user metric（user_id label）</li>
<li>per-request metric（request_id label）</li>
<li>per-trace metric（trace_id label）</li>
</ul>
<p><strong>為什麼會爆</strong>：Prometheus 等 metric system 為每個 label 組合存獨立 time series、cardinality = 所有 label value 的笛卡爾積。100 萬 user × 100 endpoint × 10 region = 10 億 time series、儲存爆炸。</p>
<p><strong>對策</strong>：</p>
<ul>
<li>high cardinality 資訊放 log / trace、不放 metric</li>
<li>metric label 限制在 low-cardinality 維度（service、endpoint、region、status）</li>
<li>真的需要 high-cardinality 分析、用 sampled trace + log query</li>
</ul>
<p>對應 <a href="/blog/backend/04-observability/cardinality-cost-governance/" data-link-title="4.7 Cardinality 治理與成本邊界" data-link-desc="把 metric / log / trace 的 cardinality 與成本作為平台一級治理議題">04.10 cardinality cost governance</a>、跟 <a href="/blog/backend/knowledge-cards/metric-cardinality/" data-link-title="Metric Cardinality" data-link-desc="說明 metric label 組合數量如何影響觀測成本與查詢穩定性">Metric Cardinality 卡片</a>。</p>
<h2 id="訊號跟-slo-對接">訊號跟 SLO 對接</h2>
<p>最後一層整合：每個 saturation metric 都要對應一個 SLO threshold、訊號驅動行動。</p>
<p><strong>訊號 → 行動鏈</strong>：</p>
<ul>
<li>saturation metric 超 threshold → trigger alert</li>
<li>alert 觸發 → trigger autoscaler / runbook / oncall</li>
<li>持續超 threshold → trigger <a href="/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">error budget</a> burn alert</li>
<li>error budget 用完 → trigger release freeze</li>
</ul>
<p><strong>Alert 不要太敏感</strong>：</p>
<ul>
<li>false positive 浪費 oncall、長期會 alert fatigue（<a href="/blog/backend/knowledge-cards/alert-fatigue/" data-link-title="Alert Fatigue" data-link-desc="說明過多低品質告警如何降低 on-call 反應品質">Alert Fatigue 卡片</a>）</li>
<li>用 multi-window multi-burn-rate alert（Google SRE 推薦）</li>
<li>用 symptom-based alert（業務影響）而非 cause-based alert（單一資源）</li>
</ul>
<p>跟 <a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a> 直接對接。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads 99.999%</a></td>
          <td>SLO 5 個 9 的訊號治理</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys 12 個月 99.999%</a></td>
          <td>滾動 SLO 觀測</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi p99 分解</a></td>
          <td>ML inference 多 stage latency budget</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech p95 是業務 KPI</a></td>
          <td>latency 不只是技術指標</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> / <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a>（基礎訊號）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method</a></li>
<li><a href="/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED Method</a></li>
<li><a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency</a></li>
<li><a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous Profiling</a></li>
<li><a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request</a></li>
</ul>
]]></content:encoded></item><item><title>9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/</guid><description>&lt;p>這個案例的核心責任是說明「surge load」（突發遠超預期）跟 event-peak（事件型可預測峰值）的差異。Pokémon GO 在 2016-07 上線時、實際流量達到原始容量規劃目標的 50 倍 — 根因是 &lt;em>根本沒人能預測這個產品會這麼紅&lt;/em>、峰值規劃方法論本身沒有失敗。這類負載對容量設計的要求跟其他案例本質不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Niantic Pokémon GO 在 GCP 上的關鍵敘述（引自 &lt;a href="https://cloud.google.com/blog/products/gcp/bringing-pokemon-go-to-life-on-google-cloud">Bringing Pokémon GO to life on Google Cloud&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>實際流量&lt;/td>
 &lt;td>達到原始 target 的 50 倍&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>應用層&lt;/td>
 &lt;td>Google Container Engine (GKE)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容器編排&lt;/td>
 &lt;td>Kubernetes（planetary-scale 設計）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容量支援&lt;/td>
 &lt;td>Google CRE 即時擴容&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵敘述：「Niantic chose GKE for its ability to orchestrate container clusters at planetary-scale」「Google CRE seamlessly provisioned extra capacity on behalf of Niantic to stay ahead of their record-setting growth」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>這個案例最重要的判讀是「surge load 跟可預測峰值是不同問題」。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>50x surge 沒辦法事前規劃&lt;/strong>：任何合理的 capacity planning 都不會預留 50x headroom — 那會讓平日成本爆炸。surge 的工程做法不是「事前撐住」、是「事中快速補上」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">08 事故處理模組&lt;/a> 的事件管理。&lt;/li>
&lt;li>&lt;strong>CRE 不是技術、是 vendor 關係&lt;/strong>：Google Customer Reliability Engineering 是 GCP 提供給戰略客戶的 24/7 工程支援團隊。能即時為 Niantic 補容量靠的是 &lt;em>人 + 流程 + 工具&lt;/em> 的組合、不是純技術。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/operations-control-service-selection/" data-link-title="0.12 觀測、可靠性與事故服務選型" data-link-desc="從訊號、驗證與響應三層能力判斷操作控制服務的選型順序">00.6 操作控制服務選型&lt;/a> 的廠商支援能力評估。&lt;/li>
&lt;li>&lt;strong>Kubernetes 是 surge 的前置條件&lt;/strong>：如果 Niantic 用 VM-based 架構、即使 CRE 想補容量也來不及 boot up。Container orchestrator 把 provisioning 時間從分鐘級降到秒級、才讓 surge 反應變得可能。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 platform 選型。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「Google CRE 即時補容量」這種敘述對中小客戶不適用。一般客戶在 surge 下能依賴的是 &lt;em>自己的 autoscaler&lt;/em>、不是 vendor 工程師。設計 surge 對應策略時要假設「沒有 vendor 救援」。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>接受 surge 不可避免、設計快速 onboard 流程&lt;/strong>：核心問題不是「會不會 surge」、是「surge 之後 24 小時內能不能撐住」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">08.8 incident communication&lt;/a>。&lt;/li>
&lt;li>&lt;strong>降級機制作為 surge 救命稻草&lt;/strong>：當容量不足時、優先保住核心功能、暫時關閉非核心。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02.3 cache stampede&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 high concurrency access&lt;/a> 的降級設計。&lt;/li>
&lt;li>&lt;strong>預先談好 vendor 緊急支援條款&lt;/strong>：戰略服務在簽約時就要談好 surge 期間的容量配額、限流豁免、CRE / TAM 支援、不要等出事才談。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的 vendor relationship 設計。&lt;/li>
&lt;li>&lt;strong>container-first 是 surge 反應的前置&lt;/strong>：VM-based 架構在 surge 下擴容速度比 container 慢一個量級、會直接成為 bottleneck。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：AWS Enterprise Support + TAM、Azure Premier Support + CSAM 都有對等服務、但能即時動用工程師補容量的程度跟客戶等級綁定。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「surge load」（突發遠超預期）跟 event-peak（事件型可預測峰值）的差異。Pokémon GO 在 2016-07 上線時、實際流量達到原始容量規劃目標的 50 倍 — 根因是 <em>根本沒人能預測這個產品會這麼紅</em>、峰值規劃方法論本身沒有失敗。這類負載對容量設計的要求跟其他案例本質不同。</p>
<h2 id="觀察">觀察</h2>
<p>Niantic Pokémon GO 在 GCP 上的關鍵敘述（引自 <a href="https://cloud.google.com/blog/products/gcp/bringing-pokemon-go-to-life-on-google-cloud">Bringing Pokémon GO to life on Google Cloud</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>實際流量</td>
          <td>達到原始 target 的 50 倍</td>
      </tr>
      <tr>
          <td>應用層</td>
          <td>Google Container Engine (GKE)</td>
      </tr>
      <tr>
          <td>容器編排</td>
          <td>Kubernetes（planetary-scale 設計）</td>
      </tr>
      <tr>
          <td>容量支援</td>
          <td>Google CRE 即時擴容</td>
      </tr>
  </tbody>
</table>
<p>關鍵敘述：「Niantic chose GKE for its ability to orchestrate container clusters at planetary-scale」「Google CRE seamlessly provisioned extra capacity on behalf of Niantic to stay ahead of their record-setting growth」。</p>
<h2 id="判讀">判讀</h2>
<p>這個案例最重要的判讀是「surge load 跟可預測峰值是不同問題」。</p>
<ol>
<li><strong>50x surge 沒辦法事前規劃</strong>：任何合理的 capacity planning 都不會預留 50x headroom — 那會讓平日成本爆炸。surge 的工程做法不是「事前撐住」、是「事中快速補上」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 跟 <a href="/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">08 事故處理模組</a> 的事件管理。</li>
<li><strong>CRE 不是技術、是 vendor 關係</strong>：Google Customer Reliability Engineering 是 GCP 提供給戰略客戶的 24/7 工程支援團隊。能即時為 Niantic 補容量靠的是 <em>人 + 流程 + 工具</em> 的組合、不是純技術。對應 <a href="/blog/backend/00-service-selection/operations-control-service-selection/" data-link-title="0.12 觀測、可靠性與事故服務選型" data-link-desc="從訊號、驗證與響應三層能力判斷操作控制服務的選型順序">00.6 操作控制服務選型</a> 的廠商支援能力評估。</li>
<li><strong>Kubernetes 是 surge 的前置條件</strong>：如果 Niantic 用 VM-based 架構、即使 CRE 想補容量也來不及 boot up。Container orchestrator 把 provisioning 時間從分鐘級降到秒級、才讓 surge 反應變得可能。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 platform 選型。</li>
</ol>
<p>需要警惕：「Google CRE 即時補容量」這種敘述對中小客戶不適用。一般客戶在 surge 下能依賴的是 <em>自己的 autoscaler</em>、不是 vendor 工程師。設計 surge 對應策略時要假設「沒有 vendor 救援」。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>接受 surge 不可避免、設計快速 onboard 流程</strong>：核心問題不是「會不會 surge」、是「surge 之後 24 小時內能不能撐住」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 跟 <a href="/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">08.8 incident communication</a>。</li>
<li><strong>降級機制作為 surge 救命稻草</strong>：當容量不足時、優先保住核心功能、暫時關閉非核心。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02.3 cache stampede</a> 跟 <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 high concurrency access</a> 的降級設計。</li>
<li><strong>預先談好 vendor 緊急支援條款</strong>：戰略服務在簽約時就要談好 surge 期間的容量配額、限流豁免、CRE / TAM 支援、不要等出事才談。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 vendor relationship 設計。</li>
<li><strong>container-first 是 surge 反應的前置</strong>：VM-based 架構在 surge 下擴容速度比 container 慢一個量級、會直接成為 bottleneck。</li>
</ol>
<p>跨平台等效：AWS Enterprise Support + TAM、Azure Premier Support + CSAM 都有對等服務、但能即時動用工程師補容量的程度跟客戶等級綁定。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想對應 surge load → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/08-incident-response/incident-severity-trigger/" data-link-title="8.1 事故分級與啟動條件" data-link-desc="建立統一分級標準與事故啟動門檻">08.6 incident severity trigger</a></li>
<li>想設計降級策略 → <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 high concurrency access</a> + <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a></li>
<li>想評估 vendor 支援 → <a href="/blog/backend/00-service-selection/operations-control-service-selection/" data-link-title="0.12 觀測、可靠性與事故服務選型" data-link-desc="從訊號、驗證與響應三層能力判斷操作控制服務的選型順序">00.6 operations control service selection</a></li>
<li>對照可預測峰值案例 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/blog/products/gcp/bringing-pokemon-go-to-life-on-google-cloud">Bringing Pokémon GO to life on Google Cloud</a></li>
<li><a href="https://cloud.google.com/customer-reliability-engineering">Google Customer Reliability Engineering</a></li>
</ul>
]]></content:encoded></item><item><title>9.9 Performance Improvement Loop</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>Improvement loop 的責任是把效能優化從「事件型 hotfix」變成「持續改進的工程流程」。沒有 loop 時、效能問題靠 oncall 觸發、改了又改、改完又退化；有 loop 之後、每次 release 都通過 perf gate、退化在發布前就攔住。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">06.13 perf regression gate&lt;/a> 的關係：06.13 是 release gate 的一個環節、9.9 是這個 gate 背後的完整工程閉環。06.13 處理「進 gate 後怎麼判斷」、9.9 處理「進 gate 前怎麼產生比較資料」。&lt;/p>
&lt;p>本章聚焦在 &lt;em>閉環設計&lt;/em> — 怎麼建 baseline、怎麼跑 re-test、怎麼用 profile diff、怎麼整合 CI。讀完後讀者能設計一個 perf improvement workflow、不是只有 ad-hoc 壓測。&lt;/p>
&lt;h2 id="loop-五個階段">Loop 五個階段&lt;/h2>
&lt;p>完整的 improvement loop 包含五個階段、缺一不可：&lt;/p>
&lt;p>&lt;strong>1. Baseline 建立&lt;/strong>：壓測 + profile 取得「當前正常」snapshot。
&lt;strong>2. 變更 + re-test&lt;/strong>：每次 release candidate 跑壓測、跟 baseline diff。
&lt;strong>3. Profile diff&lt;/strong>：用 flame graph diff 定位退化原因。
&lt;strong>4. Fix&lt;/strong>：rollback 或修正 code path。
&lt;strong>5. Update baseline&lt;/strong>：通過後更新 baseline、進下個 cycle。&lt;/p>
&lt;p>少了 baseline → re-test 沒有比較對象、看絕對數字會錯判。
少了 profile diff → 退化定位靠猜、修錯方向。
少了 update baseline → 永遠跟 old baseline 比、退化累積看不出來。
少了 fix → 退化通過 gate、production 出事。&lt;/p>
&lt;h2 id="baseline-設計">Baseline 設計&lt;/h2>
&lt;p>Baseline 不是「歷史最佳」、是「最低可接受效能」。&lt;/p>
&lt;p>&lt;strong>設計原則&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>不只一個 baseline、按 workload model 訂多個（不同 endpoint、不同 user tier 各自 baseline）&lt;/li>
&lt;li>baseline 必須可重複：固定 seed、固定資料集、固定環境、固定壓測參數&lt;/li>
&lt;li>定期 review：硬體 / 軟體升級會讓 baseline 該往好的方向走、不更新就是裝盲&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>儲存策略&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>baseline as artifact：存進 release artifact、隨 release 帶走&lt;/li>
&lt;li>baseline as code：用 Pulumi / Terraform / dedicated config 管理、可 version control&lt;/li>
&lt;li>baseline as service：dedicated service 管 baseline、提供 query API&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Drift 監控&lt;/strong>：baseline 每月對比上月、看趨勢是否往好方向。drift 超門檻 → re-baseline 並 review 原因。&lt;/p>
&lt;h2 id="profile-diff">Profile diff&lt;/h2>
&lt;p>退化定位的關鍵工具是 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">profile diff&lt;/a> — 對比兩次 profile 找 hottest 變化。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>Improvement loop 的責任是把效能優化從「事件型 hotfix」變成「持續改進的工程流程」。沒有 loop 時、效能問題靠 oncall 觸發、改了又改、改完又退化；有 loop 之後、每次 release 都通過 perf gate、退化在發布前就攔住。</p>
<p>跟 <a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">06.13 perf regression gate</a> 的關係：06.13 是 release gate 的一個環節、9.9 是這個 gate 背後的完整工程閉環。06.13 處理「進 gate 後怎麼判斷」、9.9 處理「進 gate 前怎麼產生比較資料」。</p>
<p>本章聚焦在 <em>閉環設計</em> — 怎麼建 baseline、怎麼跑 re-test、怎麼用 profile diff、怎麼整合 CI。讀完後讀者能設計一個 perf improvement workflow、不是只有 ad-hoc 壓測。</p>
<h2 id="loop-五個階段">Loop 五個階段</h2>
<p>完整的 improvement loop 包含五個階段、缺一不可：</p>
<p><strong>1. Baseline 建立</strong>：壓測 + profile 取得「當前正常」snapshot。
<strong>2. 變更 + re-test</strong>：每次 release candidate 跑壓測、跟 baseline diff。
<strong>3. Profile diff</strong>：用 flame graph diff 定位退化原因。
<strong>4. Fix</strong>：rollback 或修正 code path。
<strong>5. Update baseline</strong>：通過後更新 baseline、進下個 cycle。</p>
<p>少了 baseline → re-test 沒有比較對象、看絕對數字會錯判。
少了 profile diff → 退化定位靠猜、修錯方向。
少了 update baseline → 永遠跟 old baseline 比、退化累積看不出來。
少了 fix → 退化通過 gate、production 出事。</p>
<h2 id="baseline-設計">Baseline 設計</h2>
<p>Baseline 不是「歷史最佳」、是「最低可接受效能」。</p>
<p><strong>設計原則</strong>：</p>
<ul>
<li>不只一個 baseline、按 workload model 訂多個（不同 endpoint、不同 user tier 各自 baseline）</li>
<li>baseline 必須可重複：固定 seed、固定資料集、固定環境、固定壓測參數</li>
<li>定期 review：硬體 / 軟體升級會讓 baseline 該往好的方向走、不更新就是裝盲</li>
</ul>
<p><strong>儲存策略</strong>：</p>
<ul>
<li>baseline as artifact：存進 release artifact、隨 release 帶走</li>
<li>baseline as code：用 Pulumi / Terraform / dedicated config 管理、可 version control</li>
<li>baseline as service：dedicated service 管 baseline、提供 query API</li>
</ul>
<p><strong>Drift 監控</strong>：baseline 每月對比上月、看趨勢是否往好方向。drift 超門檻 → re-baseline 並 review 原因。</p>
<h2 id="profile-diff">Profile diff</h2>
<p>退化定位的關鍵工具是 <a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">profile diff</a> — 對比兩次 profile 找 hottest 變化。</p>
<p><strong>工具實作</strong>：</p>
<ul>
<li>Brendan Gregg 的 differential flame graph：開源、需要手動 generate</li>
<li>Pyroscope diff：UI 直接對比兩個時間段</li>
<li>Datadog Continuous Profiler diff：跟 deployment marker 整合</li>
<li>Parca compare：CNCF 標準</li>
<li>AWS CodeGuru Profiler：自動偵測 CPU / memory anti-pattern</li>
</ul>
<p><strong>正確使用方法</strong>：</p>
<ul>
<li>在 <em>相同負載 + 相同硬體 + 相同 sampling rate</em> 下取兩次 profile</li>
<li>比較 <em>相對變化</em>、不是絕對 CPU%</li>
<li>看 wider stack（不只看 leaf function）找 systemic regression</li>
</ul>
<p><strong>Profile diff 結果通常需要工程師判讀</strong>：「多花 20% CPU 但 throughput 多 50%」可能是好變化、不能純自動化判斷退化是否可接受。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix Aurora 統一</a> — DB 層統一後 profile diff 噪音降低、退化來源更容易識別。</p>
<h2 id="regression-gate-整合-ci">Regression gate 整合 CI</h2>
<p>效能改進閉環必須整合到 CI、不能只在 release 前一次性跑。</p>
<p><strong>Multi-tier 壓測策略</strong>：</p>
<ul>
<li>每個 PR：跑 lightweight perf test（單 endpoint、5 分鐘）、合併前比 baseline</li>
<li>主分支 nightly：跑 medium perf test（多 endpoint、30 分鐘）</li>
<li>Release candidate：跑 complete perf test（完整 workload model、數小時）</li>
</ul>
<p><strong>Gate 觸發條件</strong>：</p>
<ul>
<li>p99 退化 &gt; X%（例如 10%）</li>
<li>吞吐降 &gt; Y%（例如 5%）</li>
<li>error rate 升 &gt; Z%</li>
<li>cost per request 升 &gt; W%</li>
</ul>
<p><strong>Gate 通過 / 不通過的後果</strong>：</p>
<ul>
<li>通過：自動 promote 到下個 stage（staging / canary / production）</li>
<li>不通過：block release、自動 notify owner、附 profile diff link</li>
</ul>
<p><strong>Gate 太敏感的反模式</strong>：</p>
<ul>
<li>每天 false positive、最後沒人看（alert fatigue）</li>
<li>false positive 來源：壓測環境噪音、baseline drift 未更新、業務變化</li>
<li>對策：multi-window detection（變化必須持續 N 個 sample）、配合 manual override（資深工程師判斷異常正常）</li>
</ul>
<p>對應案例：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">06.13 perf regression gate</a> 的實作建議。</p>
<h2 id="canary-perf-check">Canary perf check</h2>
<p><a href="/blog/backend/knowledge-cards/canary-perf-check/" data-link-title="Canary Perf Check" data-link-desc="canary release 中針對 latency / throughput 而非 error rate 的退化檢查">Canary perf check</a> 是 release 階段的另一道 perf gate。跟 regression gate（pre-release）對應、是 <em>production</em> 階段的監控。</p>
<p><strong>Canary 階段除了看 error rate、也看</strong>：</p>
<ul>
<li>latency p99 / p999（最先看到的 regression 訊號）</li>
<li>throughput（是否處理變慢）</li>
<li>resource utilization（CPU / RAM / connection 變化）</li>
<li>cost per request（是否更貴）</li>
</ul>
<p><strong>Canary 流量 vs control 流量比較</strong>：</p>
<ul>
<li>同樣流量同樣時段、不同版本的差才有意義</li>
<li>不能拿 canary 跟 historical baseline 比（外部變數太多）</li>
<li>abort condition：canary p99 比 control 退化 &gt; X%</li>
</ul>
<p><strong>漸進放大策略</strong>：1% → 5% → 25% → 50% → 100%、每階段觀察足夠時間（至少 15 分鐘看 long-tail）。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day FIS 8x chaos</a> — canary 模式跟 chaos test 並行、確保新版本在故障場景也撐得住。</p>
<h2 id="pre-release-改進迴圈頻率">Pre-release 改進迴圈頻率</h2>
<p>不同層級的 review 在不同節奏：</p>
<ul>
<li><strong>每日 PR 級 perf check</strong>：lightweight、單 endpoint、5 分鐘</li>
<li><strong>每週 release candidate 完整壓測</strong>：完整 workload model、數小時</li>
<li><strong>每月 baseline review + drift 評估</strong>：對比歷史趨勢、決定是否 re-baseline</li>
<li><strong>每季容量地圖 review</strong>：跟 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 連動</li>
</ul>
<p>頻率不夠 → 退化累積看不到；頻率太高 → 工程資源吃緊。按團隊規模跟 release 節奏調整。</p>
<h2 id="退化的常見來源">退化的常見來源</h2>
<p>知道退化怎麼來、才能設計對應的 detection：</p>
<ul>
<li><strong>新功能引入 N+1 query</strong>：ORM lazy loading、loop 內 query。看 DB call count 變化</li>
<li><strong>ORM 沒下 index、cache miss 飆升</strong>：看 slow query 跟 cache hit rate</li>
<li><strong>第三方 library upgrade 帶來 overhead</strong>：新版本可能多了 telemetry / validation。看 profile diff</li>
<li><strong>GC tuning 變動</strong>：JVM / Go GC config 調整造成 pause time 變化。看 p999</li>
<li><strong>container resource limit 變動</strong>：Kubernetes limit 改、限制更嚴造成 throttling。看 CPU throttling event</li>
</ul>
<h2 id="反模式">反模式</h2>
<ul>
<li><strong>只在 release 前一次性壓測</strong>：退化已累積數月、找不出原因</li>
<li><strong>baseline 不更新</strong>：永遠跟舊版本比、低估目前狀態</li>
<li><strong>改了又改、改完忘記更新 baseline</strong>：下次 release 又跟過時 baseline 比、迴圈失效</li>
<li><strong>缺 profile diff、退化原因靠猜</strong>：修錯方向、退化還在</li>
<li><strong>gate 訊號跟業務無關</strong>：技術指標退化但業務 metric 沒事、被當 false positive</li>
</ul>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></td>
          <td>統一 DB 後 profile 變單純</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a></td>
          <td>遷移後重新做 baseline</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day FIS 8x</a></td>
          <td>持續改進的混沌 + 壓測迴圈</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> / <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>跨模組：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">06.13 perf regression gate</a> / <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">Profile Diff</a></li>
<li><a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous Profiling</a></li>
<li><a href="/blog/backend/knowledge-cards/canary-perf-check/" data-link-title="Canary Perf Check" data-link-desc="canary release 中針對 latency / throughput 而非 error rate 的退化檢查">Canary Perf Check</a></li>
</ul>
]]></content:encoded></item><item><title>9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/</guid><description>&lt;p>這個案例的核心責任是說明「事件交付系統的容量規劃，靠 managed service 卸載 vs 自管 broker」的長期成本對照。Spotify 從 Kafka 遷到 Pub/Sub 的驅動力是 &lt;em>容量規劃的工程成本&lt;/em> 在 sustained growth 下變得不划算、Kafka 能力本身不是瓶頸。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Spotify 在 Google Cloud 的遷移敘述（引自 &lt;a href="https://cloud.google.com/blog/products/gcp/spotifys-journey-to-cloud-why-spotify-migrated-its-event-delivery-system-from-kafka-to-google-cloud-pubsub">Spotify&amp;rsquo;s journey to cloud&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>用戶規模&lt;/td>
 &lt;td>7500 萬 + 用戶（遷移時期）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移系統&lt;/td>
 &lt;td>Event Delivery System（事件交付）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷出技術&lt;/td>
 &lt;td>自管 Apache Kafka&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷入技術&lt;/td>
 &lt;td>Google Cloud Pub/Sub&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>大數據生態&lt;/td>
 &lt;td>BigQuery / Dataflow / Dataproc / Pub/Sub&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵動機：「moving event delivery to a managed service」— 卸下 Kafka broker 的容量規劃與運維負擔。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Spotify 遷移揭露三個 broker 容量規劃的長期工程問題。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>自管 broker 的容量規劃是長期 tax&lt;/strong>：Kafka cluster 需要 partition planning、broker 數量、副本因子、disk capacity、network bandwidth、ZooKeeper / KRaft 治理 — 每個維度都要持續規劃、每次擴容都是工程專案。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> 的 broker basics 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的人力成本評估。&lt;/li>
&lt;li>&lt;strong>managed service 的容量是 trade-off、不是免費午餐&lt;/strong>：Pub/Sub 自動 scaling、但 vendor lock-in、cost-per-message 累積、message ordering / latency 特性跟 Kafka 不同。遷移本身要驗證 &lt;em>業務語意&lt;/em> 跟 Pub/Sub 兼容。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/broker-basics/" data-link-title="3.1 broker 基礎與投遞模型" data-link-desc="先理解 broker、queue、consumer 與 delivery semantics">03.4 broker basics&lt;/a>。&lt;/li>
&lt;li>&lt;strong>遷移本身是容量規劃題目&lt;/strong>：把 7500 萬用戶的事件交付從 A 平台搬到 B 平台、不能停機、不能丟 message。這個遷移過程本身就是高併發容量工程。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence&lt;/a> 的同類流程。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：Spotify 這個決定不是「Kafka 不好」、是「Spotify 規模下、自管 Kafka 的工程投入不划算」。對中小團隊、自管 Kafka 可能是更便宜的選項。讀案例時要看 &lt;em>規模門檻&lt;/em> 跟 &lt;em>團隊能力&lt;/em>。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>broker 自管 vs managed 是長期 TCO 評估&lt;/strong>：算「平日運維 + 容量擴容 + 故障處理 + 升級遷移」的人力成本、不只算「broker 雲端費用」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;li>&lt;strong>遷移分階段：dual write → shadow → cutover&lt;/strong>：先寫兩邊、驗證一致性、再切流量。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence&lt;/a> 的同類流程。&lt;/li>
&lt;li>&lt;strong>業務語意對映是遷移關鍵&lt;/strong>：Kafka 的 partition / offset / consumer group 在 Pub/Sub 對映成不同概念（subscription / ordering key / message attribute）、不是 1:1。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：AWS SNS / SQS / Kinesis、Amazon MSK（managed Kafka）、Azure Service Bus / Event Hubs / Event Grid 都是對等候選。差異是 message ordering 保證、delivery guarantee、cost model。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「事件交付系統的容量規劃，靠 managed service 卸載 vs 自管 broker」的長期成本對照。Spotify 從 Kafka 遷到 Pub/Sub 的驅動力是 <em>容量規劃的工程成本</em> 在 sustained growth 下變得不划算、Kafka 能力本身不是瓶頸。</p>
<h2 id="觀察">觀察</h2>
<p>Spotify 在 Google Cloud 的遷移敘述（引自 <a href="https://cloud.google.com/blog/products/gcp/spotifys-journey-to-cloud-why-spotify-migrated-its-event-delivery-system-from-kafka-to-google-cloud-pubsub">Spotify&rsquo;s journey to cloud</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>用戶規模</td>
          <td>7500 萬 + 用戶（遷移時期）</td>
      </tr>
      <tr>
          <td>遷移系統</td>
          <td>Event Delivery System（事件交付）</td>
      </tr>
      <tr>
          <td>遷出技術</td>
          <td>自管 Apache Kafka</td>
      </tr>
      <tr>
          <td>遷入技術</td>
          <td>Google Cloud Pub/Sub</td>
      </tr>
      <tr>
          <td>大數據生態</td>
          <td>BigQuery / Dataflow / Dataproc / Pub/Sub</td>
      </tr>
  </tbody>
</table>
<p>關鍵動機：「moving event delivery to a managed service」— 卸下 Kafka broker 的容量規劃與運維負擔。</p>
<h2 id="判讀">判讀</h2>
<p>Spotify 遷移揭露三個 broker 容量規劃的長期工程問題。</p>
<ol>
<li><strong>自管 broker 的容量規劃是長期 tax</strong>：Kafka cluster 需要 partition planning、broker 數量、副本因子、disk capacity、network bandwidth、ZooKeeper / KRaft 治理 — 每個維度都要持續規劃、每次擴容都是工程專案。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 的 broker basics 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的人力成本評估。</li>
<li><strong>managed service 的容量是 trade-off、不是免費午餐</strong>：Pub/Sub 自動 scaling、但 vendor lock-in、cost-per-message 累積、message ordering / latency 特性跟 Kafka 不同。遷移本身要驗證 <em>業務語意</em> 跟 Pub/Sub 兼容。對應 <a href="/blog/backend/03-message-queue/broker-basics/" data-link-title="3.1 broker 基礎與投遞模型" data-link-desc="先理解 broker、queue、consumer 與 delivery semantics">03.4 broker basics</a>。</li>
<li><strong>遷移本身是容量規劃題目</strong>：把 7500 萬用戶的事件交付從 A 平台搬到 B 平台、不能停機、不能丟 message。這個遷移過程本身就是高併發容量工程。對應 <a href="/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence</a> 的同類流程。</li>
</ol>
<p>需要警惕：Spotify 這個決定不是「Kafka 不好」、是「Spotify 規模下、自管 Kafka 的工程投入不划算」。對中小團隊、自管 Kafka 可能是更便宜的選項。讀案例時要看 <em>規模門檻</em> 跟 <em>團隊能力</em>。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>broker 自管 vs managed 是長期 TCO 評估</strong>：算「平日運維 + 容量擴容 + 故障處理 + 升級遷移」的人力成本、不只算「broker 雲端費用」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
<li><strong>遷移分階段：dual write → shadow → cutover</strong>：先寫兩邊、驗證一致性、再切流量。對應 <a href="/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence</a> 的同類流程。</li>
<li><strong>業務語意對映是遷移關鍵</strong>：Kafka 的 partition / offset / consumer group 在 Pub/Sub 對映成不同概念（subscription / ordering key / message attribute）、不是 1:1。</li>
</ol>
<p>跨平台等效：AWS SNS / SQS / Kinesis、Amazon MSK（managed Kafka）、Azure Service Bus / Event Hubs / Event Grid 都是對等候選。差異是 message ordering 保證、delivery guarantee、cost model。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想評估 broker 自管 vs managed → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a></li>
<li>想做大規模 message 系統遷移 → <a href="/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence</a> 的對等流程</li>
<li>想理解 broker 容量規劃 → <a href="/blog/backend/03-message-queue/broker-basics/" data-link-title="3.1 broker 基礎與投遞模型" data-link-desc="先理解 broker、queue、consumer 與 delivery semantics">03.4 broker basics</a></li>
<li>對照其他事件型負載 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/blog/products/gcp/spotifys-journey-to-cloud-why-spotify-migrated-its-event-delivery-system-from-kafka-to-google-cloud-pubsub">Spotify&rsquo;s journey to cloud: why Spotify migrated its event delivery system from Kafka to Google Cloud Pub/Sub</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/spotify-chooses-google-cloud-platform-to-power-data-infrastructure/">Spotify chooses Google Cloud Platform</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/spotifys-experiments-with-stream-processing-on-google-cloud-dataflow">Spotify&rsquo;s experiments with stream processing on Google Cloud Dataflow</a></li>
</ul>
]]></content:encoded></item><item><title>模組九：效能工程與容量規劃</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/</guid><description>&lt;p>效能工程與容量規劃模組的核心目標是回答兩個工程問題：目前的服務配置能承載多少負載，以及面對預期或意外的流量增長時要加多少資源。語言教材會處理 algorithm、hot path 與 memory profile 等程式層效能；本模組負責 workload modeling、壓測工具選型、saturation discovery、瓶頸定位、容量規劃、成本邊界、效能可觀測性與改進閉環。&lt;/p>
&lt;p>本模組跟 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">模組六：可靠性驗證流程&lt;/a> 是 sibling 工程紀律。06 看「失敗模式如何被驗證」，走 SLO、Error Budget、Failure Mode、Chaos Hypothesis 的詞彙；09 看「正常負載如何被量化與規劃」，走 Workload、Saturation、Capacity、Cost、Throughput、Latency 的詞彙。兩個模組共用案例庫但讀法不同：06 從案例讀「失敗模式驗證」、09 從案例讀「容量量化實踐」。&lt;/p>
&lt;h2 id="教材定位">教材定位&lt;/h2>
&lt;p>效能工程的角色是把「我不知道目前配置能撐多少」這個常見焦慮，變成可量測、可重播、可改進的工程流程。&lt;/p>
&lt;p>多數後端服務不會每天遇到高併發，真正的工程問題是平常運作時的容量地圖。平常運作正常時，目前的配置距離 saturation 還有多遠；當意外流量出現時，現有配置能撐到 autoscaling 介入嗎；要加機器時，怎麼算出該加多少、加在哪一層；加了機器之後，怎麼確認瓶頸真的被移除了。&lt;/p>
&lt;p>這四個問題不需要假設高併發場景，而是要求系統在任何配置下都能回答「現在的容量地圖長什麼樣」。沒有這張地圖，加機器是猜測、不加機器是賭運氣、改架構是恐慌。&lt;/p>
&lt;h2 id="教材邊界">教材邊界&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>類型&lt;/th>
 &lt;th>放在語言教材&lt;/th>
 &lt;th>放在本模組&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>程式層效能&lt;/td>
 &lt;td>algorithm、data structure、hot path、memory profile、micro benchmark&lt;/td>
 &lt;td>workload model、production traffic replay、end-to-end load test&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>並發模型&lt;/td>
 &lt;td>goroutine、event loop、thread pool、connection pool 的程式邊界&lt;/td>
 &lt;td>並發設計如何決定 saturation 與 connection pressure 邊界&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Profiling&lt;/td>
 &lt;td>runtime profiler、flame graph、heap dump 解讀&lt;/td>
 &lt;td>continuous profiling 接入、profile diff 作為 regression 定位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容量量測&lt;/td>
 &lt;td>resource metric API、process memory、GC pause 訊號&lt;/td>
 &lt;td>saturation metric、USE method、RED method、cost dashboard&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容量規劃&lt;/td>
 &lt;td>（不負責）&lt;/td>
 &lt;td>peak forecast、headroom model、growth curve、autoscaling sizing、cost ceiling&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>壓測工具&lt;/td>
 &lt;td>（不負責）&lt;/td>
 &lt;td>k6、JMeter、Gatling、Locust、Vegeta、production traffic replay 工具的選型與整合&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="問題節點">問題節點&lt;/h2>
&lt;p>問題節點先描述「不知道答案會發生什麼」，再描述「怎麼建立答案」。讀者能先理解這個問題為什麼重要，再看到怎麼處理。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>節點&lt;/th>
 &lt;th>工程問題&lt;/th>
 &lt;th>觀察訊號&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Workload Modeling&lt;/td>
 &lt;td>壓測模型是否貼近 production traffic shape&lt;/td>
 &lt;td>percentile distribution、cohort mix、burst pattern&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Load Test Tooling&lt;/td>
 &lt;td>該用哪種工具、怎麼整合 CI 跟 staging&lt;/td>
 &lt;td>tool capability vs workload shape、CI 整合成本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Saturation Discovery&lt;/td>
 &lt;td>配置距離飽和還有多少 headroom&lt;/td>
 &lt;td>throughput plateau、latency knee、resource saturation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bottleneck Localization&lt;/td>
 &lt;td>瓶頸在哪一層、是 app / DB / cache / broker&lt;/td>
 &lt;td>resource utilization、queue depth、connection exhaustion&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Capacity Planning&lt;/td>
 &lt;td>要加多少機器、加在哪一層&lt;/td>
 &lt;td>peak forecast、headroom budget、growth curve&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cost Engineering&lt;/td>
 &lt;td>容量擴張的成本曲線、降級的成本邊界&lt;/td>
 &lt;td>cost per request、autoscaling cost ceiling、over-provision waste&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Performance Observability&lt;/td>
 &lt;td>容量訊號怎麼看、跟 SLO 怎麼接&lt;/td>
 &lt;td>saturation metric、cost attribution、SLO budget&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Improvement Loop&lt;/td>
 &lt;td>從壓測到 release 怎麼閉環&lt;/td>
 &lt;td>profile diff、regression gate、canary perf signal&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production Validation&lt;/td>
 &lt;td>怎麼在 production 安全驗證新配置&lt;/td>
 &lt;td>shadow traffic、dark launch、canary perf check&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Peak Event Readiness&lt;/td>
 &lt;td>預知的流量事件怎麼準備&lt;/td>
 &lt;td>event capacity forecast、pre-warm checklist、rollback path&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這張表的責任是路由。當讀者卡住時，先問三個問題：是模型還是訊號的問題、是量測還是規劃的問題、是技術瓶頸還是成本邊界的問題。這三個問題會把讀者導向不同主章。&lt;/p></description><content:encoded><![CDATA[<p>效能工程與容量規劃模組的核心目標是回答兩個工程問題：目前的服務配置能承載多少負載，以及面對預期或意外的流量增長時要加多少資源。語言教材會處理 algorithm、hot path 與 memory profile 等程式層效能；本模組負責 workload modeling、壓測工具選型、saturation discovery、瓶頸定位、容量規劃、成本邊界、效能可觀測性與改進閉環。</p>
<p>本模組跟 <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">模組六：可靠性驗證流程</a> 是 sibling 工程紀律。06 看「失敗模式如何被驗證」，走 SLO、Error Budget、Failure Mode、Chaos Hypothesis 的詞彙；09 看「正常負載如何被量化與規劃」，走 Workload、Saturation、Capacity、Cost、Throughput、Latency 的詞彙。兩個模組共用案例庫但讀法不同：06 從案例讀「失敗模式驗證」、09 從案例讀「容量量化實踐」。</p>
<h2 id="教材定位">教材定位</h2>
<p>效能工程的角色是把「我不知道目前配置能撐多少」這個常見焦慮，變成可量測、可重播、可改進的工程流程。</p>
<p>多數後端服務不會每天遇到高併發，真正的工程問題是平常運作時的容量地圖。平常運作正常時，目前的配置距離 saturation 還有多遠；當意外流量出現時，現有配置能撐到 autoscaling 介入嗎；要加機器時，怎麼算出該加多少、加在哪一層；加了機器之後，怎麼確認瓶頸真的被移除了。</p>
<p>這四個問題不需要假設高併發場景，而是要求系統在任何配置下都能回答「現在的容量地圖長什麼樣」。沒有這張地圖，加機器是猜測、不加機器是賭運氣、改架構是恐慌。</p>
<h2 id="教材邊界">教材邊界</h2>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>放在語言教材</th>
          <th>放在本模組</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>程式層效能</td>
          <td>algorithm、data structure、hot path、memory profile、micro benchmark</td>
          <td>workload model、production traffic replay、end-to-end load test</td>
      </tr>
      <tr>
          <td>並發模型</td>
          <td>goroutine、event loop、thread pool、connection pool 的程式邊界</td>
          <td>並發設計如何決定 saturation 與 connection pressure 邊界</td>
      </tr>
      <tr>
          <td>Profiling</td>
          <td>runtime profiler、flame graph、heap dump 解讀</td>
          <td>continuous profiling 接入、profile diff 作為 regression 定位</td>
      </tr>
      <tr>
          <td>容量量測</td>
          <td>resource metric API、process memory、GC pause 訊號</td>
          <td>saturation metric、USE method、RED method、cost dashboard</td>
      </tr>
      <tr>
          <td>容量規劃</td>
          <td>（不負責）</td>
          <td>peak forecast、headroom model、growth curve、autoscaling sizing、cost ceiling</td>
      </tr>
      <tr>
          <td>壓測工具</td>
          <td>（不負責）</td>
          <td>k6、JMeter、Gatling、Locust、Vegeta、production traffic replay 工具的選型與整合</td>
      </tr>
  </tbody>
</table>
<h2 id="問題節點">問題節點</h2>
<p>問題節點先描述「不知道答案會發生什麼」，再描述「怎麼建立答案」。讀者能先理解這個問題為什麼重要，再看到怎麼處理。</p>
<table>
  <thead>
      <tr>
          <th>節點</th>
          <th>工程問題</th>
          <th>觀察訊號</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Workload Modeling</td>
          <td>壓測模型是否貼近 production traffic shape</td>
          <td>percentile distribution、cohort mix、burst pattern</td>
      </tr>
      <tr>
          <td>Load Test Tooling</td>
          <td>該用哪種工具、怎麼整合 CI 跟 staging</td>
          <td>tool capability vs workload shape、CI 整合成本</td>
      </tr>
      <tr>
          <td>Saturation Discovery</td>
          <td>配置距離飽和還有多少 headroom</td>
          <td>throughput plateau、latency knee、resource saturation</td>
      </tr>
      <tr>
          <td>Bottleneck Localization</td>
          <td>瓶頸在哪一層、是 app / DB / cache / broker</td>
          <td>resource utilization、queue depth、connection exhaustion</td>
      </tr>
      <tr>
          <td>Capacity Planning</td>
          <td>要加多少機器、加在哪一層</td>
          <td>peak forecast、headroom budget、growth curve</td>
      </tr>
      <tr>
          <td>Cost Engineering</td>
          <td>容量擴張的成本曲線、降級的成本邊界</td>
          <td>cost per request、autoscaling cost ceiling、over-provision waste</td>
      </tr>
      <tr>
          <td>Performance Observability</td>
          <td>容量訊號怎麼看、跟 SLO 怎麼接</td>
          <td>saturation metric、cost attribution、SLO budget</td>
      </tr>
      <tr>
          <td>Improvement Loop</td>
          <td>從壓測到 release 怎麼閉環</td>
          <td>profile diff、regression gate、canary perf signal</td>
      </tr>
      <tr>
          <td>Production Validation</td>
          <td>怎麼在 production 安全驗證新配置</td>
          <td>shadow traffic、dark launch、canary perf check</td>
      </tr>
      <tr>
          <td>Peak Event Readiness</td>
          <td>預知的流量事件怎麼準備</td>
          <td>event capacity forecast、pre-warm checklist、rollback path</td>
      </tr>
  </tbody>
</table>
<p>這張表的責任是路由。當讀者卡住時，先問三個問題：是模型還是訊號的問題、是量測還是規劃的問題、是技術瓶頸還是成本邊界的問題。這三個問題會把讀者導向不同主章。</p>
<h2 id="跟既有模組的分工">跟既有模組的分工</h2>
<table>
  <thead>
      <tr>
          <th>既有模組</th>
          <th>09 與其分工</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型</a></td>
          <td>00 提供需求量化輸入（traffic / data / failure cost），09 把這些輸入翻成壓測模型與容量計畫</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性</a></td>
          <td>04 提供 metric / dashboard / SLO baseline，09 定義 saturation metric、USE / RED 訊號、cost attribution 需求</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台</a></td>
          <td>05 處理 autoscaling、HPA、load balancer 的平台實作，09 提供 capacity 規劃輸入（要 scale 到多少、什麼條件觸發）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">06 可靠性驗證</a></td>
          <td>06 看失敗模式（chaos / error budget / SLO），09 看正常負載（workload / saturation / capacity），共享 6.2 / 6.9 / 6.13 入口</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">08 事故處理</a></td>
          <td>08 處理 capacity-related incident 的事中事後，09 提供事前演練與容量門檻</td>
      </tr>
  </tbody>
</table>
<p>跟 06 的邊界要特別清楚。06.2 load-testing、6.9 capacity-cost、6.13 perf regression gate 留下「在驗證流程中的角色」入口；09 負責「壓測理論、模型、工具、瓶頸定位、容量規劃、成本邊界」的深化。當讀者問「load test 在 release gate 的判讀條件」屬 06；問「load test 的 workload model 怎麼設計、工具怎麼選、瓶頸怎麼定位」屬 09。</p>
<h2 id="從章節到實作的-chain">從章節到實作的 chain</h2>
<p>各章節交付三樣：問題節點、判讀訊號、控制面 link。判讀完成後沿兩條 chain 進入 implementation。</p>
<ol>
<li><strong>Mechanism chain</strong>：點問題節點表的 <code>[control-name]</code> link 進 <a href="/blog/backend/knowledge-cards/" data-link-title="Knowledge Cards" data-link-desc="用原子化卡片整理後端服務選型前需要理解的 domain knowhow">knowledge-cards</a>，那層展開機制、邊界、context-dependence。例：<code>[saturation point]</code> 的 knowledge-card 是該 control 的 mechanism SSoT。</li>
<li><strong>Delivery chain</strong>：章節「交接路由」欄位指向下游模組，包括可觀測性（saturation metric / cost dashboard）、部署平台（autoscaling policy / HPA sizing）、可靠性（perf regression gate / SLO budget）與事故處理（capacity incident playbook）。</li>
</ol>
<p>兩條 chain 走完，控制面交付完整。Implementation 強度取決於兩條 chain 的完成度，章節閱讀本身完成 routing 階段。</p>
<h2 id="主章規劃">主章規劃</h2>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>主題</th>
          <th>核心責任</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論與系統行為</a></td>
          <td>Performance Theory</td>
          <td>Little&rsquo;s Law、queueing theory、USL、saturation curve 的工程意義</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></td>
          <td>Workload Modeling</td>
          <td>把 production traffic shape 翻成可重播的壓測模型</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></td>
          <td>Load Test Tooling</td>
          <td>k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的選型判讀</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a></td>
          <td>Saturation Discovery</td>
          <td>找出 throughput plateau 與 latency knee 的方法</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></td>
          <td>Bottleneck Localization</td>
          <td>從 app 到 DB、cache、broker、第三方 quota 的逐層定位</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a></td>
          <td>Capacity Planning</td>
          <td>peak forecast、headroom、growth curve、autoscaling sizing</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a></td>
          <td>Cost Engineering</td>
          <td>cost per request、cost curve、降級成本、over-provisioning trade-off</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></td>
          <td>Performance Observability</td>
          <td>saturation metric、USE / RED method、cost dashboard</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a></td>
          <td>Improvement Loop</td>
          <td>壓測 → profile → fix → re-test → release gate 的閉環</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></td>
          <td>Production Validation</td>
          <td>shadow traffic、dark launch、canary、production-like load test</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a></td>
          <td>Peak Event Readiness</td>
          <td>活動、季節性流量、推廣事件的 capacity readiness 流程</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a></td>
          <td>SLO Coupling</td>
          <td>performance budget 跟 SLO / error budget 的對接</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a></td>
          <td>Scaling Axes</td>
          <td>垂直 / 水平擴展取捨、stateless 前提、auto scaling 操作模型</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/connection-pool-amplification/" data-link-title="9.14 連線池放大解法（PgBouncer / RDS Proxy / ProxySQL）" data-link-desc="水平擴展應用層時 DB 連線池放大問題的具體解法、connection pooler 三大選項對比、解 9.13 提出但未深入的隱性成本">9.14 連線池放大解法</a></td>
          <td>Connection Pool Amplification</td>
          <td>PgBouncer / RDS Proxy / ProxySQL 對比、解 9.13 提出的連線池放大隱性成本</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>14 個主章已完成首輪正文。後續工作是補 <code>vendors/</code> 工具入口、提升案例回寫密度，並校正各章與 06 reliability 的分工。</p></blockquote>
<p>主章撰寫順序：9.1 → 9.2 → 9.4 → 9.5 → 9.6 → 9.3 → 9.8 → 9.9 → 9.7 → 9.10 → 9.11 → 9.12。理論與模型先行，工具落地放在 saturation 與 bottleneck 概念成熟之後，最後處理成本與 production 驗證的進階主題。</p>
<h2 id="案例庫規劃">案例庫規劃</h2>
<p>案例庫主軸採「AWS Customer Success Stories」公開案例。這層案例提供具體流量、實例、延遲、成本數字，比一般 engineering blog 更接近實戰判讀。完整索引、讀法與規劃中案例見 <a href="/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C 案例正文</a>。</p>
<h3 id="已發佈案例">已發佈案例</h3>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>主題</th>
          <th>負載形狀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1</a></td>
          <td>AWS Prime Day 2025 dogfood</td>
          <td>可預期極端峰值（SQS 1.66 億 msg/sec）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2</a></td>
          <td>GR8 Tech 體育博彩 AI 預測式擴容</td>
          <td>事件型不可預期峰值（54K TPS @ 25ms p95）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3</a></td>
          <td>Coinbase 超低延遲交易</td>
          <td>無峰值低延遲（100K msg/sec、sub-ms）</td>
      </tr>
  </tbody>
</table>
<p>三篇對應三種負載形狀，讀完可以開始把自己的服務歸類，再回到對應主章規劃容量地圖。</p>
<h3 id="規劃中案例補不同視角與規模">規劃中案例（補不同視角與規模）</h3>
<table>
  <thead>
      <tr>
          <th>候選來源</th>
          <th>預期教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Lyft / Slack</td>
          <td>微服務 + Auto Scaling、事件型流量的擴容粒度治理</td>
      </tr>
      <tr>
          <td>Riot Games</td>
          <td>EKS 多集群（246 cluster）治理、跨地區延遲與成本平衡</td>
      </tr>
      <tr>
          <td>FanDuel</td>
          <td>直播流量 + 投注峰值的雙重峰值對齊</td>
      </tr>
      <tr>
          <td>Hotstar</td>
          <td>即時 live streaming 全球峰值（1860 萬同時觀看）</td>
      </tr>
      <tr>
          <td>Zoom</td>
          <td>COVID 期間 30 倍成長（1000 萬 → 3 億 DAU）</td>
      </tr>
  </tbody>
</table>
<h3 id="engineering-blog-補充候選">Engineering Blog 補充候選</h3>
<p>當 AWS 案例缺乏某些工程紀律的深度（例如 chaos hypothesis、cell-based architecture 細節），補引 engineering blog 作為交叉驗證。候選來源：Shopify BFCM、Netflix Tech Blog、Amazon Builders&rsquo; Library、Google SRE Book、LinkedIn Engineering、Stripe Engineering、Cloudflare Blog、Discord Engineering、Uber Engineering、Pinterest Engineering 等。這層不另開資料夾，補在主章「案例對照」段。</p>
<h2 id="跨語言適配評估">跨語言適配評估</h2>
<p>效能工程使用方式會受語言的並發模型、runtime overhead、profiler 工具鏈與 client library 成熟度影響。</p>
<ol>
<li>同步 thread-based runtime（Java、C#、傳統 Python / Ruby）：<a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">connection pool</a> 是首要瓶頸、blocking I/O 會把 thread 鎖住、壓測時要量 thread saturation 跟 pool exhaustion。</li>
<li>async / event-loop runtime（Node.js、Python asyncio、Tokio）：要量 event loop lag、避免 CPU-bound work 阻塞 loop、<a href="/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">backpressure</a> 失控時 throughput 跟 latency 會同時崩。</li>
<li>Goroutine 或 lightweight task runtime（Go、Erlang）：goroutine 廉價但下游連線、檔案 handle、broker channel 仍是昂貴資源、要量「廉價並發 → 昂貴資源」的轉換點。</li>
<li>JIT 語言（JVM、.NET）：warmup 期 latency 高、壓測要區分 cold 與 warm 階段、profile diff 要排除 GC noise。</li>
<li>AOT 語言（Go、Rust、C++）：<a href="/blog/backend/knowledge-cards/cold-start/" data-link-title="Cold Start" data-link-desc="說明服務或快取剛啟動時尚未累積狀態造成的延遲與壓力">cold start</a> 較快、但 GC（Go）或 allocator 行為仍影響長時間 latency。</li>
<li>動態語言（Python、Ruby、PHP）：interpreter overhead 是基線、要先排除 framework 預設配置的隱性成本（worker model、GIL、autoload）。</li>
</ol>
<h2 id="服務分類規範">服務分類規範</h2>
<p>每個討論具體壓測工具或容量服務的章節（k6、JMeter、Gatling、Locust、Vegeta、Grafana k6 Cloud、AWS Distributed Load Testing、Datadog Synthetics、Akamas），都必須包含「成本權衡與機會成本」段落，至少回答：</p>
<ol>
<li>這個工具降低哪一種風險（容量未知、缺少持續驗證、缺少瓶頸定位）。</li>
<li>工具本身的維運成本：runner、artifact、結果儲存、CI 整合成本。</li>
<li>在大規模壓測下會增加哪些雲端成本（流量費、跨區、目標服務的容量壓力）。</li>
<li>團隊需要承擔哪些前置成本：workload model 設計、結果判讀、baseline 維護。</li>
<li>若選擇更簡單方案（人工 ad-hoc 壓測），會承擔哪些風險。</li>
<li>什麼條件出現時，原本的工具選擇應該被重新評估。</li>
</ol>
<h2 id="vendor-清單">Vendor 清單</h2>
<p>實作工具見 <a href="/blog/backend/09-performance-capacity/vendors/" data-link-title="效能與容量工具清單" data-link-desc="整理效能工程、容量規劃、壓測、production replay 與 profiling 工具的服務責任與選型路由">vendors</a> — 已建立 k6 / JMeter / Gatling / Locust / Vegeta 五個壓測工具頁、GoReplay / Service Mesh Mirroring / AWS VPC Traffic Mirroring 三個 production traffic replay 頁，Datadog Continuous Profiler / Pyroscope / Parca 三個 continuous profiling 頁，以及 Akamas / Vantage / CloudHealth / AWS Cost Explorer 四個 capacity / cost analysis 頁。跟 <a href="/blog/backend/06-reliability/vendors/" data-link-title="可靠性 Vendor 清單" data-link-desc="規劃 CI、壓測、chaos engineering 與 SLO 工具的服務頁撰寫順序與判準">06 vendors</a> 的差異：06 收錄壓測工具是為了「驗證流程的工具鏈」、09 收錄是為了「效能工程的工具鏈」、選型角度不同。</p>
<p>Deep article（工具自身的配置、故障、容量）跟 migration playbook（跨工具遷移流程）的撰寫進度見 <a href="/blog/backend/09-performance-capacity/vendors/" data-link-title="效能與容量工具清單" data-link-desc="整理效能工程、容量規劃、壓測、production replay 與 profiling 工具的服務責任與選型路由">vendors/</a> 的「內容覆蓋進度」段。</p>
<h2 id="09-模組專屬知識卡片">09 模組專屬知識卡片</h2>
<p>09 模組已建立 22 張效能工程與容量規劃專屬卡片、覆蓋理論基礎、量測方法、規劃決策、production 驗證與 SLO 治理四個面向。</p>
<p><strong>理論基礎（5 張）</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/little-law/" data-link-title="Little&#39;s Law" data-link-desc="說明系統內並發數、到達率與逗留時間三者的數學關係">Little&rsquo;s Law</a> — 並發、到達率、逗留時間的數學關係</li>
<li><a href="/blog/backend/knowledge-cards/universal-scalability-law/" data-link-title="Universal Scalability Law (USL)" data-link-desc="說明系統擴容到一定規模後吞吐反而下降的數學模型">Universal Scalability Law</a> — 擴容到某點後 throughput 反向下降的數學模型</li>
<li><a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point</a> — linear / knee / cliff 三段曲線的臨界點</li>
<li><a href="/blog/backend/knowledge-cards/use-method/" data-link-title="USE Method" data-link-desc="Brendan Gregg 提出的資源層 Utilization / Saturation / Errors 三維度量測法">USE Method</a> — 資源層 Utilization / Saturation / Errors</li>
<li><a href="/blog/backend/knowledge-cards/red-method/" data-link-title="RED Method" data-link-desc="Tom Wilkie 提出的請求層 Rate / Errors / Duration 三維度量測法">RED Method</a> — 請求層 Rate / Errors / Duration</li>
</ul>
<p><strong>Workload 與容量規劃（8 張）</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/workload-model/" data-link-title="Workload Model" data-link-desc="描述 production traffic 形狀的可重播模型 — 容量規劃跟壓測的共同輸入">Workload Model</a> — production traffic shape 量化模型</li>
<li><a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency</a> — p99 / p999 長尾為何比平均更能反映 saturation</li>
<li><a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">Hot Partition</a> — 分散式 KV 的隱性 saturation</li>
<li><a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast</a> — 預期峰值的預測方法</li>
<li><a href="/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &#43; AZ 故障 &#43; forecast 誤差的安全餘量">Headroom Budget</a> — 容量規劃的安全餘量</li>
<li><a href="/blog/backend/knowledge-cards/growth-curve/" data-link-title="Growth Curve" data-link-desc="說明用戶 / 流量隨時間成長的五種典型形狀、影響容量規劃方法">Growth Curve</a> — 五種典型成長形狀</li>
<li><a href="/blog/backend/knowledge-cards/predictive-scaling/" data-link-title="Predictive Scaling" data-link-desc="說明用歷史模式或 ML 模型預測流量、提前擴容的 autoscaler 模式">Predictive Scaling</a> — 預測式擴容</li>
<li><a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling</a> — 已知時間表預先擴容</li>
</ul>
<p><strong>Production 驗證（5 張）</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a> — production traffic 複製驗證</li>
<li><a href="/blog/backend/knowledge-cards/dark-launch/" data-link-title="Dark Launch" data-link-desc="新功能上線但暫不開放 UI 入口、走 production traffic 但對用戶不可見的發布模式">Dark Launch</a> — UI 入口暫不開放的發布模式</li>
<li><a href="/blog/backend/knowledge-cards/canary-perf-check/" data-link-title="Canary Perf Check" data-link-desc="canary release 中針對 latency / throughput 而非 error rate 的退化檢查">Canary Perf Check</a> — canary 階段的 latency 退化檢查</li>
<li><a href="/blog/backend/knowledge-cards/profile-diff/" data-link-title="Profile Diff" data-link-desc="對比兩次 profile（如 release candidate vs baseline）找出 hottest 變化">Profile Diff</a> — 兩次 profile 對比找退化原因</li>
<li><a href="/blog/backend/knowledge-cards/continuous-profiling/" data-link-title="Continuous Profiling" data-link-desc="在 production 持續取得低 overhead profile 的觀察方法">Continuous Profiling</a> — production 持續低 overhead profile</li>
</ul>
<p><strong>成本與 SLO（4 張）</strong>：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request</a> — 雲端成本 unit economics</li>
<li><a href="/blog/backend/knowledge-cards/performance-budget/" data-link-title="Performance Budget" data-link-desc="跟 error budget 同類概念、但用於 latency / throughput 退化的可控額度">Performance Budget</a> — 跟 error budget 並列的效能退化額度</li>
<li><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget</a> — end-to-end latency 拆到每 stage 配額</li>
<li><a href="/blog/backend/knowledge-cards/slo-baseline-drift/" data-link-title="SLO Baseline Drift" data-link-desc="SLO baseline 因業務變化 / surge / 架構改動而需要重新校準的現象">SLO Baseline Drift</a> — SLO 需要重新校準的現象</li>
</ul>
<h2 id="既有可引用卡片">既有可引用卡片</h2>
<p>從其他模組沿用的卡片：</p>
<ul>
<li><a href="/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">Load Test</a></li>
<li><a href="/blog/backend/knowledge-cards/throughput/" data-link-title="Throughput" data-link-desc="整理系統單位時間內可處理的工作量">Throughput</a></li>
<li><a href="/blog/backend/knowledge-cards/consumer-capacity/" data-link-title="Consumer Capacity" data-link-desc="說明 consumer 群組每秒能穩定處理多少工作">Consumer Capacity</a></li>
<li><a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">Connection Pool</a></li>
<li><a href="/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">Backpressure</a></li>
<li><a href="/blog/backend/knowledge-cards/load-shedding/" data-link-title="Load Shedding" data-link-desc="說明服務過載時如何主動拒絕低優先工作以保護核心能力">Load Shedding</a></li>
<li><a href="/blog/backend/knowledge-cards/rate-limit/" data-link-title="Rate Limit" data-link-desc="說明限流如何保護服務入口、下游依賴與租戶公平性">Rate Limit</a></li>
<li><a href="/blog/backend/knowledge-cards/cold-start/" data-link-title="Cold Start" data-link-desc="說明服務或快取剛啟動時尚未累積狀態造成的延遲與壓力">Cold Start</a></li>
<li><a href="/blog/backend/knowledge-cards/thundering-herd/" data-link-title="Thundering Herd" data-link-desc="說明大量工作同時被喚醒或同時競爭資源時的尖峰風險">Thundering Herd</a></li>
<li><a href="/blog/backend/knowledge-cards/bulkhead/" data-link-title="Bulkhead" data-link-desc="說明 bulkhead 如何用資源分艙限制故障擴散">Bulkhead</a></li>
<li><a href="/blog/backend/knowledge-cards/sli-slo/" data-link-title="SLI / SLO" data-link-desc="說明服務品質指標與服務品質目標如何連接產品承諾">SLI / SLO</a></li>
<li><a href="/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">Error Budget</a></li>
<li><a href="/blog/backend/knowledge-cards/metric-cardinality/" data-link-title="Metric Cardinality" data-link-desc="說明 metric label 組合數量如何影響觀測成本與查詢穩定性">Metric Cardinality</a></li>
<li><a href="/blog/backend/knowledge-cards/game-day/" data-link-title="Game Day" data-link-desc="說明事故演練如何驗證流程、工具與團隊協作">Game Day</a></li>
<li><a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">Blast Radius</a></li>
<li><a href="/blog/backend/knowledge-cards/autoscaling/" data-link-title="Autoscaling" data-link-desc="說明系統如何依負載自動調整服務實例數量">Autoscaling</a></li>
</ul>
<h2 id="模組方法">模組方法</h2>
<p>問題驅動方法的核心是讓案例退到證據角色，讓知識網以「容量量化問題」為主體。</p>
<ol>
<li>先定義效能或容量問題的責任邊界。</li>
<li>再定義判讀訊號（saturation curve、cost curve、percentile distribution）與門檻條件。</li>
<li>接著定義交接路由與前置控制面。</li>
<li>最後在問題觸發時引用對應服務案例。</li>
</ol>
<h2 id="規劃方向">規劃方向</h2>
<p>本模組的核心是把模組架構為「容量量化問題 + 服務級實踐案例」兩層結構。</p>
<ol>
<li><strong>問題節點先行</strong>：9.1-9.12 主章已建立理論、模型、工具、saturation、瓶頸、容量、成本、可觀測性、改進閉環、production 驗證、高峰準備與 SLO 對接的基礎。</li>
<li><strong>服務級案例庫</strong>：以公開效能與容量實踐（Shopify BFCM / Netflix scale / Amazon cost / Google performance budget / LinkedIn capacity planning）作 cases，每個服務累積容量規劃脈絡。</li>
<li><strong>跟 06 共用案例但不同讀法</strong>：服務 case 同一批、但 06 讀「失敗模式驗證」、09 讀「容量量化實踐」、避免重複案例蒐集成本。</li>
</ol>
<p>不經實作即可推進的理由：效能工程的價值在「容量地圖建立與成本邊界判讀」，這層跟具體框架解耦，performance engineering 公開素材成熟，符合先建概念層的條件。</p>
<h2 id="tripwire">Tripwire</h2>
<ul>
<li>寫到第 6 章發現持續繞回 06 已有章節 → 軸線過於相似、合併回 06 或重切。</li>
<li>案例庫跟 06 cases/ 重疊度 &gt; 70% → 改共用 06 案例、不另起一份。</li>
<li>工具章節寫起來像 vendor 比較表、缺判讀邏輯 → 改寫成「workload model → 工具選型」的決策章節。</li>
<li>9.6 capacity planning 跟 9.7 cost engineering 變成兩篇都在講同一個 trade-off → 合併。</li>
<li>9.10 production validation 跟 <a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> 內容開始重疊 → 明確分工：9.10 走「正常負載驗證」、6.20 走「故障注入安全邊界」。</li>
<li>寫 T1 服務第 3 個時、若 case 之間無共通分類軸 → 改用單服務獨立檔，不開資料夾。</li>
</ul>
<h2 id="模組完成狀態">模組完成狀態</h2>
<p>模組主章與案例庫已完成首輪正文，<code>vendors/</code> 已建立壓測工具、production traffic replay 與 continuous profiling 第一批工具頁。後續工作排序：先補 capacity / cost analysis 工具頁，再提高 9.7-9.12 對案例的回寫密度，最後整理跟 06 reliability 共用案例的分工。</p>
<hr>
<p><em>文件版本：v0.1.0</em>
<em>最後更新：2026-05-12</em>
<em>系列狀態：主章首輪完成，進入工具入口與案例回寫補強</em></p>
]]></content:encoded></item><item><title>Prometheus 容量規劃與故障模式</title><link>https://tarrragon.github.io/blog/backend/04-observability/vendors/prometheus/capacity-failure-modes/</link><pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/04-observability/vendors/prometheus/capacity-failure-modes/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/prometheus/" data-link-title="Prometheus" data-link-desc="Pull-based metrics 主流 OSS、PromQL 與 alerting">Prometheus&lt;/a> 的 vendor deep article，深化 overview「Cardinality 管理」跟「Memory pressure」段。初次接觸 Prometheus 的讀者建議先讀 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/prometheus/" data-link-title="Prometheus" data-link-desc="Pull-based metrics 主流 OSS、PromQL 與 alerting">Prometheus 服務頁&lt;/a>。&lt;/p>&lt;/blockquote>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>Prometheus 的容量模型跟傳統資料庫不同 — 它的容量邊界主要受 active series 數量（cardinality）跟 retention 期決定，而非資料筆數或 disk size。理解 Prometheus 的資源消耗模型，才能判斷什麼時候單機夠用、什麼時候需要 remote write 卸載或遷移到 Mimir / Thanos。&lt;/p>
&lt;h2 id="資源消耗模型">資源消耗模型&lt;/h2>
&lt;h3 id="memory由-active-series-決定">Memory：由 active series 決定&lt;/h3>
&lt;p>Prometheus 把近期的 time series 保存在記憶體（head block）。每個 active series 大約消耗 3-4 KB 記憶體（含 index、chunks、postings；Prometheus TSDB 的業界經驗值，實際依 label 長度與 chunk encoding 而定）。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Active series&lt;/th>
 &lt;th>預估 memory（head block）&lt;/th>
 &lt;th>適合的機器規格&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>10 萬&lt;/td>
 &lt;td>~400 MB&lt;/td>
 &lt;td>任何 VM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>100 萬&lt;/td>
 &lt;td>~4 GB&lt;/td>
 &lt;td>8 GB VM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>500 萬&lt;/td>
 &lt;td>~20 GB&lt;/td>
 &lt;td>32 GB VM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1000 萬&lt;/td>
 &lt;td>~40 GB&lt;/td>
 &lt;td>64 GB VM&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這是 head block 的記憶體，不含 query execution 跟 WAL replay 的暫時開銷。Heavy PromQL query（大範圍 aggregation、多 series join）會額外消耗數 GB 的暫時記憶體。&lt;/p>
&lt;p>判讀指標：&lt;code>prometheus_tsdb_head_series&lt;/code> 代表當前 active series 數量，&lt;code>process_resident_memory_bytes&lt;/code> 代表實際記憶體使用。兩者的比值偏離預期時（例如 50 萬 series 但記憶體用了 10 GB），可能是 query 記憶體壓力或 WAL corruption。&lt;/p>
&lt;h3 id="disk由-retention-期與-ingestion-rate-決定">Disk：由 retention 期與 ingestion rate 決定&lt;/h3>
&lt;p>Prometheus 的 disk 消耗 = ingestion rate × retention 期 × 壓縮後每 sample 大小（約 1-2 bytes，Gorilla 壓縮算法下的業界經驗值）。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Ingestion rate&lt;/th>
 &lt;th>Retention&lt;/th>
 &lt;th>預估 disk&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>10 萬 samples/sec&lt;/td>
 &lt;td>15 天&lt;/td>
 &lt;td>~130 GB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>10 萬 samples/sec&lt;/td>
 &lt;td>30 天&lt;/td>
 &lt;td>~260 GB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>50 萬 samples/sec&lt;/td>
 &lt;td>15 天&lt;/td>
 &lt;td>~650 GB&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Disk I/O 的瓶頸通常在 compaction — Prometheus 定期把 head block 壓縮成 persistent block。Compaction 期間的 disk write 跟 CPU 使用會短暫上升。SSD 環境下 compaction 通常不是問題；HDD 環境下可能造成 scrape timeout。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <a href="/blog/backend/04-observability/vendors/prometheus/" data-link-title="Prometheus" data-link-desc="Pull-based metrics 主流 OSS、PromQL 與 alerting">Prometheus</a> 的 vendor deep article，深化 overview「Cardinality 管理」跟「Memory pressure」段。初次接觸 Prometheus 的讀者建議先讀 <a href="/blog/backend/04-observability/vendors/prometheus/" data-link-title="Prometheus" data-link-desc="Pull-based metrics 主流 OSS、PromQL 與 alerting">Prometheus 服務頁</a>。</p></blockquote>
<h2 id="定位">定位</h2>
<p>Prometheus 的容量模型跟傳統資料庫不同 — 它的容量邊界主要受 active series 數量（cardinality）跟 retention 期決定，而非資料筆數或 disk size。理解 Prometheus 的資源消耗模型，才能判斷什麼時候單機夠用、什麼時候需要 remote write 卸載或遷移到 Mimir / Thanos。</p>
<h2 id="資源消耗模型">資源消耗模型</h2>
<h3 id="memory由-active-series-決定">Memory：由 active series 決定</h3>
<p>Prometheus 把近期的 time series 保存在記憶體（head block）。每個 active series 大約消耗 3-4 KB 記憶體（含 index、chunks、postings；Prometheus TSDB 的業界經驗值，實際依 label 長度與 chunk encoding 而定）。</p>
<table>
  <thead>
      <tr>
          <th>Active series</th>
          <th>預估 memory（head block）</th>
          <th>適合的機器規格</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>10 萬</td>
          <td>~400 MB</td>
          <td>任何 VM</td>
      </tr>
      <tr>
          <td>100 萬</td>
          <td>~4 GB</td>
          <td>8 GB VM</td>
      </tr>
      <tr>
          <td>500 萬</td>
          <td>~20 GB</td>
          <td>32 GB VM</td>
      </tr>
      <tr>
          <td>1000 萬</td>
          <td>~40 GB</td>
          <td>64 GB VM</td>
      </tr>
  </tbody>
</table>
<p>這是 head block 的記憶體，不含 query execution 跟 WAL replay 的暫時開銷。Heavy PromQL query（大範圍 aggregation、多 series join）會額外消耗數 GB 的暫時記憶體。</p>
<p>判讀指標：<code>prometheus_tsdb_head_series</code> 代表當前 active series 數量，<code>process_resident_memory_bytes</code> 代表實際記憶體使用。兩者的比值偏離預期時（例如 50 萬 series 但記憶體用了 10 GB），可能是 query 記憶體壓力或 WAL corruption。</p>
<h3 id="disk由-retention-期與-ingestion-rate-決定">Disk：由 retention 期與 ingestion rate 決定</h3>
<p>Prometheus 的 disk 消耗 = ingestion rate × retention 期 × 壓縮後每 sample 大小（約 1-2 bytes，Gorilla 壓縮算法下的業界經驗值）。</p>
<table>
  <thead>
      <tr>
          <th>Ingestion rate</th>
          <th>Retention</th>
          <th>預估 disk</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>10 萬 samples/sec</td>
          <td>15 天</td>
          <td>~130 GB</td>
      </tr>
      <tr>
          <td>10 萬 samples/sec</td>
          <td>30 天</td>
          <td>~260 GB</td>
      </tr>
      <tr>
          <td>50 萬 samples/sec</td>
          <td>15 天</td>
          <td>~650 GB</td>
      </tr>
  </tbody>
</table>
<p>Disk I/O 的瓶頸通常在 compaction — Prometheus 定期把 head block 壓縮成 persistent block。Compaction 期間的 disk write 跟 CPU 使用會短暫上升。SSD 環境下 compaction 通常不是問題；HDD 環境下可能造成 scrape timeout。</p>
<h3 id="cpu由-scrape-數量與-query-負載決定">CPU：由 scrape 數量與 query 負載決定</h3>
<p>Scrape 本身的 CPU 消耗不高（HTTP GET + parse），但 scrape 數量 × scrape 間隔決定了基本的 CPU 基線。1000 個 target × 15 秒間隔 = 每秒 ~67 次 scrape，單核可以處理。</p>
<p>Query 是 CPU 的主要消耗者。Recording rule evaluation、alert rule evaluation、dashboard panel 查詢各自佔 CPU。Recording rule 數量增長到數百條時，evaluation 的 CPU 消耗可能成為瓶頸。</p>
<p>判讀指標：<code>prometheus_rule_evaluation_duration_seconds</code> 的 p99 超過 evaluation interval 時，rule 跑不完、alert 會延遲。</p>
<h2 id="cardinality-失控的判讀">Cardinality 失控的判讀</h2>
<p>Cardinality 是 Prometheus 最常見的容量問題。一個意外的高 cardinality label（user_id、request_id、完整 URL）可以在分鐘內把 series 數從 10 萬推到 100 萬、消耗數 GB 記憶體。</p>
<h3 id="判讀訊號">判讀訊號</h3>
<ul>
<li><code>prometheus_tsdb_head_series</code> 持續成長、斜率陡峭</li>
<li><code>prometheus_tsdb_head_active_appenders</code> 成長（新 series 的寫入速率）</li>
<li>Prometheus 的 memory 持續上升、最終 OOM kill</li>
<li>Query 延遲增加（更多 series 要掃描）</li>
<li>Compaction 時間變長</li>
</ul>
<h3 id="定位方式">定位方式</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl"># 找出哪個 metric name 的 series 最多
</span></span><span class="line"><span class="ln">2</span><span class="cl">topk(10, count by (__name__)({__name__=~&#34;.+&#34;}))
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"># 找出哪個 job（scrape target）的 series 最多
</span></span><span class="line"><span class="ln">5</span><span class="cl">topk(10, count by (job)({__name__=~&#34;.+&#34;}))
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"># 找出某個 metric 的哪個 label 組合在爆
</span></span><span class="line"><span class="ln">8</span><span class="cl">count by (method, status) (http_requests_total)</span></span></code></pre></div><h3 id="修復方向">修復方向</h3>
<ul>
<li><strong>Label 白名單</strong>：在 scrape config 或 relabeling rule 中 drop 高 cardinality label</li>
<li><strong>Metric relabeling</strong>：<code>metric_relabel_configs</code> 在 scrape 後、寫入前移除特定 label</li>
<li><strong>Recording rule 替代</strong>：把高 cardinality metric 聚合成低 cardinality 的 recording rule，下游只讀 recording rule</li>
<li><strong>移到 traces</strong>：user_id / request_id 這類維度放在 <a href="/blog/backend/knowledge-cards/trace/" data-link-title="Trace" data-link-desc="說明 trace 如何重建跨服務請求的路徑、耗時與依賴關係">trace</a> 的 span attribute 而非 metric label</li>
</ul>
<h2 id="常見故障模式">常見故障模式</h2>
<h3 id="oom-kill">OOM Kill</h3>
<p><strong>觸發條件</strong>：active series 超過記憶體容量、或 heavy query 消耗大量暫時記憶體。</p>
<p><strong>表現</strong>：Prometheus process 被 kernel OOM killer 終止。重啟後 WAL replay 可能需要分鐘到十分鐘（取決於 WAL 大小），期間 scrape 跟 query 都不可用。</p>
<p><strong>預防</strong>：設定 memory limit alert（process_resident_memory_bytes / machine memory &gt; 70%）、tracking cardinality growth slope、query timeout 限制。</p>
<h3 id="scrape-timeout-連鎖">Scrape timeout 連鎖</h3>
<p><strong>觸發條件</strong>：target 的 metrics endpoint 回應慢（&gt; scrape_timeout）、或 target 數量超過 Prometheus 的並行 scrape 能力。</p>
<p><strong>表現</strong>：<code>up</code> metric 為 0、<code>scrape_duration_seconds</code> 升高、dashboard 出現資料斷層（missing data points）。大量 target 同時 timeout 時，Prometheus 的 scrape goroutine pool 被佔滿，影響其他健康 target 的 scrape。</p>
<p><strong>修復</strong>：調整 <code>scrape_timeout</code>（預設 10s，太短會造成 false timeout）、把慢 target 移到獨立的 scrape pool、或把 metrics endpoint 的回應最佳化（減少 expose 的 metric 數量）。</p>
<h3 id="wal-corruption">WAL corruption</h3>
<p><strong>觸發條件</strong>：Prometheus process 非正常終止（OOM kill、機器斷電）時，WAL 可能損壞。</p>
<p><strong>表現</strong>：重啟後 WAL replay 失敗、Prometheus 無法啟動。Error log 顯示 <code>WAL corrupted</code> 或 <code>invalid segment</code>。</p>
<p><strong>修復</strong>：刪除損壞的 WAL segment（丟失對應時間段的資料），重啟 Prometheus。嚴重時刪除整個 data 目錄重新開始（丟失所有歷史資料）。WAL 的持久性保證不如資料庫 — Prometheus 設計上允許短暫資料丟失，長期儲存靠 remote write 到 Mimir / Thanos。</p>
<h3 id="recording-rule-evaluation-lag">Recording rule evaluation lag</h3>
<p><strong>觸發條件</strong>：recording rule 數量多且表達式複雜、evaluation 時間超過 evaluation interval。</p>
<p><strong>表現</strong>：<code>prometheus_rule_group_last_duration_seconds</code> 超過 <code>prometheus_rule_group_interval_seconds</code>。Dashboard 讀 recording rule 的 panel 看到的資料落後當前時間。Alert rule 也在同一個 evaluation pipeline 裡，evaluation lag 會讓 alert 延遲觸發。</p>
<p><strong>修復</strong>：把重的 recording rule 拆到獨立的 rule group（各自 evaluation interval）、最佳化 PromQL expression（減少 aggregation 層數、縮小 time range）、或把 recording rule 卸載到 Mimir（ruler component 獨立擴展）。</p>
<h2 id="何時該從單機-prometheus-遷出">何時該從單機 Prometheus 遷出</h2>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>下一步</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Active series &gt; 500 萬、memory 吃緊（32 GB VM 上 head block ~20 GB + query overhead 接近上限）</td>
          <td>Remote write 到 Mimir / Thanos 做長期儲存</td>
      </tr>
      <tr>
          <td>需要跨 region / cluster 查詢</td>
          <td>Thanos query 或 Mimir multi-tenant</td>
      </tr>
      <tr>
          <td>Recording rule evaluation lag 持續</td>
          <td>把 rule evaluation 卸載到 Mimir ruler</td>
      </tr>
      <tr>
          <td>需要 HA（single Prometheus = SPOF）</td>
          <td>兩個 instance + Thanos dedup</td>
      </tr>
      <tr>
          <td>Retention 要 &gt; 90 天但 disk 不夠</td>
          <td>Remote write + 短 local retention</td>
      </tr>
  </tbody>
</table>
<p>遷出的第一步通常是加 remote write — Prometheus 繼續本地 scrape 跟短期查詢，長期資料寫到遠端。這是最低風險的演進路徑，不需要改 scrape config 或 PromQL。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li><a href="/blog/backend/04-observability/vendors/prometheus/" data-link-title="Prometheus" data-link-desc="Pull-based metrics 主流 OSS、PromQL 與 alerting">Prometheus 服務頁</a>：overview 跟日常操作</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 治理的完整策略</li>
<li><a href="/blog/backend/04-observability/metrics-basics/" data-link-title="4.2 metrics 與 SLI/SLO" data-link-desc="整理 counter、gauge、histogram 與服務健康指標">4.2 metrics basics</a>：recording rule 跟 rollup 的查詢面設計</li>
<li><a href="/blog/backend/04-observability/vendors/grafana-stack/" data-link-title="Grafana Stack" data-link-desc="Grafana / Loki / Tempo / Mimir / Pyroscope 全棧">Grafana Stack</a>：Mimir 作為 Prometheus 的長期儲存後端</li>
<li><a href="/blog/backend/04-observability/observability-query-design/" data-link-title="4.23 觀測查詢設計" data-link-desc="把觀測資料的讀取路徑當系統設計問題處理：三種查詢模式、storage tiering、pre-aggregation 與資源治理">4.23 觀測查詢設計</a>：recording rule 在查詢設計中的定位</li>
</ul>
]]></content:encoded></item><item><title>1.10 KV / Document DB 容量規劃</title><link>https://tarrragon.github.io/blog/backend/01-database/kv-document-capacity-planning/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/kv-document-capacity-planning/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>KV / Document DB 的容量規劃跟傳統 OLTP 完全不同。OLTP 容量靠「instance type 升級 + read replica」、KV 靠「partition 切分 + capacity unit 配置」。兩者瓶頸不同、可擴範圍不同、設計取捨也不同。&lt;/p>
&lt;p>本章針對 DynamoDB、Azure Cosmos DB、Google Cloud Bigtable、MongoDB Atlas 等主流 KV / Document DB、整理容量規劃的共通方法論。讀完後讀者能回答：partition key 怎麼設計才不會 hot partition、on-demand vs provisioned 怎麼選、什麼時候從 single-region 升到 multi-region。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取&lt;/a> 的關係：1.1 處理 OLTP 高併發、本章處理 KV 高併發。兩者讀者群有重疊但解法不同。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型&lt;/a> 的關係：本章從 &lt;em>DB 視角&lt;/em> 看容量、9.4 / 9.6 從 &lt;em>workload 視角&lt;/em> 看容量、兩者互補。&lt;/p>
&lt;h2 id="kv--document-db-的容量模型">KV / Document DB 的容量模型&lt;/h2>
&lt;p>KV 容量模型可以簡化成一條公式：&lt;strong>總容量 = partition 數量 × 每 partition 上限&lt;/strong>。&lt;/p>
&lt;p>vendor 不同、細節不同，但都遵循這個邏輯。&lt;/p>
&lt;h3 id="http-api-db-vs-connection-based-db-的本質差異">HTTP API DB vs connection-based DB 的本質差異&lt;/h3>
&lt;p>KV DB 在 surge 場景比 OLTP 有結構性優勢的主因、不只是 partition 設計、是 &lt;em>連線模型&lt;/em> 的本質差異。&lt;/p>
&lt;p>&lt;strong>Connection-based DB&lt;/strong>（PostgreSQL、MySQL、MongoDB、Cassandra）：&lt;/p>
&lt;ul>
&lt;li>用戶端跟 DB 維持 TCP connection、connection 有 state（authenticated session）&lt;/li>
&lt;li>每個 connection 在 DB server 端佔記憶體 + 一個 process/thread&lt;/li>
&lt;li>connection 上限通常 1K-5K&lt;/li>
&lt;li>application 想開更多 connection、DB 直接拒絕&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>HTTP API DB&lt;/strong>（DynamoDB、Cosmos DB、Bigtable、Firestore）：&lt;/p>
&lt;ul>
&lt;li>用戶端每次 request 開新 HTTP connection（或用 keep-alive 池）&lt;/li>
&lt;li>DB 端沒有「per-user connection state」、是 stateless API server&lt;/li>
&lt;li>沒有 connection 上限概念、能力上限是 &lt;em>每 partition 的 RU / RCU&lt;/em>&lt;/li>
&lt;li>application 加多少 instance 都不影響 DB&lt;/li>
&lt;/ul>
&lt;p>對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &amp;#43; AWS Media Services 撐 30 channels live &amp;#43; 5M MAU、工程工時下降 90%">9.C29 Lemino&lt;/a> — NTT DOCOMO 串流服務選 DynamoDB 而非 RDB 的關鍵原因是 RDB 的 connection limit 在 surge 場景變成 bottleneck、HTTP API 模型沒這個問題。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>KV / Document DB 的容量規劃跟傳統 OLTP 完全不同。OLTP 容量靠「instance type 升級 + read replica」、KV 靠「partition 切分 + capacity unit 配置」。兩者瓶頸不同、可擴範圍不同、設計取捨也不同。</p>
<p>本章針對 DynamoDB、Azure Cosmos DB、Google Cloud Bigtable、MongoDB Atlas 等主流 KV / Document DB、整理容量規劃的共通方法論。讀完後讀者能回答：partition key 怎麼設計才不會 hot partition、on-demand vs provisioned 怎麼選、什麼時候從 single-region 升到 multi-region。</p>
<p>跟 <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取</a> 的關係：1.1 處理 OLTP 高併發、本章處理 KV 高併發。兩者讀者群有重疊但解法不同。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a> 跟 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 的關係：本章從 <em>DB 視角</em> 看容量、9.4 / 9.6 從 <em>workload 視角</em> 看容量、兩者互補。</p>
<h2 id="kv--document-db-的容量模型">KV / Document DB 的容量模型</h2>
<p>KV 容量模型可以簡化成一條公式：<strong>總容量 = partition 數量 × 每 partition 上限</strong>。</p>
<p>vendor 不同、細節不同，但都遵循這個邏輯。</p>
<h3 id="http-api-db-vs-connection-based-db-的本質差異">HTTP API DB vs connection-based DB 的本質差異</h3>
<p>KV DB 在 surge 場景比 OLTP 有結構性優勢的主因、不只是 partition 設計、是 <em>連線模型</em> 的本質差異。</p>
<p><strong>Connection-based DB</strong>（PostgreSQL、MySQL、MongoDB、Cassandra）：</p>
<ul>
<li>用戶端跟 DB 維持 TCP connection、connection 有 state（authenticated session）</li>
<li>每個 connection 在 DB server 端佔記憶體 + 一個 process/thread</li>
<li>connection 上限通常 1K-5K</li>
<li>application 想開更多 connection、DB 直接拒絕</li>
</ul>
<p><strong>HTTP API DB</strong>（DynamoDB、Cosmos DB、Bigtable、Firestore）：</p>
<ul>
<li>用戶端每次 request 開新 HTTP connection（或用 keep-alive 池）</li>
<li>DB 端沒有「per-user connection state」、是 stateless API server</li>
<li>沒有 connection 上限概念、能力上限是 <em>每 partition 的 RU / RCU</em></li>
<li>application 加多少 instance 都不影響 DB</li>
</ul>
<p>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a> — NTT DOCOMO 串流服務選 DynamoDB 而非 RDB 的關鍵原因是 RDB 的 connection limit 在 surge 場景變成 bottleneck、HTTP API 模型沒這個問題。</p>
<p>判讀含義：選 KV DB 不只是「擴容容易」、是 <em>連線模型</em> 適合無 state HTTP 服務的天然契合。微服務數量增加時、HTTP API DB 不需要每次都 review connection pool 設定。但若 application 仍以 SQL transaction 為主流程設計、改 KV 需要 <em>改 application 架構</em>、不是換 driver 而已。</p>
<p><strong>Amazon DynamoDB</strong>：</p>
<ul>
<li>容量單位是 RCU（Read Capacity Unit）跟 WCU（Write Capacity Unit）</li>
<li>1 RCU = 1 strongly consistent read of 4KB / sec、2 eventually consistent reads</li>
<li>1 WCU = 1 write of 1KB / sec</li>
<li>每個 partition 上限：3000 RCU / 1000 WCU、底層 partition 數量透明</li>
</ul>
<p><strong>Azure Cosmos DB</strong>：</p>
<ul>
<li>容量單位是 RU（Request Unit）— 把 read / write / query 統一抽象</li>
<li>1 RU = strongly consistent read of 1KB document</li>
<li>寫成本約 5x read、複雜 query 可達數百 RU</li>
<li>每個 logical partition 上限：10,000 RU/s</li>
</ul>
<p><strong>Google Cloud Bigtable</strong>：</p>
<ul>
<li>容量單位是 node（SSD / HDD）</li>
<li>每個 node 約 10,000 reads/sec、10,000 writes/sec（依 row size）</li>
<li>partition 透明、靠 tablet 自動分裂</li>
</ul>
<p><strong>MongoDB Atlas</strong>：</p>
<ul>
<li>容量單位是 cluster tier（M10、M30、M60 等）+ shard</li>
<li>每個 shard 是獨立 mongod replica set、容量按 instance type 跟 storage</li>
<li>主動 sharding 設計、跟 DynamoDB 透明 partition 不同</li>
</ul>
<p><strong>共通點</strong>：容量上限不是「單一 number」、是「partition / shard 數量 × 每 partition 上限」。要擴容、要嘛加 partition、要嘛升級 partition、不能像 OLTP 一樣換更大 instance。</p>
<h2 id="partition-key-設計容量的命脈">Partition key 設計：容量的命脈</h2>
<p>partition key 設計不均勻、實際容量遠低於名義。這是 KV DB 最常見的 production issue。</p>
<p><strong>Hot partition 的成因</strong>：</p>
<ul>
<li>名義容量 = partition 數量 × 每 partition 上限</li>
<li>實際容量 = 最熱 partition 上限（如果分布不均）</li>
<li>100K RPS 名義能撐、若 80% 流量集中在 1 個 partition、實際 <em>只能撐 3K RPS（DynamoDB partition 上限）</em></li>
</ul>
<p><strong>識別 hot partition 的訊號</strong>：</p>
<ul>
<li>throughput 上不去、但 average resource utilization 低</li>
<li>某些 key 的 request latency 飆、其他 key 正常</li>
<li>DynamoDB throttling event 出現（即使 capacity 還沒滿）</li>
<li>Cosmos DB 顯示「per-partition RU consumption skew」</li>
</ul>
<p><strong>設計策略</strong>：</p>
<ol>
<li><strong>天然均勻 partition key</strong>：user_id、order_id、device_id 等天然分布廣的 ID。最簡單、最常用。</li>
<li><strong>Composite partition key</strong>：把容易集中的維度（event_id）跟均勻的維度（user_id_hash）組合。例如 <code>event_id#user_id_hash_mod_100</code>、強制把同一 event 的流量分散到 100 個 sub-partition。</li>
<li><strong>Write sharding</strong>：在 partition key 後加 random suffix。<code>event_id#0</code> ~ <code>event_id#9</code> 讓同一個 event 變成 10 個 partition。讀的時候要 scatter-gather 從 10 個 partition 讀回來。</li>
<li><strong>Time-bucket</strong>：對時序資料、加 minute / hour bucket。<code>metric#2026-05-13-T12</code>、每個時段一個 partition。</li>
</ol>
<p><strong>對應案例</strong>：</p>
<ul>
<li><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> — 9000 萬 reads/sec 靠 partition 設計均勻、不是純擴 capacity</li>
<li><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> — 售票 event_id 天然容易 hot、必須用 composite key 或 write sharding 分散</li>
<li><a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> — Cosmos DB synthetic partition key 強制分散</li>
</ul>
<p>詳見 <a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">Hot Partition 卡片</a>。</p>
<h3 id="彈性來自-partition-key-均勻分布">彈性來自 partition key 均勻分布</h3>
<p>KV DB 的吞吐彈性等於 partition key 均勻分布的結果。partition key 均勻時、總容量 ≈ partition 數量 × 單 partition 上限；partition key 不均時、實際容量 = 最熱 partition 上限（DynamoDB 每 partition 3000 RCU / 1000 WCU）、跟 partition 總數無關。</p>
<p>對應 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> — 售票 IOPS 從 20 衝到 135K 的 6,750 倍彈性、前提是 partition key 把流量分散到大量 partition（合理做法是 composite key <code>event_id + user_id_hash</code> 或 write sharding <code>event_id + random_suffix</code>）。若用裸 <code>event_id</code> 當 partition key、同一場演唱會所有訂單擠進同一個 partition、實際 IOPS 上限被鎖在 1000 WCU、跟 partition 總數無關。</p>
<p>判讀重點：讀「Amazon Ads 9000 萬 reads/sec」、「DynamoDB 1.51 億 RPS」這類數字、要追問「partition 設計是什麼」、再判斷自己的服務能否複製。換 DynamoDB 是必要前提、partition key 設計是充分前提；只換 DB 而沒解決 partition key、會出「換了 DB 但 hot partition 依舊」的事故。</p>
<h2 id="capacity-modeon-demand-vs-provisioned">Capacity mode：on-demand vs provisioned</h2>
<p>DynamoDB / Cosmos DB 都提供兩種容量模式、各有適用場景。</p>
<p><strong>On-demand（pay-per-use）</strong>：</p>
<ul>
<li>不需事前配置 RCU / WCU / RU</li>
<li>自動 scale up / down、處理突發流量</li>
<li>單位成本高（約 7x provisioned）</li>
<li>適合：流量不可預測、burst 頻繁、開發 / 測試環境</li>
</ul>
<p><strong>Provisioned（預配置）</strong>：</p>
<ul>
<li>預先訂購 RCU / WCU / RU</li>
<li>超過配額會 throttle（除非開 auto-scaling）</li>
<li>單位成本低</li>
<li>適合：流量可預測、sustained workload、生產環境</li>
</ul>
<p><strong>選型決策</strong>：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>建議 mode</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>流量 peak/avg 比 &lt; 3x</td>
          <td>provisioned + auto-scaling</td>
      </tr>
      <tr>
          <td>流量 peak/avg 比 &gt; 5x</td>
          <td>on-demand</td>
      </tr>
      <tr>
          <td>流量極端 bursty（flash-sale）</td>
          <td>on-demand</td>
      </tr>
      <tr>
          <td>sustained growth 穩定上升</td>
          <td>provisioned + scheduled scaling</td>
      </tr>
      <tr>
          <td>短期測試 / POC</td>
          <td>on-demand</td>
      </tr>
      <tr>
          <td>已知大事件（Black Friday）</td>
          <td>provisioned baseline + scheduled scale-up</td>
      </tr>
  </tbody>
</table>
<p><strong>對應案例</strong>：</p>
<ul>
<li><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> — TiDB 必須長期 over-provision、換 DynamoDB on-demand 後 pay-per-use、50% 成本下降</li>
<li><a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay</a> — sustained 3 億 msg/day 適合 provisioned + auto-scaling</li>
<li><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> — 9000 萬 RPS sustained workload 必然 provisioned + careful tuning</li>
</ul>
<p>詳見 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 的成本曲線分析。</p>
<h3 id="計費粒度-vs-工程顆粒">計費粒度 vs 工程顆粒</h3>
<p>KV / Document DB 的計費單位（DynamoDB 的 RCU/WCU、Cosmos DB 的 RU、Spanner 的 processing unit）決定容量規劃可以從多小開始。計費粒度太大、中小規模負載付過多錢；計費粒度太小、大規模負載要管理很多細項。</p>
<p>對應 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> — Spanner 早期最小單位是 100 processing units（pu）≈ 1 node、對中小負載門檻過高。後來推出 100 pu 起跳的 granular sizing、讓容量規劃可以從小開始、降低 onboarding 門檻。</p>
<p><strong>選型含義</strong>：</p>
<ul>
<li><strong>新服務 / 中小規模</strong>：選計費粒度小的選項（Cosmos DB serverless、Spanner granular sizing、DynamoDB on-demand）、避免一開始就為了「未來會用到」過配。中小規模付過配成本、實際就是替「不確定的未來」付保險費、保險費過高代表選錯產品。</li>
<li><strong>穩定大規模</strong>：計費粒度可大（DynamoDB provisioned with reserved capacity、Spanner full-node provisioning）、單價較低。Reserved capacity 通常綁 1-3 年合約、要看業務 <em>未來 12-24 月需求是否穩定</em>、若業務量可能下降或遷移、Reserved 反成沉沒成本；若業務量穩定上升、Reserved 是合理 hedging。</li>
<li><strong>POC / 測試</strong>：選 on-demand 或 serverless、付實際用量、別為了未實際 production 的 workload 付 reserved 成本。</li>
</ul>
<p>判讀重點：計費粒度同時是 <em>vendor 商業策略</em> 跟 <em>工程顆粒</em>、選 vendor 時要看 <em>min sizing</em> 跟 <em>增量 granularity</em>、不只看 max throughput。</p>
<h3 id="業務邏輯變化--讀寫比跳量級">業務邏輯變化 → 讀寫比跳量級</h3>
<p>讀寫比變化是容量規劃的早期警訊、但常被忽略。原始容量規劃通常基於某個讀寫比（例如 1:1 或 5:1）、業務邏輯改變可能讓比例跳一個量級、原容量規劃失效。</p>
<p>對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> — 廣告事件量測讀寫比 18:1（曝光發生 1 次、後續查詢 18 次）。如果業務新增即時報表功能、讀次數從 18 跳到 50、容量規劃要重做、不是「再加一點 capacity」。</p>
<p><strong>常見業務變化導致讀寫比跳量級</strong>：</p>
<ul>
<li>新增即時 dashboard：每筆資料被查詢頻率從 1 次跳到 N 次</li>
<li>新增推薦演算法：每用戶 read profile 從每次登入 1 次變成每次推薦 1 次（× 推薦頻率）</li>
<li>新增 audit / compliance 查詢：每筆敏感資料額外被查 5-10 次</li>
<li>新增 cache：讀次數從 100 降到 5（cache hit rate 95%）— 跟其他變化方向相反、是 <em>capacity 該縮容</em> 的訊號、若沒同步 review 反而會繼續按舊容量付錢</li>
<li>新增 anti-fraud 檢測：每寫入觸發 N 次 read 驗證</li>
</ul>
<p>判讀重點：容量規劃 review cadence 不只看流量、要 review <em>讀寫比</em> 是否漂移。比例跳量級是設計需要重做的訊號、不是單純 capacity 增加（或減少）的訊號。</p>
<h2 id="一致性模型strong-vs-eventual-vs-session">一致性模型：strong vs eventual vs session</h2>
<p>KV / Document DB 通常提供多個 <a href="/blog/backend/knowledge-cards/consistency-level/" data-link-title="Consistency Level" data-link-desc="資料系統對讀寫一致性語意的可選擇層級">consistency level</a>、不同 level 對應不同延遲跟可用性。</p>
<p><strong>DynamoDB</strong>：</p>
<ul>
<li>Eventually consistent reads（預設、便宜）：1 sec 內收斂、cost = 0.5 RCU</li>
<li>Strongly consistent reads：跨 AZ <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a>、cost = 1 RCU、不可跨 region</li>
<li>沒有中間 level</li>
</ul>
<p><strong>Cosmos DB</strong>（最豐富）：</p>
<ul>
<li><strong>Strong</strong>：linearizable、跨 region quorum、最高 latency</li>
<li><strong>Bounded staleness</strong>：訂上限（時間 / 版本差異）</li>
<li><strong>Session</strong>：同一 session 內強一致（最常用）</li>
<li><strong>Consistent prefix</strong>：保證寫入順序、不保證收斂時間</li>
<li><strong>Eventual</strong>：最便宜、最終一致</li>
</ul>
<p><strong>Bigtable</strong>：</p>
<ul>
<li>Single-region：strongly consistent</li>
<li>Replicated：eventually consistent</li>
</ul>
<p><strong>選 consistency level 的工程後果</strong>：</p>
<ul>
<li>Strong consistency → 跨 region 延遲（quorum round-trip）</li>
<li>Eventual → 用戶可能看到舊資料、需要 application 容忍</li>
<li>Session → 大多數網路服務的 sweet spot（用戶看自己寫的東西要立即、別人寫的可以稍晚）</li>
</ul>
<p><strong>對應案例</strong>：</p>
<ul>
<li><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> — external consistency（線性化）跨地區、付出 quorum 延遲代價</li>
<li><a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365 Cosmos DB</a> — 分析平台用 weakest consistency 換最大 throughput</li>
</ul>
<p>詳見 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">1.3 Transaction Boundary</a> 的一致性取捨。</p>
<h2 id="multi-model-取捨">Multi-model 取捨</h2>
<p>部分 KV / Document DB 支援多個 model interface、同一服務跑不同抽象。</p>
<p><strong>Cosmos DB（最廣 multi-model）</strong>：</p>
<ul>
<li>SQL API（document）</li>
<li>MongoDB API（document、wire-protocol compatible）</li>
<li>Cassandra API（wide-column）</li>
<li>Gremlin（graph）</li>
<li>Table（key-value）</li>
</ul>
<p><strong>DynamoDB（KV + document）</strong>：</p>
<ul>
<li>原生 KV、但 attribute 可以是 nested map / list（document-like）</li>
<li>沒有 SQL interface（PartiQL 是 query language、不是 model）</li>
</ul>
<p><strong>Bigtable（wide-column）</strong>：</p>
<ul>
<li>沒有 multi-model、純 wide-column</li>
<li>替代方案：用 Spanner + Bigtable 組合</li>
</ul>
<p><strong>Multi-model 的優缺</strong>：</p>
<ul>
<li>優勢：同一團隊不必管多個 vendor、ops 簡化</li>
<li>優勢：不同 use case 用同一 datastore、減少 data sync</li>
<li>限制：vendor lock-in 加深、難換</li>
<li>限制：每個 API 都不是 <em>最好</em> 的（compromise）— MongoDB API 跟 native MongoDB 有 behavior 差異</li>
</ul>
<p><strong>選型建議</strong>：</p>
<ul>
<li>已用 single model → 不必為 multi-model 而換</li>
<li>多種 use case 同時上 → 評估 Cosmos DB（特別是 MongoDB workload + 新需求）</li>
<li>純 KV 高吞吐 → DynamoDB / Bigtable 比 Cosmos DB 通常便宜</li>
</ul>
<p><strong>對應案例</strong>：</p>
<ul>
<li><a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a> — MongoDB → Cosmos DB MongoDB API、應用層幾乎不改、底層改用 Cosmos 分散式架構</li>
<li><a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> — 用 SQL API、不需要 MongoDB compat</li>
</ul>
<h2 id="kv-db-作為寫入緩衝的特殊用法">KV DB 作為寫入緩衝的特殊用法</h2>
<p>本節展開 KV 在 <em>flash-sale 架構</em> 的特殊角色、屬於資料層責任、但跟 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a> 跟 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 互補（後者主寫 broker / queue 設計、本節聚焦把 KV 當 buffer 的取捨）。</p>
<p><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 揭露一個非傳統用法：DynamoDB 不當 OLTP、當 <em>durable queue</em>。</p>
<p><strong>模式</strong>：前端把訂單塞進 DynamoDB（高吞吐、partition 均勻）、後端 legacy server 按自己能承受的速度從 DynamoDB 消費。</p>
<p><strong>為什麼用 DynamoDB 而非 SQS / Kafka</strong>：</p>
<ul>
<li>DynamoDB Stream 提供 change data capture、後端可以 stream 消費</li>
<li>寫入後立即可查（OLTP-like）、不是純 fire-and-forget</li>
<li>partition 設計讓單一事件可以分散到多個 partition</li>
<li>同樣 vendor、不必另起一個 broker 服務</li>
</ul>
<p><strong>適用場景</strong>：</p>
<ul>
<li>突發流量遠超後端處理能力</li>
<li>後端是 legacy、不容易擴</li>
<li>需要寫入後立即可查（用戶看「我下單成功了」）</li>
</ul>
<p><strong>不適用場景</strong>：</p>
<ul>
<li>純 fire-and-forget（用 SQS 更便宜）</li>
<li>高吞吐 stream processing（用 Kafka 更專業）</li>
<li>順序性嚴格要求（DynamoDB Streams 只在 partition 內保證順序）</li>
</ul>
<p>詳見 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 案例</a> 的詳細分析。</p>
<h2 id="連線管理跟-oltp-完全不同">連線管理：跟 OLTP 完全不同</h2>
<p>KV / Document DB 通常是 <em>HTTP / gRPC 介面</em>、不是 <em>connection pool</em>。這是跟 OLTP 完全不同的設計、影響應用層架構。</p>
<p><strong>OLTP（PostgreSQL / MySQL）</strong>：</p>
<ul>
<li>每個 application instance 維護 connection pool（10-100 connections）</li>
<li>connection 是有狀態的（transaction、session variable）</li>
<li>pool size × instance 數量 ≤ DB 上限（PostgreSQL 預設 100、PgBouncer 可破百）</li>
<li><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino 案例</a> 揭露 RDB connection 是隱性 bottleneck</li>
</ul>
<p><strong>KV（DynamoDB / Cosmos DB）</strong>：</p>
<ul>
<li>純 HTTP / gRPC、無 stateful connection</li>
<li>每個 request 獨立、不必預先 establish connection</li>
<li>沒有 connection limit 概念</li>
<li>應用層擴容不會打爆 DB connection</li>
</ul>
<p>這個差異是 KV DB 在 <em>surge 場景</em> 比 OLTP 有優勢的主因 — KV 不會 connection saturate。</p>
<h2 id="隱性限流-vs-明確限流">隱性限流 vs 明確限流</h2>
<p>flash-sale 或極端負載場景的限流可能分散在多層元件、不是單一「rate limiter」。同一架構可能同時包含 <em>隱性</em> 限流（用 DB / LB 上限自然攔截）跟 <em>明確</em> 限流（用排隊系統精確控速）。</p>
<p>對應 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> — 售票架構圖上看不到明確「rate limiter」元件、但限流發生在多層：</p>
<ul>
<li><strong>DynamoDB 寫入排隊</strong>：DynamoDB 把訂單塞進 queue、傳統 server 按自己能力消費 — DynamoDB throughput 就是隱性限流</li>
<li><strong>ELB max connection</strong>：load balancer 上限自動拒絕超量請求</li>
<li><strong>Application 層 connection pool</strong>：超過 pool size 的 request 排隊或被拒</li>
<li><strong>付款層獨立</strong>：搶票流量塞爆時、付款不受影響、低頻路徑「自然限流」</li>
</ul>
<p>對比 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek Virtual Waiting Room</a> 的 <em>明確限流</em>：用 Counters table 精確控發 token 速率、用戶看得到排隊位置。</p>
<p><strong>選擇取捨</strong>：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>隱性限流（Tixcraft）</th>
          <th>明確限流（SeatGeek）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>用戶體驗</td>
          <td>用戶以為成功、實際排隊</td>
          <td>用戶看得到等待時間</td>
      </tr>
      <tr>
          <td>流量吸收能力</td>
          <td>極高（DB 直接吸）</td>
          <td>受限於 token 發放速度</td>
      </tr>
      <tr>
          <td>開發複雜度</td>
          <td>低（用 DB 自帶 throughput）</td>
          <td>高（需要 token 系統）</td>
      </tr>
      <tr>
          <td>失敗模式</td>
          <td>DB 滿了用戶才被拒</td>
          <td>排隊系統爆了用戶被拒</td>
      </tr>
      <tr>
          <td>適合業務</td>
          <td>流量瞬間到頂、要全收</td>
          <td>流量持續高、要排序公平</td>
      </tr>
  </tbody>
</table>
<p><strong>失敗模式延伸</strong>：隱性限流的失敗特徵是「provisioned capacity / connection pool 飽和、用戶看到 5xx / timeout、沒人收到排隊位置」— 監控訊號是 DynamoDB throttling event 或 ELB queue length 飆。明確限流的失敗特徵是「排隊系統本身的 DB / counter 飽和、token 發不出來、所有用戶包含 VIP 都被擋」— 監控訊號是 token issuance success rate 掉。兩種失敗對應不同 runbook、混在同一 alert dashboard 會誤判。</p>
<p><strong>適合業務延伸</strong>：隱性限流適合「流量瞬間到頂、業務願意接受用戶看不見排隊」的場景（演唱會搶票、Black Friday 開賣瞬間、限量商品）— 業務優先收住流量、用戶體驗可以事後解釋。明確限流適合「流量持續高、用戶等待時間長、需要顯示進度減少跳離」的場景（IPO 開盤、長期熱門商品上架、跨小時的搶購事件）— 用戶能看到「我還有 30 分鐘」會繼續等。</p>
<p>判讀重點：選哪種限流取決於業務願意接受什麼用戶體驗、不是工程偏好。隱性限流用透明度換流量吸收能力、明確限流用流量吸收能力換體驗可見度。兩者並存、沒有「best practice」。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day 2025</a></td>
          <td>DynamoDB 24 小時 1.51 億 RPS、毫秒級延遲、可預期峰值上限參考</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></td>
          <td>9000 萬 RPS + 99.999% 可用 — partition 均勻設計典範</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a></td>
          <td>Cosmos DB 1M RU/s + multi-model + global distribution</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
          <td>DynamoDB 當 durable queue、IOPS 20→135K</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a></td>
          <td>DynamoDB 4 表 + Lambda 實作 virtual waiting room、跟 Tixcraft 的隱性緩衝形成姊妹案</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a></td>
          <td>30x DAU surge、DynamoDB 撐 <a href="/blog/backend/knowledge-cards/control-plane/" data-link-title="Control Plane" data-link-desc="負責下發策略、配置與路由決策的控制層">control plane</a></td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a></td>
          <td>遊戲後端 KV、billions of requests + single-digit ms</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a></td>
          <td>TiDB → DynamoDB、50% 成本下降的取捨</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS</a></td>
          <td>Black Friday 1.67 億請求 / 24h、Cosmos DB 多 region</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a></td>
          <td>99.999% 跨 15 region、DynamoDB 為預設 DB</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay</a></td>
          <td>3 億訊息 / 天、TTL 自動清理</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">9.C27 Disney+</a></td>
          <td>billions of actions daily、watchlist + 播放進度</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a></td>
          <td>connection limit 才是 RDB bottleneck、改用 DynamoDB</td>
      </tr>
  </tbody>
</table>
<p><a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a> 把 DynamoDB 當 <em>排隊調度系統</em>、不只當 queue buffer：用 Counters table 控發 token 的速率、Queue table 紀錄序號、Connection table 串 WebSocket。這個架構跟 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 的「全部塞進 DynamoDB 隱性緩衝」是兩種對立取捨 — Tixcraft 用透明度換流量吸收能力、SeatGeek 用流量吸收能力換體驗可見度。判讀重點：KV DB 不只能當 OLTP 替代品、4 張表組合就能變成業務級調度引擎、選表前要先確定業務需要哪一面。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/00-service-selection/state-storage-selection/" data-link-title="0.2 狀態與資料儲存選型" data-link-desc="區分 source of truth、快取、搜尋索引、event log 與 object storage 的選型邊界">0.2 State Storage Selection</a> — KV vs OLTP vs SearchIndex 選型</li>
<li>平行：<a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取</a>（OLTP 版本）/ <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">1.3 Transaction Boundary</a></li>
<li>下游：<a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a>、<a href="/blog/backend/01-database/large-scale-db-migration/" data-link-title="1.12 大規模 DB 遷移實戰" data-link-desc="跨 DB 遷移的 dual-write、[shadow read](/backend/knowledge-cards/shadow-read/)、cutover、rollback 流程 — 從實戰案例提煉的工程做法">1.12 大規模 DB 遷移實戰</a>（含「預設 DB 治理 pattern」— KV 在大規模平台的選型治理）</li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>（hot partition 量測）、<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>、<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界</a></li>
<li>DynamoDB 深入：<a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">partition key 反模式</a>、<a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">on-demand vs provisioned 切換</a>、<a href="/blog/backend/01-database/vendors/dynamodb/single-table-design-pattern/" data-link-title="DynamoDB Single-Table Design：從適用度前置判讀到 access pattern 反推 PK/SK" data-link-desc="DynamoDB single-table 設計不是「資料表越少越好」，而是 access pattern 反推 PK/SK 跟 GSI；本文先做 DynamoDB 適用度 4 軸前置判讀（PK 天然均勻 / control plane vs data plane / consistency / access pattern 穩定），再展開設計流程、failure modes 與 durable queue 正向用例">single-table design</a>、<a href="/blog/backend/01-database/vendors/dynamodb/gsi-lsi-design/" data-link-title="DynamoDB GSI 與 LSI 設計：access pattern 補位、projection、consistency 跟 DAX 補位" data-link-desc="GSI / LSI 是 single-table 沒覆蓋的 access pattern 補位、不是萬靈丹；本文涵蓋 projection 三型選擇、sparse index、GSI 自己會 hot partition、DAX 讀峰值補位的觸發條件（含 Capcom 是 derive vs Lemino 是 case fact 的分層）">GSI / LSI 設計</a></li>
<li>Cosmos DB 深入：<a href="/blog/backend/01-database/vendors/cosmosdb/partition-key-design/" data-link-title="Cosmos DB Partition Key Design：synthetic / composite / hierarchical &#43; 不可逆性硬約束" data-link-desc="Cosmos DB logical partition 10000 RU/s 上限、partition key 不可改、三種設計模式（synthetic / composite / hierarchical）、跟 DynamoDB / MongoDB 可逆性對比、latency budget 拆解 — 從 Minecraft Earth &#43; ASOS 切入">partition key 設計</a>、<a href="/blog/backend/01-database/vendors/cosmosdb/ru-cost-model-sizing/" data-link-title="Cosmos DB RU/s 成本模型 &#43; 容量規劃：RU 思維、payload、index、provisioned vs autoscale vs serverless" data-link-desc="從 CPU&#43;IOPS 思維轉到 RU 思維的學習曲線、依負載形狀選容量模式、payload &#43; index policy 對 RU 的影響、autoscale reactive 限制 — 從 ASOS Black Friday &#43; Minecraft Earth 1M RU/s 壓測切入">RU 成本模型</a>、<a href="/blog/backend/01-database/vendors/cosmosdb/consistency-levels-engineering/" data-link-title="Cosmos DB 5 Consistency Levels：Session 預設、Bounded staleness、Strong 邊界跟跨 collection 分流策略" data-link-desc="Cosmos DB 5 個 consistency level 的工程選擇邏輯、Session 為何是 production 預設、per-request override 跟跨 collection 分流的進階策略、Strong &#43; multi-region 互斥的 cross-link — 從 Minecraft Earth &#43; ASOS 切入">一致性層次工程</a></li>
<li>MongoDB 深入：<a href="/blog/backend/01-database/vendors/mongodb/shard-key-selection/" data-link-title="MongoDB Shard Key Selection：hashed vs ranged、單 cluster 切 shard vs 多 cluster 切 blast radius" data-link-desc="MongoDB sharded cluster shard key 選型（hashed / ranged / compound）、單 cluster 分 shard vs 多 cluster 分 blast radius 對照、跟 DynamoDB / Cosmos DB partition key 可逆性的跨 vendor 紀律">shard key 選型</a>、<a href="/blog/backend/01-database/vendors/mongodb/schema-design-pattern/" data-link-title="MongoDB Schema Design Pattern：contract layer 在哪 vs embedded / reference" data-link-desc="MongoDB document schema 真正的 production 議題不是 embedded vs reference 二選一、是 schema contract 該放 DB 層 validator 還是 app 層 abstraction；含 Toyota polymorphic governance、Forbes abstraction layer、time-series collection 邊界">schema design pattern</a>、<a href="/blog/backend/01-database/vendors/mongodb/connection-management-and-cache-layer/" data-link-title="MongoDB Connection Management and Cache Layer：driver × 部署模型 × cache × predictive scaling" data-link-desc="MongoDB 大規模 OLTP 撞牆不是單一 driver 議題、是 driver × 部署模型 × cache × scaling trigger 三層協作；含 Coinbase mongobetween / freshness token / ML 預測擴容三件套 &#43; 適用範圍紀律">connection 管理與 cache 層</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">Hot Partition</a></li>
<li><a href="/blog/backend/knowledge-cards/saturation-point/" data-link-title="Saturation Point" data-link-desc="說明系統從線性穩態進入 latency 指數成長區的關鍵流量點">Saturation Point</a></li>
<li><a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">Connection Pool</a></li>
<li><a href="/blog/backend/knowledge-cards/tail-latency/" data-link-title="Tail Latency" data-link-desc="說明 p99 / p999 等長尾延遲為何比平均延遲更能反映 saturation">Tail Latency</a></li>
</ul>
]]></content:encoded></item><item><title>9.10 Production-Side 驗證</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>Production-side 驗證的責任是回答「staging 過了 production 一定過嗎」。多數 staging 環境的硬體 / 流量 / 資料 / 第三方依賴都跟 production 不一樣、staging 通過不代表 production 安全。本章處理「在 production 安全驗證新配置」的工程做法。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary&lt;/a> 的關係：06.20 走「故障注入」的安全邊界（chaos）、9.10 走「正常負載」的 production 驗證（perf）。兩者方法論類似、目標完全不同。chaos test 是「主動破壞看會不會出事」、production perf validation 是「真實流量看新版本能不能跑」。&lt;/p>
&lt;p>本章四個工具（shadow traffic、dark launch、canary、production-like load test）按 &lt;em>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius&lt;/a>&lt;/em> 從小到大排列、每個適合不同驗證場景。&lt;/p>
&lt;h2 id="shadow-traffic">Shadow traffic&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow traffic&lt;/a> 是 blast radius 最小的工具：複製 production traffic 到新版本、但 &lt;em>不把結果返回用戶&lt;/em>。&lt;/p>
&lt;p>&lt;strong>運作機制&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>用戶看到的還是舊版本回應、體驗不變&lt;/li>
&lt;li>新版本只是「並行跑、看會不會崩」&lt;/li>
&lt;li>新版本的結果可以跟舊版本對比、找出邏輯差異&lt;/li>
&lt;li>對下游的寫入要 &lt;em>特別處理&lt;/em>：要麼寫入 sandbox、要麼 dry-run（純驗證 query plan、不真寫）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>工具實作&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>GoReplay：tcpdump-based 開源、適合 HTTP&lt;/li>
&lt;li>Service mesh shadow（Istio、Linkerd mirror）：mesh 層 mirror、零 application invasion&lt;/li>
&lt;li>AWS VPC Traffic Mirroring：底層網路層、加密 traffic 要另處理&lt;/li>
&lt;li>Diffy（已 deprecated 但概念有效）：dual-write 對比結果&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>適合場景&lt;/strong>：架構大改、想驗證 &lt;em>是否能撐 production traffic&lt;/em> 但不能影響用戶。例如「DB 從 PostgreSQL 換 Aurora、想看新 DB 在真實 query pattern 下穩不穩」。&lt;/p>
&lt;p>&lt;strong>注意事項&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>shadow traffic 也消耗 production 下游資源（DB read、API call）— 必須算進容量&lt;/li>
&lt;li>加密 / PII 資料需要處理&lt;/li>
&lt;li>shadow 通常跑 1-7 天看 long-tail、不是 30 分鐘就下結論&lt;/li>
&lt;/ul>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">Tixcraft 10K t2.micro 壓測&lt;/a> — pre-event 壓測但走 staging；real shadow 則是 &lt;em>production-traffic-driven&lt;/em> 而非合成。&lt;/p>
&lt;h2 id="dark-launch">Dark launch&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/dark-launch/" data-link-title="Dark Launch" data-link-desc="新功能上線但暫不開放 UI 入口、走 production traffic 但對用戶不可見的發布模式">Dark launch&lt;/a> 介於 shadow 跟 canary 之間：程式碼上線、走 production traffic、但 &lt;em>UI 入口暫不開放&lt;/em>。&lt;/p>
&lt;p>&lt;strong>跟 shadow 的差別&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>Shadow：traffic 複製、新版本 &lt;em>不寫入真實狀態&lt;/em>&lt;/li>
&lt;li>Dark launch：&lt;em>真實寫入 production&lt;/em>、但用戶看不到 UI&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>運作機制&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>Production-side 驗證的責任是回答「staging 過了 production 一定過嗎」。多數 staging 環境的硬體 / 流量 / 資料 / 第三方依賴都跟 production 不一樣、staging 通過不代表 production 安全。本章處理「在 production 安全驗證新配置」的工程做法。</p>
<p>跟 <a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> 的關係：06.20 走「故障注入」的安全邊界（chaos）、9.10 走「正常負載」的 production 驗證（perf）。兩者方法論類似、目標完全不同。chaos test 是「主動破壞看會不會出事」、production perf validation 是「真實流量看新版本能不能跑」。</p>
<p>本章四個工具（shadow traffic、dark launch、canary、production-like load test）按 <em><a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius</a></em> 從小到大排列、每個適合不同驗證場景。</p>
<h2 id="shadow-traffic">Shadow traffic</h2>
<p><a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow traffic</a> 是 blast radius 最小的工具：複製 production traffic 到新版本、但 <em>不把結果返回用戶</em>。</p>
<p><strong>運作機制</strong>：</p>
<ul>
<li>用戶看到的還是舊版本回應、體驗不變</li>
<li>新版本只是「並行跑、看會不會崩」</li>
<li>新版本的結果可以跟舊版本對比、找出邏輯差異</li>
<li>對下游的寫入要 <em>特別處理</em>：要麼寫入 sandbox、要麼 dry-run（純驗證 query plan、不真寫）</li>
</ul>
<p><strong>工具實作</strong>：</p>
<ul>
<li>GoReplay：tcpdump-based 開源、適合 HTTP</li>
<li>Service mesh shadow（Istio、Linkerd mirror）：mesh 層 mirror、零 application invasion</li>
<li>AWS VPC Traffic Mirroring：底層網路層、加密 traffic 要另處理</li>
<li>Diffy（已 deprecated 但概念有效）：dual-write 對比結果</li>
</ul>
<p><strong>適合場景</strong>：架構大改、想驗證 <em>是否能撐 production traffic</em> 但不能影響用戶。例如「DB 從 PostgreSQL 換 Aurora、想看新 DB 在真實 query pattern 下穩不穩」。</p>
<p><strong>注意事項</strong>：</p>
<ul>
<li>shadow traffic 也消耗 production 下游資源（DB read、API call）— 必須算進容量</li>
<li>加密 / PII 資料需要處理</li>
<li>shadow 通常跑 1-7 天看 long-tail、不是 30 分鐘就下結論</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 10K t2.micro 壓測</a> — pre-event 壓測但走 staging；real shadow 則是 <em>production-traffic-driven</em> 而非合成。</p>
<h2 id="dark-launch">Dark launch</h2>
<p><a href="/blog/backend/knowledge-cards/dark-launch/" data-link-title="Dark Launch" data-link-desc="新功能上線但暫不開放 UI 入口、走 production traffic 但對用戶不可見的發布模式">Dark launch</a> 介於 shadow 跟 canary 之間：程式碼上線、走 production traffic、但 <em>UI 入口暫不開放</em>。</p>
<p><strong>跟 shadow 的差別</strong>：</p>
<ul>
<li>Shadow：traffic 複製、新版本 <em>不寫入真實狀態</em></li>
<li>Dark launch：<em>真實寫入 production</em>、但用戶看不到 UI</li>
</ul>
<p><strong>運作機制</strong>：</p>
<ul>
<li>後端 code 部署到 production</li>
<li>用 feature flag 控制 UI 暴露</li>
<li>從內部 API、cron job、employee-only access 觸發新功能</li>
<li>真正寫入 production DB / cache / queue</li>
<li>用戶看不到 UI 入口、無感</li>
</ul>
<p><strong>Exit criteria</strong>：</p>
<ul>
<li>跑足夠時間（通常 1-2 週）</li>
<li>內部使用沒有 critical issue</li>
<li>metric 在預期範圍</li>
</ul>
<p><strong>適合場景</strong>：新功能後端風險高、想 production-validate 再開放給用戶。
<strong>不適合</strong>：純 UI 改動（沒有後端風險、直接 canary）。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">SeatGeek Virtual Waiting Room</a> 從第三方換到自建、必然有 dark launch 階段驗證 token 配發機制、再正式 cutover。</p>
<h2 id="canary">Canary</h2>
<p>Canary 是 production-side 驗證最常用工具：小比例流量導到新版本、跟舊版本對比。</p>
<p><strong>運作機制</strong>：</p>
<ul>
<li>小比例（1% / 5% / 10%）流量導到新版本</li>
<li>大部分流量（99% / 95% / 90%）走舊版本</li>
<li>比較 perf / error / business metric</li>
<li>通過 → 漸進放大；不通過 → 自動 rollback</li>
</ul>
<p><strong>漸進放大策略</strong>：1% → 5% → 25% → 50% → 100%、每階段觀察足夠時間（至少 15 分鐘看 long-tail）。</p>
<p><strong>自動 rollback 條件</strong>：</p>
<ul>
<li>error rate canary 比 control 高 X%（例如 50%）</li>
<li>p99 latency canary 比 control 退化 X%（例如 10%）</li>
<li>business metric（conversion rate）canary 比 control 低 X%</li>
</ul>
<p><strong>Canary perf check 跟一般 canary 的差異</strong>：</p>
<ul>
<li>一般 canary：看 error rate 為主</li>
<li><a href="/blog/backend/knowledge-cards/canary-perf-check/" data-link-title="Canary Perf Check" data-link-desc="canary release 中針對 latency / throughput 而非 error rate 的退化檢查">Canary perf check</a>：看 latency / throughput / cost、退化通常早於 error rate</li>
</ul>
<p><strong>比較的對象是 control（同時跑的舊版本）、不是 baseline</strong>：同樣流量同樣時段才能對比、不能拿 canary 跟昨天 baseline 比（外部變數太多）。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day pre-event 驗證</a> / <a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">FanDuel canary across 20 州</a> — 按 region 漸進放大、控制 blast radius。</p>
<h2 id="production-like-load-test">Production-like load test</h2>
<p>當需要驗證 <em>peak 場景</em> 但 production 平日流量達不到時、在 production 跑額外的 synthetic load。</p>
<p><strong>為什麼要在 production 跑</strong>：</p>
<ul>
<li>staging 環境的硬體 / 網路 / 第三方依賴跟 production 不同</li>
<li>staging 沒有 production 級資料量、cache hit pattern 不一樣</li>
<li>只有 production 才能驗證真實 peak</li>
</ul>
<p><strong>風險高、必須有安全邊界</strong>：</p>
<ul>
<li>blast radius 限制（用 dedicated test endpoint、限制影響範圍）</li>
<li>abort condition（什麼訊號觸發停止）</li>
<li>rollback path（rollback 流程跟時間）</li>
<li>通訊（相關 oncall 通知、避免誤判 incident）</li>
</ul>
<p><strong>通常用在</strong>：</p>
<ul>
<li>Pre-event 壓測（Black Friday、Super Bowl、IPL 決賽 前一週）</li>
<li>重大架構變更後驗證</li>
<li>容量規劃 review（每年 / 每季）</li>
</ul>
<p><strong>跟 <a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> 同等嚴格的安全要求</strong>：production 壓測本質是 controlled experiment、必須有 game day-level 的計畫跟人員。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day FIS 8x chaos</a> — 把 chaos test 跟 load test 結合、production-like 驗證；<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 10K t2.micro 壓測</a> — pre-event 大規模壓測模擬實際售票場景。</p>
<h2 id="ab-test-與-perf-對齊">A/B test 與 perf 對齊</h2>
<p>Product A/B test（測試新功能對 conversion 的影響）同時也是 perf A/B test。</p>
<p><strong>為什麼要對齊</strong>：</p>
<ul>
<li>新 feature 可能帶來 perf 退化（多 query、多 component、額外 logic）</li>
<li>純看 conversion lift 會誤判：「conversion 上升、所以 OK」可能掩蓋「但 p99 上升 30%」</li>
<li>A/B 同時看 conversion 跟 perf 兩個 metric</li>
</ul>
<p><strong>Guardrails</strong>：</p>
<ul>
<li>業務 metric 改善 + perf 退化 → 工程判斷是否值得（trade-off review）</li>
<li>業務 metric 沒改善 + perf 退化 → 直接 reject</li>
<li>業務 metric 改善 + perf 改善 → 直接 ship</li>
<li>業務 metric 退化 → 不論 perf 怎樣、reject</li>
</ul>
<p>對應 <a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> 的 experiment guardrails。</p>
<h2 id="pre-event-readiness-checkgame-day">Pre-event readiness check（game day）</h2>
<p>大事件前跑「全系統 production-like 壓測」、是 production-side 驗證的整合演練。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a> 直接對接 — game day 是 readiness 流程的一個 stage。</p>
<p>Shopify game day、Stripe game day 是業界範本（<a href="/blog/backend/06-reliability/cases/" data-link-title="可靠性服務案例庫" data-link-desc="按服務組織的 SRE 實踐案例庫，累積架構脈絡與工程文化">06 cases</a> 有完整案例）。</p>
<h2 id="安全邊界設計">安全邊界設計</h2>
<p>任何 production-side 驗證都要有清楚的安全邊界、不能臨機應變。</p>
<p><strong>Blast radius</strong>：</p>
<ul>
<li>影響哪些用戶（X% 流量、特定 cohort、特定 region）</li>
<li>影響哪些 service（受 perf 影響的下游）</li>
<li>影響哪些 metric（哪些 business metric 可能變化）</li>
</ul>
<p><strong>Abort condition</strong>：</p>
<ul>
<li>什麼訊號觸發停止（error rate &gt; X%、latency &gt; Y ms、特定 alert 觸發）</li>
<li>由誰觸發（自動 vs oncall 手動）</li>
<li>觸發後多久內必須完成 abort（&lt; 60 秒）</li>
</ul>
<p><strong>Rollback path</strong>：</p>
<ul>
<li>rollback 流程是什麼（feature flag、deployment rollback、traffic shift）</li>
<li>rollback 需要多久（target &lt; 5 分鐘）</li>
<li>rollback 是否需要 data 處理（已寫入的資料怎麼處理）</li>
</ul>
<p><strong>通訊</strong>：</p>
<ul>
<li>啟動驗證前 notify 哪些 channel</li>
<li>期間 oncall 待命</li>
<li>結束後 retro</li>
</ul>
<h2 id="反模式">反模式</h2>
<ul>
<li><strong>Canary 比例太大</strong>（50% 起跳）：出事影響大、blast radius 失控</li>
<li><strong>沒 control group</strong>：不知道 baseline、看絕對數字會誤判</li>
<li><strong>Canary 跑太短時間</strong>（&lt; 15 分鐘）：看不到 long-tail、看不到 user pattern shift</li>
<li><strong>沒 abort condition</strong>：人工監控失誤就出事、不可預測</li>
<li><strong>shadow traffic 寫入真實狀態</strong>：可能造成 double charge、duplicate notification</li>
<li><strong>production load test 沒 notify 相關團隊</strong>：被當成 incident、誤觸 escalation</li>
</ul>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day FIS 8x</a></td>
          <td>pre-event chaos + perf 驗證</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 10K t2.micro 壓測</a></td>
          <td>pre-event 大規模壓測</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a></td>
          <td>跨 20 州 canary 控制 blast radius</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a></td>
          <td>從第三方換到自建的 dark launch</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a></li>
<li>跨模組：<a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> / <a href="/blog/backend/06-reliability/chaos-testing/" data-link-title="6.4 chaos testing" data-link-desc="把故障注入從工具操作升級成可驗證流程：先定義穩態，再按依賴類型設計注入、控制 blast radius 與收集證據">06.4 chaos testing</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
<li><a href="/blog/backend/knowledge-cards/dark-launch/" data-link-title="Dark Launch" data-link-desc="新功能上線但暫不開放 UI 入口、走 production traffic 但對用戶不可見的發布模式">Dark Launch</a></li>
<li><a href="/blog/backend/knowledge-cards/canary-perf-check/" data-link-title="Canary Perf Check" data-link-desc="canary release 中針對 latency / throughput 而非 error rate 的退化檢查">Canary Perf Check</a></li>
</ul>
]]></content:encoded></item><item><title>9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/</guid><description>&lt;p>這個案例的核心責任是提供「全球一致性 OLTP」的容量參考點。Spanner 是 Google 內部支撐 Ads、Play、Cloud Search 等服務的核心 DB、後來開放為 GCP 服務、是少數公開能撐每秒 10 億請求且維持強一致性的 OLTP 資料庫。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Spanner 公開數字（引自 &lt;a href="https://cloud.google.com/spanner">Spanner overview&lt;/a> / &lt;a href="https://cloud.google.com/spanner/docs/performance">Spanner performance docs&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>內部峰值&lt;/td>
 &lt;td>&amp;gt; 10 億 requests / 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Spanner Omni 區域峰值&lt;/td>
 &lt;td>數百萬 QPS、PB 級資料量&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>線性擴展性&lt;/td>
 &lt;td>2 nodes → 45000 reads/sec、4 nodes → 90000 reads/sec&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>一致性模型&lt;/td>
 &lt;td>external consistency（強一致 + 線性化）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>代表性客戶：Google 內部所有支付、廣告計費、Play 商店、Search 索引；公開客戶包括 Blockchain.com、Niantic（部分服務）、Sharechat、ZEE5、Wayfair。&lt;/p>
&lt;p>關鍵設計：TrueTime API（GPS + 原子鐘）讓跨地區交易能維持 external consistency、不是 eventual。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Spanner 案例最值得讀的不是「能撐多大」、是「為什麼要這樣設計才能撐」。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>線性擴展是 OLTP 的最高設計目標&lt;/strong>：「2 nodes → 45K reads/sec、4 nodes → 90K reads/sec」這個 linear scaling 在傳統 OLTP（PostgreSQL、MySQL）做不到 — 因為 &lt;em>跨節點交易&lt;/em> 需要 coordinator、coordinator 是 bottleneck。Spanner 用 Paxos + TrueTime 把 coordinator 變成「拓樸感知的多 leader」、才達成線性。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a> 的設計取捨。&lt;/li>
&lt;li>&lt;strong>強一致 vs 全球部署不是必須二選&lt;/strong>：CAP 定理常被解讀為「全球部署只能 eventual consistency」、Spanner 顯示「投入專屬硬體（GPS、原子鐘）+ 演算法（TrueTime）可以同時拿到 strong consistency + global distribution」。但這套硬體投資對其他 vendor 不容易複製。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的全球 OLTP 選項。&lt;/li>
&lt;li>&lt;strong>計費粒度 = 容量規劃顆粒&lt;/strong>：Spanner 早期最小單位是 100 processing units（pu）≈ 1 node、太大讓中小負載難以用。後來推出 100 pu 起跳的 granular sizing、讓容量規劃可以從小開始。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的容量單位選擇。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「10 億 req/sec」是 Google 內部的某個峰值瞬間、是 Spanner 服務 &lt;em>全部使用者加總&lt;/em>、不是單一 instance 數字。讀案例時要區分「全球聚合峰值」跟「單一客戶能拿到的最大配額」。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>跨地區一致性需求要在設計初期決定&lt;/strong>：如果業務必需 strong consistency（金融、ticketing）、選 Spanner 等對等服務；如果 eventual 可接受（社群、推薦）、選 Cassandra / DynamoDB Global Tables 等更便宜的選項。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的全球一致性需求識別。&lt;/li>
&lt;li>&lt;strong>節點數即容量單位、預先規劃 sizing&lt;/strong>：Spanner 容量 = 節點數 × 單節點 QPS。每年 capacity review 主要在調節點數、不在調 schema。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a>。&lt;/li>
&lt;li>&lt;strong>跨地區 latency 是強一致的代價&lt;/strong>：external consistency 必須等多區 quorum、跨洲交易延遲可達 100-200ms。延遲敏感型業務不能用跨地區 strong consistency。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 latency budget 反推。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：AWS Aurora DSQL（2024 推出、跨地區 strong consistency）、CockroachDB（自管）、TiDB（自管或 cloud）都是對等候選。差異是 TrueTime / 同等同步機制的成熟度。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供「全球一致性 OLTP」的容量參考點。Spanner 是 Google 內部支撐 Ads、Play、Cloud Search 等服務的核心 DB、後來開放為 GCP 服務、是少數公開能撐每秒 10 億請求且維持強一致性的 OLTP 資料庫。</p>
<h2 id="觀察">觀察</h2>
<p>Spanner 公開數字（引自 <a href="https://cloud.google.com/spanner">Spanner overview</a> / <a href="https://cloud.google.com/spanner/docs/performance">Spanner performance docs</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>內部峰值</td>
          <td>&gt; 10 億 requests / 秒</td>
      </tr>
      <tr>
          <td>Spanner Omni 區域峰值</td>
          <td>數百萬 QPS、PB 級資料量</td>
      </tr>
      <tr>
          <td>線性擴展性</td>
          <td>2 nodes → 45000 reads/sec、4 nodes → 90000 reads/sec</td>
      </tr>
      <tr>
          <td>一致性模型</td>
          <td>external consistency（強一致 + 線性化）</td>
      </tr>
  </tbody>
</table>
<p>代表性客戶：Google 內部所有支付、廣告計費、Play 商店、Search 索引；公開客戶包括 Blockchain.com、Niantic（部分服務）、Sharechat、ZEE5、Wayfair。</p>
<p>關鍵設計：TrueTime API（GPS + 原子鐘）讓跨地區交易能維持 external consistency、不是 eventual。</p>
<h2 id="判讀">判讀</h2>
<p>Spanner 案例最值得讀的不是「能撐多大」、是「為什麼要這樣設計才能撐」。</p>
<ol>
<li><strong>線性擴展是 OLTP 的最高設計目標</strong>：「2 nodes → 45K reads/sec、4 nodes → 90K reads/sec」這個 linear scaling 在傳統 OLTP（PostgreSQL、MySQL）做不到 — 因為 <em>跨節點交易</em> 需要 coordinator、coordinator 是 bottleneck。Spanner 用 Paxos + TrueTime 把 coordinator 變成「拓樸感知的多 leader」、才達成線性。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的設計取捨。</li>
<li><strong>強一致 vs 全球部署不是必須二選</strong>：CAP 定理常被解讀為「全球部署只能 eventual consistency」、Spanner 顯示「投入專屬硬體（GPS、原子鐘）+ 演算法（TrueTime）可以同時拿到 strong consistency + global distribution」。但這套硬體投資對其他 vendor 不容易複製。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的全球 OLTP 選項。</li>
<li><strong>計費粒度 = 容量規劃顆粒</strong>：Spanner 早期最小單位是 100 processing units（pu）≈ 1 node、太大讓中小負載難以用。後來推出 100 pu 起跳的 granular sizing、讓容量規劃可以從小開始。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的容量單位選擇。</li>
</ol>
<p>需要警惕：「10 億 req/sec」是 Google 內部的某個峰值瞬間、是 Spanner 服務 <em>全部使用者加總</em>、不是單一 instance 數字。讀案例時要區分「全球聚合峰值」跟「單一客戶能拿到的最大配額」。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>跨地區一致性需求要在設計初期決定</strong>：如果業務必需 strong consistency（金融、ticketing）、選 Spanner 等對等服務；如果 eventual 可接受（社群、推薦）、選 Cassandra / DynamoDB Global Tables 等更便宜的選項。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的全球一致性需求識別。</li>
<li><strong>節點數即容量單位、預先規劃 sizing</strong>：Spanner 容量 = 節點數 × 單節點 QPS。每年 capacity review 主要在調節點數、不在調 schema。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a>。</li>
<li><strong>跨地區 latency 是強一致的代價</strong>：external consistency 必須等多區 quorum、跨洲交易延遲可達 100-200ms。延遲敏感型業務不能用跨地區 strong consistency。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 latency budget 反推。</li>
</ol>
<p>跨平台等效：AWS Aurora DSQL（2024 推出、跨地區 strong consistency）、CockroachDB（自管）、TiDB（自管或 cloud）都是對等候選。差異是 TrueTime / 同等同步機制的成熟度。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想評估全球一致性需求 → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a></li>
<li>想規劃 OLTP 容量 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想對照其他 OLTP 案例 → <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora</a></li>
<li>想看不需要強一致的全球 KV → <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth Cosmos DB</a></li>
<li>想理解 TrueTime ε 與外部一致性實作 → <a href="/blog/backend/01-database/vendors/spanner/truetime-api-depth/" data-link-title="Spanner TrueTime API 深度：GPS &#43; 原子鐘、commit wait、為什麼 line-rate scaling 才是設計目的" data-link-desc="TrueTime 是手段、line-rate scaling 才是 Spanner 的設計目的。本文先扣商業邏輯：傳統 OLTP coordinator 為什麼是 bottleneck、Spanner 怎麼用 TrueTime &#43; Paxos 換成拓樸感知多 leader；再展開 TrueTime ε / commit wait 數學、ε 暴衝失敗模式、cross-region voting 對 latency 的影響、跟 9.C10 Google internal dogfood 揭露的線性擴展模式對照">Spanner TrueTime API 深入</a></li>
<li>想對照 Spanner / Aurora DSQL / CockroachDB 不同一致性層 → <a href="/blog/backend/01-database/vendors/spanner/consistency-models-comparison/" data-link-title="Spanner Consistency Models 對照：external consistency vs serializability vs linearizability" data-link-desc="external consistency、serializability、linearizability 是三個常被混用的概念。本文先精確定義三者差異、再用 line-rate scaling 對照表（PG SSI / CockroachDB / Spanner / Aurora DSQL）回答為什麼 Spanner 不只是『更強的 serializable』、最後用 9.C10 揭露的 cross-region quorum 100-200ms 物理硬限解釋『強一致 &#43; 全球部署』的真實 cost">Spanner 一致性模型對照</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/spanner">Spanner: Always-on, virtually unlimited scale database</a></li>
<li><a href="https://cloud.google.com/spanner/docs/performance">Spanner Performance overview</a></li>
<li><a href="https://cloud.google.com/blog/products/databases/using-cloud-spanner-to-handle-high-throughput-writes/">Using Cloud Spanner to handle high throughput writes</a></li>
<li><a href="https://cloud.google.com/blog/products/databases/get-more-out-of-spanner-with-granular-instance-sizing">Get more out of Spanner with granular instance sizing</a></li>
<li><a href="https://aws.amazon.com/blogs/database/amazon-aurora-dsql-for-global-scale-financial-transactions/">Amazon Aurora DSQL for global-scale financial transactions</a></li>
</ul>
]]></content:encoded></item><item><title>9.11 高峰事件準備</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>高峰事件準備的責任是把「事件臨頭才動手」變成「事前數週流程化準備」。沒有 readiness 流程時、年度活動靠 oncall 撐、出事率高；有流程之後、活動成「routine event」、工程資源穩定釋放。&lt;/p>
&lt;p>本章 &lt;em>是&lt;/em> &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型&lt;/a> 在「事件型場景」的應用組合、不重新建立方法論。要看具體方法回到那兩章、本章聚焦在 &lt;em>流程整合&lt;/em>。&lt;/p>
&lt;p>讀完後讀者能設計一個 T-90 → T-0 的事件準備時程、回答「Black Friday 該怎麼準備、Super Bowl 該怎麼準備、新片發布該怎麼準備」。&lt;/p>
&lt;h2 id="事件分類五種負載形狀">事件分類：五種負載形狀&lt;/h2>
&lt;p>不同事件對應不同準備強度、第一步要分類。&lt;/p>
&lt;p>&lt;strong>可預期極端峰值&lt;/strong>：年度活動、預售、賽事決賽。提前數月已知時間、業務影響大。例：Prime Day、Black Friday、Super Bowl、IPL 決賽。
&lt;strong>事件型不可預期峰值&lt;/strong>：賽事高潮、突發新聞、KOL 推廣。時間或大小不完全可預測。例：賽事進球瞬間、KOL 帶貨、突發新聞引發的流量。
&lt;strong>Flash-sale 瞬間爆量&lt;/strong>：售票開賣、報名活動、限量搶購。t=0 瞬間爆量、5-30 分鐘結束。例：演唱會售票、限量商品搶購、報名截止前最後一小時。
&lt;strong>產品爆紅 surge&lt;/strong>：新 app 紅、病毒擴散。完全不可預期、流量會隨熱度消退。例：Pokemon GO、ChatGPT 爆紅初期、TikTok challenge。
&lt;strong>結構性 surge&lt;/strong>：COVID 類外部衝擊、永久 baseline 上移。不會回到舊水準。例：COVID 期間遠距工作工具、烏俄戰爭期間能源類 app。&lt;/p>
&lt;p>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C1 / 9.C13 / 9.C21 / 9.C27 / 9.C29&lt;/a>（predictable）/ &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C2 / 9.C4 / 9.C7 / 9.C28&lt;/a>（event）/ &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C15 / 9.C16 / 9.C17&lt;/a>（flash-sale）/ &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C8 / 9.C18&lt;/a>（surge）。&lt;/p>
&lt;h2 id="t-90--t-0-準備時程">T-90 → T-0 準備時程&lt;/h2>
&lt;p>可預期極端峰值的完整準備時程：&lt;/p>
&lt;p>&lt;strong>T-90 天&lt;/strong>：流量 forecast + 容量計畫敲定。確認預期峰值倍數、確認 headroom 比例、確認跨 region / AZ 分布。產出 &lt;em>容量計畫文件&lt;/em>。&lt;/p>
&lt;p>&lt;strong>T-30 天&lt;/strong>：基礎設施 quota 申請。雲端 instance limit、connection pool、API rate limit、DynamoDB throughput、Lambda concurrency 都要 &lt;em>提前申請&lt;/em>、不能事件當天才發現 quota 不夠。AWS Infrastructure Event Management（IEM）等服務在這階段啟動。&lt;/p>
&lt;p>&lt;strong>T-14 天&lt;/strong>：第一輪 production-like 壓測。驗證容量計畫是否真的能撐預期峰值、找出第一輪 bottleneck。&lt;/p>
&lt;p>&lt;strong>T-7 天&lt;/strong>：完整 game day 演練。注入故障場景（DB failure、AZ outage、第三方 quota 耗盡）、驗證降級、failover、rollback 流程。修正最後問題、更新 runbook。&lt;/p>
&lt;p>&lt;strong>T-2 天&lt;/strong>：pre-scaling 開始。CDN cache pre-warm、Lambda provisioned concurrency 啟動、autoscaler scheduled 開始、DB capacity 預先 scale up。避免事件當天還在 boot。&lt;/p>
&lt;p>&lt;strong>T-0 day&lt;/strong>：watch room 待命、runbook 開機可執行。所有相關 oncall 跨團隊聯合 channel、dashboard 集中、escalation path 清楚。&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>高峰事件準備的責任是把「事件臨頭才動手」變成「事前數週流程化準備」。沒有 readiness 流程時、年度活動靠 oncall 撐、出事率高；有流程之後、活動成「routine event」、工程資源穩定釋放。</p>
<p>本章 <em>是</em> <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 跟 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 在「事件型場景」的應用組合、不重新建立方法論。要看具體方法回到那兩章、本章聚焦在 <em>流程整合</em>。</p>
<p>讀完後讀者能設計一個 T-90 → T-0 的事件準備時程、回答「Black Friday 該怎麼準備、Super Bowl 該怎麼準備、新片發布該怎麼準備」。</p>
<h2 id="事件分類五種負載形狀">事件分類：五種負載形狀</h2>
<p>不同事件對應不同準備強度、第一步要分類。</p>
<p><strong>可預期極端峰值</strong>：年度活動、預售、賽事決賽。提前數月已知時間、業務影響大。例：Prime Day、Black Friday、Super Bowl、IPL 決賽。
<strong>事件型不可預期峰值</strong>：賽事高潮、突發新聞、KOL 推廣。時間或大小不完全可預測。例：賽事進球瞬間、KOL 帶貨、突發新聞引發的流量。
<strong>Flash-sale 瞬間爆量</strong>：售票開賣、報名活動、限量搶購。t=0 瞬間爆量、5-30 分鐘結束。例：演唱會售票、限量商品搶購、報名截止前最後一小時。
<strong>產品爆紅 surge</strong>：新 app 紅、病毒擴散。完全不可預期、流量會隨熱度消退。例：Pokemon GO、ChatGPT 爆紅初期、TikTok challenge。
<strong>結構性 surge</strong>：COVID 類外部衝擊、永久 baseline 上移。不會回到舊水準。例：COVID 期間遠距工作工具、烏俄戰爭期間能源類 app。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C1 / 9.C13 / 9.C21 / 9.C27 / 9.C29</a>（predictable）/ <a href="/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C2 / 9.C4 / 9.C7 / 9.C28</a>（event）/ <a href="/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C15 / 9.C16 / 9.C17</a>（flash-sale）/ <a href="/blog/backend/09-performance-capacity/cases/" data-link-title="模組九案例正文" data-link-desc="雲端服務商實戰案例庫 — 從 AWS / GCP / Azure 公開案例整理高併發、峰值流量與容量規劃實踐">9.C8 / 9.C18</a>（surge）。</p>
<h2 id="t-90--t-0-準備時程">T-90 → T-0 準備時程</h2>
<p>可預期極端峰值的完整準備時程：</p>
<p><strong>T-90 天</strong>：流量 forecast + 容量計畫敲定。確認預期峰值倍數、確認 headroom 比例、確認跨 region / AZ 分布。產出 <em>容量計畫文件</em>。</p>
<p><strong>T-30 天</strong>：基礎設施 quota 申請。雲端 instance limit、connection pool、API rate limit、DynamoDB throughput、Lambda concurrency 都要 <em>提前申請</em>、不能事件當天才發現 quota 不夠。AWS Infrastructure Event Management（IEM）等服務在這階段啟動。</p>
<p><strong>T-14 天</strong>：第一輪 production-like 壓測。驗證容量計畫是否真的能撐預期峰值、找出第一輪 bottleneck。</p>
<p><strong>T-7 天</strong>：完整 game day 演練。注入故障場景（DB failure、AZ outage、第三方 quota 耗盡）、驗證降級、failover、rollback 流程。修正最後問題、更新 runbook。</p>
<p><strong>T-2 天</strong>：pre-scaling 開始。CDN cache pre-warm、Lambda provisioned concurrency 啟動、autoscaler scheduled 開始、DB capacity 預先 scale up。避免事件當天還在 boot。</p>
<p><strong>T-0 day</strong>：watch room 待命、runbook 開機可執行。所有相關 oncall 跨團隊聯合 channel、dashboard 集中、escalation path 清楚。</p>
<p><strong>T+7 天</strong>：retro。對比預測 vs 實際、紀錄 incident 跟 near-miss、列下個事件要改的事。寫進 <a href="/blog/backend/06-reliability/cases/" data-link-title="可靠性服務案例庫" data-link-desc="按服務組織的 SRE 實踐案例庫，累積架構脈絡與工程文化">06 cases</a> 或本模組 cases。</p>
<h2 id="pre-scaling-策略">Pre-scaling 策略</h2>
<p>T-2 階段的 pre-scaling 是「不依賴 autoscaler 反應」的容量保險。</p>
<p><strong>Pre-scaling 涵蓋層次</strong>：</p>
<ul>
<li><strong>ELB warm-up</strong>：請 AWS 預先 warm up ELB，避免流量上來時 ELB 自身需要時間擴容</li>
<li><strong>Lambda provisioned concurrency</strong>：預先 boot 一定數量 instance、避免 cold start</li>
<li><strong>DynamoDB / Cosmos DB capacity</strong>：scheduled 提前 scale up</li>
<li><strong>EC2 ASG</strong>：min instances 提前拉高</li>
<li><strong>CDN cache pre-warm</strong>：重要 URL 提前 invalidate / pre-populate</li>
<li><strong>DB connection pool</strong>：應用層提前 warm up connection</li>
<li><strong>Cache warmup</strong>：把 hot key 提前 populate 進 cache</li>
</ul>
<p><strong>Pre-warm window 通常 30 分鐘到 2 小時</strong>、取決於：</p>
<ul>
<li>Instance boot time（VM-based 慢、container 快）</li>
<li>Cache warmup 時間（cold cache 命中率低、要時間 populate）</li>
<li>Connection pool 預熱（DB connection establish 有 latency）</li>
</ul>
<h3 id="cdn-pre-warm-操作細節">CDN Pre-warm 操作細節</h3>
<p>CDN pre-warm 在 T-2 階段是 high-impact 操作、但跟其他 pre-scaling 的特性不同。具體做法：</p>
<ul>
<li><strong>找出活動會大量被讀取的 URL 清單</strong>：商品頁、活動 landing page、新 release 內容</li>
<li><strong>在每個 CDN edge POP 觸發 cache populate</strong>：可以用 vendor warmup API（Cloudflare Argo、Fastly Image Optimizer pre-fetch、Akamai NetStorage push），或從多個 region 發 synthetic request 強制 edge 拉取</li>
<li><strong>驗證 hit ratio 已升高</strong>：用 vendor dashboard 觀察 cache_status=HIT 比例、確認 pre-warm 生效</li>
<li><strong>預估 origin 流量曲線</strong>：pre-warm 完成後、活動開始時 edge miss 流量應該大幅降低、origin 容量規劃可以對應放鬆</li>
</ul>
<p>跟其他 pre-scaling 不同的是 <strong>CDN pre-warm 沒有「容量上限」這個概念</strong> — edge cache 是被動填的、warm 完就是 warm、不像 EC2 / Lambda 那樣需要 reserve 容量。風險不在「填不夠」、在「填錯」（key 不對、TTL 設錯讓 pre-warm 立刻過期）。詳見 <a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發</a> 的 purge 與 cacheable 判讀。</p>
<p><strong>事件結束後也要 <em>scheduled scale down</em></strong>：autoscaler 通常 scale up 快、scale down 慢、長期 over-provision 浪費錢。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 30 分鐘擴 130 倍</a> — pre-scaling + Auto Scaling Group + AMI prebuild + ELB warmup 組合；<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">Prime Day pre-scaling</a> — predictive scaling + scheduled scaling 兩種組合。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/predictive-scaling/" data-link-title="Predictive Scaling" data-link-desc="說明用歷史模式或 ML 模型預測流量、提前擴容的 autoscaler 模式">Predictive Scaling 卡片</a> 跟 <a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling 卡片</a>。</p>
<h2 id="watch-room-設計">Watch room 設計</h2>
<p>T-0 當天的指揮中心、跨團隊聯合 channel。</p>
<p><strong>人員配置</strong>：</p>
<ul>
<li>跨團隊聯合 channel：app / infra / network / SRE / business / customer support</li>
<li>24/7 輪班（國際事件可能跨 24 小時）</li>
<li>明確 incident commander（<a href="/blog/backend/08-incident-response/incident-command-roles/" data-link-title="8.2 事故指揮與角色分工" data-link-desc="定義 incident commander 與跨角色協作責任">08.7 incident command roles</a>）</li>
</ul>
<p><strong>Dashboard 集中</strong>：</p>
<ul>
<li>流量 dashboard：總 RPS、按 region 拆分、按 endpoint 拆分</li>
<li>延遲 dashboard：p50 / p95 / p99 即時、按 service 拆分</li>
<li>錯誤 dashboard：error rate、按 endpoint、按 status code</li>
<li>成本 dashboard：當前 hourly cost、預估全天 cost</li>
<li>業務 dashboard：訂單數、轉換率、收入</li>
</ul>
<p><strong>Runbook 隨手可用</strong>：常見問題 → 對應動作的明確指引。不要事件當下還在 wiki 找資料。</p>
<p><strong>Escalation path</strong>：什麼狀況找誰、多久升級。寫成決策樹、不要靠人記。對應 <a href="/blog/backend/08-incident-response/incident-command-roles/" data-link-title="8.2 事故指揮與角色分工" data-link-desc="定義 incident commander 與跨角色協作責任">08.7 incident command roles</a>。</p>
<p>對應 <a href="/blog/backend/knowledge-cards/game-day/" data-link-title="Game Day" data-link-desc="說明事故演練如何驗證流程、工具與團隊協作">Game Day 卡片</a>。</p>
<h2 id="vendor-緊急支援">Vendor 緊急支援</h2>
<p>戰略事件可以申請 vendor 工程師待命、是「人力 backup」。</p>
<p><strong>AWS Infrastructure Event Management（IEM）</strong>：年度重大事件可以申請、提供 pre-scaling 與專屬監控通道。
<strong>GCP Customer Reliability Engineering（CRE）</strong>：戰略客戶的 24/7 工程支援、能即時為客戶補容量。
<strong>Azure Premier Support + CSAM</strong>：對等服務。</p>
<p><strong>注意</strong>：這類服務通常綁定 enterprise 等級合約、不是所有客戶都能用。設計事件準備時要假設「沒有 vendor 救援」、vendor 是 bonus 而非 primary plan。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">GR8 Tech World Cup IEM</a> — AWS Infrastructure Event Management 在 2022 FIFA World Cup 期間支援；<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">Pokemon GO CRE</a> — GCP CRE 即時補容量、撐過 50x surge。</p>
<h2 id="game-day-演練">Game day 演練</h2>
<p>T-7 階段的核心活動、把 readiness 從計畫變實戰。</p>
<p><strong>演練場景</strong>：</p>
<ul>
<li>模擬「事件當天 worst case」</li>
<li>注入故障：DB primary failure、AZ outage、第三方 quota 達標、network partition</li>
<li>演練降級：哪些功能關閉、用戶看到什麼</li>
<li>演練 failover：流量切到備援</li>
<li>演練 rollback：發現新版本問題、能不能快速回退</li>
</ul>
<p><strong>Game day 學習目標</strong>：</p>
<ul>
<li>runbook 不夠詳細 → 補</li>
<li>訊號不夠 → 加 metric / alert</li>
<li>人員不夠 → 排班補</li>
<li>工具不夠 → 工程補</li>
</ul>
<p>對應 <a href="/blog/backend/06-reliability/cases/shopify/" data-link-title="Shopify" data-link-desc="Shopify BFCM Scaling / Pod-based Isolation / Capacity Planning">06 cases Shopify game day</a> — Shopify game day 是業界範本、值得直接參考。</p>
<h2 id="event-tier-分級">Event tier 分級</h2>
<p>不同事件規模對應不同準備強度、不能一律照 T-90 流程跑。</p>
<p><strong>Regular event</strong>（每週 promo、small feature launch）：</p>
<ul>
<li>scheduled scaling 即可</li>
<li>無 dedicated watch room</li>
<li>對應 <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate</a> 的常規 release</li>
</ul>
<p><strong>Major event</strong>（季度行銷、新功能發布）：</p>
<ul>
<li>pre-scaling + watch room</li>
<li>簡化版 T-14 → T-0 流程</li>
<li>跨 team coordination</li>
</ul>
<p><strong>Critical event</strong>（年度大促、Super Bowl、IPL）：</p>
<ul>
<li>完整 T-90 流程</li>
<li>vendor IEM + game day</li>
<li>24/7 watch room</li>
<li>C-level visibility</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">FanDuel</a> regular game → playoff → Super Bowl 三 tier — NFL 賽季 baseline → playoffs 升 2-3x → championship 升 4-5x → Super Bowl 升 5-10x、每 tier 對應不同準備強度。</p>
<h2 id="事後-retro">事後 retro</h2>
<p>T+7 retro 是讓 readiness 持續改進的關鍵。</p>
<p><strong>Retro 必答的問題</strong>：</p>
<ul>
<li>流量 forecast 跟實際差多少？（forecast 改進方向）</li>
<li>容量 utilization 峰值多少？（headroom 是否合適）</li>
<li>有沒有 incident 跟 near-miss？（runbook 更新方向）</li>
<li>下個事件要改的事是什麼？</li>
</ul>
<p><strong>Retro 產出</strong>：</p>
<ul>
<li>forecast 改進建議（給 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6</a>）</li>
<li>新 runbook 或 runbook 更新</li>
<li>新 monitoring / alert</li>
<li>新工程任務（補容量、補工具）</li>
</ul>
<p>對應 <a href="/blog/backend/08-incident-response/post-incident-review/" data-link-title="8.5 復盤與改進追蹤" data-link-desc="把 RCA 與 action items 轉成可驗證閉環">08.13 post-incident review</a> — retro 不只用在 incident、event readiness 也需要。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day</a></td>
          <td>可預期極端峰值教科書範本</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
          <td>flash-sale T-2 pre-scaling</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a></td>
          <td>全球直播 watch room</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a></td>
          <td>AWS IEM + 自家 AI 預測組合</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a></td>
          <td>event tier 分級（playoff → SB）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokemon GO</a></td>
          <td>surge 場景的 vendor 救援（CRE）</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> / <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸</a>（pre-scaling 前要分辨可不可水平擴展）</li>
<li>跨模組：<a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源</a>（CDN pre-warm / origin protection 是 T-2 核心）</li>
<li>跨模組：<a href="/blog/backend/06-reliability/experiment-safety-boundary/" data-link-title="6.20 Experiment Safety Boundary" data-link-desc="定義 chaos、load test、DR drill 的 [blast radius](/backend/knowledge-cards/blast-radius/)、停止條件與權限約束">06.20 experiment safety boundary</a> / <a href="/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">08 事故處理模組</a></li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/predictive-scaling/" data-link-title="Predictive Scaling" data-link-desc="說明用歷史模式或 ML 模型預測流量、提前擴容的 autoscaler 模式">Predictive Scaling</a></li>
<li><a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling</a></li>
<li><a href="/blog/backend/knowledge-cards/game-day/" data-link-title="Game Day" data-link-desc="說明事故演練如何驗證流程、工具與團隊協作">Game Day</a></li>
<li><a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">Peak Forecast</a></li>
<li><a href="/blog/backend/knowledge-cards/headroom-budget/" data-link-title="Headroom Budget" data-link-desc="說明容量規劃中為應付異常 burst &#43; AZ 故障 &#43; forecast 誤差的安全餘量">Headroom Budget</a></li>
</ul>
]]></content:encoded></item><item><title>9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/</guid><description>&lt;p>這個案例的核心責任是說明「全球分散式 multi-model DB」的容量設計取捨。Minecraft Earth 是 AR 手機遊戲（已停運、但案例本身保留）、跟 Pokémon GO 同類負載 — 玩家位置即時更新、跨地區即時互動、預期會在熱門地區 surge。Cosmos DB 的設計回應這類「跨地區 + 多 model」需求。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Minecraft Earth 在 Azure Cosmos DB 的關鍵敘述（引自 &lt;a href="https://azure.microsoft.com/en-us/blog/minecraft-earth-and-azure-cosmos-db-part-2-delivering-turnkey-geographic-distribution/">Minecraft Earth and Azure Cosmos DB&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字 / 內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>容量測試&lt;/td>
 &lt;td>100 萬 RU/s（Request Units / 秒）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>延遲承諾&lt;/td>
 &lt;td>99 百分位 &amp;lt; 10ms（地區內讀）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>一致性選項&lt;/td>
 &lt;td>5 個一致性層級（strong → eventual）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>地理分散&lt;/td>
 &lt;td>turnkey global distribution&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性 SLA&lt;/td>
 &lt;td>99.99%（multi-region 99.999%）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Cosmos DB 平台特性（引自 &lt;a href="https://azure.microsoft.com/en-us/blog/a-technical-overview-of-azure-cosmos-db/">Cosmos DB technical overview&lt;/a>）：&lt;/p>
&lt;ul>
&lt;li>配置擴容延遲：99 百分位 5 秒內生效&lt;/li>
&lt;li>多 model 支援：SQL API、MongoDB API、Cassandra API、Gremlin、Table&lt;/li>
&lt;li>partition 動態分裂：透明&lt;/li>
&lt;li>5 個 well-defined consistency levels（strong / bounded staleness / session / consistent prefix / eventual）&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Cosmos DB 設計揭露三個全球 KV / document DB 的容量設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>一致性是 spectrum、不是 binary&lt;/strong>：Cosmos DB 提供 5 個層級、每個延遲與吞吐特性不同。AR 遊戲的玩家位置不需要 strong consistency（位置稍微 stale 沒問題）、但庫存交易需要 strong。同一 application 內不同操作選不同 consistency、是進階的容量設計策略。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a> 的一致性取捨。&lt;/li>
&lt;li>&lt;strong>Request Unit (RU) 是抽象容量單位&lt;/strong>：1 RU = 1 KB document 的 strong read 成本、寫成本約 5 RU、複雜 query 可達數百 RU。容量規劃變成「估每個操作多少 RU × 操作頻率」、跟「估 CPU / IOPS」是不同的思維。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的容量單位設計。&lt;/li>
&lt;li>&lt;strong>turnkey global distribution = 容量單位的全球複製&lt;/strong>：開啟跨地區後、容量在每個地區都 mirror 一份、成本乘以地區數。對中等規模團隊、turnkey 省下大量 ops、但要算「全球複製的成本是否值得業務需求」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「100 萬 RU/s 通過測試」是 &lt;em>壓測通過&lt;/em>、不是 &lt;em>生產持續跑&lt;/em>。實際營運要看 partition key 設計是否均勻、是否有 hot partition、跨地區複製延遲是否符合業務需求。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>一致性需求分流到不同 collection / table&lt;/strong>：同一 application 不同操作有不同一致性需求、用不同 collection 配不同 consistency level、不要一刀切。&lt;/li>
&lt;li>&lt;strong>partition key 設計影響容量上限&lt;/strong>：跟 DynamoDB 一樣、hot partition 會讓名義容量達不到。Cosmos DB 的特殊性是「synthetic partition key」可以混合多個 field 強制分散。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 hot partition 識別。&lt;/li>
&lt;li>&lt;strong>RU-based pricing 鼓勵 query 最佳化&lt;/strong>：每個 expensive query 都吃 RU、優化 query 直接降成本。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9 Performance Improvement Loop&lt;/a> 的持續改進迴圈。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：AWS DynamoDB Global Tables（global KV）、GCP Spanner（global SQL with strong consistency）、ScyllaDB Cloud（自管 Cassandra）都是對等候選。差異是 multi-model 廣度（Cosmos 最廣）vs 一致性深度（Spanner 最強）。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「全球分散式 multi-model DB」的容量設計取捨。Minecraft Earth 是 AR 手機遊戲（已停運、但案例本身保留）、跟 Pokémon GO 同類負載 — 玩家位置即時更新、跨地區即時互動、預期會在熱門地區 surge。Cosmos DB 的設計回應這類「跨地區 + 多 model」需求。</p>
<h2 id="觀察">觀察</h2>
<p>Minecraft Earth 在 Azure Cosmos DB 的關鍵敘述（引自 <a href="https://azure.microsoft.com/en-us/blog/minecraft-earth-and-azure-cosmos-db-part-2-delivering-turnkey-geographic-distribution/">Minecraft Earth and Azure Cosmos DB</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字 / 內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>容量測試</td>
          <td>100 萬 RU/s（Request Units / 秒）</td>
      </tr>
      <tr>
          <td>延遲承諾</td>
          <td>99 百分位 &lt; 10ms（地區內讀）</td>
      </tr>
      <tr>
          <td>一致性選項</td>
          <td>5 個一致性層級（strong → eventual）</td>
      </tr>
      <tr>
          <td>地理分散</td>
          <td>turnkey global distribution</td>
      </tr>
      <tr>
          <td>可用性 SLA</td>
          <td>99.99%（multi-region 99.999%）</td>
      </tr>
  </tbody>
</table>
<p>Cosmos DB 平台特性（引自 <a href="https://azure.microsoft.com/en-us/blog/a-technical-overview-of-azure-cosmos-db/">Cosmos DB technical overview</a>）：</p>
<ul>
<li>配置擴容延遲：99 百分位 5 秒內生效</li>
<li>多 model 支援：SQL API、MongoDB API、Cassandra API、Gremlin、Table</li>
<li>partition 動態分裂：透明</li>
<li>5 個 well-defined consistency levels（strong / bounded staleness / session / consistent prefix / eventual）</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>Cosmos DB 設計揭露三個全球 KV / document DB 的容量設計重點。</p>
<ol>
<li><strong>一致性是 spectrum、不是 binary</strong>：Cosmos DB 提供 5 個層級、每個延遲與吞吐特性不同。AR 遊戲的玩家位置不需要 strong consistency（位置稍微 stale 沒問題）、但庫存交易需要 strong。同一 application 內不同操作選不同 consistency、是進階的容量設計策略。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的一致性取捨。</li>
<li><strong>Request Unit (RU) 是抽象容量單位</strong>：1 RU = 1 KB document 的 strong read 成本、寫成本約 5 RU、複雜 query 可達數百 RU。容量規劃變成「估每個操作多少 RU × 操作頻率」、跟「估 CPU / IOPS」是不同的思維。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的容量單位設計。</li>
<li><strong>turnkey global distribution = 容量單位的全球複製</strong>：開啟跨地區後、容量在每個地區都 mirror 一份、成本乘以地區數。對中等規模團隊、turnkey 省下大量 ops、但要算「全球複製的成本是否值得業務需求」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
</ol>
<p>需要警惕：「100 萬 RU/s 通過測試」是 <em>壓測通過</em>、不是 <em>生產持續跑</em>。實際營運要看 partition key 設計是否均勻、是否有 hot partition、跨地區複製延遲是否符合業務需求。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>一致性需求分流到不同 collection / table</strong>：同一 application 不同操作有不同一致性需求、用不同 collection 配不同 consistency level、不要一刀切。</li>
<li><strong>partition key 設計影響容量上限</strong>：跟 DynamoDB 一樣、hot partition 會讓名義容量達不到。Cosmos DB 的特殊性是「synthetic partition key」可以混合多個 field 強制分散。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 hot partition 識別。</li>
<li><strong>RU-based pricing 鼓勵 query 最佳化</strong>：每個 expensive query 都吃 RU、優化 query 直接降成本。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9 Performance Improvement Loop</a> 的持續改進迴圈。</li>
</ol>
<p>跨平台等效：AWS DynamoDB Global Tables（global KV）、GCP Spanner（global SQL with strong consistency）、ScyllaDB Cloud（自管 Cassandra）都是對等候選。差異是 multi-model 廣度（Cosmos 最廣）vs 一致性深度（Spanner 最強）。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計全球分散 KV → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想對照強一致全球 OLTP → <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想對照單區 KV 高吞吐 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB</a></li>
<li>想理解 consistency level 的取捨 → <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a></li>
<li>想理解 Cosmos DB 五層一致性的工程選擇 → <a href="/blog/backend/01-database/vendors/cosmosdb/consistency-levels-engineering/" data-link-title="Cosmos DB 5 Consistency Levels：Session 預設、Bounded staleness、Strong 邊界跟跨 collection 分流策略" data-link-desc="Cosmos DB 5 個 consistency level 的工程選擇邏輯、Session 為何是 production 預設、per-request override 跟跨 collection 分流的進階策略、Strong &#43; multi-region 互斥的 cross-link — 從 Minecraft Earth &#43; ASOS 切入">Cosmos DB 一致性層次工程</a></li>
<li>想做全球 multi-region write 衝突收斂 → <a href="/blog/backend/01-database/vendors/cosmosdb/multi-region-write-conflict/" data-link-title="Cosmos DB Multi-Region Write：active-active、LWW、custom merge、Strong &#43; multi-region 互斥的 AP 取捨" data-link-desc="Multi-region active-active write 的 conflict resolution（LWW / custom merge / conflict feed）、Strong 跟 multi-region write 為什麼互斥、廣告 SLA vs 實測可用性鏈路拆解 — 從 Minecraft Earth &#43; Toyota Connected 切入">Cosmos DB 多 region write 衝突</a></li>
<li>想拆 partition key 設計與全球分散搭配 → <a href="/blog/backend/01-database/vendors/cosmosdb/partition-key-design/" data-link-title="Cosmos DB Partition Key Design：synthetic / composite / hierarchical &#43; 不可逆性硬約束" data-link-desc="Cosmos DB logical partition 10000 RU/s 上限、partition key 不可改、三種設計模式（synthetic / composite / hierarchical）、跟 DynamoDB / MongoDB 可逆性對比、latency budget 拆解 — 從 Minecraft Earth &#43; ASOS 切入">Cosmos DB partition key 設計</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://azure.microsoft.com/en-us/blog/minecraft-earth-and-azure-cosmos-db-part-2-delivering-turnkey-geographic-distribution/">Minecraft Earth and Azure Cosmos DB part 2: Delivering turnkey geographic distribution</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/a-technical-overview-of-azure-cosmos-db/">A technical overview of Azure Cosmos DB</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/azure-cosmos-db-pushing-the-frontier-of-globally-distributed-databases/">Azure Cosmos DB: Pushing the frontier of globally distributed databases</a></li>
</ul>
]]></content:encoded></item><item><title>9.12 SLO 與 Performance Budget</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/slo-performance-budget/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/slo-performance-budget/</guid><description>&lt;h2 id="概念定位">概念定位&lt;/h2>
&lt;p>SLO 與 performance budget 的責任是讓容量決策有「可衡量的目標 + 可審查的代價」。沒有 SLO 時、容量規劃容易變「越大越好」、沒邊界；有 SLO + budget 之後、所有決策都能回答「是否在 budget 內」、「超出 budget 該怎麼辦」。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO 與 Error Budget&lt;/a> 的關係：06.6 處理「可靠性 SLO」（用 error budget 凍結 release）、9.12 處理「效能 SLO」（用 performance budget 約束容量）。兩者用同一套方法論、目標不同。讀者可以把本章當作 06.6 的 &lt;em>效能對應&lt;/em> 章節。&lt;/p>
&lt;p>本章覆蓋 SLI/SLO/SLA 分層、latency budget 分解、performance budget vs error budget、SLO 等級的成本含義、多 SLO 對齊、SLO drift 維護。讀完後讀者能設計一套完整的 SLO + budget 系統、把容量決策跟 SLO 對接。&lt;/p>
&lt;h2 id="sli--slo--sla-三層分清">SLI / SLO / SLA 三層分清&lt;/h2>
&lt;p>三個名詞常被混用、實際是三個不同層的概念。&lt;/p>
&lt;p>&lt;strong>SLI（Service Level Indicator）&lt;/strong>：客觀量測值。p99 latency、availability、throughput、error rate 都是 SLI。
&lt;strong>SLO（Service Level Objective）&lt;/strong>：團隊內部目標。「99.95% 用戶請求 &amp;lt; 500ms」這類具體承諾。
&lt;strong>SLA（Service Level Agreement）&lt;/strong>：對外合約承諾。達不到要退款、違約金、信用補償。&lt;/p>
&lt;p>&lt;strong>SLO 比 SLA 嚴 — 給內部 buffer&lt;/strong>。SLA 訂 99.9%、SLO 訂 99.95% — 萬一 SLO 沒達到、SLA 還沒違約、有反應時間。&lt;/p>
&lt;p>&lt;strong>容量規劃針對 SLO、不是 SLA&lt;/strong>：SLA 是「最低不能跌破」、SLO 才是「日常目標」。用 SLA 做容量規劃會經常 violate SLA、給用戶 / 客戶不好體驗。&lt;/p>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/sli-slo/" data-link-title="SLI / SLO" data-link-desc="說明服務品質指標與服務品質目標如何連接產品承諾">SLI / SLO 卡片&lt;/a>。&lt;/p>
&lt;h2 id="latency-budget-分解">Latency budget 分解&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency budget&lt;/a> 是把 SLO 翻成可分解工程目標的關鍵工具。&lt;/p>
&lt;p>&lt;strong>從 end-to-end latency 開始&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>用戶感受到的 latency：DNS resolution + TLS handshake + CDN + load balancer + application + cache + DB + serialization + network back&lt;/li>
&lt;li>SLO 訂在 user-perceived：例如「p99 end-to-end &amp;lt; 500ms」&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>拆到每個 stage 的 budget&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>DNS：5ms（assume cached）&lt;/li>
&lt;li>TLS handshake：50ms（first request）&lt;/li>
&lt;li>CDN：20ms&lt;/li>
&lt;li>Load balancer：5ms&lt;/li>
&lt;li>Application：100ms&lt;/li>
&lt;li>Cache lookup：5ms（hit）/ 100ms（miss）&lt;/li>
&lt;li>DB query：30ms&lt;/li>
&lt;li>Serialization：10ms&lt;/li>
&lt;li>Network return：15ms&lt;/li>
&lt;li>&lt;strong>總和&lt;/strong>：240ms（cache hit）/ 335ms（miss）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>每個 stage 的 budget 必須 &lt;em>跟 SLO 對齊&lt;/em>&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<h2 id="概念定位">概念定位</h2>
<p>SLO 與 performance budget 的責任是讓容量決策有「可衡量的目標 + 可審查的代價」。沒有 SLO 時、容量規劃容易變「越大越好」、沒邊界；有 SLO + budget 之後、所有決策都能回答「是否在 budget 內」、「超出 budget 該怎麼辦」。</p>
<p>跟 <a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO 與 Error Budget</a> 的關係：06.6 處理「可靠性 SLO」（用 error budget 凍結 release）、9.12 處理「效能 SLO」（用 performance budget 約束容量）。兩者用同一套方法論、目標不同。讀者可以把本章當作 06.6 的 <em>效能對應</em> 章節。</p>
<p>本章覆蓋 SLI/SLO/SLA 分層、latency budget 分解、performance budget vs error budget、SLO 等級的成本含義、多 SLO 對齊、SLO drift 維護。讀完後讀者能設計一套完整的 SLO + budget 系統、把容量決策跟 SLO 對接。</p>
<h2 id="sli--slo--sla-三層分清">SLI / SLO / SLA 三層分清</h2>
<p>三個名詞常被混用、實際是三個不同層的概念。</p>
<p><strong>SLI（Service Level Indicator）</strong>：客觀量測值。p99 latency、availability、throughput、error rate 都是 SLI。
<strong>SLO（Service Level Objective）</strong>：團隊內部目標。「99.95% 用戶請求 &lt; 500ms」這類具體承諾。
<strong>SLA（Service Level Agreement）</strong>：對外合約承諾。達不到要退款、違約金、信用補償。</p>
<p><strong>SLO 比 SLA 嚴 — 給內部 buffer</strong>。SLA 訂 99.9%、SLO 訂 99.95% — 萬一 SLO 沒達到、SLA 還沒違約、有反應時間。</p>
<p><strong>容量規劃針對 SLO、不是 SLA</strong>：SLA 是「最低不能跌破」、SLO 才是「日常目標」。用 SLA 做容量規劃會經常 violate SLA、給用戶 / 客戶不好體驗。</p>
<p>詳見 <a href="/blog/backend/knowledge-cards/sli-slo/" data-link-title="SLI / SLO" data-link-desc="說明服務品質指標與服務品質目標如何連接產品承諾">SLI / SLO 卡片</a>。</p>
<h2 id="latency-budget-分解">Latency budget 分解</h2>
<p><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency budget</a> 是把 SLO 翻成可分解工程目標的關鍵工具。</p>
<p><strong>從 end-to-end latency 開始</strong>：</p>
<ul>
<li>用戶感受到的 latency：DNS resolution + TLS handshake + CDN + load balancer + application + cache + DB + serialization + network back</li>
<li>SLO 訂在 user-perceived：例如「p99 end-to-end &lt; 500ms」</li>
</ul>
<p><strong>拆到每個 stage 的 budget</strong>：</p>
<ul>
<li>DNS：5ms（assume cached）</li>
<li>TLS handshake：50ms（first request）</li>
<li>CDN：20ms</li>
<li>Load balancer：5ms</li>
<li>Application：100ms</li>
<li>Cache lookup：5ms（hit）/ 100ms（miss）</li>
<li>DB query：30ms</li>
<li>Serialization：10ms</li>
<li>Network return：15ms</li>
<li><strong>總和</strong>：240ms（cache hit）/ 335ms（miss）</li>
</ul>
<p><strong>每個 stage 的 budget 必須 <em>跟 SLO 對齊</em></strong>：</p>
<ul>
<li>每個 stage 加總 = SLO 上限</li>
<li>任何 stage 超 budget → 該 stage 必須改善（不是其他 stage 來補）</li>
<li>每個 stage 必須有 <em>current measurement</em> — 不能訂了沒量</li>
</ul>
<p><strong>Cross-region call 自帶不可壓縮 latency</strong>：</p>
<ul>
<li>同 AZ：&lt; 1ms</li>
<li>跨 AZ：1-2ms</li>
<li>跨 region 同 continent：20-30ms</li>
<li>跨 continent：100-200ms</li>
<li>SLO 訂 50ms 但服務要跨 region 設計 → 不可能達成</li>
</ul>
<p><strong>任何新增 stage 都會吃 budget</strong>：middleware、sidecar、interceptor、API gateway 都會增加 latency。設計時要明確認知這層代價。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase sub-ms</a> — sub-millisecond 反推所有架構選擇（Cluster Placement Group 壓網路、z1d 壓 CPU、RAFT 壓共識）；<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">Tubi p99 &lt; 10ms</a> — ML inference 多 stage 各自分配 budget。</p>
<h2 id="performance-budget">Performance budget</h2>
<p><a href="/blog/backend/knowledge-cards/performance-budget/" data-link-title="Performance Budget" data-link-desc="跟 error budget 同類概念、但用於 latency / throughput 退化的可控額度">Performance budget</a> 跟 error budget 是 <em>姊妹概念</em> — 用同一套方法論處理可靠性 vs 效能。</p>
<p><strong>Error budget</strong>（<a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6</a>）：</p>
<ul>
<li>每月有允許的 unavailability 額度</li>
<li>例如 SLO 99.95% → error budget = 0.05% × 30 days = 21.6 分鐘 / 月</li>
<li>額度用完 → freeze new release、focus on reliability</li>
</ul>
<p><strong>Performance budget</strong>（本章）：</p>
<ul>
<li>每月有允許的 latency 退化額度</li>
<li>例如「p99 允許比 baseline 高 10ms 連續 X 分鐘」、用 <a href="/blog/backend/knowledge-cards/burn-rate/" data-link-title="Burn Rate" data-link-desc="說明 error budget 消耗速度如何支援告警與事故分級">burn rate</a> alert</li>
<li>額度用完 → freeze new feature release、focus on perf</li>
</ul>
<p><strong>兩個 budget 並列、不衝突</strong>：</p>
<ul>
<li>一個燒一個健康 → 部分 freeze（freeze 對應的那條）</li>
<li>兩個都健康 → 全速 release</li>
<li>兩個都燒 → 全面 freeze、deep review</li>
</ul>
<p><strong>Burn rate alert 比 threshold alert 好</strong>：</p>
<ul>
<li>threshold：p99 &gt; 500ms 就 alert → false positive 多</li>
<li>burn rate：過去 1 小時 budget burn rate &gt; 14.4x 就 alert（Google SRE 推薦）→ 對應「再這樣下去 budget 5 分鐘內燒光」</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">Coinbase 延遲就是收入</a> — 沒 performance budget 等於沒 release control；<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">FanDuel 多 SLO</a> — 直播 vs 投注不同 budget。</p>
<h2 id="slo-等級的成本含義">SLO 等級的成本含義</h2>
<p>不同 SLO 等級對應不同容量成本、選 SLO 就是選成本。</p>
<table>
  <thead>
      <tr>
          <th>SLO</th>
          <th>年 downtime 上限</th>
          <th>工程含義</th>
          <th>適用場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>99%</td>
          <td>年 87.6 小時</td>
          <td>單 AZ 部署可接受</td>
          <td>B2C 內部工具、非 critical SaaS</td>
      </tr>
      <tr>
          <td>99.9%</td>
          <td>年 8.76 小時</td>
          <td>多 AZ、reactive failover</td>
          <td>B2C consumer-facing</td>
      </tr>
      <tr>
          <td>99.95%</td>
          <td>年 4.38 小時</td>
          <td>多 AZ active-active、autoscale 必要</td>
          <td>B2B SaaS minimum</td>
      </tr>
      <tr>
          <td>99.99%</td>
          <td>年 52.6 分鐘</td>
          <td>多 region active-active、無人工介入</td>
          <td>mission-critical SaaS</td>
      </tr>
      <tr>
          <td>99.999%</td>
          <td>年 5.26 分鐘</td>
          <td>全球多 region、即時 failover、人工極少</td>
          <td>金融 / 醫療 / 電信</td>
      </tr>
  </tbody>
</table>
<p><strong>每多一個 9、容量成本指數成長</strong>：</p>
<ul>
<li>99 → 99.9：成本 +30-50%</li>
<li>99.9 → 99.99：成本 +50-100%</li>
<li>99.99 → 99.999：成本 +200-500%</li>
</ul>
<p><strong>選 SLO 不是 marketing 決策、是工程經濟決策</strong>：選太高、燒錢；選太低、用戶不滿。要算 <em>每個 9 對應的業務價值</em>、是否值得對應的容量投資。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">Amazon Ads 99.999%</a> — 廣告計費 1 分鐘斷線損失幾百萬美金、5 個 9 是真實營收邊界；<a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">Genesys 99.999%</a> — B2B 客服 SaaS、客戶停線 = 客戶失去用戶信任、5 個 9 是合約義務。</p>
<h2 id="多-slo-對齊">多 SLO 對齊</h2>
<p>同一系統不同工作負載可以有不同 SLO、按業務重要性分級。</p>
<p><strong>設計原則</strong>：</p>
<ul>
<li>按「業務重要性 × 用戶感知」分級</li>
<li>同一個 endpoint 不同情境可能有不同 SLO（例如登入 vs 結帳）</li>
<li>多 SLO 必須有 <em>優先順序</em>、衝突時知道犧牲哪個</li>
</ul>
<p><strong>範例</strong>：</p>
<table>
  <thead>
      <tr>
          <th>Endpoint</th>
          <th>SLO</th>
          <th>業務影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>登入</td>
          <td>p99 200ms</td>
          <td>用戶 onboarding</td>
      </tr>
      <tr>
          <td>瀏覽商品</td>
          <td>p99 500ms</td>
          <td>用戶 retention</td>
      </tr>
      <tr>
          <td>結帳</td>
          <td>p99 300ms</td>
          <td>直接影響收入</td>
      </tr>
      <tr>
          <td>推薦</td>
          <td>p99 1000ms</td>
          <td>影響 conversion 但非阻斷</td>
      </tr>
  </tbody>
</table>
<p><strong>衝突處理</strong>：當 capacity 不夠時、優先保 <em>結帳</em> 而非 <em>推薦</em>、即使技術上推薦比較好擴容。</p>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">FanDuel</a> 直播秒級 SLO vs 投注毫秒級 SLO、同一個 user 同一場 NFL Super Bowl、兩個服務必須分開部署、各自 SLO。</p>
<h2 id="slo-演進baseline-drift">SLO 演進：baseline drift</h2>
<p><a href="/blog/backend/knowledge-cards/slo-baseline-drift/" data-link-title="SLO Baseline Drift" data-link-desc="SLO baseline 因業務變化 / surge / 架構改動而需要重新校準的現象">SLO 不是訂了就不動</a> — 業務變化要重新校準。</p>
<p><strong>SLO drift 來源</strong>：</p>
<ul>
<li>Structural surge：COVID 類外部衝擊讓 baseline 永久上移</li>
<li>Product change：新 feature 改變用戶 journey</li>
<li>Architectural improvement：DB 換型、cache 加強、CDN 擴點</li>
<li>User behavior：mobile share 上升、跨 region 比例變化</li>
</ul>
<p><strong>Drift 不是 anomaly、是 <em>新常態</em></strong>。</p>
<p><strong>Review 節奏</strong>：</p>
<ul>
<li>每季 review SLO：拉過去 90 天 SLI 分布、看是否需要調整</li>
<li>重大產品改動立即 review</li>
<li>Drift 確認後要更新：alert threshold、autoscaler trigger、performance budget 額度、容量規劃 baseline</li>
</ul>
<p>對應案例：<a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">Zoom 30x COVID</a> — 30 倍成長後 baseline 永久上移、SLO threshold 跟著重新校準、不能套用 COVID 前的標準。</p>
<h2 id="slo-跟容量規劃對接">SLO 跟容量規劃對接</h2>
<p>回到本章開頭的論點 — SLO 是容量決策的目標。</p>
<p><strong>容量公式</strong>：能撐多少 RPS @ SLO 條件。
<strong>規劃時用「SLO-constrained capacity」、不是「max capacity」</strong>：</p>
<ul>
<li>max capacity：絕對極限、進 cliff</li>
<li>SLO-constrained capacity：知道在 SLO 條件下能撐多少</li>
<li>兩者差 30-50%（headroom）</li>
</ul>
<p><strong>9.4 saturation 找 knee 是技術指標、9.6 容量規劃用 SLO-constrained knee</strong>：</p>
<ul>
<li>saturation 在 utilization 80% 時開始</li>
<li>但 SLO 可能要求 utilization 60% 以下</li>
<li>容量規劃用 60% 而非 80%</li>
</ul>
<p><strong>跟 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本工程</a> 對接</strong>：</p>
<ul>
<li>每多一個 9 多花多少錢</li>
<li>業務需要這個 9 嗎</li>
<li>不需要的話降 SLO 省成本</li>
</ul>
<h2 id="slo-跟-performance-budget-一起用">SLO 跟 performance budget 一起用</h2>
<p>最後的整合 — error budget + performance budget 一起治理 release 節奏。</p>
<p><strong>Error budget 控制 <em>變更節奏</em></strong>：</p>
<ul>
<li>error budget 健康 → release 可以快</li>
<li>error budget 燒光 → freeze release</li>
</ul>
<p><strong>Performance budget 控制 <em>容量決策</em></strong>：</p>
<ul>
<li>performance budget 健康 → 新 feature 可以引入 perf cost</li>
<li>performance budget 燒光 → freeze new feature</li>
</ul>
<p><strong>兩個 budget 並列</strong>：</p>
<ul>
<li>都健康 → 全速 release + 新 feature</li>
<li>error 健康 + perf 燒 → release 但只接 perf-neutral 變更</li>
<li>error 燒 + perf 健康 → 暫停 release、修可靠性</li>
<li>都燒 → 全面 freeze、deep review</li>
</ul>
<p>對應 <a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO</a> 跟 <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate</a>。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a></td>
          <td>latency budget 反推架構</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 / C24 99.999%</a></td>
          <td>5 個 9 的容量代價</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi ML stage budget</a></td>
          <td>p99 多 stage 分配</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 多 SLO</a></td>
          <td>直播 vs 投注不同 SLO 並存</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a></td>
          <td>SLO baseline 重新校準</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-theory/" data-link-title="9.1 壓測理論與系統行為" data-link-desc="Little&#39;s Law、queueing theory、USL、saturation curve 在容量規劃中的角色">9.1 壓測理論</a>（latency budget 反推）</li>
<li>上游：<a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>（SLO-constrained capacity）</li>
<li>跨模組：<a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO 與 Error Budget 政策</a>（可靠性 SLO）</li>
<li>跨模組：<a href="/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號</a>（量測層）</li>
</ul>
<h2 id="既建知識卡片">既建知識卡片</h2>
<ul>
<li><a href="/blog/backend/knowledge-cards/sli-slo/" data-link-title="SLI / SLO" data-link-desc="說明服務品質指標與服務品質目標如何連接產品承諾">SLI / SLO</a></li>
<li><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget</a></li>
<li><a href="/blog/backend/knowledge-cards/performance-budget/" data-link-title="Performance Budget" data-link-desc="跟 error budget 同類概念、但用於 latency / throughput 退化的可控額度">Performance Budget</a></li>
<li><a href="/blog/backend/knowledge-cards/slo-baseline-drift/" data-link-title="SLO Baseline Drift" data-link-desc="SLO baseline 因業務變化 / surge / 架構改動而需要重新校準的現象">SLO Baseline Drift</a></li>
<li><a href="/blog/backend/knowledge-cards/error-budget/" data-link-title="Error Budget" data-link-desc="說明 SLO 允許的失敗額度如何影響發版與可靠性投入">Error Budget</a></li>
</ul>
]]></content:encoded></item><item><title>9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/</guid><description>&lt;p>這個案例的核心責任是說明「K8s 多 cluster 治理」對容量規劃的影響。Riot Games 經營 League of Legends、VALORANT、TFT 等多款全球遊戲、單一遊戲跨多地區、需要 &amp;lt; 35ms 延遲、需要做到「快速部署新遊戲 / 新區域」— 這套需求把容量規劃的單位從「instance」改成「cluster」。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Riot Games 遷移到 EKS 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/riot-games-case-study/">Riot Games case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>月活用戶&lt;/td>
 &lt;td>1.8 億 +&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cluster 數量&lt;/td>
 &lt;td>246 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>基礎設施年省&lt;/td>
 &lt;td>1000 萬美金&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>部署速度提升&lt;/td>
 &lt;td>12x&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>基礎設施設定速度&lt;/td>
 &lt;td>+90%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>延遲門檻&lt;/td>
 &lt;td>35ms（VALORANT 等競技遊戲）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>標準化覆蓋率&lt;/td>
 &lt;td>80% 基礎設施移到中央管理&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>開發者基礎設施工作下降&lt;/td>
 &lt;td>-40%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>事件回應時間下降&lt;/td>
 &lt;td>-50%&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Amazon EKS（主要）、AWS Local Zones（低延遲就近部署）、AWS Outposts（on-prem edge）、Karpenter（node lifecycle）、Terraform（IaC）。&lt;/p>
&lt;p>關鍵架構決策：從 multi-tenant cluster 模型改成 &lt;em>single-tenant per game&lt;/em> — 每個遊戲一個獨立 cluster、避免跨遊戲互相影響。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Riot Games 案例揭露三個多 cluster K8s 容量治理重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Cluster 隔離是容量規劃的單位&lt;/strong>：246 個 cluster 看似很多、但 &lt;em>每個 cluster 是獨立容量單位&lt;/em>、不互相影響。一個遊戲的擴容不會吃掉另一個遊戲的容量。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 multi-tenant vs single-tenant 取捨。&lt;/li>
&lt;li>&lt;strong>延遲門檻反推 region 部署&lt;/strong>：35ms 是競技遊戲（VALORANT、League）的可接受上限、超過會「卡」。從這個門檻反推：玩家所在 region 不能跨洲、需要區域 cluster。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 latency budget。Local Zones / Outposts 是這個門檻的工程回應。&lt;/li>
&lt;li>&lt;strong>Karpenter + Terraform = cluster 容量自動化&lt;/strong>：246 個 cluster 手動管理會崩。Karpenter（node 動態 lifecycle）+ Terraform（IaC）讓 cluster 級操作可重複、可審查。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9 Performance Improvement Loop&lt;/a> 的自動化迴圈。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「年省 1000 萬」是 &lt;em>vs 自管 Mesos&lt;/em>、不是 &lt;em>vs 沒上雲&lt;/em>。EKS 仍有 vendor cost、只是比自管便宜。讀案例時要看 baseline 是什麼。另外、單一 cluster 的容量上限（pod 數、node 數）仍是工程現實、超過時要做 cluster sharding（這正是 Riot 走 246 個 cluster 的部分原因）。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>single-tenant cluster per workload&lt;/strong>：每個高敏感度工作負載（每個遊戲、每個關鍵服務）一個獨立 cluster、避免 noisy neighbor。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a>。&lt;/li>
&lt;li>&lt;strong>延遲門檻反推 region 部署數量&lt;/strong>：先訂 latency budget、再算 &lt;em>玩家分布 × region cluster 數量&lt;/em>。region 增加會線性增加 ops 成本、要在 latency 跟 cost 之間找平衡。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;li>&lt;strong>cluster 級 IaC + 自動化是 multi-cluster 治理前置&lt;/strong>：Terraform / Pulumi / Crossplane + Karpenter / Cluster Autoscaler 是基本工具。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP GKE Fleet management（multi-cluster）、Azure Fleet Manager、自建 Cluster API + ArgoCD 都可以做 multi-cluster 治理。差異是 vendor 整合度跟政策。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「K8s 多 cluster 治理」對容量規劃的影響。Riot Games 經營 League of Legends、VALORANT、TFT 等多款全球遊戲、單一遊戲跨多地區、需要 &lt; 35ms 延遲、需要做到「快速部署新遊戲 / 新區域」— 這套需求把容量規劃的單位從「instance」改成「cluster」。</p>
<h2 id="觀察">觀察</h2>
<p>Riot Games 遷移到 EKS 的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/riot-games-case-study/">Riot Games case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>月活用戶</td>
          <td>1.8 億 +</td>
      </tr>
      <tr>
          <td>Cluster 數量</td>
          <td>246 個</td>
      </tr>
      <tr>
          <td>基礎設施年省</td>
          <td>1000 萬美金</td>
      </tr>
      <tr>
          <td>部署速度提升</td>
          <td>12x</td>
      </tr>
      <tr>
          <td>基礎設施設定速度</td>
          <td>+90%</td>
      </tr>
      <tr>
          <td>延遲門檻</td>
          <td>35ms（VALORANT 等競技遊戲）</td>
      </tr>
      <tr>
          <td>標準化覆蓋率</td>
          <td>80% 基礎設施移到中央管理</td>
      </tr>
      <tr>
          <td>開發者基礎設施工作下降</td>
          <td>-40%</td>
      </tr>
      <tr>
          <td>事件回應時間下降</td>
          <td>-50%</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Amazon EKS（主要）、AWS Local Zones（低延遲就近部署）、AWS Outposts（on-prem edge）、Karpenter（node lifecycle）、Terraform（IaC）。</p>
<p>關鍵架構決策：從 multi-tenant cluster 模型改成 <em>single-tenant per game</em> — 每個遊戲一個獨立 cluster、避免跨遊戲互相影響。</p>
<h2 id="判讀">判讀</h2>
<p>Riot Games 案例揭露三個多 cluster K8s 容量治理重點。</p>
<ol>
<li><strong>Cluster 隔離是容量規劃的單位</strong>：246 個 cluster 看似很多、但 <em>每個 cluster 是獨立容量單位</em>、不互相影響。一個遊戲的擴容不會吃掉另一個遊戲的容量。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 multi-tenant vs single-tenant 取捨。</li>
<li><strong>延遲門檻反推 region 部署</strong>：35ms 是競技遊戲（VALORANT、League）的可接受上限、超過會「卡」。從這個門檻反推：玩家所在 region 不能跨洲、需要區域 cluster。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 latency budget。Local Zones / Outposts 是這個門檻的工程回應。</li>
<li><strong>Karpenter + Terraform = cluster 容量自動化</strong>：246 個 cluster 手動管理會崩。Karpenter（node 動態 lifecycle）+ Terraform（IaC）讓 cluster 級操作可重複、可審查。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.9 Performance Improvement Loop</a> 的自動化迴圈。</li>
</ol>
<p>需要警惕：「年省 1000 萬」是 <em>vs 自管 Mesos</em>、不是 <em>vs 沒上雲</em>。EKS 仍有 vendor cost、只是比自管便宜。讀案例時要看 baseline 是什麼。另外、單一 cluster 的容量上限（pod 數、node 數）仍是工程現實、超過時要做 cluster sharding（這正是 Riot 走 246 個 cluster 的部分原因）。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>single-tenant cluster per workload</strong>：每個高敏感度工作負載（每個遊戲、每個關鍵服務）一個獨立 cluster、避免 noisy neighbor。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a>。</li>
<li><strong>延遲門檻反推 region 部署數量</strong>：先訂 latency budget、再算 <em>玩家分布 × region cluster 數量</em>。region 增加會線性增加 ops 成本、要在 latency 跟 cost 之間找平衡。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
<li><strong>cluster 級 IaC + 自動化是 multi-cluster 治理前置</strong>：Terraform / Pulumi / Crossplane + Karpenter / Cluster Autoscaler 是基本工具。</li>
</ol>
<p>跨平台等效：GCP GKE Fleet management（multi-cluster）、Azure Fleet Manager、自建 Cluster API + ArgoCD 都可以做 multi-cluster 治理。差異是 vendor 整合度跟政策。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計 multi-cluster K8s → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想做延遲門檻反推部署 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a></li>
<li>想對照微服務 vs multi-cluster → <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/riot-games-case-study/">Riot Games Cuts $10M Annual Infrastructure Costs by Migrating to Amazon EKS</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/riot-games-reinvent/">Riot Games on Using AWS to Improve Gaming</a></li>
</ul>
]]></content:encoded></item><item><title>9.C13 Disney+ Hotstar：IPL 板球決賽 1860 萬人同時直播</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/</guid><description>&lt;p>這個案例的核心責任是說明「全球大型直播」的容量設計 — 跟 Prime Day 同屬「可預期極端峰值」、但形狀完全不同：Prime Day 是分散全球的購物峰值、Hotstar IPL 是 &lt;em>單一時間點 + 高度集中地理區&lt;/em> 的直播峰值。容量規劃的挑戰在於 CDN、串流伺服器、live encoder、message queue 同時 saturate。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Hotstar IPL 直播的關鍵數字（引自 &lt;a href="https://aws.amazon.com/blogs/media/in-the-news-hotstar-sets-new-global-record-for-live-viewership/">Hotstar global record&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>同時觀看峰值&lt;/td>
 &lt;td>1860 萬 人（2021-03 IPL 決賽）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>全球記錄&lt;/td>
 &lt;td>該時點全球同時觀看直播的最高記錄&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>AWS Media Services + AWS CloudFront&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>客戶基礎&lt;/td>
 &lt;td>印度為主、跨亞洲&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>AWS Media Services 在大型事件的歷史記錄：Olympics、Super Bowl、IPL Cricket（引自 &lt;a href="https://aws.amazon.com/developer/application-security-performance/articles/large-scale-video-streaming-events/">AWS large-scale streaming events&lt;/a>）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Hotstar 案例揭露三個全球直播容量重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>集中地理區 = CDN 壓力集中&lt;/strong>：Prime Day 的流量分散全球、單一地區 CDN 不會 saturate；IPL 主要觀眾在印度、所有印度 PoP 同一時間 saturate。CDN 容量規劃必須按地區獨立做、不能用「全球總容量」當保證。對應 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組&lt;/a> 的 cardinality 與地區訊號治理、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的「地理分片容量」。&lt;/li>
&lt;li>&lt;strong>直播跟 VoD 是不同容量問題&lt;/strong>：VoD 觀眾分散時間、CDN 可預先 cache；直播觀眾集中時間、每一個 manifest / segment 都是 live 拉取、cache hit 反而是危險（拉到舊的 segment）。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 cache freshness boundary、跟 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列&lt;/a> 的 fan-out 設計。&lt;/li>
&lt;li>&lt;strong>多 bitrate 動態切換 = 真實容量是 bitrate 加權&lt;/strong>：1860 萬觀眾不是都看 1080p — 印度行動網路下大多看 720p 或 480p、bitrate 加權後的 total bandwidth 可能比想像低。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling&lt;/a> 的真實 workload shape。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「1860 萬同時觀看」是 &lt;em>峰值瞬間&lt;/em>、不是全程平均。決賽 4 小時、觀眾數呈鐘形曲線、峰值維持時間可能只有 10-30 分鐘（比賽關鍵時刻）。容量規劃要看峰值持續時間、不只看峰值高度。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>CDN 容量規劃按地理區分割&lt;/strong>：不要假設「全球 CDN 總量」夠用、要按主要觀眾分布的地區做容量保證。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a>。&lt;/li>
&lt;li>&lt;strong>直播必須 pre-scaling、不能依賴 reactive&lt;/strong>：直播開始之後 CDN reactive 擴容已經太晚、觀眾體驗已壞。事件型 scheduled scaling + over-provisioning 是必須。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a>。&lt;/li>
&lt;li>&lt;strong>multi-bitrate / ABR streaming 是容量緩衝&lt;/strong>：當網路擁塞、player 自動降 bitrate、總頻寬壓力下降。這層降級是隱性容量緩衝、要在壓測時驗證。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 saturation 行為。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP CDN + Media CDN、Azure Front Door + Media Services、Akamai / Cloudflare / Fastly 等 multi-CDN 都是對等候選。差異是 PoP 地理分布跟 manifest 處理能力。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「全球大型直播」的容量設計 — 跟 Prime Day 同屬「可預期極端峰值」、但形狀完全不同：Prime Day 是分散全球的購物峰值、Hotstar IPL 是 <em>單一時間點 + 高度集中地理區</em> 的直播峰值。容量規劃的挑戰在於 CDN、串流伺服器、live encoder、message queue 同時 saturate。</p>
<h2 id="觀察">觀察</h2>
<p>Hotstar IPL 直播的關鍵數字（引自 <a href="https://aws.amazon.com/blogs/media/in-the-news-hotstar-sets-new-global-record-for-live-viewership/">Hotstar global record</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>同時觀看峰值</td>
          <td>1860 萬 人（2021-03 IPL 決賽）</td>
      </tr>
      <tr>
          <td>全球記錄</td>
          <td>該時點全球同時觀看直播的最高記錄</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>AWS Media Services + AWS CloudFront</td>
      </tr>
      <tr>
          <td>客戶基礎</td>
          <td>印度為主、跨亞洲</td>
      </tr>
  </tbody>
</table>
<p>AWS Media Services 在大型事件的歷史記錄：Olympics、Super Bowl、IPL Cricket（引自 <a href="https://aws.amazon.com/developer/application-security-performance/articles/large-scale-video-streaming-events/">AWS large-scale streaming events</a>）。</p>
<h2 id="判讀">判讀</h2>
<p>Hotstar 案例揭露三個全球直播容量重點。</p>
<ol>
<li><strong>集中地理區 = CDN 壓力集中</strong>：Prime Day 的流量分散全球、單一地區 CDN 不會 saturate；IPL 主要觀眾在印度、所有印度 PoP 同一時間 saturate。CDN 容量規劃必須按地區獨立做、不能用「全球總容量」當保證。對應 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 的 cardinality 與地區訊號治理、跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的「地理分片容量」。</li>
<li><strong>直播跟 VoD 是不同容量問題</strong>：VoD 觀眾分散時間、CDN 可預先 cache；直播觀眾集中時間、每一個 manifest / segment 都是 live 拉取、cache hit 反而是危險（拉到舊的 segment）。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 cache freshness boundary、跟 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列</a> 的 fan-out 設計。</li>
<li><strong>多 bitrate 動態切換 = 真實容量是 bitrate 加權</strong>：1860 萬觀眾不是都看 1080p — 印度行動網路下大多看 720p 或 480p、bitrate 加權後的 total bandwidth 可能比想像低。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a> 的真實 workload shape。</li>
</ol>
<p>需要警惕：「1860 萬同時觀看」是 <em>峰值瞬間</em>、不是全程平均。決賽 4 小時、觀眾數呈鐘形曲線、峰值維持時間可能只有 10-30 分鐘（比賽關鍵時刻）。容量規劃要看峰值持續時間、不只看峰值高度。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>CDN 容量規劃按地理區分割</strong>：不要假設「全球 CDN 總量」夠用、要按主要觀眾分布的地區做容量保證。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a>。</li>
<li><strong>直播必須 pre-scaling、不能依賴 reactive</strong>：直播開始之後 CDN reactive 擴容已經太晚、觀眾體驗已壞。事件型 scheduled scaling + over-provisioning 是必須。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a>。</li>
<li><strong>multi-bitrate / ABR streaming 是容量緩衝</strong>：當網路擁塞、player 自動降 bitrate、總頻寬壓力下降。這層降級是隱性容量緩衝、要在壓測時驗證。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 saturation 行為。</li>
</ol>
<p>跨平台等效：GCP CDN + Media CDN、Azure Front Door + Media Services、Akamai / Cloudflare / Fastly 等 multi-CDN 都是對等候選。差異是 PoP 地理分布跟 manifest 處理能力。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃全球直播 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想做 CDN 容量設計 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a></li>
<li>想理解 cache freshness 在直播的影響 → <a href="/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary</a></li>
<li>對照其他可預期峰值 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a>（分散全球的峰值）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/media/in-the-news-hotstar-sets-new-global-record-for-live-viewership/">In the news: Hotstar sets new global record for live viewership</a></li>
<li><a href="https://aws.amazon.com/developer/application-security-performance/articles/large-scale-video-streaming-events/">Large scale streaming events on AWS</a></li>
<li><a href="https://aws.amazon.com/media/direct-to-consumer-d2c-streaming/">Direct to Consumer &amp; Streaming on AWS</a></li>
</ul>
]]></content:encoded></item><item><title>9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/</guid><description>&lt;p>這個案例的核心責任是說明「受監管產業」的容量規劃跟「網路服務」的本質差異。銀行交易系統的容量目標不只是「能撐多少」、還要同時滿足合規（資料駐留、稽核、加密、可恢復性）、跟一般工程性能優化的取捨完全不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Standard Chartered 在 Aurora 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/search/">AWS search results&lt;/a> 與相關 case study）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>遷移前&lt;/th>
 &lt;th>遷移後 (Aurora)&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>交易吞吐 (TPS)&lt;/td>
 &lt;td>（未公開、基線值）&lt;/td>
 &lt;td>4000 TPS&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>吞吐倍數&lt;/td>
 &lt;td>1x baseline&lt;/td>
 &lt;td>10x&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>受監管市場&lt;/td>
 &lt;td>-&lt;/td>
 &lt;td>7 個（首批遷移）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本下降&lt;/td>
 &lt;td>-&lt;/td>
 &lt;td>「顯著」（未公開具體數字）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主要驅動&lt;/td>
 &lt;td>韌性 + 性能&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Amazon Aurora（PostgreSQL 或 MySQL 相容）、加密 at rest / in transit、多 AZ 部署、跨地區複製（受監管市場各自獨立）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>受監管銀行案例揭露三個合規驅動容量規劃的重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>資料駐留限制 = 容量規劃的單位是「per 市場」&lt;/strong>：7 個受監管市場代表 7 個獨立 cluster（資料不能跨境）、容量規劃變成「7 個獨立規劃 × 各自合規門檻」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的合規要求識別、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的地理分片。&lt;/li>
&lt;li>&lt;strong>「韌性 + 性能」並列、不是 trade-off&lt;/strong>：傳統工程文化常把可靠性跟性能視為對立、銀行業務要求兩者同時達標。Aurora 的多 AZ storage + replica 同時提供性能（讀分流）跟韌性（故障切換）、達成 &lt;em>韌性即性能&lt;/em> 的目標。對應 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/reliability-metrics-governance/" data-link-title="6.18 Reliability Metrics Governance" data-link-desc="DORA / SPACE 指標的選用、量測陷阱、anti-gaming 與團隊階段適配">06.18 reliability metrics governance&lt;/a> 的可靠性指標。&lt;/li>
&lt;li>&lt;strong>遷移本身的合規驗證 = 容量規劃延伸&lt;/strong>：受監管系統遷移不只是技術測試、還要過合規審查（中央銀行 / 金融監管機關）、每個市場各自審。這個審查 lead time（數月）必須算進遷移時程。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook&lt;/a> 的合規驅動 migration。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「10x throughput」是 &lt;em>vs 舊系統&lt;/em>、不是 &lt;em>vs 競爭對手&lt;/em>。受監管銀行的舊系統通常是 1990s-2000s 的 mainframe 或自建 OLTP、性能本來就低。讀案例時要對標的是「自家改善幅度」、不是「絕對性能」。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>資料駐留是容量規劃的硬限制、不是優化選項&lt;/strong>：受監管市場必須各自獨立 cluster、不能用「全球單一 cluster」優化。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/traffic-data-scale/" data-link-title="0.5 流量與資料量評估" data-link-desc="用流量形狀、資料成長、hot key、保留期限與尖峰模式評估後端需求規模">00.4 traffic data scale&lt;/a> 的合規限制。&lt;/li>
&lt;li>&lt;strong>多 AZ + 跨地區複製是合規基線、不是優化&lt;/strong>：銀行業務 RPO / RTO 通常由監管要求（不能丟資料、必須 X 小時內恢復）、不是業務 SLA 選項。對應 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/dr-rollback-rehearsal/" data-link-title="6.7 DR 演練與 Rollback Rehearsal" data-link-desc="把回復路徑從紙面計畫變成定期可重播、可量測的驗證流程">06.7 DR rollback rehearsal&lt;/a>。&lt;/li>
&lt;li>&lt;strong>遷移時程要算合規 lead time&lt;/strong>：每個受監管市場的審查可能 3-12 個月、合計遷移時程是「市場數 × 平均審查月份」、不是「技術遷移月份」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：Azure SQL Hyperscale + Azure regions、GCP Cloud SQL / Spanner + regional configurations、各家雲端的受監管雲端方案（AWS GovCloud、Azure Government、GCP Assured Workloads）都是對等候選。差異是各家對特定監管框架（PCI-DSS、ISO27001、各國金融法規）的認證覆蓋。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「受監管產業」的容量規劃跟「網路服務」的本質差異。銀行交易系統的容量目標不只是「能撐多少」、還要同時滿足合規（資料駐留、稽核、加密、可恢復性）、跟一般工程性能優化的取捨完全不同。</p>
<h2 id="觀察">觀察</h2>
<p>Standard Chartered 在 Aurora 的關鍵敘述（引自 <a href="https://aws.amazon.com/search/">AWS search results</a> 與相關 case study）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>遷移前</th>
          <th>遷移後 (Aurora)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>交易吞吐 (TPS)</td>
          <td>（未公開、基線值）</td>
          <td>4000 TPS</td>
      </tr>
      <tr>
          <td>吞吐倍數</td>
          <td>1x baseline</td>
          <td>10x</td>
      </tr>
      <tr>
          <td>受監管市場</td>
          <td>-</td>
          <td>7 個（首批遷移）</td>
      </tr>
      <tr>
          <td>成本下降</td>
          <td>-</td>
          <td>「顯著」（未公開具體數字）</td>
      </tr>
      <tr>
          <td>主要驅動</td>
          <td>韌性 + 性能</td>
          <td>-</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Amazon Aurora（PostgreSQL 或 MySQL 相容）、加密 at rest / in transit、多 AZ 部署、跨地區複製（受監管市場各自獨立）。</p>
<h2 id="判讀">判讀</h2>
<p>受監管銀行案例揭露三個合規驅動容量規劃的重點。</p>
<ol>
<li><strong>資料駐留限制 = 容量規劃的單位是「per 市場」</strong>：7 個受監管市場代表 7 個獨立 cluster（資料不能跨境）、容量規劃變成「7 個獨立規劃 × 各自合規門檻」。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的合規要求識別、跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的地理分片。</li>
<li><strong>「韌性 + 性能」並列、不是 trade-off</strong>：傳統工程文化常把可靠性跟性能視為對立、銀行業務要求兩者同時達標。Aurora 的多 AZ storage + replica 同時提供性能（讀分流）跟韌性（故障切換）、達成 <em>韌性即性能</em> 的目標。對應 <a href="/blog/backend/06-reliability/reliability-metrics-governance/" data-link-title="6.18 Reliability Metrics Governance" data-link-desc="DORA / SPACE 指標的選用、量測陷阱、anti-gaming 與團隊階段適配">06.18 reliability metrics governance</a> 的可靠性指標。</li>
<li><strong>遷移本身的合規驗證 = 容量規劃延伸</strong>：受監管系統遷移不只是技術測試、還要過合規審查（中央銀行 / 金融監管機關）、每個市場各自審。這個審查 lead time（數月）必須算進遷移時程。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> 的合規驅動 migration。</li>
</ol>
<p>需要警惕：「10x throughput」是 <em>vs 舊系統</em>、不是 <em>vs 競爭對手</em>。受監管銀行的舊系統通常是 1990s-2000s 的 mainframe 或自建 OLTP、性能本來就低。讀案例時要對標的是「自家改善幅度」、不是「絕對性能」。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>資料駐留是容量規劃的硬限制、不是優化選項</strong>：受監管市場必須各自獨立 cluster、不能用「全球單一 cluster」優化。對應 <a href="/blog/backend/00-service-selection/traffic-data-scale/" data-link-title="0.5 流量與資料量評估" data-link-desc="用流量形狀、資料成長、hot key、保留期限與尖峰模式評估後端需求規模">00.4 traffic data scale</a> 的合規限制。</li>
<li><strong>多 AZ + 跨地區複製是合規基線、不是優化</strong>：銀行業務 RPO / RTO 通常由監管要求（不能丟資料、必須 X 小時內恢復）、不是業務 SLA 選項。對應 <a href="/blog/backend/06-reliability/dr-rollback-rehearsal/" data-link-title="6.7 DR 演練與 Rollback Rehearsal" data-link-desc="把回復路徑從紙面計畫變成定期可重播、可量測的驗證流程">06.7 DR rollback rehearsal</a>。</li>
<li><strong>遷移時程要算合規 lead time</strong>：每個受監管市場的審查可能 3-12 個月、合計遷移時程是「市場數 × 平均審查月份」、不是「技術遷移月份」。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a>。</li>
</ol>
<p>跨平台等效：Azure SQL Hyperscale + Azure regions、GCP Cloud SQL / Spanner + regional configurations、各家雲端的受監管雲端方案（AWS GovCloud、Azure Government、GCP Assured Workloads）都是對等候選。差異是各家對特定監管框架（PCI-DSS、ISO27001、各國金融法規）的認證覆蓋。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃受監管產業 OLTP → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想做合規驅動的容量規劃 → <a href="/blog/backend/00-service-selection/traffic-data-scale/" data-link-title="0.5 流量與資料量評估" data-link-desc="用流量形狀、資料成長、hot key、保留期限與尖峰模式評估後端需求規模">00.4 traffic data scale</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想理解韌性跟性能的同步達成 → <a href="/blog/backend/06-reliability/reliability-metrics-governance/" data-link-title="6.18 Reliability Metrics Governance" data-link-desc="DORA / SPACE 指標的選用、量測陷阱、anti-gaming 與團隊階段適配">06.18 reliability metrics governance</a></li>
<li>對照其他金融交易案例 → <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora</a> / <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a></li>
<li>想拆解跨 AZ failover RTO 量級與合規 anti-recommendation → <a href="/blog/backend/01-database/vendors/aurora/cross-az-failover-rto/" data-link-title="Aurora Cross-AZ Failover：RTO 量測、endpoint routing 與 application reconnect 契約" data-link-desc="Aurora cross-AZ failover lifecycle（detection / promotion / DNS update）、&lt; 30 秒 RTO、application DNS cache 跟 connection pool 對齊、Standard Chartered 受監管場景為什麼用獨立 cluster 而非 Global Database failover">Aurora 跨 AZ failover RTO</a></li>
<li>想評估全球資料常駐與多 region 部署 → <a href="/blog/backend/01-database/vendors/aurora/global-database-multi-region/" data-link-title="Aurora Global Database：跨 region async replication、&lt; 1 秒 lag 與合規 anti-recommendation" data-link-desc="Aurora Global Database 跨 region storage-level async replication、&lt; 1 秒 typical lag、planned vs unplanned failover RTO 數量級對比、Standard Chartered 合規禁止跨境複製為什麼讓 Global Database 變反指標">Aurora global database 多 region</a></li>
<li>想對照 distributed SQL（CockroachDB / Aurora DSQL / Spanner）的合規場景 → <a href="/blog/backend/01-database/vendors/cockroachdb/aurora-dsql-spanner-decision-tree/" data-link-title="CockroachDB vs Aurora DSQL vs Spanner：撞牆訊號分型 &#43; 七問題決策樹" data-link-desc="Distributed SQL 三選一決策樹。先用撞牆訊號分型識別 driver path（DoorDash 單主寫入撞牆 / Netflix Cassandra 缺口 / Hard Rock 合規驅動）、再走七問題（跨雲 / 雲商生態 / 風險預算 / PG 相容 / 管理負擔 / team size / vendor sizing barrier）。PostgreSQL 相容性 audit checklist 4 項、Spanner 100 pu sizing barrier、Hard Rock 「省 10-20 工程師」機會成本警示、Netflix Database Platform Team 規模">Aurora DSQL / Spanner / CockroachDB 決策樹</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/rds/aurora/customers/">Amazon Aurora Customer Stories</a></li>
<li><a href="https://aws.amazon.com/blogs/industries/amazon-aurora-for-core-banking-systems/">Amazon Aurora for Core Banking Systems</a></li>
<li><a href="https://aws.amazon.com/blogs/database/amazon-aurora-dsql-for-global-scale-financial-transactions/">Amazon Aurora DSQL for global-scale financial transactions</a></li>
</ul>
]]></content:encoded></item><item><title>9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/</guid><description>&lt;p>這個案例的核心責任是說明「售票搶購型 flash-sale」的負載形狀 — 跟現有所有案例都不同的極端形狀。售票開賣在精確時間點（例如 12:00:00）瞬間湧入數十萬使用者、5 分鐘內賣完、之後流量歸零。這種「t=0 起跳、t=300 結束」的負載沒有「峰值預測」可言、只有「瞬間吸收」。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>拓元 Tixcraft 在 AWS 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/tixcraft/">tixCraft Case Study&lt;/a> 與 &lt;a href="https://www.slideshare.net/slideshow/case-sharing-tixcraft-on-aws-reinvent-2015-recap/55681198">AWS re:Invent 2015 簡報&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>同時選位用戶&lt;/td>
 &lt;td>100,000+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訂單峰值&lt;/td>
 &lt;td>每分鐘 70,000+ 訂單、單秒最高 2,500+ 訂單&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3 分鐘內售出&lt;/td>
 &lt;td>30,000+ 張票&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DynamoDB IOPS 範圍&lt;/td>
 &lt;td>20 → 135,000（2015/8/29 峰值）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資源擴張幅度&lt;/td>
 &lt;td>30 分鐘內從 6 台擴到 800 台（130x）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>部署時間&lt;/td>
 &lt;td>1,600 工時 → 20 分鐘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>壓測規模&lt;/td>
 &lt;td>10,000 台 t2.micro、$130 / 小時&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務總成本&lt;/td>
 &lt;td>&amp;lt; 2 台 MacBook Pro（約 $4,200）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>vs 傳統基礎設施成本&lt;/td>
 &lt;td>0.26%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成立年份&lt;/td>
 &lt;td>2013 年底（雲原生）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合（依用戶提供的架構圖）：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>入口&lt;/strong>：Amazon Route 53（DNS）+ CloudFront + S3（靜態資源 static.tixcraft.com）&lt;/li>
&lt;li>&lt;strong>UI 層&lt;/strong>：Elastic Load Balancing → EC2 跨 3 個 Availability Zone（Tixcraft UI）&lt;/li>
&lt;li>&lt;strong>API 層&lt;/strong>：ELB → EC2 跨 3 個 AZ（API）+ ElastiCache 加速 session&lt;/li>
&lt;li>&lt;strong>資料層&lt;/strong>：DynamoDB 作為主要寫入目標（接 UI 寫入跟 API 寫入）&lt;/li>
&lt;li>&lt;strong>付款層&lt;/strong>：獨立的 EC2 Payment、連到 traditional server（合作金流、跑於企業 data center）&lt;/li>
&lt;li>&lt;strong>同步層&lt;/strong>：S3 Sync + EC2 Bridge 跟 corporate data center 的 backend 雙向同步&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>拓元案例最值得讀的、是它揭露三個 flash-sale 工程設計的非直覺事實。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>DynamoDB 作為寫入緩衝、不是 OLTP&lt;/strong>：搶票時的「訂單」先丟進 DynamoDB、傳統 server 用自己能承受的速度消費、即時生效在此架構下不是目標。架構上 DynamoDB 扮演 &lt;em>durable queue&lt;/em> 的角色、不是傳統 OLTP DB。這層解耦讓「前端可以擴 130 倍、後端不用同步擴」、避免後端被前端拖垮。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> 的 outbox / async delivery 概念、跟 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 transaction boundary 分離。&lt;/li>
&lt;li>&lt;strong>DynamoDB IOPS 從 20 衝到 135,000 = partition 設計能撐&lt;/strong>：這個 6,750 倍的彈性不是 DynamoDB 魔法、是 &lt;em>partition key 設計均勻&lt;/em> 的結果。partition key 不均、IOPS 上限是「最熱 partition 上限」、不是「總和」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 的同一判讀重點、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 hot partition 識別。&lt;/li>
&lt;li>&lt;strong>30 分鐘擴 130 倍 = 雲原生架構的存在證明&lt;/strong>：6 台 → 800 台不是手動操作、是 Auto Scaling Group + AMI prebuild + load balancer warmup 的組合。傳統 IDC 做不到。這層彈性是「30 秒內」flash-sale 的前置條件。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 autoscaling 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>需要警惕的判讀盲點：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「售票搶購型 flash-sale」的負載形狀 — 跟現有所有案例都不同的極端形狀。售票開賣在精確時間點（例如 12:00:00）瞬間湧入數十萬使用者、5 分鐘內賣完、之後流量歸零。這種「t=0 起跳、t=300 結束」的負載沒有「峰值預測」可言、只有「瞬間吸收」。</p>
<h2 id="觀察">觀察</h2>
<p>拓元 Tixcraft 在 AWS 的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/tixcraft/">tixCraft Case Study</a> 與 <a href="https://www.slideshare.net/slideshow/case-sharing-tixcraft-on-aws-reinvent-2015-recap/55681198">AWS re:Invent 2015 簡報</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>同時選位用戶</td>
          <td>100,000+</td>
      </tr>
      <tr>
          <td>訂單峰值</td>
          <td>每分鐘 70,000+ 訂單、單秒最高 2,500+ 訂單</td>
      </tr>
      <tr>
          <td>3 分鐘內售出</td>
          <td>30,000+ 張票</td>
      </tr>
      <tr>
          <td>DynamoDB IOPS 範圍</td>
          <td>20 → 135,000（2015/8/29 峰值）</td>
      </tr>
      <tr>
          <td>資源擴張幅度</td>
          <td>30 分鐘內從 6 台擴到 800 台（130x）</td>
      </tr>
      <tr>
          <td>部署時間</td>
          <td>1,600 工時 → 20 分鐘</td>
      </tr>
      <tr>
          <td>壓測規模</td>
          <td>10,000 台 t2.micro、$130 / 小時</td>
      </tr>
      <tr>
          <td>任務總成本</td>
          <td>&lt; 2 台 MacBook Pro（約 $4,200）</td>
      </tr>
      <tr>
          <td>vs 傳統基礎設施成本</td>
          <td>0.26%</td>
      </tr>
      <tr>
          <td>成立年份</td>
          <td>2013 年底（雲原生）</td>
      </tr>
  </tbody>
</table>
<p>服務組合（依用戶提供的架構圖）：</p>
<ul>
<li><strong>入口</strong>：Amazon Route 53（DNS）+ CloudFront + S3（靜態資源 static.tixcraft.com）</li>
<li><strong>UI 層</strong>：Elastic Load Balancing → EC2 跨 3 個 Availability Zone（Tixcraft UI）</li>
<li><strong>API 層</strong>：ELB → EC2 跨 3 個 AZ（API）+ ElastiCache 加速 session</li>
<li><strong>資料層</strong>：DynamoDB 作為主要寫入目標（接 UI 寫入跟 API 寫入）</li>
<li><strong>付款層</strong>：獨立的 EC2 Payment、連到 traditional server（合作金流、跑於企業 data center）</li>
<li><strong>同步層</strong>：S3 Sync + EC2 Bridge 跟 corporate data center 的 backend 雙向同步</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>拓元案例最值得讀的、是它揭露三個 flash-sale 工程設計的非直覺事實。</p>
<ol>
<li><strong>DynamoDB 作為寫入緩衝、不是 OLTP</strong>：搶票時的「訂單」先丟進 DynamoDB、傳統 server 用自己能承受的速度消費、即時生效在此架構下不是目標。架構上 DynamoDB 扮演 <em>durable queue</em> 的角色、不是傳統 OLTP DB。這層解耦讓「前端可以擴 130 倍、後端不用同步擴」、避免後端被前端拖垮。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 的 outbox / async delivery 概念、跟 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 transaction boundary 分離。</li>
<li><strong>DynamoDB IOPS 從 20 衝到 135,000 = partition 設計能撐</strong>：這個 6,750 倍的彈性不是 DynamoDB 魔法、是 <em>partition key 設計均勻</em> 的結果。partition key 不均、IOPS 上限是「最熱 partition 上限」、不是「總和」。對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 的同一判讀重點、跟 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 hot partition 識別。</li>
<li><strong>30 分鐘擴 130 倍 = 雲原生架構的存在證明</strong>：6 台 → 800 台不是手動操作、是 Auto Scaling Group + AMI prebuild + load balancer warmup 的組合。傳統 IDC 做不到。這層彈性是「30 秒內」flash-sale 的前置條件。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 autoscaling 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a>。</li>
</ol>
<p>需要警惕的判讀盲點：</p>
<ul>
<li>「限流到底怎麼做」這個工程社群關心的問題、架構圖上看不到明確元件。可能是「DynamoDB 寫入排隊 = 隱性限流」、也可能是 ELB / WAF / 應用層限流。沒有公開資訊不要過度推測。</li>
<li>2015 年的數字、用的還是 t2.micro 跟舊版 DynamoDB throughput model。現在等效實作可能會用 DynamoDB on-demand、AWS WAF、CloudFront WAF rules、或 SeatGeek-style Virtual Waiting Room（見 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16</a>）。</li>
<li>「30,000 張 / 3 分鐘」是 <em>票房成績</em>、不是 <em>系統極限</em>。系統能撐遠不止這個量、只是票本身賣完了。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>flash-sale 的核心架構模式：寫入緩衝 + 慢速消費</strong>：前端把訂單塞進可彈性擴容的儲存（DynamoDB / Redis Stream / Kafka）、後端按自己能力消費。這個模式讓「短時間吸收洪峰」跟「實際處理」解耦。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 與 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a>。</li>
<li><strong>partition key 設計是 flash-sale 的命脈</strong>：搶票場景天然容易 hot partition（同一場演唱會 = 同一 event_id）、必須用 composite key（event_id + user_id_hash）或 write sharding（event_id + random_suffix）分散。對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a>。</li>
<li><strong>flash-sale 必須事先 ELB / Auto Scaling 預熱</strong>：開賣前 30-60 分鐘 pre-warm ELB、預先啟動最低額度的 EC2、避免 t=0 時冷啟動。對應 AWS 官方 <a href="https://aws.amazon.com/blogs/mt/top-considerations-for-flash-sale-events/">Flash Sale 工程指引</a>。</li>
<li><strong>付款層獨立、不被搶票流量影響</strong>：拓元把 Payment EC2 拉出來、直連傳統金流 server。讓「選位 + 下單」的高頻流量不會塞爆「付款」的低頻流量。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的關鍵路徑切分。</li>
<li><strong>限流（rate limiting）通常是隱性的、不一定看得到 component</strong>：DynamoDB 寫入排隊本身就是隱性限流；也可以加 WAF rate-based rule、ELB request throttling、或前置 Virtual Waiting Room 做明確限流（見 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16</a>）。</li>
</ol>
<p>跨平台等效：GCP Cloud Spanner / Bigtable + Cloud Pub/Sub 作 buffer + GKE autoscaling；Azure Cosmos DB + Service Bus + AKS；自建 PostgreSQL + Kafka + Kubernetes 都可以實作對等架構。差異是 vendor 整合度跟擴容速度。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計 flash-sale 緩衝架構 → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想做 partition key 設計 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> + <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a></li>
<li>想做明確限流 / 排隊機制 → <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek Virtual Waiting Room</a></li>
<li>想預熱 ELB / Auto Scaling → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a></li>
<li>對照其他售票市場 → <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a>（印度市場、年售 2 億張）</li>
<li>想理解 flash-sale 場景的 partition key 反模式 → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a></li>
<li>想評估 on-demand vs provisioned 在 flash-sale 的搭配 → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/tixcraft/">tixCraft Case Study (AWS)</a></li>
<li><a href="https://www.slideshare.net/slideshow/case-sharing-tixcraft-on-aws-reinvent-2015-recap/55681198">tixCraft on AWS re:Invent 2015 Recap (SlideShare)</a></li>
<li><a href="https://www.youtube.com/watch?v=Bi-1xjXvKgs">tixCraft: Handling Millions of Ticketing Requests with AWS (YouTube)</a></li>
<li><a href="https://aws.amazon.com/blogs/mt/top-considerations-for-flash-sale-events/">Top considerations for Flash sale events (AWS Cloud Operations Blog)</a></li>
<li><a href="https://aws.amazon.com/blogs/database/handle-traffic-spikes-with-amazon-dynamodb-provisioned-capacity/">Handle traffic spikes with Amazon DynamoDB provisioned capacity</a></li>
</ul>
]]></content:encoded></item><item><title>9.C16 SeatGeek：DynamoDB + Lambda 打造的虛擬等候室</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/</guid><description>&lt;p>這個案例的核心責任是說明「flash-sale 場景下、限流如何明確設計」。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft&lt;/a> 的「DynamoDB 隱性緩衝」是姊妹案 — Tixcraft 用 DynamoDB 作為寫入緩衝吸收洪峰、SeatGeek 走更上游一層、在用戶到達系統前就明確排隊。兩種架構並存於票務業界、適合不同業務場景。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>SeatGeek Virtual Waiting Room 架構（引自 &lt;a href="https://aws.amazon.com/blogs/architecture/build-a-virtual-waiting-room-with-amazon-dynamodb-and-aws-lambda-at-seatgeek/">AWS Architecture Blog&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>元件&lt;/th>
 &lt;th>角色&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Protected Zone table&lt;/td>
 &lt;td>紀錄受保護資源的 metadata（哪個 event 受 waiting room 保護）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Counters table&lt;/td>
 &lt;td>紀錄「每分鐘發出多少 access token」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>User Connection table&lt;/td>
 &lt;td>紀錄訪客 token 與 WebSocket connection ID&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Queue table&lt;/td>
 &lt;td>把訪客 token 對映到 access token（排隊序號）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bouncer Lambda&lt;/td>
 &lt;td>配發與失效 access token 的「守門員」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>API Gateway&lt;/td>
 &lt;td>接受外部請求、轉發 Bouncer&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>業務動機：取代「第三方 waiting room 服務」、原因是缺乏客製化（VIP 規則、優先級）跟 metrics 可見度。&lt;/p>
&lt;p>關鍵機制：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Token = 庫存單位&lt;/strong>：access token 總數 = 可售票數量。沒拿到 token 的用戶被導到 waiting room 頁面、看到排隊位置與預估等待時間。&lt;/li>
&lt;li>&lt;strong>FIFO 或 priority queue&lt;/strong>：可以按進入順序、也可以對 VIP 客戶優先發 token。&lt;/li>
&lt;li>&lt;strong>Token 失效機制&lt;/strong>：用戶完成購票 / 主動退出時、token 釋放回 pool、給下一位等候用戶。&lt;/li>
&lt;/ol>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>SeatGeek 案例揭露三個明確限流設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>隱性緩衝 vs 明確排隊是兩種架構取捨&lt;/strong>：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">Tixcraft 模式&lt;/a>「全部塞進 DynamoDB」、用戶以為下單成功、實際處理排隊。SeatGeek 模式「明確告訴你排隊位置」、用戶看得到等待時間。前者犧牲透明度換流量吸收、後者犧牲流量吸收換體驗。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.10 Production-Side 驗證&lt;/a> 的用戶體驗 vs 系統行為取捨。&lt;/li>
&lt;li>&lt;strong>WebSocket connection 是 stateful 容量單位&lt;/strong>：100 萬個 active waiting room 用戶 = 100 萬個 WebSocket connection、每個 connection 都吃記憶體跟 file descriptor。Lambda 沒辦法保持 WebSocket、需要 API Gateway WebSocket API 或 AppSync 配合。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 stateful service 容量規劃。&lt;/li>
&lt;li>&lt;strong>限流粒度 = 業務粒度&lt;/strong>：「每分鐘發 N 個 token」這個參數直接決定「每分鐘成交 N 張票」。N 太小、賣不完；N 太大、後端撐不住。N 不是技術參數、是業務 × 後端容量的協商結果。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 把容量規劃跟業務 KPI 對接。&lt;/li>
&lt;/ol>
&lt;p>需要警惕的判讀盲點：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「flash-sale 場景下、限流如何明確設計」。跟 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 的「DynamoDB 隱性緩衝」是姊妹案 — Tixcraft 用 DynamoDB 作為寫入緩衝吸收洪峰、SeatGeek 走更上游一層、在用戶到達系統前就明確排隊。兩種架構並存於票務業界、適合不同業務場景。</p>
<h2 id="觀察">觀察</h2>
<p>SeatGeek Virtual Waiting Room 架構（引自 <a href="https://aws.amazon.com/blogs/architecture/build-a-virtual-waiting-room-with-amazon-dynamodb-and-aws-lambda-at-seatgeek/">AWS Architecture Blog</a>）：</p>
<table>
  <thead>
      <tr>
          <th>元件</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Protected Zone table</td>
          <td>紀錄受保護資源的 metadata（哪個 event 受 waiting room 保護）</td>
      </tr>
      <tr>
          <td>Counters table</td>
          <td>紀錄「每分鐘發出多少 access token」</td>
      </tr>
      <tr>
          <td>User Connection table</td>
          <td>紀錄訪客 token 與 WebSocket connection ID</td>
      </tr>
      <tr>
          <td>Queue table</td>
          <td>把訪客 token 對映到 access token（排隊序號）</td>
      </tr>
      <tr>
          <td>Bouncer Lambda</td>
          <td>配發與失效 access token 的「守門員」</td>
      </tr>
      <tr>
          <td>API Gateway</td>
          <td>接受外部請求、轉發 Bouncer</td>
      </tr>
  </tbody>
</table>
<p>業務動機：取代「第三方 waiting room 服務」、原因是缺乏客製化（VIP 規則、優先級）跟 metrics 可見度。</p>
<p>關鍵機制：</p>
<ol>
<li><strong>Token = 庫存單位</strong>：access token 總數 = 可售票數量。沒拿到 token 的用戶被導到 waiting room 頁面、看到排隊位置與預估等待時間。</li>
<li><strong>FIFO 或 priority queue</strong>：可以按進入順序、也可以對 VIP 客戶優先發 token。</li>
<li><strong>Token 失效機制</strong>：用戶完成購票 / 主動退出時、token 釋放回 pool、給下一位等候用戶。</li>
</ol>
<h2 id="判讀">判讀</h2>
<p>SeatGeek 案例揭露三個明確限流設計重點。</p>
<ol>
<li><strong>隱性緩衝 vs 明確排隊是兩種架構取捨</strong>：<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 模式</a>「全部塞進 DynamoDB」、用戶以為下單成功、實際處理排隊。SeatGeek 模式「明確告訴你排隊位置」、用戶看得到等待時間。前者犧牲透明度換流量吸收、後者犧牲流量吸收換體驗。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.10 Production-Side 驗證</a> 的用戶體驗 vs 系統行為取捨。</li>
<li><strong>WebSocket connection 是 stateful 容量單位</strong>：100 萬個 active waiting room 用戶 = 100 萬個 WebSocket connection、每個 connection 都吃記憶體跟 file descriptor。Lambda 沒辦法保持 WebSocket、需要 API Gateway WebSocket API 或 AppSync 配合。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 stateful service 容量規劃。</li>
<li><strong>限流粒度 = 業務粒度</strong>：「每分鐘發 N 個 token」這個參數直接決定「每分鐘成交 N 張票」。N 太小、賣不完；N 太大、後端撐不住。N 不是技術參數、是業務 × 後端容量的協商結果。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 把容量規劃跟業務 KPI 對接。</li>
</ol>
<p>需要警惕的判讀盲點：</p>
<ul>
<li>AWS Architecture Blog 沒提具體流量數字（concurrent users、queue depth、throughput）。讀者無法直接套用到自家容量規劃、必須自己壓測。</li>
<li>DynamoDB 4 張表的設計 <em>看似簡單</em>、實際上每張表的 partition key / sort key 設計都要仔細想。複製這個架構不等於拿到 SeatGeek 的吞吐能力。</li>
<li>「token expiration」機制如果設計不好（例如用戶關閉瀏覽器、token 沒回收）、會導致「排隊很長但實際空著」、影響轉換率。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>明確 vs 隱性限流的選擇</strong>：高價值門票（演唱會、限量周邊）適合明確排隊（用戶願意等）；高頻低價值商品（FCFS 折扣）適合隱性緩衝（讓用戶快速完成）。</li>
<li><strong>Virtual Waiting Room 是 stateful service、要規劃連線容量</strong>：不是 stateless Lambda 一招到底、需要 WebSocket gateway + DynamoDB state store。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的混合架構。</li>
<li><strong>token 過期策略要寫進設計初稿</strong>：用戶離開、付款超時、瀏覽器當掉 — 三種狀況的 token 回收邏輯都不一樣、要明確設計。</li>
<li><strong>可觀測性是「自建 waiting room」勝過「第三方」的關鍵</strong>：SeatGeek 換掉第三方就是要 metrics 可見、知道每分鐘 token issue rate、queue depth distribution、token expiration rate、conversion funnel。對應 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a>。</li>
</ol>
<p>跨平台等效：GCP Cloud Functions + Firestore + Pub/Sub；Azure Functions + Cosmos DB + SignalR；自建 Redis（INCR / TTL）+ WebSocket gateway（Soketi / Socket.IO + Redis adapter）都可以實作對等架構。AWS 還推出官方 <a href="https://aws.amazon.com/solutions/implementations/virtual-waiting-room-on-aws/">Virtual Waiting Room on AWS</a> Solutions、是 SeatGeek 模式的可重用版本。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計明確排隊限流 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a></li>
<li>對照隱性緩衝模式 → <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></li>
<li>想做 conversion funnel 可觀測性 → <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> + <a href="/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號</a></li>
<li>想了解 stateful service 容量規劃 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/architecture/build-a-virtual-waiting-room-with-amazon-dynamodb-and-aws-lambda-at-seatgeek/">Build a Virtual Waiting Room with Amazon DynamoDB and AWS Lambda at SeatGeek</a></li>
<li><a href="https://aws.amazon.com/solutions/implementations/virtual-waiting-room-on-aws/">Virtual Waiting Room on AWS (Solutions)</a></li>
<li><a href="https://aws.amazon.com/blogs/apn/how-to-manage-peak-traffic-on-aws-using-queue-its-virtual-waiting-room/">How to manage peak traffic on AWS using Queue-it&rsquo;s virtual waiting room</a></li>
</ul>
]]></content:encoded></item><item><title>9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/</guid><description>&lt;p>這個案例的核心責任是說明「規模化 ticketing 平台」的長期工程議題 — 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft&lt;/a> 的「單一搶票事件」不同、BookMyShow 是 &lt;em>每天都有上百個 flash-sale 事件&lt;/em> 的平台、年售 2 億張票、跨 5 個國家。容量問題從「單一峰值」變成「峰值的常態化」、加上「資料層怎麼跟得上業務變化」。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>BookMyShow 在 AWS 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/blogs/business-intelligence/how-bookmyshow-saved-80-in-costs-by-migrating-to-an-aws-modern-data-architecture/">BookMyShow AWS Migration Blog&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>年售票量&lt;/td>
 &lt;td>2 億張 / 年（pre-COVID baseline）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>印度 + 斯里蘭卡 + 新加坡 + 印尼 + 中東&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移時程&lt;/td>
 &lt;td>4 個月完成&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>舊系統年數&lt;/td>
 &lt;td>15 年自建 analytics solution&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>儲存成本下降&lt;/td>
 &lt;td>90%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>分析成本下降&lt;/td>
 &lt;td>80%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料整合&lt;/td>
 &lt;td>從 80 TB 多份副本 → 單一 source of truth&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>資料架構：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Data Lake&lt;/strong>：Amazon S3 統一儲存&lt;/li>
&lt;li>&lt;strong>Ingestion&lt;/strong>：Kafka consumers、AWS Glue ETL、AWS IoT Core（MQTT）&lt;/li>
&lt;li>&lt;strong>Processing&lt;/strong>：Amazon EMR（streaming permanent cluster + batch transient cluster）&lt;/li>
&lt;li>&lt;strong>Data Warehouse&lt;/strong>：Amazon Redshift + materialized views&lt;/li>
&lt;li>&lt;strong>Analytics&lt;/strong>：Amazon Athena（ad-hoc）+ Amazon QuickSight（dashboard）&lt;/li>
&lt;li>&lt;strong>ML&lt;/strong>：Amazon SageMaker（內容熱度、活動熱度、搜尋趨勢模型）&lt;/li>
&lt;li>&lt;strong>Orchestration&lt;/strong>：Amazon MWAA + AWS Step Functions&lt;/li>
&lt;/ul>
&lt;p>關鍵業務支撐：「sudden spikes with new movies or events launched」靠 serverless（S3、Glue、Athena、Step Functions、Lambda）自動擴容、無需人工介入。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>BookMyShow 案例揭露三個規模化 ticketing 平台的長期工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>單一搶票 → 常態多事件 = 架構從「為峰值設計」變「為流量分佈設計」&lt;/strong>：每天上百場電影 + 數十場演唱會 + 各種活動同時開票、每場都是 mini flash-sale。容量問題不再是「為一場演唱會準備」、而是「為每天上百個峰值同時準備」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling&lt;/a> 從單一 workload 變成 workload portfolio。&lt;/li>
&lt;li>&lt;strong>資料層比交易層更難擴&lt;/strong>：8 TB → 80 TB 過程中、舊 analytics 系統用 15 年才走到極限。交易層擴容靠 stateless EC2 + auto-scaling 相對容易、資料層 schema migration、ETL 重寫、報表回對都是長 lead time 工作。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 schema migration 與 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組&lt;/a> 的 cost attribution。&lt;/li>
&lt;li>&lt;strong>跨國市場 = 多重合規約束&lt;/strong>：印度、新加坡、印尼、中東各自有資料駐留 / 加密 / 報稅規則。S3 + EMR + Redshift 的「資料分區」不只是性能議題、也是合規議題。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered&lt;/a> 的合規容量規劃。&lt;/li>
&lt;/ol>
&lt;p>需要警惕的判讀盲點：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「規模化 ticketing 平台」的長期工程議題 — 跟 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 的「單一搶票事件」不同、BookMyShow 是 <em>每天都有上百個 flash-sale 事件</em> 的平台、年售 2 億張票、跨 5 個國家。容量問題從「單一峰值」變成「峰值的常態化」、加上「資料層怎麼跟得上業務變化」。</p>
<h2 id="觀察">觀察</h2>
<p>BookMyShow 在 AWS 的關鍵敘述（引自 <a href="https://aws.amazon.com/blogs/business-intelligence/how-bookmyshow-saved-80-in-costs-by-migrating-to-an-aws-modern-data-architecture/">BookMyShow AWS Migration Blog</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>年售票量</td>
          <td>2 億張 / 年（pre-COVID baseline）</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>印度 + 斯里蘭卡 + 新加坡 + 印尼 + 中東</td>
      </tr>
      <tr>
          <td>遷移時程</td>
          <td>4 個月完成</td>
      </tr>
      <tr>
          <td>舊系統年數</td>
          <td>15 年自建 analytics solution</td>
      </tr>
      <tr>
          <td>儲存成本下降</td>
          <td>90%</td>
      </tr>
      <tr>
          <td>分析成本下降</td>
          <td>80%</td>
      </tr>
      <tr>
          <td>資料整合</td>
          <td>從 80 TB 多份副本 → 單一 source of truth</td>
      </tr>
  </tbody>
</table>
<p>資料架構：</p>
<ul>
<li><strong>Data Lake</strong>：Amazon S3 統一儲存</li>
<li><strong>Ingestion</strong>：Kafka consumers、AWS Glue ETL、AWS IoT Core（MQTT）</li>
<li><strong>Processing</strong>：Amazon EMR（streaming permanent cluster + batch transient cluster）</li>
<li><strong>Data Warehouse</strong>：Amazon Redshift + materialized views</li>
<li><strong>Analytics</strong>：Amazon Athena（ad-hoc）+ Amazon QuickSight（dashboard）</li>
<li><strong>ML</strong>：Amazon SageMaker（內容熱度、活動熱度、搜尋趨勢模型）</li>
<li><strong>Orchestration</strong>：Amazon MWAA + AWS Step Functions</li>
</ul>
<p>關鍵業務支撐：「sudden spikes with new movies or events launched」靠 serverless（S3、Glue、Athena、Step Functions、Lambda）自動擴容、無需人工介入。</p>
<h2 id="判讀">判讀</h2>
<p>BookMyShow 案例揭露三個規模化 ticketing 平台的長期工程重點。</p>
<ol>
<li><strong>單一搶票 → 常態多事件 = 架構從「為峰值設計」變「為流量分佈設計」</strong>：每天上百場電影 + 數十場演唱會 + 各種活動同時開票、每場都是 mini flash-sale。容量問題不再是「為一場演唱會準備」、而是「為每天上百個峰值同時準備」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a> 從單一 workload 變成 workload portfolio。</li>
<li><strong>資料層比交易層更難擴</strong>：8 TB → 80 TB 過程中、舊 analytics 系統用 15 年才走到極限。交易層擴容靠 stateless EC2 + auto-scaling 相對容易、資料層 schema migration、ETL 重寫、報表回對都是長 lead time 工作。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema migration 與 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 的 cost attribution。</li>
<li><strong>跨國市場 = 多重合規約束</strong>：印度、新加坡、印尼、中東各自有資料駐留 / 加密 / 報稅規則。S3 + EMR + Redshift 的「資料分區」不只是性能議題、也是合規議題。對應 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 的合規容量規劃。</li>
</ol>
<p>需要警惕的判讀盲點：</p>
<ul>
<li>「年售 2 億張」是 <em>年度總和</em>、不是 <em>峰值</em>。實際單秒峰值（板球比賽決賽開票、寶萊塢新片首映）案例本身沒揭露。</li>
<li>案例聚焦在 <em>資料分析層</em> 的遷移、不是 <em>交易層</em> 的 flash-sale 設計。讀者若想學「單場 flash-sale 怎麼撐」、應該回 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 或 <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a>。</li>
<li>「80% 成本下降」是 <em>vs 15 年舊系統</em>、不是 <em>vs 競爭對手</em>。舊系統的儲存效率、運維成本本來就低、改善幅度部分來自「現代化紅利」、不只是 AWS 服務本身。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>大規模 ticketing 平台要分「交易層」跟「資料層」兩條容量規劃</strong>：交易層為單一 event flash-sale 設計（<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15</a> / <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16</a> 模式）；資料層為「上千場活動的長期分析」設計（BookMyShow 模式）。兩者用不同服務、不同 SLO。</li>
<li><strong>跨國平台先解決資料駐留、再規劃跨國 analytics</strong>：印度資料不能搬到新加坡分析、合規必須各國資料本地處理、再彙整 metadata。對應 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a>。</li>
<li><strong>serverless data stack 是 ticketing 平台的長期方向</strong>：S3 + Glue + Athena + Step Functions 的成本曲線比 EMR cluster 平穩、沒事件時近乎 0、有事件時自動擴。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
<li><strong>遷移時程 4 個月 = 計畫密度極高</strong>：15 年資產 4 個月遷完不是常態、需要先把 <em>資料模型</em> canonical 化、再 batch 平行遷。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> 的 schema 對映先行。</li>
</ol>
<p>跨平台等效：GCP BigQuery + Dataflow + Cloud Storage + Pub/Sub 是對等 stack；Azure Synapse + Data Lake + Event Hubs；自建 Delta Lake + Spark + Kafka 都可以實作對等架構。差異是 vendor 整合度跟 serverless 透明度。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃多事件 ticketing 平台 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想看單一 flash-sale 設計 → <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> + <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a></li>
<li>想做跨國合規容量規劃 → <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> + <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a></li>
<li>想做大規模 migration → <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> + <a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify migration</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/business-intelligence/how-bookmyshow-saved-80-in-costs-by-migrating-to-an-aws-modern-data-architecture/">How BookMyShow saved 80% in costs by migrating to an AWS modern data architecture</a></li>
<li><a href="https://aws.amazon.com/architecture/analytics-big-data/">AWS Modern Data Architecture</a></li>
</ul>
]]></content:encoded></item><item><title>9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/</guid><description>&lt;p>這個案例的核心責任是說明「SaaS 類 surge」跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokemon GO&lt;/a> 的「product surge」差異。Zoom 的 30 倍成長不是「產品爆紅」、是「外部事件（COVID）逼全世界改變工作模式」、突發是 &lt;em>結構性&lt;/em> 的、不是回歸均值的暫時現象。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Zoom 在 2020 年 COVID 期間的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>日活參與者&lt;/td>
 &lt;td>1000 萬 → 3 億（2020 年 3 月）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成長倍數&lt;/td>
 &lt;td>30x&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主資料層&lt;/td>
 &lt;td>Amazon DynamoDB（會議 metadata）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>擴容描述&lt;/td>
 &lt;td>「nearly infinitely with no performance issues」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵敘述：「On the backend, they were able to manage this surge with Amazon DynamoDB for Zoom Meetings.」&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Zoom surge 揭露三個 SaaS 突發成長的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>SaaS surge 是結構性、不是暫時性&lt;/strong>：Pokemon GO 上線爆紅後流量會隨熱度消退、Zoom COVID 成長是「永久 baseline 上移」。容量規劃不能假設「過幾個月會回來」、必須假設「3 億 DAU 是新常態」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的長期 baseline 重新校準。&lt;/li>
&lt;li>&lt;strong>DynamoDB 「無限擴容」對 SaaS 元資料層特別適用&lt;/strong>：Zoom 會議 metadata（room ID、participant list、permission state）是典型 KV 工作負載、partition key（meeting_id）天然均勻、不會 hot partition。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 同樣的 partition 均勻優勢。&lt;/li>
&lt;li>&lt;strong>媒體串流不在 DynamoDB&lt;/strong>：Zoom 的影音流量是 P2P + edge servers、不經 DynamoDB。DynamoDB 只承擔「control plane」、不承擔「data plane」。這個分離是擴 30 倍的前提 — 控制面跟資料面解耦、控制面用 managed 服務、資料面用專屬基礎設施。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 的關鍵路徑切分。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「nearly infinitely」是行銷敘述、不是工程承諾。實務上 Zoom 在 COVID 初期確實遇到 outage 與性能問題、後續才穩定。讀案例時要看 &lt;em>最終狀態&lt;/em> 跟 &lt;em>過程中的 incident&lt;/em>。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>控制面跟資料面分離&lt;/strong>：高頻 metadata 操作放 managed KV（DynamoDB / Cosmos DB / Firestore）、大資料量串流放專屬基礎設施（CDN / WebRTC / 自管 servers）。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a>。&lt;/li>
&lt;li>&lt;strong>surge 後重新校準 SLO baseline&lt;/strong>：30x 成長之後、SLO 的「正常範圍」要更新、否則 monitoring 會誤報。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 SLO 演進。&lt;/li>
&lt;li>&lt;strong>長期 surge 觸發架構重新評估&lt;/strong>：DynamoDB 是「擴大量」的好選擇、但成本也跟著放大。當 baseline 從 1000 萬永久升到 3 億、原本的 on-demand 模式可能變得貴、要考慮 provisioned + auto-scaling 組合。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：Google Meet 也用 Spanner / Firestore、Microsoft Teams 用 Cosmos DB — 三家視訊會議都靠 managed KV 撐 metadata、是同一個架構模式的不同 vendor 實作。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「SaaS 類 surge」跟 <a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokemon GO</a> 的「product surge」差異。Zoom 的 30 倍成長不是「產品爆紅」、是「外部事件（COVID）逼全世界改變工作模式」、突發是 <em>結構性</em> 的、不是回歸均值的暫時現象。</p>
<h2 id="觀察">觀察</h2>
<p>Zoom 在 2020 年 COVID 期間的關鍵敘述（引自 <a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>日活參與者</td>
          <td>1000 萬 → 3 億（2020 年 3 月）</td>
      </tr>
      <tr>
          <td>成長倍數</td>
          <td>30x</td>
      </tr>
      <tr>
          <td>主資料層</td>
          <td>Amazon DynamoDB（會議 metadata）</td>
      </tr>
      <tr>
          <td>擴容描述</td>
          <td>「nearly infinitely with no performance issues」</td>
      </tr>
  </tbody>
</table>
<p>關鍵敘述：「On the backend, they were able to manage this surge with Amazon DynamoDB for Zoom Meetings.」</p>
<h2 id="判讀">判讀</h2>
<p>Zoom surge 揭露三個 SaaS 突發成長的工程重點。</p>
<ol>
<li><strong>SaaS surge 是結構性、不是暫時性</strong>：Pokemon GO 上線爆紅後流量會隨熱度消退、Zoom COVID 成長是「永久 baseline 上移」。容量規劃不能假設「過幾個月會回來」、必須假設「3 億 DAU 是新常態」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的長期 baseline 重新校準。</li>
<li><strong>DynamoDB 「無限擴容」對 SaaS 元資料層特別適用</strong>：Zoom 會議 metadata（room ID、participant list、permission state）是典型 KV 工作負載、partition key（meeting_id）天然均勻、不會 hot partition。對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 同樣的 partition 均勻優勢。</li>
<li><strong>媒體串流不在 DynamoDB</strong>：Zoom 的影音流量是 P2P + edge servers、不經 DynamoDB。DynamoDB 只承擔「control plane」、不承擔「data plane」。這個分離是擴 30 倍的前提 — 控制面跟資料面解耦、控制面用 managed 服務、資料面用專屬基礎設施。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的關鍵路徑切分。</li>
</ol>
<p>需要警惕：「nearly infinitely」是行銷敘述、不是工程承諾。實務上 Zoom 在 COVID 初期確實遇到 outage 與性能問題、後續才穩定。讀案例時要看 <em>最終狀態</em> 跟 <em>過程中的 incident</em>。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>控制面跟資料面分離</strong>：高頻 metadata 操作放 managed KV（DynamoDB / Cosmos DB / Firestore）、大資料量串流放專屬基礎設施（CDN / WebRTC / 自管 servers）。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a>。</li>
<li><strong>surge 後重新校準 SLO baseline</strong>：30x 成長之後、SLO 的「正常範圍」要更新、否則 monitoring 會誤報。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 SLO 演進。</li>
<li><strong>長期 surge 觸發架構重新評估</strong>：DynamoDB 是「擴大量」的好選擇、但成本也跟著放大。當 baseline 從 1000 萬永久升到 3 億、原本的 on-demand 模式可能變得貴、要考慮 provisioned + auto-scaling 組合。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
</ol>
<p>跨平台等效：Google Meet 也用 Spanner / Firestore、Microsoft Teams 用 Cosmos DB — 三家視訊會議都靠 managed KV 撐 metadata、是同一個架構模式的不同 vendor 實作。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照 product surge → <a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokemon GO</a></li>
<li>想理解 control plane vs data plane → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> + <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a></li>
<li>想規劃 surge 後的 SLO → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/04-observability/sli-slo-signal/" data-link-title="4.6 SLI 量測與 SLO 訊號設計" data-link-desc="把可靠性目標的訊號從 metric 端設計好、餵給 6.6 SLO 政策">04.16 SLI / SLO 訊號</a></li>
<li>想評估 surge 下的 on-demand vs provisioned 切換 → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
<li>想避免 surge 觸發 hot partition → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/innovators/zoom/">Zoom Video Communications on AWS</a></li>
</ul>
]]></content:encoded></item><item><title>9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB + EKS 上的遊戲後端</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/</guid><description>&lt;p>這個案例的核心責任是說明「遊戲後端 KV」跟「廣告 KV」「電商 KV」的業務語意差異。遊戲後端的 KV 工作負載特性是：玩家狀態（角色、裝備、戰績）必須次秒讀寫、跨 region 同步、防作弊 — 這層需求跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 的「廣告量測」或 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth&lt;/a> 的「AR 玩家位置」都不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Capcom 在 AWS 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/capcom/">Capcom Case Study&lt;/a> 與 &lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>遊戲 IP&lt;/td>
 &lt;td>Resident Evil、Street Fighter、Monster Hunter&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>後端請求量&lt;/td>
 &lt;td>billions of requests&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>響應時間&lt;/td>
 &lt;td>single-digit millisecond&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>營運成本下降&lt;/td>
 &lt;td>30%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>Amazon DynamoDB + Amazon EKS&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工程資源再配置&lt;/td>
 &lt;td>從 DB 運維轉到遊戲品質與開發週期&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵敘述：「Capcom uses Amazon DynamoDB to meet this demand with single-digit millisecond response times」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Capcom 案例揭露三個遊戲後端 KV 的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>遊戲後端 KV = 跨遊戲共用基礎設施&lt;/strong>：Resident Evil / Street Fighter / Monster Hunter 是不同類型遊戲（單機+多人 / 對戰 / 合作打怪）、卻共用 &lt;em>同一套後端 KV&lt;/em>。這個共用降低了單一遊戲的維運成本、也讓新遊戲上線時不用重做基礎設施。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 multi-tenant platform。&lt;/li>
&lt;li>&lt;strong>single-digit ms response time = 玩家體感「即時」的底線&lt;/strong>：戰鬥動作、技能釋放、玩家對戰都要次秒級反應、超過 10ms 就「卡」。這個延遲門檻反推 Capcom 必須用 sub-region cache（ElastiCache / 本地 game server）+ DynamoDB DAX、不能單靠 DynamoDB。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &amp;#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase&lt;/a> 的延遲反推。&lt;/li>
&lt;li>&lt;strong>「工程資源從 DB 運維轉到遊戲品質」是 managed 服務的真實價值&lt;/strong>：Capcom 不是 IT 公司、是遊戲公司。把 DBA 時間從「Postgres patching、replication 設定、backup 排程」釋放到「遊戲機制設計、玩家行為分析」、才是 30% 成本下降的本質。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的人力成本工程化。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「billions of requests」沒指明時間單位（每秒、每天、每月）。讀案例時要找具體單位、不要直接套用到自家。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>遊戲後端 KV 用 DynamoDB / Cosmos DB / Bigtable&lt;/strong>：partition key 用 player_id 天然均勻、不會 hot partition。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 schema 設計。&lt;/li>
&lt;li>&lt;strong>EKS 跑 game server、不直接連 DynamoDB&lt;/strong>：game server 處理遊戲邏輯（戰鬥、配對、防作弊）、DynamoDB 處理持久狀態。中間用 DAX 或 ElastiCache 減少 DynamoDB 呼叫。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a>。&lt;/li>
&lt;li>&lt;strong>多 IP / 多遊戲共用平台是降本核心&lt;/strong>：每個新遊戲不重做基礎設施、共用同一套 DynamoDB + EKS。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games&lt;/a> 的「single-tenant per game」對照 — 不同 IP 公司有不同取捨。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP Bigtable + GKE + Memorystore、Azure Cosmos DB + AKS + Cache for Redis 都可實作對等架構。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「遊戲後端 KV」跟「廣告 KV」「電商 KV」的業務語意差異。遊戲後端的 KV 工作負載特性是：玩家狀態（角色、裝備、戰績）必須次秒讀寫、跨 region 同步、防作弊 — 這層需求跟 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 的「廣告量測」或 <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> 的「AR 玩家位置」都不同。</p>
<h2 id="觀察">觀察</h2>
<p>Capcom 在 AWS 的關鍵敘述（引自 <a href="https://aws.amazon.com/solutions/case-studies/capcom/">Capcom Case Study</a> 與 <a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>遊戲 IP</td>
          <td>Resident Evil、Street Fighter、Monster Hunter</td>
      </tr>
      <tr>
          <td>後端請求量</td>
          <td>billions of requests</td>
      </tr>
      <tr>
          <td>響應時間</td>
          <td>single-digit millisecond</td>
      </tr>
      <tr>
          <td>營運成本下降</td>
          <td>30%</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>Amazon DynamoDB + Amazon EKS</td>
      </tr>
      <tr>
          <td>工程資源再配置</td>
          <td>從 DB 運維轉到遊戲品質與開發週期</td>
      </tr>
  </tbody>
</table>
<p>關鍵敘述：「Capcom uses Amazon DynamoDB to meet this demand with single-digit millisecond response times」。</p>
<h2 id="判讀">判讀</h2>
<p>Capcom 案例揭露三個遊戲後端 KV 的工程重點。</p>
<ol>
<li><strong>遊戲後端 KV = 跨遊戲共用基礎設施</strong>：Resident Evil / Street Fighter / Monster Hunter 是不同類型遊戲（單機+多人 / 對戰 / 合作打怪）、卻共用 <em>同一套後端 KV</em>。這個共用降低了單一遊戲的維運成本、也讓新遊戲上線時不用重做基礎設施。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 multi-tenant platform。</li>
<li><strong>single-digit ms response time = 玩家體感「即時」的底線</strong>：戰鬥動作、技能釋放、玩家對戰都要次秒級反應、超過 10ms 就「卡」。這個延遲門檻反推 Capcom 必須用 sub-region cache（ElastiCache / 本地 game server）+ DynamoDB DAX、不能單靠 DynamoDB。對應 <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> 的延遲反推。</li>
<li><strong>「工程資源從 DB 運維轉到遊戲品質」是 managed 服務的真實價值</strong>：Capcom 不是 IT 公司、是遊戲公司。把 DBA 時間從「Postgres patching、replication 設定、backup 排程」釋放到「遊戲機制設計、玩家行為分析」、才是 30% 成本下降的本質。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的人力成本工程化。</li>
</ol>
<p>需要警惕：「billions of requests」沒指明時間單位（每秒、每天、每月）。讀案例時要找具體單位、不要直接套用到自家。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>遊戲後端 KV 用 DynamoDB / Cosmos DB / Bigtable</strong>：partition key 用 player_id 天然均勻、不會 hot partition。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema 設計。</li>
<li><strong>EKS 跑 game server、不直接連 DynamoDB</strong>：game server 處理遊戲邏輯（戰鬥、配對、防作弊）、DynamoDB 處理持久狀態。中間用 DAX 或 ElastiCache 減少 DynamoDB 呼叫。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a>。</li>
<li><strong>多 IP / 多遊戲共用平台是降本核心</strong>：每個新遊戲不重做基礎設施、共用同一套 DynamoDB + EKS。跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a> 的「single-tenant per game」對照 — 不同 IP 公司有不同取捨。</li>
</ol>
<p>跨平台等效：GCP Bigtable + GKE + Memorystore、Azure Cosmos DB + AKS + Cache for Redis 都可實作對等架構。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他遊戲後端 → <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS</a>（cluster 隔離 vs 共用）</li>
<li>想設計遊戲 KV → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a></li>
<li>想理解 sub-ms latency 反推 → <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a></li>
<li>想規劃遊戲 KV access pattern 與 single-table design → <a href="/blog/backend/01-database/vendors/dynamodb/single-table-design-pattern/" data-link-title="DynamoDB Single-Table Design：從適用度前置判讀到 access pattern 反推 PK/SK" data-link-desc="DynamoDB single-table 設計不是「資料表越少越好」，而是 access pattern 反推 PK/SK 跟 GSI；本文先做 DynamoDB 適用度 4 軸前置判讀（PK 天然均勻 / control plane vs data plane / consistency / access pattern 穩定），再展開設計流程、failure modes 與 durable queue 正向用例">DynamoDB single-table design</a></li>
<li>想評估遊戲流量的 on-demand vs provisioned → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/capcom/">CAPCOM Case Study</a></li>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
<li><a href="https://aws.amazon.com/blogs/big-data/powering-gaming-applications-with-amazon-dynamodb/">Powering Gaming Applications with Amazon DynamoDB</a></li>
</ul>
]]></content:encoded></item><item><title>Akamas</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/akamas/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/akamas/</guid><description>&lt;p>Akamas 的核心責任是把 workload、SLO constraint、runtime configuration 與雲端成本放進同一個最佳化迴圈。它適合 Kubernetes、VM、database、runtime 與雲端資源調校，重點在用實驗與約束條件產生 rightsizing、configuration tuning 與 capacity efficiency 建議。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>Akamas 適合已經有可量測 workload 與成本壓力的服務。當團隊能說清楚 request rate、latency SLO、error budget、CPU / memory headroom、replica policy 與雲端費用目標，Akamas 可以把這些條件轉成 optimization objective，找出更好的配置組合。&lt;/p>
&lt;p>這個定位讓 Akamas 接到三個主章。它從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型&lt;/a> 接收 headroom 與 growth curve，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 接收 cost per request 與 cost curve，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop&lt;/a> 接收 test、profile、fix、re-test 的閉環。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Akamas 的核心定位是 &lt;em>AI-driven autonomous optimization&lt;/em>、不是 monitoring、不是 cost reporting、也不是手動 rightsizing 工具。它用 ML 在 &lt;em>parameter space&lt;/em> 中找出可同時降 cost 並達到 SLO 的配置組合、目標是把 &lt;em>效能調校&lt;/em> 從 expert-driven 手工活、轉成可重跑的工程實驗。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth&lt;/a> 這類 FinOps cost tool 的差異是 &lt;em>動作面&lt;/em>。FinOps tool 看到 &lt;em>cost 已經發生&lt;/em>、把帳單拆 tag、推薦保留方案；Akamas 看 workload 在 SLO 邊界下能不能跑得更便宜、輸出的是 &lt;em>configuration change&lt;/em>、不是 invoice 切片。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Datadog APM&lt;/a> / Prometheus 這類 observability stack 的差異是 &lt;em>決策面&lt;/em>。APM 告訴你 &lt;em>哪裡慢、哪個 endpoint p99 飆&lt;/em>；Akamas 接 APM / metrics 訊號當輸入、輸出 &lt;em>該怎麼改 JVM heap、HPA target、connection pool&lt;/em> 的 recommendation。Observability 是 &lt;em>看&lt;/em>、Akamas 是 &lt;em>動&lt;/em>。&lt;/p>
&lt;p>跟手動 tuning（SRE 拍腦袋、grid search、A/B configuration test）的差異是 &lt;em>參數空間規模&lt;/em>。Manual tuning 在 3-5 個參數還可控；JVM + container limit + HPA + DB pool + node packing 同時轉動時、組合爆炸、ML-driven search 才能在合理 budget 內收斂。&lt;/p></description><content:encoded><![CDATA[<p>Akamas 的核心責任是把 workload、SLO constraint、runtime configuration 與雲端成本放進同一個最佳化迴圈。它適合 Kubernetes、VM、database、runtime 與雲端資源調校，重點在用實驗與約束條件產生 rightsizing、configuration tuning 與 capacity efficiency 建議。</p>
<h2 id="定位">定位</h2>
<p>Akamas 適合已經有可量測 workload 與成本壓力的服務。當團隊能說清楚 request rate、latency SLO、error budget、CPU / memory headroom、replica policy 與雲端費用目標，Akamas 可以把這些條件轉成 optimization objective，找出更好的配置組合。</p>
<p>這個定位讓 Akamas 接到三個主章。它從 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 接收 headroom 與 growth curve，從 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 接收 cost per request 與 cost curve，從 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 接收 test、profile、fix、re-test 的閉環。</p>
<h2 id="服務定位">服務定位</h2>
<p>Akamas 的核心定位是 <em>AI-driven autonomous optimization</em>、不是 monitoring、不是 cost reporting、也不是手動 rightsizing 工具。它用 ML 在 <em>parameter space</em> 中找出可同時降 cost 並達到 SLO 的配置組合、目標是把 <em>效能調校</em> 從 expert-driven 手工活、轉成可重跑的工程實驗。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a> / <a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a> 這類 FinOps cost tool 的差異是 <em>動作面</em>。FinOps tool 看到 <em>cost 已經發生</em>、把帳單拆 tag、推薦保留方案；Akamas 看 workload 在 SLO 邊界下能不能跑得更便宜、輸出的是 <em>configuration change</em>、不是 invoice 切片。</p>
<p>跟 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">Datadog APM</a> / Prometheus 這類 observability stack 的差異是 <em>決策面</em>。APM 告訴你 <em>哪裡慢、哪個 endpoint p99 飆</em>；Akamas 接 APM / metrics 訊號當輸入、輸出 <em>該怎麼改 JVM heap、HPA target、connection pool</em> 的 recommendation。Observability 是 <em>看</em>、Akamas 是 <em>動</em>。</p>
<p>跟手動 tuning（SRE 拍腦袋、grid search、A/B configuration test）的差異是 <em>參數空間規模</em>。Manual tuning 在 3-5 個參數還可控；JVM + container limit + HPA + DB pool + node packing 同時轉動時、組合爆炸、ML-driven search 才能在合理 budget 內收斂。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Akamas optimization study 是否健康、最少看四件事：</p>
<ul>
<li><strong>Agent / collector 部署完整度</strong>：哪些 target（JVM / container / K8s / DB）裝了 Akamas agent 或接到 metrics source、metrics window 是否涵蓋 representative peak、是否漏 tail latency 與 GC pause</li>
<li><strong>Target system 邊界定義</strong>：optimization 是針對單一 service / 一組 microservice / 整個 K8s cluster、tunable parameter list 是否經 service owner 審核、不在 list 內的參數是否會被間接影響</li>
<li><strong>Optimization goal 對得上 business outcome</strong>：goal 是「降 cost 30%」還是「同 SLO 下 cost minimize」、是否同時聲明 latency / error budget / throughput 的下界、避免 ML 為達 cost target 把 latency 推到邊緣</li>
<li><strong>Safety bound 緊 / 鬆的取捨</strong>：bound 太緊收斂不到方案、bound 太鬆 production validation 會出事、是否有 staging tenant 跑完再 promote、autopilot 範圍是否限定 non-critical workload</li>
</ul>
<p>四項任一缺、就是 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 邊界的待補項目、不是 Akamas 設定問題。</p>
<h2 id="適用場景">適用場景</h2>
<p>Kubernetes rightsizing 是 Akamas 的主要入口。多服務平台常見問題是 requests / limits、HPA target、replica floor、node pool 與 runtime 參數互相牽動；Akamas 的價值是把這些參數放進同一個優化空間，而非逐項手動調整。</p>
<p>Runtime 與 database tuning 適合需要穩定 SLO 的服務。JVM heap、Go runtime、PostgreSQL、MongoDB、Elasticsearch 或 Spark workload 會同時受配置、資料形狀與流量尖峰影響；optimization tool 可以用可重跑實驗保留調校證據。</p>
<p>FinOps 與 SRE 協作適合用 Akamas 建立共同語言。FinOps 關心浪費與預算，SRE 關心 latency、error rate 與可靠性；Akamas 類工具把節省幅度、性能風險與回退條件放在同一份 recommendation 裡，降低跨團隊溝通成本。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Akamas 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>優化目標</td>
          <td>把 cost、latency、throughput 與 SLO 一起建模</td>
          <td>明確 business objective 與風險上限</td>
      </tr>
      <tr>
          <td>參數空間</td>
          <td>支援 runtime、container、database 與雲端配置</td>
          <td>服務 owner 對參數語意的審核</td>
      </tr>
      <tr>
          <td>執行模式</td>
          <td>支援 human approval、pipeline 與自動化調校</td>
          <td>rollout guardrail、變更紀錄與回退</td>
      </tr>
      <tr>
          <td>證據保存</td>
          <td>recommendation 可以回寫實驗、約束與預期效益</td>
          <td>production validation 與長期 drift 追蹤</td>
      </tr>
  </tbody>
</table>
<p>優化目標價值來自約束透明。成本降低只有在 latency、availability 與 error budget 邊界內才成立，因此 Akamas 頁面要先問目標函數與 guardrail，再談節省幅度。</p>
<p>參數空間價值來自跨層調校。單看 CPU request 可能會誤判，因為 GC、DB connection、thread pool、replica policy 與 node packing 會一起改變 cost per request。</p>
<p>執行模式價值來自可控自動化。Human-in-the-loop 適合早期導入，pipeline mode 適合 release gate，autopilot 適合 guardrail、rollback 與 owner model 已成熟的環境。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Akamas 和 Vantage 的主要差異是控制面。Vantage 偏 cost visibility、allocation、forecast 與報表；Akamas 偏把效能約束放進 configuration optimization，適合需要直接調整 capacity 與 runtime 參數的場景。</p>
<p>Akamas 和 CloudHealth 的主要差異是操作層級。CloudHealth 偏 enterprise FinOps governance、policy、showback / chargeback 與多雲管理；Akamas 偏 service-level optimization 與工程調校閉環。</p>
<p>Akamas 和 AWS Cost Explorer 的主要差異是範圍與自動化。Cost Explorer 是 AWS-native 成本分析入口；Akamas 可以把成本訊號跟 workload、SLO 與配置實驗接起來，適合需要跨層優化的服務。</p>
<h2 id="操作成本">操作成本</h2>
<p>Akamas 的主要成本是 optimization model 建立。團隊要定義目標、約束、可調參數、測試窗口、流量代表性與成功門檻，並讓 service owner 審核每個 recommendation 的業務風險。</p>
<p>導入成本會隨自動化程度上升。早期可以用 approval workflow 接 recommendation；進入 pipeline 或 autopilot 後，要補 change window、deploy marker、rollback、SLO guardrail、audit log 與 incident handoff。</p>
<p>資料品質會直接影響結果可信度。Metric 延遲、缺少 tail latency、成本 tag 錯誤、workload window 偏差或測試環境差異，都會讓 recommendation 的 confidence 下降。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Akamas 結果應回寫到 optimization evidence package。最小欄位包括 optimization goal、constraint、tunable parameters、workload window、baseline cost、baseline performance、recommended configuration、expected saving、risk note、validation result 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Akamas 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>optimization report、experiment result、recommendation</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>workload sample、test window、production validation</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / cost dashboard / Akamas report</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>workload representativeness、metric freshness、tag coverage</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>SLO guardrail、repeatability、rollback readiness</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 cohort、未納入下游 quota、測試環境差異</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓成本調校可以被審查。Akamas recommendation 要能回答「節省來自哪個配置變更、哪個 SLO 保護這次變更、哪個訊號觸發回退」。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Akamas（AI optimization）</th>
          <th>FinOps tool（Vantage / CloudHealth）</th>
          <th>APM（Datadog / Prometheus）</th>
          <th>Manual tuning（SRE / 性能工程師）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主要動作</td>
          <td>產出 configuration change recommend</td>
          <td>拆帳單、報表、保留方案推薦</td>
          <td>顯示瓶頸位置與 metric</td>
          <td>拍腦袋 / grid search / A/B test</td>
      </tr>
      <tr>
          <td>決策訊號</td>
          <td>workload + SLO + cost 同模型</td>
          <td>帳單 + tag</td>
          <td>latency / saturation / error metric</td>
          <td>經驗 + ad-hoc benchmark</td>
      </tr>
      <tr>
          <td>適用參數空間</td>
          <td>多參數（JVM + container + HPA + DB）</td>
          <td>N/A（不動參數）</td>
          <td>N/A（不動參數）</td>
          <td>3-5 個參數還可控</td>
      </tr>
      <tr>
          <td>自動化程度</td>
          <td>human approval / pipeline / autopilot</td>
          <td>recommendation + dashboard、不自動執行</td>
          <td>alert + dashboard</td>
          <td>全人工</td>
      </tr>
      <tr>
          <td>風險邊界</td>
          <td>靠 safety bound + staging validation</td>
          <td>低（只動 commitment、不動 runtime）</td>
          <td>低（觀察、不動）</td>
          <td>靠人盯、容易遺漏 cross-parameter</td>
      </tr>
      <tr>
          <td>何時不適用</td>
          <td>參數空間小 / SLO 未明確 / metric 不全</td>
          <td>需要動 runtime 才能省的場景</td>
          <td>不解決「改什麼」、只解決「在哪裡」</td>
          <td>參數爆炸時 ROI 太差</td>
      </tr>
  </tbody>
</table>
<p>選 Akamas 的核心訴求是 <em>參數空間大 + workload 可重跑 + cost 壓力夠高、值得投入 optimization study setup 成本</em>。小規模 / 參數少 / SLO 不明、直接走 manual tuning 更快；只想看帳單拆解、走 FinOps tool；只想知道哪裡慢、走 APM。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Optimization study 的三要素</strong>：goal（目標函數、常見 <code>minimize cost subject to p99 latency &lt; X, error rate &lt; Y</code>）、parameter list（哪些 knob 可動、各自合法區間）、safety bound（哪些 metric 不能越界、越界即 reject candidate）。study setup 是 Akamas 最重的人力投入、value 來自 <em>把隱性調校 know-how 寫成可重跑配置</em>、不是 ML 本身。</p>
<p><strong>Live experiment vs offline study</strong>：offline study 用 staging 環境跑代表性 workload、安全但與 production 流量結構有偏差；live experiment 在 production 上小範圍試 candidate（例如 single canary pod）、訊號真實但需要嚴格 safety bound 與 rollback。多數團隊先 offline 找候選 region、再 live 收斂 — 不要一開始就 production autopilot。</p>
<p><strong>跟 K8s VPA / HPA 互補不互斥</strong>：HPA 處理 <em>replica 數量</em>、VPA 處理 <em>單 pod request / limit</em>、Akamas 處理 <em>參數組合 + 跨層協同</em>（含 JVM heap、HPA target、replica floor、node pool selection）。三者並用時要明確分工 — Akamas 不該跟 VPA 同時調 request，否則彼此推翻；常見作法是 Akamas 設 <em>baseline configuration</em>、VPA / HPA 在 baseline 上做即時微調。</p>
<p><strong>跟 observability stack integration</strong>：Akamas 接 Datadog / Prometheus / New Relic / Dynatrace 取 metrics、接 Kubernetes API 取 workload state、接 cloud billing API 取 cost。integration 品質直接決定 recommendation 信度 — metric 缺 tail latency 或 cost tag 不準、ML 會找到 <em>看起來省、實際出事</em> 的配置。對應 <a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.4 Performance Observability</a> 的訊號治理。</p>
<p><strong>安全邊界 — 不該全 autopilot production</strong>：critical workload（payment / auth / DB primary）即使 SLO bound 寫清楚也不該 autopilot、recommendation 要走 human approval + change window；non-critical workload（batch job / dev cluster / internal tool）autopilot 可接受。ML black-box 是 production safety 的本質風險、不是設定問題。</p>
<p><strong>ML 黑箱可解釋性</strong>：Akamas recommendation 給出 <em>why this configuration</em> 的 sensitivity analysis（哪個參數影響最大、哪個參數對 cost / latency 是 trade-off curve），但根因解釋仍弱於人類性能工程師的 mental model。Production 採用前、service owner 要能用自己的 domain knowledge 對 recommendation 做 sanity check、不是純靠 ML score 拍板。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Optimization goal 對不上 business outcome</strong>：goal 寫「降 cost 30%」但沒寫 latency / error budget 下界 — ML 把 cost 壓到 SLO 邊緣、production 上線就 incident、回頭補 safety bound + business KPI alignment</li>
<li><strong>Safety bound 太鬆 / 太緊</strong>：太鬆 candidate 過 staging 但 production validation 出事、太緊 study 跑不出有意義方案 — bound 應綁 production-observed p99 / error rate baseline + 20% 緩衝、不是拍數字</li>
<li><strong>ML black-box 沒辦法解釋</strong>：service owner 看不懂為何 recommendation 改某個 obscure JVM flag — 跑 sensitivity analysis、不接受 <em>無 domain rationale</em> 的 recommendation、視為 candidate 而非 final</li>
<li><strong>參數空間 leak 到 list 外</strong>：Akamas 改 JVM heap 但間接讓 GC 行為變、撞到沒納入的 thread pool — 補 cross-parameter dependency 到 list、或縮小 study scope</li>
<li><strong>Workload window 不代表 production</strong>：staging 跑 50% 流量、ML 找到的方案在 100% peak hour 出事 — workload sample 必須涵蓋 representative peak、不是平均值</li>
<li><strong>Autopilot 推到 critical service</strong>：non-critical workload 試出甜頭、團隊把 autopilot 推到 payment service、incident 後 rollback 困難 — autopilot 範圍要寫進政策、critical service 永遠 human approval</li>
<li><strong>Recommendation 跟 VPA 互推</strong>：Akamas 設 request = X、VPA 立刻調回 Y、循環 — Akamas baseline 跟 VPA scope 要分層、不要在同一個 dimension 兩個 controller 同時動</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Akamas 目前在 09 案例庫中適合作為 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 的工具承接點。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato TiDB → DynamoDB 遷移</a> 的成本下降 50% 取捨、<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 EKS cluster</a> 的年省 1000 萬美金的 Kubernetes capacity 調校、<a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom 遊戲後端</a> 的營運成本下降 30%、以及 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech 體育博彩</a> 的需求降低時成本下降 25% 彈性曲線。</p>
<p>這些案例的重點是優化條件。Akamas 頁引用案例時，應把「某公司節省成本」轉成 workload window、SLO constraint、調整參數、驗證方式與回退條件 — 例如 Zomato 的 4x throughput / 90% latency 改善是同時優化目標、不是只看成本欄位。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a></li>
<li>官方：<a href="https://docs.akamas.io/akamas-docs/getting-started/introduction-to-akamas">Akamas documentation</a></li>
</ul>
]]></content:encoded></item><item><title>GoReplay</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/goreplay/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/goreplay/</guid><description>&lt;p>GoReplay 的核心責任是捕捉 production HTTP traffic，並把真實請求形狀重播到 staging、shadow environment 或新版本。它適合驗證 synthetic load 難以建模的 endpoint mix、header、payload size、burst pattern 與 long-tail 行為，重點在把 production reality 轉成可控 replay artifact。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>GoReplay 適合在 synthetic workload 可信度偏低時使用。當 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 很難準確描述使用者路徑、payload 分布或 endpoint mix，GoReplay 可以從 production traffic 擷取真實樣本，再用 rate limit、filter、rewrite 與 output target 控制重播範圍。&lt;/p>
&lt;p>這個定位讓 GoReplay 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> 的 shadow traffic。它的價值在於保留 production 請求形狀；它的風險在於 PII、credential、side effect、下游容量與 capture host overhead 都要被治理。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a> 的 synthetic load 設計 mindset 完全不同。Scripted load 假設 &lt;em>測試者能描述使用者行為&lt;/em> — 寫 script、設 rate、跑 scenario；GoReplay 假設 &lt;em>production 才是 source of truth&lt;/em> — endpoint mix、header 分布、payload size、burst pattern 都從真實 traffic 抽樣、不靠人為建模。對 long-tail 行為（少見 endpoint、巨大 payload、特殊 header 組合）這個差異決定了 capacity 規劃的真實度。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 GoReplay deployment 是否健康、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Capture mode&lt;/strong>：用 &lt;code>raw&lt;/code> (libpcap-based)、&lt;code>pcap-file&lt;/code>（離線 replay 已存檔的 pcap）、&lt;code>file&lt;/code>（GoReplay 原生 gor format）哪一種？raw 對 production host 有 CPU / network overhead、pcap-file 適合事後 replay、file 適合 long-running capture buffer&lt;/li>
&lt;li>&lt;strong>Replay target&lt;/strong>：打到 staging full-stack、shadow service、還是 isolated sandbox？POST / PUT / DELETE 是否導到 dry-run path 或 idempotent mock？webhook / payment / notification 是否被攔截？&lt;/li>
&lt;li>&lt;strong>Rate adjustment&lt;/strong>：用原始 production rate replay，還是 2x / 10x / 0.1x？capacity 規劃通常需要 &lt;em>speed up&lt;/em> 來測未來流量、debug 通常需要 &lt;em>slow down&lt;/em> 跟單一請求追查&lt;/li>
&lt;li>&lt;strong>Middleware filter&lt;/strong>：PII / token / cookie / credential redaction 在哪一段做（capture 前、capture 後、replay 前）？是否走 GoReplay middleware binary（stdin / stdout pipeline）統一處理&lt;/li>
&lt;/ul>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>架構遷移驗證適合 GoReplay。DB、cache、search、API gateway 或 framework 重寫時，可以把真實 HTTP traffic replay 到新路徑，觀察 latency、error、resource saturation 與 response diff。&lt;/p></description><content:encoded><![CDATA[<p>GoReplay 的核心責任是捕捉 production HTTP traffic，並把真實請求形狀重播到 staging、shadow environment 或新版本。它適合驗證 synthetic load 難以建模的 endpoint mix、header、payload size、burst pattern 與 long-tail 行為，重點在把 production reality 轉成可控 replay artifact。</p>
<h2 id="定位">定位</h2>
<p>GoReplay 適合在 synthetic workload 可信度偏低時使用。當 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 很難準確描述使用者路徑、payload 分布或 endpoint mix，GoReplay 可以從 production traffic 擷取真實樣本，再用 rate limit、filter、rewrite 與 output target 控制重播範圍。</p>
<p>這個定位讓 GoReplay 接到 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 的 shadow traffic。它的價值在於保留 production 請求形狀；它的風險在於 PII、credential、side effect、下游容量與 capture host overhead 都要被治理。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> / <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a> 的 synthetic load 設計 mindset 完全不同。Scripted load 假設 <em>測試者能描述使用者行為</em> — 寫 script、設 rate、跑 scenario；GoReplay 假設 <em>production 才是 source of truth</em> — endpoint mix、header 分布、payload size、burst pattern 都從真實 traffic 抽樣、不靠人為建模。對 long-tail 行為（少見 endpoint、巨大 payload、特殊 header 組合）這個差異決定了 capacity 規劃的真實度。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 GoReplay deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Capture mode</strong>：用 <code>raw</code> (libpcap-based)、<code>pcap-file</code>（離線 replay 已存檔的 pcap）、<code>file</code>（GoReplay 原生 gor format）哪一種？raw 對 production host 有 CPU / network overhead、pcap-file 適合事後 replay、file 適合 long-running capture buffer</li>
<li><strong>Replay target</strong>：打到 staging full-stack、shadow service、還是 isolated sandbox？POST / PUT / DELETE 是否導到 dry-run path 或 idempotent mock？webhook / payment / notification 是否被攔截？</li>
<li><strong>Rate adjustment</strong>：用原始 production rate replay，還是 2x / 10x / 0.1x？capacity 規劃通常需要 <em>speed up</em> 來測未來流量、debug 通常需要 <em>slow down</em> 跟單一請求追查</li>
<li><strong>Middleware filter</strong>：PII / token / cookie / credential redaction 在哪一段做（capture 前、capture 後、replay 前）？是否走 GoReplay middleware binary（stdin / stdout pipeline）統一處理</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p>架構遷移驗證適合 GoReplay。DB、cache、search、API gateway 或 framework 重寫時，可以把真實 HTTP traffic replay 到新路徑，觀察 latency、error、resource saturation 與 response diff。</p>
<p>Long-tail workload 校正適合 GoReplay。Synthetic scenario 通常覆蓋主路徑，GoReplay 可以揭露少見 endpoint、特殊 header、巨大 payload、冷門 tenant 與尖峰 cohort。</p>
<p>事故後修補驗證適合 GoReplay。若事故由特定請求形狀觸發，capture sample 可以在修補環境重播，確認 latency、error 或 resource usage 是否回到可接受範圍。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>GoReplay 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>真實 traffic</td>
          <td>endpoint mix、payload、header 分布接近 production</td>
          <td>PII / credential 遮罩與權限治理</td>
      </tr>
      <tr>
          <td>HTTP replay</td>
          <td>對 HTTP API 路徑直接有效</td>
          <td>非 HTTP protocol 與加密流量處理</td>
      </tr>
      <tr>
          <td>Filter / rewrite</td>
          <td>可控制 host、path、header、rate</td>
          <td>side effect 隔離與 sandbox target</td>
      </tr>
      <tr>
          <td>Capture artifact</td>
          <td>可保存樣本做回歸驗證</td>
          <td>retention、存取控制與樣本代表性</td>
      </tr>
  </tbody>
</table>
<p>真實 traffic 價值來自分布保真。它能捕捉 synthetic script 容易漏掉的 query parameter、header、payload size 與 endpoint mix，但 capture sample 也會帶入 production 資料治理責任。</p>
<p>Filter / rewrite 價值來自安全邊界。Replay 前要改寫 target、移除 credential、遮罩 PII、限制 rate，並把寫入類請求導到 sandbox 或 dry-run path。</p>
<h2 id="跟其他方式的取捨">跟其他方式的取捨</h2>
<p>GoReplay 和 k6 / Gatling / Locust 的主要差異是流量來源。GoReplay 取 production sample，保真度高；scripted load test 取人工模型，可控性高。</p>
<p>GoReplay 和 service mesh mirroring 的主要差異是部署位置。GoReplay 在 host / network capture 層工作，適合沒有 mesh 的服務；service mesh mirroring 在 sidecar / proxy 層工作，適合已經落地 mesh 的平台。</p>
<p>GoReplay 和 AWS VPC Traffic Mirroring 的主要差異是應用語意。GoReplay 對 HTTP replay 更直接；VPC Traffic Mirroring 在網路層複製封包，侵入性低但應用層 rewrite、遮罩與 replay 控制需要額外處理。</p>
<h3 id="核心取捨表">核心取捨表</h3>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>GoReplay</th>
          <th>k6 / JMeter (synthetic)</th>
          <th>AWS VPC Traffic Mirroring</th>
          <th>Service Mesh Mirroring</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>流量來源</td>
          <td>Production sniff（real shape）</td>
          <td>Scripted scenario（builder&rsquo;s model）</td>
          <td>VPC 網路層封包複製</td>
          <td>Sidecar / proxy 層複製</td>
      </tr>
      <tr>
          <td>工作層級</td>
          <td>HTTP / L7（capture host）</td>
          <td>HTTP / L7（client-side script）</td>
          <td>L3-L4（packet level）</td>
          <td>L7（sidecar in-mesh）</td>
      </tr>
      <tr>
          <td>Rate adjust</td>
          <td>原生支援（0.1x - 10x）</td>
          <td>scenario 內 ramp / arrival rate</td>
          <td>全量、無 rate control</td>
          <td>mesh policy 控制</td>
      </tr>
      <tr>
          <td>Replay 控制</td>
          <td>filter / rewrite / middleware binary</td>
          <td>程式內 logic 完整可控</td>
          <td>需自寫 application-level rewriter</td>
          <td>mesh-level routing rule</td>
      </tr>
      <tr>
          <td>Long-tail 覆蓋</td>
          <td>強（real distribution）</td>
          <td>弱（取決於 scenario design）</td>
          <td>強（real distribution）但需後處理</td>
          <td>強（in-mesh real traffic）</td>
      </tr>
      <tr>
          <td>PII / 安全成本</td>
          <td>高（middleware 自己寫 redaction）</td>
          <td>低（fixture 由人控制）</td>
          <td>高（packet-level 難語意化遮罩）</td>
          <td>中（mesh policy 可協助）</td>
      </tr>
      <tr>
          <td>部署條件</td>
          <td>host agent + libpcap，需有權限 sniff interface</td>
          <td>無（client / load generator 機台即可）</td>
          <td>AWS-only、ENI mirroring 配額</td>
          <td>已落地 mesh（Istio / Linkerd）</td>
      </tr>
  </tbody>
</table>
<p>選 GoReplay 的核心訴求：<em>HTTP 應用層 replay + production shape 保真 + 沒落地 mesh</em>；若已用 mesh、優先看 mesh 內建 mirroring；若要跨 protocol（gRPC / 自家 binary）GoReplay 開源版受限、需考慮 Pro 版或 mesh 方案。</p>
<h2 id="操作成本">操作成本</h2>
<p>GoReplay 的主要成本是資料安全。Production request 可能包含 token、cookie、PII、payment payload、internal IDs 與 tenant 資料，capture、保存、重播與刪除都要有明確 owner。</p>
<p>Replay 成本來自下游副作用。POST、PUT、DELETE、webhook、email、payment、notification 與 queue publish 都要導到 sandbox、mock 或 idempotent dry-run，避免 replay 造成重複交易或通知。</p>
<p>Capture 成本來自主機資源。高流量服務上的 capture agent 會消耗 CPU、network 與 disk，正式啟用前要先量測 overhead，並設定 sampling、rate limit 與 stop condition。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>GoReplay 結果應回寫到 evidence package。最小欄位包括 capture source、capture time range、filter / rewrite rule、sample size、replay rate、target environment、data masking status、p95 / p99、error rate、resource saturation、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>GoReplay 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>capture command、sample hash、replay command</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>capture start / end、replay start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>APM / metrics / logs / diff 查詢連結</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>sample representativeness、masking status</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>replay rate、target parity、capture coverage</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未捕捉 protocol、資料遮罩限制、sandbox 差異</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 replay 結論可審查。Reviewer 要能知道樣本來自哪段 production、經過哪些 filter、打到哪個 target，以及哪些 side effect 被 mock 或隔離。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Capture to file（pcap-like artifact）</strong>：用 <code>--output-file</code> 把 capture 寫成 GoReplay 原生 gor file（或讀 pcap）、之後用 <code>--input-file</code> 重複 replay。這個模式讓 <em>capture window</em> 跟 <em>replay run</em> 解耦 — capture 一次，可在不同 staging branch / 不同 rate / 不同 target 重播多次。對 regression 驗證跟「事故當時的 traffic shape」回放特別關鍵、但 file artifact 也成為 PII 儲存物、retention 跟存取控制要跟 production log 同級。</p>
<p><strong>Replay with rate adjustment（10x speed）</strong>：<code>--input-file-replay-speed 10</code>（gor format）或加 <code>--input-file-loop</code> 反覆播放。10x speed 對 capacity headroom 驗證直接有用 — 用真實 traffic shape 模擬「未來流量翻 10 倍」、避開 scripted scenario 自帶的人為偏差。反向用法 0.1x 跟 isolated request replay 適合排錯特定 endpoint 的 long-tail latency。注意 10x 會把下游 DB / cache / external API 同樣放大，sandbox target 容量要先評估。</p>
<p><strong>Middleware filter（PII redaction）</strong>：GoReplay middleware 是獨立 binary、用 stdin / stdout 跟 GoReplay process 串接、可寫任何語言。典型責任：JSON body 解析、Authorization / Cookie / Set-Cookie header strip、Email / phone / card number regex 遮罩、cross-request session ID rewriting（讓 staging 不撞 production session）。middleware 邏輯本身需要 code review、寫進版控、staging 測過再放到 production capture host。</p>
<p><strong>Pro version（GoReplay Pro - binary protocols）</strong>：開源版聚焦 HTTP/1.x；GoReplay Pro 支援 binary protocol（自家 protocol、protobuf-over-TCP、部分 gRPC pattern）跟 enterprise 維護 SLA。判斷點：若服務是純 HTTP REST 開源版夠用、若有 gRPC 或自家 binary 且不在 mesh 內、要評估 Pro 或改走 service mesh mirroring。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Capture loss / sample 不完整</strong>：libpcap 在高流量下會 drop packet、<code>gor stat</code> 的 capture stats 顯示 drop &gt; 1% 就不可信 — 加 capture host CPU、改用 PF_RING / AF_PACKET、或縮 capture filter 範圍（只 capture target port + sampling）</li>
<li><strong>TCP reassembly 失敗 / replay 結果亂碼</strong>：跨 packet 的 HTTP body 沒被正確組裝、常見於 MTU / TCP segment offload 設定異常 — 確認 capture interface 沒開 TSO / GRO、或用 application-level capture（HEC-style sidecar）取代 packet capture</li>
<li><strong>PII / secret 漏 redact 進 staging</strong>：middleware 規則沒覆蓋新加的 header / 新的 body schema — 建立 redaction allowlist（只放行已知 schema）而非 denylist、每次 schema 變更同步更新 middleware、staging 入口加 secret scanner 做 last-mile 攔截</li>
<li><strong>Replay 觸發下游真實副作用</strong>：POST / PUT 沒導 sandbox、webhook 真的打出去、payment 真的扣款 — replay target 預設 <em>deny all write</em>、白名單放行特定 idempotent endpoint、其餘走 mock 或 dry-run flag</li>
<li><strong>Replay rate 拖垮 capture host</strong>：同機 capture + replay、CPU / NIC 互相搶 — capture host 只負責 sniff + write to file、replay 機器獨立、用 gor file 解耦</li>
<li><strong>長時間 capture 寫爆 disk</strong>：未設 rotation 或 size limit — <code>--output-file</code> 加 size / time rotation、定期 archive 到 S3 + 過期刪除</li>
<li><strong>Staging 容量比 production 小、放大流量打爆</strong>：10x replay 沒先估下游 — capacity 規劃前先用 1x 暖機、觀察下游 saturation、再 ramp 到目標倍率</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>GoReplay 適合回寫 migration 與 production validation 案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft 售票壓測</a> 的 production-shaped load、<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek waiting room</a> 的 cutover 前 replay、<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 這類資料庫整併前的 query pattern 驗證、<a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato TiDB → DynamoDB</a> 跨 DB 遷移的請求 pattern 重播，以及 <a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365 MongoDB → Cosmos DB</a> 的全球分析平台遷移 query 驗證。</p>
<p>這些案例的重點是 production request shape。GoReplay 頁引用案例時，要把 case 轉成 capture window、filter、rewrite、target isolation、rate limit 與 diff / saturation metric — 例如 Zomato 遷 DB 時、replay 必須先 mask PII + 改寫 SQL 方言、不能直接把 TiDB query 打進 DynamoDB SDK。</p>
<p>Capacity 規劃用 real workload model 是這些案例的共通對照啟示。Tixcraft 的售票 spike、SeatGeek 的 waiting room cutover、Netflix 的 Aurora 整併、Microsoft 365 的全球 query 分布 — 共通點是 <em>scripted scenario 無法事先列舉所有 endpoint 跟 payload 組合</em>。GoReplay 的回應是把「使用者行為建模」這個工作丟回給 production traffic 本身、規劃者只負責決定 capture window、replay rate 跟 target boundary，不再試圖窮舉 scenario。這個 mindset 才是 GoReplay 跟 <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> / <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a> 在 capacity 規劃流程中的真正分工點。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring</a></li>
<li>知識卡：<a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
<li>官方：<a href="https://docs.goreplay.org/">GoReplay documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/</guid><description>&lt;p>這個案例的核心責任是提供「同樣業務需求、不同 DB 技術」的具體對照數字。Zomato 帳單系統從 TiDB 遷移到 DynamoDB、留下三個關鍵改善百分比、是 DB 選型決策的少見 &lt;em>可量化&lt;/em> 對照樣本。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Zomato 帳單系統遷移的關鍵數字（引自 &lt;a href="https://aws.amazon.com/blogs/database/unlocking-performance-scalability-and-cost-efficiency-of-zomatos-billing-platform-by-switching-from-tidb-to-dynamodb/">AWS Database Blog&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>TiDB（遷移前）&lt;/th>
 &lt;th>DynamoDB（遷移後）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>微服務吞吐&lt;/td>
 &lt;td>2,000 RPM&lt;/td>
 &lt;td>8,000 RPM（4x）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>延遲降幅&lt;/td>
 &lt;td>baseline&lt;/td>
 &lt;td>-90%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本降幅&lt;/td>
 &lt;td>baseline&lt;/td>
 &lt;td>-50%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>每日事件量&lt;/td>
 &lt;td>10M（共用）&lt;/td>
 &lt;td>10M&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>餐廳合作夥伴&lt;/td>
 &lt;td>350,000+&lt;/td>
 &lt;td>350,000+&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵動機：TiDB 必須為「突發流量峰值」提前 over-provision、付出常態成本；DynamoDB on-demand 模式「pay only for what we use」、避免 over-provisioning。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Zomato 遷移揭露三個 DB 選型決策的判讀重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>NewSQL vs NoSQL 的取捨不只是 schema&lt;/strong>：TiDB 提供 SQL 介面跟 ACID、DynamoDB 提供 KV 介面跟最終一致性。Zomato 選 DynamoDB 是判斷「帳單事件本身可以接受 eventually consistent」、用一致性換性能跟成本。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a> 的一致性取捨。&lt;/li>
&lt;li>&lt;strong>TiDB 必須 over-provision 是分散式 SQL 的常態&lt;/strong>：分散式 SQL 為了支援跨節點交易、必須有預留容量、否則峰值會出現 leader election storm 或 follower lag。這跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner&lt;/a> 的「節點數即容量」是同類取捨、Spanner 也必須預先 scale 節點。&lt;/li>
&lt;li>&lt;strong>2K → 8K RPM 是 4 倍、但延遲降 90% 才是真關鍵&lt;/strong>：吞吐改善可能來自架構優化、延遲改善才是 DB 本質差。從 baseline → 10% 通常代表少了 1-2 個 hop（例如 cross-region replication、coordinator round-trip）。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為&lt;/a> 的 Little&amp;rsquo;s Law。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p>
&lt;ul>
&lt;li>「成本降 50%」是 &lt;em>當下流量下的對照&lt;/em>。如果未來流量繼續成長、DynamoDB 的 cost-per-request 成長率比 TiDB 自管 cluster 高 — 達到某規模後 TiDB 反而更便宜。讀遷移案例要看「在當下流量下划算」、不等於「永遠划算」。&lt;/li>
&lt;li>「90% 延遲降」可能只是 p50、p99 / p999 改善幅度通常較小。&lt;/li>
&lt;/ul>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>DB 遷移前先確認業務一致性需求&lt;/strong>：能接受 eventually consistent 的工作負載適合 KV / NoSQL；必須 strong consistency 的工作負載必須 SQL / NewSQL。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a>。&lt;/li>
&lt;li>&lt;strong>遷移評估要看「總成本曲線」、不是「當下 snapshot」&lt;/strong>：算未來 12-24 個月在預期流量下的成本對照、不是只算現在。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a>。&lt;/li>
&lt;li>&lt;strong>遷移過程要 dual-write + shadow read 驗證&lt;/strong>：避免新舊系統行為不一致導致業務問題。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence&lt;/a>。&lt;/li>
&lt;li>&lt;strong>on-demand vs provisioned 的選擇與業務流量形狀對應&lt;/strong>：突發流量適合 on-demand、可預測流量適合 provisioned。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft&lt;/a> 的 on-demand 應用。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：MongoDB Atlas → DynamoDB、Cassandra → DynamoDB、PostgreSQL → Aurora、CockroachDB → Spanner 都是常見遷移路徑。每條路徑的取捨類似。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是提供「同樣業務需求、不同 DB 技術」的具體對照數字。Zomato 帳單系統從 TiDB 遷移到 DynamoDB、留下三個關鍵改善百分比、是 DB 選型決策的少見 <em>可量化</em> 對照樣本。</p>
<h2 id="觀察">觀察</h2>
<p>Zomato 帳單系統遷移的關鍵數字（引自 <a href="https://aws.amazon.com/blogs/database/unlocking-performance-scalability-and-cost-efficiency-of-zomatos-billing-platform-by-switching-from-tidb-to-dynamodb/">AWS Database Blog</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>TiDB（遷移前）</th>
          <th>DynamoDB（遷移後）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>微服務吞吐</td>
          <td>2,000 RPM</td>
          <td>8,000 RPM（4x）</td>
      </tr>
      <tr>
          <td>延遲降幅</td>
          <td>baseline</td>
          <td>-90%</td>
      </tr>
      <tr>
          <td>成本降幅</td>
          <td>baseline</td>
          <td>-50%</td>
      </tr>
      <tr>
          <td>每日事件量</td>
          <td>10M（共用）</td>
          <td>10M</td>
      </tr>
      <tr>
          <td>餐廳合作夥伴</td>
          <td>350,000+</td>
          <td>350,000+</td>
      </tr>
  </tbody>
</table>
<p>關鍵動機：TiDB 必須為「突發流量峰值」提前 over-provision、付出常態成本；DynamoDB on-demand 模式「pay only for what we use」、避免 over-provisioning。</p>
<h2 id="判讀">判讀</h2>
<p>Zomato 遷移揭露三個 DB 選型決策的判讀重點。</p>
<ol>
<li><strong>NewSQL vs NoSQL 的取捨不只是 schema</strong>：TiDB 提供 SQL 介面跟 ACID、DynamoDB 提供 KV 介面跟最終一致性。Zomato 選 DynamoDB 是判斷「帳單事件本身可以接受 eventually consistent」、用一致性換性能跟成本。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的一致性取捨。</li>
<li><strong>TiDB 必須 over-provision 是分散式 SQL 的常態</strong>：分散式 SQL 為了支援跨節點交易、必須有預留容量、否則峰值會出現 leader election storm 或 follower lag。這跟 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> 的「節點數即容量」是同類取捨、Spanner 也必須預先 scale 節點。</li>
<li><strong>2K → 8K RPM 是 4 倍、但延遲降 90% 才是真關鍵</strong>：吞吐改善可能來自架構優化、延遲改善才是 DB 本質差。從 baseline → 10% 通常代表少了 1-2 個 hop（例如 cross-region replication、coordinator round-trip）。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.1 壓測理論與系統行為</a> 的 Little&rsquo;s Law。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「成本降 50%」是 <em>當下流量下的對照</em>。如果未來流量繼續成長、DynamoDB 的 cost-per-request 成長率比 TiDB 自管 cluster 高 — 達到某規模後 TiDB 反而更便宜。讀遷移案例要看「在當下流量下划算」、不等於「永遠划算」。</li>
<li>「90% 延遲降」可能只是 p50、p99 / p999 改善幅度通常較小。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>DB 遷移前先確認業務一致性需求</strong>：能接受 eventually consistent 的工作負載適合 KV / NoSQL；必須 strong consistency 的工作負載必須 SQL / NewSQL。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a>。</li>
<li><strong>遷移評估要看「總成本曲線」、不是「當下 snapshot」</strong>：算未來 12-24 個月在預期流量下的成本對照、不是只算現在。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a>。</li>
<li><strong>遷移過程要 dual-write + shadow read 驗證</strong>：避免新舊系統行為不一致導致業務問題。對應 <a href="/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence</a>。</li>
<li><strong>on-demand vs provisioned 的選擇與業務流量形狀對應</strong>：突發流量適合 on-demand、可預測流量適合 provisioned。對應 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 的 on-demand 應用。</li>
</ol>
<p>跨平台等效：MongoDB Atlas → DynamoDB、Cassandra → DynamoDB、PostgreSQL → Aurora、CockroachDB → Spanner 都是常見遷移路徑。每條路徑的取捨類似。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想做 DB 遷移評估 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a></li>
<li>想理解一致性取捨 → <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> + <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想做總成本評估 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a></li>
<li>對照其他 DB 遷移 → <a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify Kafka→Pub/Sub</a></li>
<li>想拆 access pattern 對應的 DynamoDB schema → <a href="/blog/backend/01-database/vendors/dynamodb/single-table-design-pattern/" data-link-title="DynamoDB Single-Table Design：從適用度前置判讀到 access pattern 反推 PK/SK" data-link-desc="DynamoDB single-table 設計不是「資料表越少越好」，而是 access pattern 反推 PK/SK 跟 GSI；本文先做 DynamoDB 適用度 4 軸前置判讀（PK 天然均勻 / control plane vs data plane / consistency / access pattern 穩定），再展開設計流程、failure modes 與 durable queue 正向用例">DynamoDB single-table design</a> + <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a></li>
<li>想評估搬遷後的 capacity mode → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/database/unlocking-performance-scalability-and-cost-efficiency-of-zomatos-billing-platform-by-switching-from-tidb-to-dynamodb/">Unlocking performance, scalability, and cost-efficiency of Zomato&rsquo;s Billing Platform by switching from TiDB to DynamoDB</a></li>
<li><a href="https://aws.amazon.com/blogs/opensource/how-zomato-boosted-performance-25-and-cut-compute-cost-30-migrating-trino-and-druid-workloads-to-aws-graviton/">How Zomato Boosted Performance 25% and Cut Compute Cost 30% Migrating Trino and Druid Workloads to AWS Graviton</a></li>
</ul>
]]></content:encoded></item><item><title>Service Mesh Mirroring</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/</guid><description>&lt;p>Service mesh mirroring 的核心責任是在 proxy 層複製 production traffic 到 shadow service，讓新版本接受真實請求形狀，同時把使用者回應留在原本路徑。它適合已經落地 Istio、Linkerd 或類似 mesh 的平台，重點在用 routing policy 控制 mirror ratio、target、隔離與觀測。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay&lt;/a> 比、Service Mesh Mirroring 在 &lt;em>proxy / sidecar&lt;/em> 層、是 K8s mesh-native 的 L7 HTTP request mirror、不需要 application 或 host 端 capture binary；GoReplay 在 &lt;em>application host&lt;/em> 層、適合無 mesh 的環境或要 capture artifact 離線 replay。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring&lt;/a> 比、Service Mesh Mirroring 在 L7（HTTP route / header / subset 可控）、VPC Traffic Mirroring 在 L3-L4 packet 層、見度更底層但缺 application 語意。三者組合常見於 K8s + 多 cloud 混合環境。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Service Mesh Mirroring 部署是否健康、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mesh implementation 對齊&lt;/strong>：用哪套 mesh（Istio / Linkerd / Envoy gateway / Consul Connect）、control plane 版本、sidecar injection coverage、跨 namespace policy 邊界是否清楚&lt;/li>
&lt;li>&lt;strong>VirtualService mirror config&lt;/strong>：mirror destination 是否限制在同 namespace / 同 cluster、mirror_percent 是否從 1% 漸進、route / header filter 是否排除 write-heavy 或 PII path&lt;/li>
&lt;li>&lt;strong>Target service capacity&lt;/strong>：shadow target deployment 是否有獨立 HPA、跟 primary 同 node pool 還是隔離、DB / cache / external API 是否導 mock 或 sandbox、不會 share connection pool 造成 primary 飽和&lt;/li>
&lt;li>&lt;strong>Response handling&lt;/strong>：mirrored response 是 fire-and-forget（Istio 預設）還是有 logging、shadow 端是否能辨識 mirrored request（&lt;code>X-Envoy-Internal&lt;/code> / custom header）、side effect（payment / notification / webhook）是否走 dry-run&lt;/li>
&lt;/ul>
&lt;p>四件事任一缺失、就是 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> shadow traffic 治理的待補項目。&lt;/p></description><content:encoded><![CDATA[<p>Service mesh mirroring 的核心責任是在 proxy 層複製 production traffic 到 shadow service，讓新版本接受真實請求形狀，同時把使用者回應留在原本路徑。它適合已經落地 Istio、Linkerd 或類似 mesh 的平台，重點在用 routing policy 控制 mirror ratio、target、隔離與觀測。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a> 比、Service Mesh Mirroring 在 <em>proxy / sidecar</em> 層、是 K8s mesh-native 的 L7 HTTP request mirror、不需要 application 或 host 端 capture binary；GoReplay 在 <em>application host</em> 層、適合無 mesh 的環境或要 capture artifact 離線 replay。跟 <a href="/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring</a> 比、Service Mesh Mirroring 在 L7（HTTP route / header / subset 可控）、VPC Traffic Mirroring 在 L3-L4 packet 層、見度更底層但缺 application 語意。三者組合常見於 K8s + 多 cloud 混合環境。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Service Mesh Mirroring 部署是否健康、最少看四件事：</p>
<ul>
<li><strong>Mesh implementation 對齊</strong>：用哪套 mesh（Istio / Linkerd / Envoy gateway / Consul Connect）、control plane 版本、sidecar injection coverage、跨 namespace policy 邊界是否清楚</li>
<li><strong>VirtualService mirror config</strong>：mirror destination 是否限制在同 namespace / 同 cluster、mirror_percent 是否從 1% 漸進、route / header filter 是否排除 write-heavy 或 PII path</li>
<li><strong>Target service capacity</strong>：shadow target deployment 是否有獨立 HPA、跟 primary 同 node pool 還是隔離、DB / cache / external API 是否導 mock 或 sandbox、不會 share connection pool 造成 primary 飽和</li>
<li><strong>Response handling</strong>：mirrored response 是 fire-and-forget（Istio 預設）還是有 logging、shadow 端是否能辨識 mirrored request（<code>X-Envoy-Internal</code> / custom header）、side effect（payment / notification / webhook）是否走 dry-run</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> shadow traffic 治理的待補項目。</p>
<h2 id="定位">定位</h2>
<p>Service mesh mirroring 適合平台已經有 proxy control plane 的團隊。當 service-to-service traffic 都經過 sidecar 或 gateway，mirror policy 可以把部分 production request 複製到新版本，不需要在 application code 中加 capture / replay 邏輯。</p>
<p>這個定位讓 service mesh mirroring 接到 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 的 shadow traffic 與 canary perf check。它比 host capture 更貼近 service routing，但也依賴 mesh 的觀測、policy、資源隔離與治理能力。</p>
<h2 id="適用場景">適用場景</h2>
<p>新版本 shadow validation 適合 service mesh mirroring。平台可以把 1%、5% 或特定 route 的流量 mirror 到 shadow deployment，觀察新版本 CPU、memory、latency、DB read 與 error。</p>
<p>Service-to-service migration 適合 service mesh mirroring。當下游服務準備換 runtime、framework、DB client 或 cache client，mirror 可以讓新路徑吃到 production upstream pattern。</p>
<p>多 region / 多 version 對照適合 service mesh mirroring。Mesh policy 能按 namespace、host、route、header 或 subset 控制 mirror target，讓平台在小 blast radius 下收集 production-shaped evidence。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Service mesh mirroring 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Proxy 層控制</td>
          <td>mirror policy 不侵入 application code</td>
          <td>mesh control plane 治理與變更審核</td>
      </tr>
      <tr>
          <td>Service routing</td>
          <td>可按 host、route、subset 控制 target</td>
          <td>route 命名、ownership、policy drift</td>
      </tr>
      <tr>
          <td>Mesh observability</td>
          <td>request metric、trace、service graph 可對照</td>
          <td>shadow target 的獨立 dashboard</td>
      </tr>
      <tr>
          <td>漸進比例</td>
          <td>mirror ratio 可逐步放大</td>
          <td>下游容量與 stop condition</td>
      </tr>
  </tbody>
</table>
<p>Proxy 層控制價值來自一致性。當所有 service 都走 mesh，mirror policy 可以用同一套控制面管理，避免每個 application 自行實作 replay。</p>
<p>Mesh observability 價值來自對照能力。Shadow service 的 latency、error、resource saturation 與 dependency call 可以直接跟 primary path 對比，但 dashboard 要清楚標記 mirrored traffic，避免混入正式 SLO。</p>
<h2 id="跟其他方式的取捨">跟其他方式的取捨</h2>
<p>Service mesh mirroring 和 GoReplay 的主要差異是控制面。Service mesh mirroring 依賴既有 proxy / mesh，適合服務間流量；GoReplay 適合 HTTP capture artifact、離線 replay 與沒有 mesh 的環境。</p>
<p>Service mesh mirroring 和 AWS VPC Traffic Mirroring 的主要差異是語意層級。Mesh 在 L7 routing 層，能按 route、host、header 與 subset 控制；VPC mirroring 在網路層，能見度更底層但應用語意控制較少。</p>
<p>Service mesh mirroring 和 canary 的主要差異是使用者影響。Mirrored request 的回應不回給使用者，適合 capacity / correctness observation；canary 會讓真實使用者走新版本，適合最終放量。</p>
<h2 id="操作成本">操作成本</h2>
<p>Service mesh mirroring 的主要成本是下游容量。Shadow traffic 雖然不回應使用者，但仍會消耗 shadow service、DB、cache、third-party mock、queue 與 observability pipeline 的資源。</p>
<p>Policy 成本來自控制面治理。Mirror rule、route、subset、namespace、owner 與 rollout window 都要可審查；錯誤的 mirror policy 可能把過大比例流量導到未準備好的 target。</p>
<p>Side effect 成本來自 application 行為。Shadow service 要能辨識 mirrored request，並把 write、external API call、notification、payment 與 queue publish 導到 sandbox、mock 或 dry-run。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Service mesh mirroring 結果應回寫到 evidence package。最小欄位包括 mesh policy version、source service、route、mirror ratio、target subset、time range、shadow target resource、data / side effect isolation、p95 / p99、error rate、dependency saturation、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Service mesh mirroring 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>mesh policy、route config、deployment version</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>mirror start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>service graph、metrics、trace、logs</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>mirror ratio、route coverage、header filter</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>target parity、dependency isolation</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未 mirror route、side effect mock、mesh overhead</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 mirror 實驗可關閉。Reviewer 要能看到 mirror policy 何時啟動、何時停止、覆蓋哪些 route、消耗哪些下游資源，以及 shadow target 是否接近 production。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Istio VirtualService mirror / mirror_percent</strong>：Istio 用 <code>VirtualService</code> 的 <code>mirror</code> 欄位指定 shadow destination、<code>mirrorPercentage</code>（v1.7+；舊版 <code>mirror_percent</code>）控制比例。production 操作慣例是從 1% 起步、每 30-60min 觀察 shadow target latency / error / saturation 再放大、達到 100% 後維持一週收 evidence 才 promote。route-level config 比 mesh-wide policy 安全、blast radius 限定在指定 host / path。</p>
<p><strong>Linkerd traffic split</strong>：Linkerd 用 SMI <code>TrafficSplit</code> CRD 或 native <code>HTTPRoute</code> 分流、走 <em>active-active</em> shadow 模式而非 fire-and-forget。Linkerd mirror 預設較輕量、proxy overhead 比 Istio 低、適合資源敏感的 K8s cluster；但 L7 policy 表達力不如 Istio EnvoyFilter。</p>
<p><strong>Envoy MirrorPolicy</strong>：直接寫 Envoy config（不透過 Istio control plane）時、<code>route.RouteAction.request_mirror_policies</code> 是底層 primitive。多 cluster 邊緣 gateway（Contour / Emissary-Ingress / Gloo）都是這層的 abstraction、適合不想引入 full Istio 但要 mirror 能力的場景。</p>
<p><strong>跟 Argo Rollouts canary 整合 — shadow deployment</strong>：Argo Rollouts 的 <code>analysis</code> step 可以接 mesh mirror — <em>shadow stage</em> 先用 mirror 收 evidence、<em>canary stage</em> 才放真實流量。對應 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 的「shadow 先於 canary」原則、避免把使用者當小白鼠。</p>
<p><strong>跟 <a href="/blog/backend/04-observability/vendors/datadog/" data-link-title="Datadog" data-link-desc="All-in-one SaaS 觀測平台、APM / Logs / Metrics / RUM / Security">Datadog</a> APM trace correlation</strong>：mirrored request 應該有獨立的 trace tag（<code>env:shadow</code> 或 <code>traffic.mirror:true</code>）、讓 Datadog APM / <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">observability stack</a> 能 filter 出 shadow path 的 p95 / error rate、不混入 primary SLO dashboard。trace propagation header 要保留、否則 distributed trace 斷在 mesh 邊界。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Mirror target capacity 不足 / shadow service OOM</strong>：shadow deployment 沒獨立 HPA、跟 primary 共用 node pool — 拆 node pool、shadow 設獨立 resource request、mirror_percent 從 1% 起步</li>
<li><strong>Mirrored response 漏處理（fire-and-forget 副作用）</strong>：Istio 預設丟棄 mirrored response、shadow 端的 error 沒被 collect — shadow service 自己 emit metric / log、不依賴 mirror response、加 <code>X-Shadow-Request</code> header 讓 shadow 端可辨識並走 dry-run 路徑</li>
<li><strong>PII / sensitive data 進 staging</strong>：mirrored request 帶真實 user token / payment info 打到 staging — header / body filter 走 EnvoyFilter 做 PII redaction、或在 mesh 邊界跑 <a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">data masking proxy</a> 再 mirror</li>
<li><strong>Side effect 真的發生（payment double charge / notification 真寄）</strong>：shadow service 沒辨識 mirrored request 就走正式邏輯 — 強制 shadow 端用 sandbox credential、external API client 走 mock / dry-run mode、write 改 read-only replica</li>
<li><strong>Mesh control plane 飽和 / mirror policy drift</strong>：mirror rule 散落各 namespace 沒 owner、policy version 不一致 — 走 GitOps（Argo CD / Flux）+ policy as code、定期 audit <code>kubectl get virtualservice -A</code></li>
<li><strong>Cross-cluster mirror blast radius 失控</strong>：mirror destination 指向其他 cluster 導致跨 cluster 流量爆增 — mirror destination 限 same-cluster、跨 cluster 要走獨立的 gateway 並設 quota</li>
<li><strong>Shadow trace 混進 SLO dashboard</strong>：APM 沒分 primary / shadow tag、p95 看起來變差但其實是 shadow 拖累 — trace tag <code>env:shadow</code> 強制、observability dashboard filter</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>無 mesh 環境 / 要 capture artifact 離線重播</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a></td>
      </tr>
      <tr>
          <td>L3-L4 packet 層分析（IDS / network forensic）</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring</a></td>
      </tr>
      <tr>
          <td>合成負載 / load test 而非 production mirror</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> / <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a></td>
      </tr>
      <tr>
          <td>Production-side 整體治理</td>
          <td><a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>Istio / Linkerd / Envoy 完整 install / 升級 / control plane HA 細節</li>
<li>Service mesh 安全模型（mTLS / SPIFFE / authorization policy）— 屬 <a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">7 security</a> 邊界</li>
<li>Mesh-level retry / timeout / circuit breaker 等 resilience pattern</li>
<li>Multi-cluster mesh federation（Istio multi-primary、Linkerd multicluster）</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Service mesh mirroring 適合回寫平台遷移與新版本 shadow validation 案例。它可接 <a href="/blog/backend/05-deployment-platform/cases/miro-managed-eks-migration/" data-link-title="5.C5 Miro：Managed EKS 遷移" data-link-desc="從自維運平台轉向 managed EKS 的組織與技術協同案例。">Miro managed EKS migration</a>、<a href="/blog/backend/05-deployment-platform/cases/tradeshift-self-managed-k8s-to-eks/" data-link-title="5.C1 Tradeshift：self-managed Kubernetes 遷移到 EKS" data-link-desc="零停機平台遷移的分段策略案例。">Tradeshift self-managed K8s to EKS</a>、<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel 雙峰 workload</a> 的逐步驗證需求、<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 EKS cluster</a> 的 single-tenant per game 跨 cluster 流量 shadow，以及 <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft 100+ 微服務</a> 跨服務的 mirror 範圍治理。</p>
<p>這些案例的重點是 routing policy 與 blast radius。Service mesh mirroring 頁引用案例時，要把 case 轉成 route、mirror ratio、target subset、dependency isolation 與 abort condition — 例如 Riot Games 的 single-tenant 模式下、mirror policy 必須限制在 <em>同遊戲</em> cluster 內、不能跨 game 否則 blast radius 失控。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>上游：<a href="/blog/backend/05-deployment-platform/traffic-config-control-plane-boundary/" data-link-title="5.7 Traffic、Config 與 Control Plane Boundary" data-link-desc="說明流量、設定、secret、service discovery 與管理面如何分責任與回退。">5.6 Traffic, Config and Control Plane Boundary</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring</a></li>
<li>知識卡：<a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
</ul>
]]></content:encoded></item><item><title>Vantage</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vantage/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vantage/</guid><description>&lt;p>Vantage 是 &lt;em>modern multi-cloud FinOps SaaS&lt;/em>、2020 年由 Heroku ex-founder 創立。它的核心責任是把雲端帳單轉成工程團隊能追蹤的 cost report、allocation、forecast 與 efficiency metric。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth&lt;/a>、Apptio Cloudability、&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer&lt;/a> 同層、但賣點是 &lt;em>developer-friendly UI + 直覺定價 + 多雲 connector 一鍵啟用&lt;/em> — 適合工程團隊自助而非走 FinOps 部門申請的組織。&lt;/p>
&lt;p>它適合多 account、多 provider、Kubernetes 與 shared infrastructure 成本需要分攤到 service、team、namespace、label 或 resource 的組織。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Vantage 的差異在 &lt;em>使用者體驗與切入角度&lt;/em>、指標本身跟同類工具相近。CloudHealth / Apptio 是傳統 enterprise FinOps platform、面向 procurement、CFO、FinOps governance team；Vantage 把入口換成工程團隊 — 報表能直接 share URL、UI 接近 observability dashboard、connector 走 self-service onboarding 而非 SOW + professional service。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth&lt;/a> 比、Vantage &lt;em>淺但快上手&lt;/em>、適合 100 - 1000 人工程組織自助 FinOps；CloudHealth 走 enterprise governance、policy engine、approval workflow 更深、適合 5000+ 員工跨 BU 治理。跟 Apptio Cloudability 比、定位類似 CloudHealth、但 Apptio 把成本接到 TBM（Technology Business Management）frame、適合需要把 IT 成本對到 business service / product P&amp;amp;L 的組織。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer&lt;/a> 比、Cost Explorer 是 AWS-only 入口、免費但只有 AWS、跨 provider / Kubernetes / SaaS spend 看不到；Vantage 把 AWS + GCP + Azure + Snowflake + Databricks + Datadog + Fastly 等串成單一視圖。&lt;/p>
&lt;p>關鍵張力：&lt;em>modern SaaS 速度&lt;/em> ↔ &lt;em>enterprise governance 深度&lt;/em> 是 Vantage 的核心定位 trade-off。要 procurement-grade workflow、approval chain、custom data warehouse export 走 CloudHealth / Apptio；要工程 owner 直接打開 dashboard 看 cost trend、5 分鐘加新 connector 走 Vantage。&lt;/p></description><content:encoded><![CDATA[<p>Vantage 是 <em>modern multi-cloud FinOps SaaS</em>、2020 年由 Heroku ex-founder 創立。它的核心責任是把雲端帳單轉成工程團隊能追蹤的 cost report、allocation、forecast 與 efficiency metric。它跟 <a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a>、Apptio Cloudability、<a href="/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer</a> 同層、但賣點是 <em>developer-friendly UI + 直覺定價 + 多雲 connector 一鍵啟用</em> — 適合工程團隊自助而非走 FinOps 部門申請的組織。</p>
<p>它適合多 account、多 provider、Kubernetes 與 shared infrastructure 成本需要分攤到 service、team、namespace、label 或 resource 的組織。</p>
<h2 id="服務定位">服務定位</h2>
<p>Vantage 的差異在 <em>使用者體驗與切入角度</em>、指標本身跟同類工具相近。CloudHealth / Apptio 是傳統 enterprise FinOps platform、面向 procurement、CFO、FinOps governance team；Vantage 把入口換成工程團隊 — 報表能直接 share URL、UI 接近 observability dashboard、connector 走 self-service onboarding 而非 SOW + professional service。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a> 比、Vantage <em>淺但快上手</em>、適合 100 - 1000 人工程組織自助 FinOps；CloudHealth 走 enterprise governance、policy engine、approval workflow 更深、適合 5000+ 員工跨 BU 治理。跟 Apptio Cloudability 比、定位類似 CloudHealth、但 Apptio 把成本接到 TBM（Technology Business Management）frame、適合需要把 IT 成本對到 business service / product P&amp;L 的組織。跟 <a href="/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer</a> 比、Cost Explorer 是 AWS-only 入口、免費但只有 AWS、跨 provider / Kubernetes / SaaS spend 看不到；Vantage 把 AWS + GCP + Azure + Snowflake + Databricks + Datadog + Fastly 等串成單一視圖。</p>
<p>關鍵張力：<em>modern SaaS 速度</em> ↔ <em>enterprise governance 深度</em> 是 Vantage 的核心定位 trade-off。要 procurement-grade workflow、approval chain、custom data warehouse export 走 CloudHealth / Apptio；要工程 owner 直接打開 dashboard 看 cost trend、5 分鐘加新 connector 走 Vantage。</p>
<h2 id="定位">定位</h2>
<p>Vantage 適合把 cost attribution 帶進容量規劃流程。當團隊已經能用 workload model 描述流量，下一步要知道每個 workload、namespace、database、cache、region 與 account 對成本曲線的影響，Vantage 可以把雲端費用整理成可查詢、可分組、可預測的報表。</p>
<p>這個定位讓 Vantage 接到三個主章。它從 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 接收 cost per request 與 over-provision waste，從 <a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a> 接收 dashboard 與 ownership 訊號，從 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a> 接收 tag、label 與 attribution vocabulary。</p>
<h2 id="適用場景">適用場景</h2>
<p>Showback 與 chargeback 是 Vantage 的主要入口。當平台成本散在 shared Kubernetes cluster、managed database、network egress、storage 與 support plan 裡，Cost Reports 可以把費用依 team、service、environment 或 business unit 切開，讓討論從總帳單轉成 owner action。</p>
<p>Kubernetes 成本分析適合用 Vantage 補足平台可見性。Namespace、label、service、pod、CPU、RAM、storage 與 GPU 維度能讓團隊看到 idle cost、resource efficiency 與 rightsizing recommendation，特別適合多租戶平台。</p>
<p>Forecast 與 anomaly review 適合日常成本治理。每月 forecast、cost trend、unexpected spike 與 budget drift 可以接到 engineering review，讓容量調整、release、marketing event 與成本變化在同一個時間軸上被討論。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Vantage 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cost allocation</td>
          <td>依 provider、account、resource、Kubernetes label 分攤</td>
          <td>tag / label policy、owner taxonomy</td>
      </tr>
      <tr>
          <td>Kubernetes 成本</td>
          <td>namespace、service、label 與 pod-level efficiency</td>
          <td>agent rollout、cluster mapping</td>
      </tr>
      <tr>
          <td>Forecast</td>
          <td>成本趨勢與月末預測可接 review 節奏</td>
          <td>事件註記、release marker、業務日曆</td>
      </tr>
      <tr>
          <td>工程入口</td>
          <td>報表可讓 service owner 直接查詢與追蹤</td>
          <td>action workflow、remediation ownership</td>
      </tr>
  </tbody>
</table>
<p>Cost allocation 價值來自 owner 明確。總帳單只能告訴組織花了多少錢；service-level report 才能讓工程團隊知道哪個 workload、region、database 或 network path 改變了成本。</p>
<p>Kubernetes 成本價值來自 shared cluster 拆分。多租戶平台常把多個服務塞進同一組 node pool；Vantage 類工具把 pod lifecycle 與底層基礎設施成本接起來，讓 namespace 或 label 變成成本討論單位。</p>
<p>Forecast 價值來自提前介入。成本 review 如果只看月底結果，容量浪費和異常用量已經發生；forecast 和 anomaly 讓團隊在月中就能調整 resource request、replica、reserved capacity 或 release plan。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Vantage deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Multi-cloud connector coverage</strong>：AWS / GCP / Azure / Snowflake / Datadog / Fastly 等 connector 是否都接上 — 缺一個就有成本盲區、缺了 Snowflake 反而比缺了 AWS 痛（query cost 沒人看）</li>
<li><strong>Cost Report 設計</strong>：是否依 service / team / environment / business unit 切出可 share 的 saved report、URL 是否進 wiki / Slack canonical 位置、誰每週看</li>
<li><strong>Anomaly Detection 設定</strong>：threshold 跟 baseline 是否 tune 過、false positive rate、anomaly 出現後是否有 owner 接、不是只進 email spam</li>
<li><strong>Report sharing 機制</strong>：cost report 是否走 read-only URL share 給工程 owner、不是把每個工程師都拉進 Vantage account；team 是否有 cost retrospective 節奏</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 邊界的待補項目。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Vantage 和 Akamas 的主要差異是決策深度。Vantage 讓團隊看清成本、分攤責任與找出浪費；Akamas 更進一步把 workload constraint 與 configuration tuning 接成 optimization loop。</p>
<p>Vantage 和 CloudHealth 的主要差異是組織重心。Vantage 偏工程團隊可直接使用的 cost reports、Kubernetes 成本與 resource-level 分析；CloudHealth 偏 enterprise FinOps governance、policy 與大組織流程。</p>
<p>Vantage 和 AWS Cost Explorer 的主要差異是範圍。AWS Cost Explorer 是 AWS-native 入口；Vantage 適合跨 provider、Kubernetes 與多 workspace 的成本視圖。</p>
<h3 id="核心取捨表">核心取捨表</h3>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Vantage</th>
          <th>CloudHealth</th>
          <th>Apptio Cloudability</th>
          <th>AWS Cost Explorer</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>使用者重心</td>
          <td>工程 owner 自助</td>
          <td>FinOps / procurement team</td>
          <td>FinOps + business / product owner</td>
          <td>AWS account holder</td>
      </tr>
      <tr>
          <td>多雲覆蓋</td>
          <td>AWS + GCP + Azure + 主要 SaaS connector</td>
          <td>AWS + GCP + Azure 完整 + policy engine</td>
          <td>AWS + GCP + Azure + on-prem (TBM frame)</td>
          <td>AWS only</td>
      </tr>
      <tr>
          <td>Onboarding 速度</td>
          <td>快 — connector self-service、分鐘級</td>
          <td>慢 — SOW + professional service</td>
          <td>慢 — TBM mapping + implementation</td>
          <td>即用（AWS-native）</td>
      </tr>
      <tr>
          <td>報表分享</td>
          <td>強 — URL share、read-only viewer 免費</td>
          <td>中 — 走 RBAC、外部分享受限</td>
          <td>中 — 走 TBM portal</td>
          <td>弱 — 限 AWS console viewer</td>
      </tr>
      <tr>
          <td>Kubernetes cost</td>
          <td>強 — namespace / label / pod-level 內建</td>
          <td>中 — 整合需配置</td>
          <td>中</td>
          <td>弱</td>
      </tr>
      <tr>
          <td>Anomaly detection</td>
          <td>內建、threshold 可調</td>
          <td>內建 + policy 觸發</td>
          <td>內建</td>
          <td>基本（AWS Cost Anomaly Detection）</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>100-1000 人工程組織、cloud-native</td>
          <td>5000+ 員工跨 BU enterprise governance</td>
          <td>把 IT cost 對到 product P&amp;L 的組織</td>
          <td>純 AWS、預算敏感、初期治理</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>低-中 — report 為主、無深度 lock-in</td>
          <td>高 — policy / approval workflow 量多</td>
          <td>高 — TBM mapping 跟 business 整合</td>
          <td>零 — 本就免費內建</td>
      </tr>
  </tbody>
</table>
<p>選 Vantage 的核心訴求：<em>工程團隊自助 FinOps + 跨雲跨 SaaS 一張視圖 + UI / 報表 share 走 modern observability 體驗</em>、且不需要 enterprise approval workflow / TBM business mapping。需要重 governance 走 CloudHealth、需要 IT-to-business cost mapping 走 Apptio、純 AWS 預算敏感先用 Cost Explorer。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Cost Report builder</strong>：Vantage 的核心 primitive、走 <em>filter + group by + time range</em> 的 declarative model — 例如 <code>provider:aws AND service:ec2 AND tag:team=payments group by region</code>。Saved report 變團隊 canonical view、URL 可貼 wiki / Slack；scheduled report 走 email / Slack notification。實務上 <em>每個 service owner 都該有一張 saved report</em>、不是 FinOps team 中央集中看。</p>
<p><strong>Anomaly Detection</strong>：依 cost trend 統計 baseline、超過 threshold 觸發 anomaly。痛點是 <em>false positive</em>：deploy 新 service、月底 invoice timing、provider 計費延遲都會觸發。Tune 方向是 <em>排除 known event</em>（new connector 接入後 7 天 grace period）+ <em>調 sensitivity per service</em>（payment 可容忍 5% drift、ML training cluster 容忍 50%）。對應 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 的 anomaly governance frame。</p>
<p><strong>Resource ROI / efficiency metric</strong>：Vantage 把 cost 跟 utilization metric 對齊、算 <em>cost per unit</em>（cost / request、cost / GB stored、cost / GPU-hour）。意義是把 cost report 從 <em>absolute spend</em> 升級到 <em>efficiency frontier</em>、能識別 overprovision 跟 underutilization。需要 metric source 接上（Datadog / Prometheus / CloudWatch）、純帳單 data 算不出 ROI。</p>
<p><strong>Datadog / Slack integration</strong>：cost anomaly + scheduled report 推到 Slack channel、跟 incident channel 共用；Datadog 接成 metric source 後可在 Datadog dashboard 看 cost trend 跟 latency / error rate side-by-side、適合做 <em>cost-aware SLO review</em>。</p>
<p><strong>Vantage Network（vendor benchmark）</strong>：匿名化彙整 Vantage 客戶的 unit cost benchmark（每 GB S3 storage、每 RDS instance hour、每 Snowflake credit）、讓客戶看自己跟同產業比是貴是便宜。價值在 <em>negotiation leverage</em> — 跟 AWS / Snowflake 談 EDP / 多年合約時、benchmark 是議價素材。注意是匿名 aggregate、不是 vendor 個別揭露。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Multi-cloud tag drift</strong>：AWS 用 <code>team</code>、GCP 用 <code>Team</code>、Azure 用 <code>Team-Name</code>、Vantage report group by 後出現大量 <code>untagged</code> — 在 Vantage <em>Virtual Tag</em>（rule-based tag normalization）統一 mapping、或源頭走 tag policy enforcement（<a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html">AWS Organizations tag policy</a>、GCP organization policy）</li>
<li><strong>Anomaly false positive 過多 / SOC-like alert fatigue</strong>：threshold 設太緊、month-end billing delay 沒排除 — 拉大 baseline window、加 grace period for new resource、per-service tune sensitivity</li>
<li><strong>Cost spike root cause 不明</strong>：總帳單漲了但 group by service / region / tag 都看不出來 — 切到 <em>Resource Report</em>（最細粒度、看 instance / volume / snapshot 個別 cost）找 outlier、或開 Vantage <em>Cost Diffs</em>（兩個 time window 對比 delta breakdown）</li>
<li><strong>Kubernetes cost agent 資料缺</strong>：agent 沒裝 / cluster role 權限不足 / metric server 沒啟用、namespace breakdown 全空 — 走 Vantage Kubernetes onboarding checklist 補 agent + RBAC + metric server、確認資料 24hr 內出現</li>
<li><strong>Connector 接上但資料沒進來</strong>：跨 account assume role 失敗、CUR（Cost and Usage Report）export 沒開、Snowflake account usage 權限缺 — 在 Vantage connector page 看 sync status 跟 error log、不是盲猜</li>
<li><strong>Report share URL 被外人猜到</strong>：read-only URL 預設 <em>unauthenticated</em>、share 給 contractor 後沒 revoke — 改用 <em>Authentication-required share</em> 或定期 rotate URL、敏感成本數字（payment processor cost / customer-specific dedicated infra）走 internal-only</li>
<li><strong>Forecast 不準 / 跟實際差太多</strong>：base period 太短 / 有 one-off event（migration backfill、disaster recovery test）、forecast model 抓不到 seasonality — 拉長 base period、標記 one-off event 排除、或改走 manual override forecast 給特定 service</li>
</ul>
<h2 id="操作成本">操作成本</h2>
<p>Vantage 的主要成本是 cost taxonomy 維護。Tag、label、account、workspace、cluster、namespace 與 service owner 要有穩定規則，Cost Reports 才能被工程團隊信任。</p>
<p>Kubernetes agent 導入需要平台協作。Cluster 權限、資料上傳、node / pod mapping、provider cost delay 與 double counting 防護，都需要平台團隊與 FinOps 團隊一起定義。</p>
<p>Remediation 成本在報表之後才開始。找到 idle cost、overprovisioned workload 或 unexpected egress 只是第一步，後續要有 ticket、owner、驗證、rollback 與 saving confirmation。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Vantage 結果應回寫到 cost attribution evidence package。最小欄位包括 report name、filter、grouping、time range、provider、owner dimension、baseline cost、forecast、anomaly、efficiency metric、action item 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Vantage 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>Cost Report、Kubernetes Efficiency Report、Resource Report</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>report window、billing period、forecast period</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>Vantage report URL、cloud billing query、dashboard</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>tag coverage、agent freshness、provider data delay</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>owner mapping、double counting check、trend repeatability</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未標記 resource、shared cost allocation rule、資料延遲</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是把成本問題交給正確 owner。Vantage report 要能回答「誰的 workload 產生成本、成本從何時開始改變、哪個維度最能解釋變化」。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>Vantage 目前適合作為 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 與 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 cost attribution</a> 的工具承接點。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 EKS cluster</a> 的多 cluster 成本歸屬與年省 1000 萬美金驗證、<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的 28% 成本下降跨 DB 整併、<a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow modern data architecture</a> 的儲存 90% / 分析 80% 成本下降，以及 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> 的 on-demand cost model 50% 降幅。</p>
<p>這些案例的重點是成本歸屬。Vantage 頁引用案例時，要把 report filter、owner dimension、成本變化、action item 與驗證結果寫清楚 — 例如 Netflix 的 28% 下降需要拆到 DB tier、replication topology 與 read replica 比例，避免停在帳單 dashboard 截圖。</p>
<p>Vantage 的客戶輪廓偏 <em>modern startup 與 mid-market</em> — 工程組織 100-1000 人、cloud-native first、沒有獨立 FinOps team、由 platform / SRE 兼任成本治理。這類組織的痛點是 <em>誰看 cost report、誰調 anomaly、誰負責 saving validation</em> 的工程節奏沒建立、governance policy 本身反而不缺。引用 Riot Games / Netflix / BookMyShow / Zomato 案例時、重點是把這些 enterprise-scale 的 attribution 機制轉譯成 mid-market 可執行的 weekly review 節奏、而非照搬全部 governance overhead。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a>、<a href="/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer</a></li>
<li>官方：<a href="https://docs.vantage.sh/cost_reports">Vantage Cost Reports</a></li>
</ul>
]]></content:encoded></item><item><title>9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/</guid><description>&lt;p>這個案例的核心責任是補強 Azure 案例庫深度。Cosmos DB 過往只有 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth&lt;/a> 一篇、ASOS 提供 &lt;em>傳統零售場景 + 全球分散 + 季節性峰值&lt;/em> 的對照、跟 Minecraft Earth 的 &lt;em>AR 遊戲 + 玩家位置&lt;/em> 完全不同業務語意。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>ASOS 在 Azure 的關鍵數字（引自 &lt;a href="https://www.microsoft.com/en/customers/story/718983-asos-retail-and-consumer-goods-azure">ASOS Microsoft Customer Story&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>客戶數&lt;/td>
 &lt;td>1540 萬&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Black Friday 24 小時請求量&lt;/td>
 &lt;td>1.67 億&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Black Friday 請求峰值&lt;/td>
 &lt;td>3,500 req/sec&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Black Friday 訂單峰值&lt;/td>
 &lt;td>33 orders/sec&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>平均響應時間&lt;/td>
 &lt;td>48 ms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>商品 SKU&lt;/td>
 &lt;td>85,000、每週新增 5,000 件&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>架構轉變&lt;/td>
 &lt;td>2016 年遷移到 microservices&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>Azure Cosmos DB + microservices&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵業務驅動：「ASOS chose Azure Cosmos DB because of its global distribution and ability to handle heavy seasonal bursts like Black Friday」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>ASOS 案例揭露三個全球零售 KV 容量規劃重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Black Friday 24h 1.67 億 = 平均 1,930 req/sec、峰值 3,500 req/sec&lt;/strong>：峰值 / 平均 = 1.81 倍。這個比例顯示 Black Friday 「持續高峰」、不是「瞬間爆量」 — 24 小時內流量曲線相對平緩、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft&lt;/a> 的「5 分鐘賣完」是完全不同形狀。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling&lt;/a> 的負載形狀識別。&lt;/li>
&lt;li>&lt;strong>48ms 平均響應 = 全球分散下 Cosmos DB 的代表性數字&lt;/strong>：英國時尚電商、客戶遍及全球、Cosmos DB 在每個地區複製、讀取在最近 region 完成。這個 48ms 包含網路、DB、應用層 — DB 本身可能只佔 5-10ms、其他是網路與應用層。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 latency budget 分解。&lt;/li>
&lt;li>&lt;strong>85K SKU + 每週新增 5K = 高更新頻率 catalog&lt;/strong>：商品資料不只是讀、還有頻繁更新（價格、庫存、推薦排序）。這層 write throughput 對 Cosmos DB partition key 設計（通常用 category_id 或 brand_id）至關重要。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 hot partition 識別。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：這是 2016 年的數字、過去 10 年 ASOS 應該成長很多。但 1.67 億 req/24h 跟 33 orders/sec 對許多新興電商仍是天花板級數字、可作為「中大型零售」對標。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是補強 Azure 案例庫深度。Cosmos DB 過往只有 <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> 一篇、ASOS 提供 <em>傳統零售場景 + 全球分散 + 季節性峰值</em> 的對照、跟 Minecraft Earth 的 <em>AR 遊戲 + 玩家位置</em> 完全不同業務語意。</p>
<h2 id="觀察">觀察</h2>
<p>ASOS 在 Azure 的關鍵數字（引自 <a href="https://www.microsoft.com/en/customers/story/718983-asos-retail-and-consumer-goods-azure">ASOS Microsoft Customer Story</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>客戶數</td>
          <td>1540 萬</td>
      </tr>
      <tr>
          <td>Black Friday 24 小時請求量</td>
          <td>1.67 億</td>
      </tr>
      <tr>
          <td>Black Friday 請求峰值</td>
          <td>3,500 req/sec</td>
      </tr>
      <tr>
          <td>Black Friday 訂單峰值</td>
          <td>33 orders/sec</td>
      </tr>
      <tr>
          <td>平均響應時間</td>
          <td>48 ms</td>
      </tr>
      <tr>
          <td>商品 SKU</td>
          <td>85,000、每週新增 5,000 件</td>
      </tr>
      <tr>
          <td>架構轉變</td>
          <td>2016 年遷移到 microservices</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>Azure Cosmos DB + microservices</td>
      </tr>
  </tbody>
</table>
<p>關鍵業務驅動：「ASOS chose Azure Cosmos DB because of its global distribution and ability to handle heavy seasonal bursts like Black Friday」。</p>
<h2 id="判讀">判讀</h2>
<p>ASOS 案例揭露三個全球零售 KV 容量規劃重點。</p>
<ol>
<li><strong>Black Friday 24h 1.67 億 = 平均 1,930 req/sec、峰值 3,500 req/sec</strong>：峰值 / 平均 = 1.81 倍。這個比例顯示 Black Friday 「持續高峰」、不是「瞬間爆量」 — 24 小時內流量曲線相對平緩、跟 <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a> 的「5 分鐘賣完」是完全不同形狀。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a> 的負載形狀識別。</li>
<li><strong>48ms 平均響應 = 全球分散下 Cosmos DB 的代表性數字</strong>：英國時尚電商、客戶遍及全球、Cosmos DB 在每個地區複製、讀取在最近 region 完成。這個 48ms 包含網路、DB、應用層 — DB 本身可能只佔 5-10ms、其他是網路與應用層。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 latency budget 分解。</li>
<li><strong>85K SKU + 每週新增 5K = 高更新頻率 catalog</strong>：商品資料不只是讀、還有頻繁更新（價格、庫存、推薦排序）。這層 write throughput 對 Cosmos DB partition key 設計（通常用 category_id 或 brand_id）至關重要。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 hot partition 識別。</li>
</ol>
<p>需要警惕：這是 2016 年的數字、過去 10 年 ASOS 應該成長很多。但 1.67 億 req/24h 跟 33 orders/sec 對許多新興電商仍是天花板級數字、可作為「中大型零售」對標。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>Black Friday 類「持續高峰」適合 provisioned + scheduled scaling</strong>：跟 flash-sale 的「on-demand 吃彈性」不同、Black Friday 整天高、用 provisioned 比較划算。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 的可預期峰值準備。</li>
<li><strong>全球零售用 Cosmos DB / DynamoDB Global Tables</strong>：客戶在哪、讀取就在哪、避免跨洲 latency。對應 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> 的全球分散取捨。</li>
<li><strong>微服務 + Cosmos DB 是電商現代化典型路徑</strong>：從單體 → 微服務、從關聯式 DB → multi-model NoSQL、是 2016 後零售業常見遷移。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 與 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a>。</li>
</ol>
<p>跨平台等效：AWS DynamoDB Global Tables + Lambda、GCP Firestore + Cloud Run 都可以實作對等架構。差異是 Cosmos DB 的 multi-model（同一服務支援 SQL、Mongo、Cassandra、Gremlin、Table API）、AWS 對應有 DynamoDB（KV/Document）+ Neptune（Graph）+ Keyspaces（Cassandra）等多個服務。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他可預期峰值 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a> / <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a></li>
<li>對照 flash-sale-spike → <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></li>
<li>想對照其他 Cosmos DB 使用 → <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a></li>
<li>想規劃全球電商 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想拆 Black Friday 容量背後的 RU 成本與 sizing → <a href="/blog/backend/01-database/vendors/cosmosdb/ru-cost-model-sizing/" data-link-title="Cosmos DB RU/s 成本模型 &#43; 容量規劃：RU 思維、payload、index、provisioned vs autoscale vs serverless" data-link-desc="從 CPU&#43;IOPS 思維轉到 RU 思維的學習曲線、依負載形狀選容量模式、payload &#43; index policy 對 RU 的影響、autoscale reactive 限制 — 從 ASOS Black Friday &#43; Minecraft Earth 1M RU/s 壓測切入">Cosmos DB RU 成本模型與 sizing</a></li>
<li>想做電商 partition key 設計 → <a href="/blog/backend/01-database/vendors/cosmosdb/partition-key-design/" data-link-title="Cosmos DB Partition Key Design：synthetic / composite / hierarchical &#43; 不可逆性硬約束" data-link-desc="Cosmos DB logical partition 10000 RU/s 上限、partition key 不可改、三種設計模式（synthetic / composite / hierarchical）、跟 DynamoDB / MongoDB 可逆性對比、latency budget 拆解 — 從 Minecraft Earth &#43; ASOS 切入">Cosmos DB partition key 設計</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.microsoft.com/en/customers/story/718983-asos-retail-and-consumer-goods-azure">ASOS – Online retailer uses cloud database to deliver world-class shopping experiences</a></li>
<li><a href="https://azure.microsoft.com/en-us/products/cosmos-db/">Azure Cosmos DB</a></li>
</ul>
]]></content:encoded></item><item><title>AWS VPC Traffic Mirroring</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/</guid><description>&lt;p>AWS VPC Traffic Mirroring 的核心責任是在 VPC 網路層複製 ENI traffic，讓團隊用低 application 侵入方式觀察 production flow。它適合封包級診斷、網路安全分析、流量樣本收集與部分 replay 前置資料蒐集，重點在明確定義 mirror source、filter、target、加密邊界與保存責任。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>AWS VPC Traffic Mirroring 適合需要網路層能見度的 AWS workload。當 application code、service mesh 或 host capture 都不適合改動時，VPC 層 mirror 可以從 ENI 複製封包到 analysis appliance、IDS、packet capture 或自管處理服務。&lt;/p>
&lt;p>這個定位讓 AWS VPC Traffic Mirroring 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> 的 shadow traffic 前置觀測。它偏封包觀察與樣本收集，若要做應用層 replay、filter、rewrite 或 side effect 隔離，通常還需要 GoReplay、proxy、custom processor 或測試環境配合。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay&lt;/a> 比、VPC Traffic Mirroring 走 &lt;em>無侵入 L3 packet copy&lt;/em>、GoReplay 走 &lt;em>application-level HTTP capture / rewrite&lt;/em>；跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring&lt;/a> 比、VPC Mirror 在 ENI 層、Mesh Mirror 在 K8s pod 層；跟 AWS Network Firewall 比、Firewall 是 &lt;em>inline 阻擋&lt;/em>、Mirror 是 &lt;em>side-channel 觀察&lt;/em>、兩者目的不同但 packet path 相近。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 VPC Traffic Mirroring deployment 是否健康、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Source ENI selection&lt;/strong>：哪些 ENI 被 mirror（per-instance / per-subnet / 用 tag 自動選）、是否覆蓋瓶頸路徑上的關鍵節點（ALB target / NAT Gateway / RDS proxy / cross-AZ ENI）、漏掉哪個 ENI 就是 evidence 盲區&lt;/li>
&lt;li>&lt;strong>Filter rule 收斂&lt;/strong>：mirror filter 用 protocol / port / CIDR / direction 限定、避免「全 ENI 全 traffic」這種失控設定；filter 太寬會把 cross-AZ cost + target 處理量直接炸上去&lt;/li>
&lt;li>&lt;strong>Target NLB capacity&lt;/strong>：mirror target 是 ENI 或 NLB、target capacity（NLB flow / bandwidth）跟 source 流量比例要對得起來、target overload 會 drop 封包讓 evidence 失真&lt;/li>
&lt;li>&lt;strong>Sampling rate / packet length truncation&lt;/strong>：高流量服務不必 1:1 mirror、要設 &lt;code>packet_length&lt;/code> 截斷（只取 header）跟 mirror session ratio；忘設 sampling 等於整條 production 流量複製兩份、AWS bill 月底會出事&lt;/li>
&lt;/ul>
&lt;p>四件事任一缺失、就是 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a> 邊界的待補項目。&lt;/p></description><content:encoded><![CDATA[<p>AWS VPC Traffic Mirroring 的核心責任是在 VPC 網路層複製 ENI traffic，讓團隊用低 application 侵入方式觀察 production flow。它適合封包級診斷、網路安全分析、流量樣本收集與部分 replay 前置資料蒐集，重點在明確定義 mirror source、filter、target、加密邊界與保存責任。</p>
<h2 id="定位">定位</h2>
<p>AWS VPC Traffic Mirroring 適合需要網路層能見度的 AWS workload。當 application code、service mesh 或 host capture 都不適合改動時，VPC 層 mirror 可以從 ENI 複製封包到 analysis appliance、IDS、packet capture 或自管處理服務。</p>
<p>這個定位讓 AWS VPC Traffic Mirroring 接到 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 的 shadow traffic 前置觀測。它偏封包觀察與樣本收集，若要做應用層 replay、filter、rewrite 或 side effect 隔離，通常還需要 GoReplay、proxy、custom processor 或測試環境配合。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a> 比、VPC Traffic Mirroring 走 <em>無侵入 L3 packet copy</em>、GoReplay 走 <em>application-level HTTP capture / rewrite</em>；跟 <a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a> 比、VPC Mirror 在 ENI 層、Mesh Mirror 在 K8s pod 層；跟 AWS Network Firewall 比、Firewall 是 <em>inline 阻擋</em>、Mirror 是 <em>side-channel 觀察</em>、兩者目的不同但 packet path 相近。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 VPC Traffic Mirroring deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Source ENI selection</strong>：哪些 ENI 被 mirror（per-instance / per-subnet / 用 tag 自動選）、是否覆蓋瓶頸路徑上的關鍵節點（ALB target / NAT Gateway / RDS proxy / cross-AZ ENI）、漏掉哪個 ENI 就是 evidence 盲區</li>
<li><strong>Filter rule 收斂</strong>：mirror filter 用 protocol / port / CIDR / direction 限定、避免「全 ENI 全 traffic」這種失控設定；filter 太寬會把 cross-AZ cost + target 處理量直接炸上去</li>
<li><strong>Target NLB capacity</strong>：mirror target 是 ENI 或 NLB、target capacity（NLB flow / bandwidth）跟 source 流量比例要對得起來、target overload 會 drop 封包讓 evidence 失真</li>
<li><strong>Sampling rate / packet length truncation</strong>：高流量服務不必 1:1 mirror、要設 <code>packet_length</code> 截斷（只取 header）跟 mirror session ratio；忘設 sampling 等於整條 production 流量複製兩份、AWS bill 月底會出事</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a> 邊界的待補項目。</p>
<h2 id="適用場景">適用場景</h2>
<p>網路層瓶頸定位適合 VPC Traffic Mirroring。當 latency、packet loss、TLS handshake、connection reset、NAT、load balancer 或 cross-AZ traffic 是疑點時，封包 mirror 能提供 application metrics 看不到的證據。</p>
<p>低侵入 traffic sampling 適合 VPC Traffic Mirroring。團隊可以在不改 application code 的情況下收集 production flow，作為 workload model、security analysis 或 replay pipeline 的輸入。</p>
<p>受管 AWS 網路環境適合 VPC Traffic Mirroring。當服務主要跑在 EC2 / ENI 可 mirror 的環境中，VPC 原生能力可以讓網路團隊用既有安全與觀測流程管理。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>AWS VPC Traffic Mirroring 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>網路層鏡像</td>
          <td>application 無侵入、封包級可見</td>
          <td>L7 解碼、filter、rewrite 與 replay</td>
      </tr>
      <tr>
          <td>AWS 原生</td>
          <td>VPC / ENI / filter / target 整合</td>
          <td>AWS 約束、跨帳號與跨 VPC 設計</td>
      </tr>
      <tr>
          <td>安全分析</td>
          <td>可接 IDS、packet analyzer、forensics</td>
          <td>PII / payload 保存與存取控制</td>
      </tr>
      <tr>
          <td>流量樣本</td>
          <td>可支援 workload model 校正</td>
          <td>加密 traffic 處理與樣本代表性</td>
      </tr>
  </tbody>
</table>
<p>網路層鏡像價值來自低侵入。團隊可以在不調整 application 或 service mesh 的情況下取得 flow evidence，但也要承擔 L7 語意不足的限制。</p>
<p>安全分析價值來自封包細節。對容量工程而言，封包證據能幫忙確認 connection、TLS、NAT、load balancer 與跨區流量成本；對資安而言，則能支援 IDS 與 forensic workflow。</p>
<h2 id="跟其他方式的取捨">跟其他方式的取捨</h2>
<p>AWS VPC Traffic Mirroring 和 GoReplay 的主要差異是層級。VPC mirroring 在 L3 / L4 觀察封包；GoReplay 更接近 HTTP application replay，對 request rewrite 與 target control 更直接。</p>
<p>AWS VPC Traffic Mirroring 和 service mesh mirroring 的主要差異是控制範圍。VPC mirroring 由網路層控制，適合低侵入封包觀察；service mesh mirroring 由 L7 route policy 控制，適合服務版本與 route 對照。</p>
<p>AWS VPC Traffic Mirroring 和 synthetic load test 的主要差異是用途。VPC mirroring 提供 production traffic evidence；synthetic load test 提供可控壓力。兩者常搭配：先用 mirror 校正 workload model，再用 k6 / Gatling / Locust 產生可控負載。</p>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS VPC Traffic Mirroring</th>
          <th>GoReplay</th>
          <th>Service Mesh Mirroring</th>
          <th>AWS Network Firewall</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>鏡像層級</td>
          <td>L3 / L4 packet copy</td>
          <td>L7 HTTP capture + replay</td>
          <td>L7 pod-level（Istio / Linkerd）</td>
          <td>L3-L7 inline filter（非 mirror）</td>
      </tr>
      <tr>
          <td>Application 侵入</td>
          <td>無 — ENI 層、code 不改</td>
          <td>中 — 需 sidecar / capture host</td>
          <td>中 — service mesh 必須先佈</td>
          <td>無 — VPC gateway 層</td>
      </tr>
      <tr>
          <td>Replay 能力</td>
          <td>弱 — 需自接 packet replayer</td>
          <td>強 — 內建 request rewrite</td>
          <td>中 — mirror to shadow service</td>
          <td>無</td>
      </tr>
      <tr>
          <td>適用場景</td>
          <td>network forensics / IDS / 容量分析</td>
          <td>HTTP regression / load replay</td>
          <td>K8s service-level shadow test</td>
          <td>inline 阻擋 / IDS / IPS</td>
      </tr>
      <tr>
          <td>加密 payload</td>
          <td>看不到 — TLS 仍密</td>
          <td>看得到 — application 解密後</td>
          <td>看得到 — mesh sidecar 已 TLS terminate</td>
          <td>partial — TLS inspection 需另設</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>per-ENI / cross-AZ traffic</td>
          <td>計算 + 儲存</td>
          <td>mesh overhead + shadow service</td>
          <td>per-GB processed</td>
      </tr>
  </tbody>
</table>
<h2 id="操作成本">操作成本</h2>
<p>AWS VPC Traffic Mirroring 的主要成本是資料治理。Mirror target 可能收到 payload、token、cookie、internal identifiers 與敏感資料，因此保存、查詢、保留期限、存取權與刪除責任要先定義。</p>
<p>網路成本來自複製 traffic。Mirror session 會增加網路流量與 target processing 成本，高流量服務要先估算 mirror ratio、filter、target capacity 與跨 AZ 費用。</p>
<p>加密成本來自 L7 可讀性。TLS traffic 在網路層 mirror 後通常仍是加密封包；若需要 application payload，要搭配解密點、proxy、key 管理或 application-level capture。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>AWS VPC Traffic Mirroring 結果應回寫到 evidence package。最小欄位包括 mirror source ENI、filter rule、mirror target、session number、time range、sampling / truncation、target capacity、payload handling、packet metrics、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>AWS VPC Traffic Mirroring 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>mirror session、filter、target config</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>mirror start / end</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>packet analyzer、flow logs、metrics link</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>filter coverage、sampling、encryption status</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>target capacity、source coverage</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>加密 payload、未 mirror ENI、L7 語意不足</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是把網路層觀察接回效能判斷。Reviewer 要能知道 mirror 覆蓋哪些 ENI、哪些封包被 filter、target 是否有 capacity，以及封包證據如何對應到 application latency 或 saturation。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Filter rule 設計</strong>：mirror filter 支援 source CIDR / dest CIDR / protocol / port range / direction（ingress / egress）、rule number 決定 evaluation 順序。production 慣例是 <em>最小覆蓋原則</em> — 先用 <code>port 443 + dest CIDR = ALB target group</code> 限定到關鍵 path、再依需要擴張。filter 寫太寬會把 control-plane heartbeat、health check、internal RPC 全部 mirror 進來、target 處理量瞬間爆掉。</p>
<p><strong>跟 IDS / packet analyzer 整合</strong>：mirror target 接 ENI 後常見的下游堆疊是 <em>Zeek</em>（前 Bro、生成 connection log / protocol log）、<em>Suricata</em>（rule-based IDS / IPS 偵測）、<em>Wireshark / tshark</em>（離線封包分析）。實務上 mirror → NLB → 自管 EC2 跑 Zeek 產 JSON log → 進 <a href="/blog/backend/07-security-data-protection/vendors/datadog-security/" data-link-title="Datadog Security" data-link-desc="Datadog observability platform 上的 security suite：Cloud SIEM &#43; CSPM &#43; CWS &#43; AAP &#43; Sensitive Data Scanner、跟 observability 同 plane">Datadog</a> / Splunk 做 correlation。容量工程關心 connection reset 跟 retransmit、資安關心 protocol anomaly、共用同一份 mirror feed。</p>
<p><strong>Replay 到 staging cluster</strong>：mirror feed 不能直接 replay（沒有 stateful 重組），但可以接 packet replayer（tcpreplay / GoReplay packet mode）把樣本送到 staging。要注意 <em>side effect 隔離</em> — staging 的 DB / external API 不應該真的執行寫入、否則 mirror 變成 production fanout。</p>
<p><strong>Traffic analysis platform 整合</strong>：mirror 取得的 packet evidence 通常進 <a href="/blog/backend/07-security-data-protection/vendors/datadog-security/" data-link-title="Datadog Security" data-link-desc="Datadog observability platform 上的 security suite：Cloud SIEM &#43; CSPM &#43; CWS &#43; AAP &#43; Sensitive Data Scanner、跟 observability 同 plane">Datadog Network Performance Monitoring</a> 做 NPM dashboard、或進 Splunk Stream app 做 SIEM correlation。整合的關鍵是 <em>時間軸對齊</em> — packet timestamp、application log、metrics 三者要同步、否則 root cause 拼不回去。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Target NLB capacity 不夠 / drop packet</strong>：mirror traffic 量超過 NLB flow limit、packet 被 silently drop — 拆 mirror session 到多個 target、開 NLB flow log 看 drop reason、必要時改用 Gateway Load Balancer</li>
<li><strong>Filter rule 太寬導致流量爆</strong>：「mirror 所有 traffic」設定上線後 target ENI 跟 cross-AZ bandwidth 雙重炸 — 立刻關掉 session、改用 dest CIDR / port 收斂、加 <code>packet_length</code> 截斷只取 header</li>
<li><strong>Cross-AZ mirror cost 暴增</strong>：source ENI 跟 target 在不同 AZ、每個封包複製都收 cross-AZ traffic 費 — target NLB 部署到每個 AZ、用 AZ-affinity routing、或把 mirror target 限定在 source 同 AZ</li>
<li><strong>TLS payload 看不到</strong>：mirror 拿到加密封包、L7 內容無法分析 — 把解密點移到 ALB / NLB-TLS termination、或在 application 層加 capture（不再用 VPC mirror）</li>
<li><strong>Mirror session 漏掉新 instance</strong>：autoscaling 起新 instance 沒自動加入 mirror — 用 mirror target by tag、Terraform / CloudFormation 把 mirror session 寫進 ASC launch template</li>
<li><strong>Packet timestamp 不對齊 application log</strong>：mirror packet 時間是 source ENI capture 時間、不是 application processing 時間、做 latency 分析會偏差 — 用 packet 5-tuple + request ID 對齊 application log、不要直接相減 timestamp</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>AWS VPC Traffic Mirroring 適合回寫網路與平台層效能案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/" data-link-title="9.C34 GCP：130,000-node GKE cluster 的工程極限" data-link-desc="Google 用單一 GKE control plane 跑 13 萬個 node、AI workload &#43; 1000 Pods/sec 創建吞吐">9.C34 GCP 130K node GKE cluster</a> 的大規模網路觀測需求（雖在 GCP、但網路證據的層次拆解可類比）、<a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair GCP burst capacity</a> 的跨雲容量觀測、<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day readiness</a> 的 pre-event network evidence、<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 EKS cluster</a> 跨 cluster 的網路流量觀測、以及 <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys DynamoDB 15-region</a> 的 99.999% 可用性下封包層 evidence 補強。</p>
<p>這些案例的重點是網路層 evidence。VPC Traffic Mirroring 頁引用案例時，要把 case 轉成 mirror source、filter、target capacity、packet metric、cross-AZ cost 與 L7 correlation — 例如 Riot Games 35ms 延遲門檻下、cross-AZ traffic mirror 本身會增加成本、必須先用 filter 收斂到關鍵 ENI。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a></li>
<li>知識卡：<a href="/blog/backend/knowledge-cards/shadow-traffic/" data-link-title="Shadow Traffic" data-link-desc="把 production traffic 複製到新版本驗證、但不返回結果給用戶的測試模式">Shadow Traffic</a></li>
<li>官方：<a href="https://docs.aws.amazon.com/vpc/latest/mirroring/what-is-traffic-mirroring.html">AWS VPC Traffic Mirroring documentation</a></li>
</ul>
]]></content:encoded></item><item><title>CloudHealth</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/</guid><description>&lt;p>CloudHealth 的核心責任是把大型組織的 cloud spend、governance、policy、allocation 與 optimization workflow 放進同一個 FinOps 管理平面。它適合 account、team、business unit、provider 與採購流程複雜的組織，重點在讓成本治理、合規要求與工程 owner 能共用同一套成本事實。2018 年被 VMware 收購、2023 年隨 VMware 進入 Broadcom 旗下；現屬 Broadcom 的 enterprise FinOps 旗艦產品。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>CloudHealth 跟 AWS Cost Explorer / Azure Cost Management 那種單雲原生工具的差異在 &lt;em>跨雲一致 schema + enterprise FinOps operating model&lt;/em>、單雲帳單細節反而是原生工具更深。Cost Explorer 在 AWS-only 場景的 granularity 更深、但跨 Azure / GCP 帳單對齊、成本中心 chargeback、policy 治理就需要 CloudHealth 這類 multi-cloud platform。&lt;/p>
&lt;p>跟 Vantage 比、CloudHealth 走 &lt;em>enterprise governance-first&lt;/em>、Vantage 走 &lt;em>engineering-friendly dashboard-first&lt;/em>。Vantage 對小到中型 cloud-native 團隊更快上手、但 chargeback 流程、policy violation queue、approval workflow 都不是它的主場。跟 Apptio Cloudability（IBM 收購）比、兩者定位最接近、都吃 large enterprise FinOps 市場；CloudHealth 的差異是 VMware / Broadcom ecosystem 整合（vCenter / Tanzu / on-prem hybrid），Cloudability 強在 TBM（Technology Business Management）財務分攤模型成熟度。&lt;/p>
&lt;p>關鍵張力：&lt;em>Broadcom 收購後的 product roadmap 不確定性&lt;/em> ↔ &lt;em>enterprise FinOps ecosystem 深度&lt;/em>。Broadcom 對 VMware portfolio 的價格調整、partner 縮編、support tier 變動 2024-2025 持續發生；客戶要評估 &lt;em>退場成本（chargeback rule + tag taxonomy 量大）vs 短期 license 漲幅&lt;/em>、不是只看當下功能。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>CloudHealth 適合 enterprise FinOps 與 cloud governance。當組織需要跨 AWS、Azure、Google Cloud、Kubernetes、shared services 與成本中心建立 showback、chargeback、policy 與 optimization workflow，CloudHealth 類平台可以提供集中式成本管理與治理視角。&lt;/p>
&lt;p>這個定位讓 CloudHealth 接到三個主章。它從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 接收 cost curve 與 over-provision waste，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性&lt;/a> 接收成本 dashboard 需求，從 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因&lt;/a> 接收 owner、tag 與 attribution 規則。&lt;/p>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>多雲成本治理是 CloudHealth 的主要入口。大型企業常有不同 cloud provider、不同採購合約、不同 account 結構與不同團隊成熟度；CloudHealth 可以把成本、資產、policy 與權限治理收斂到 FinOps 工作流程。&lt;/p></description><content:encoded><![CDATA[<p>CloudHealth 的核心責任是把大型組織的 cloud spend、governance、policy、allocation 與 optimization workflow 放進同一個 FinOps 管理平面。它適合 account、team、business unit、provider 與採購流程複雜的組織，重點在讓成本治理、合規要求與工程 owner 能共用同一套成本事實。2018 年被 VMware 收購、2023 年隨 VMware 進入 Broadcom 旗下；現屬 Broadcom 的 enterprise FinOps 旗艦產品。</p>
<h2 id="服務定位">服務定位</h2>
<p>CloudHealth 跟 AWS Cost Explorer / Azure Cost Management 那種單雲原生工具的差異在 <em>跨雲一致 schema + enterprise FinOps operating model</em>、單雲帳單細節反而是原生工具更深。Cost Explorer 在 AWS-only 場景的 granularity 更深、但跨 Azure / GCP 帳單對齊、成本中心 chargeback、policy 治理就需要 CloudHealth 這類 multi-cloud platform。</p>
<p>跟 Vantage 比、CloudHealth 走 <em>enterprise governance-first</em>、Vantage 走 <em>engineering-friendly dashboard-first</em>。Vantage 對小到中型 cloud-native 團隊更快上手、但 chargeback 流程、policy violation queue、approval workflow 都不是它的主場。跟 Apptio Cloudability（IBM 收購）比、兩者定位最接近、都吃 large enterprise FinOps 市場；CloudHealth 的差異是 VMware / Broadcom ecosystem 整合（vCenter / Tanzu / on-prem hybrid），Cloudability 強在 TBM（Technology Business Management）財務分攤模型成熟度。</p>
<p>關鍵張力：<em>Broadcom 收購後的 product roadmap 不確定性</em> ↔ <em>enterprise FinOps ecosystem 深度</em>。Broadcom 對 VMware portfolio 的價格調整、partner 縮編、support tier 變動 2024-2025 持續發生；客戶要評估 <em>退場成本（chargeback rule + tag taxonomy 量大）vs 短期 license 漲幅</em>、不是只看當下功能。</p>
<h2 id="定位">定位</h2>
<p>CloudHealth 適合 enterprise FinOps 與 cloud governance。當組織需要跨 AWS、Azure、Google Cloud、Kubernetes、shared services 與成本中心建立 showback、chargeback、policy 與 optimization workflow，CloudHealth 類平台可以提供集中式成本管理與治理視角。</p>
<p>這個定位讓 CloudHealth 接到三個主章。它從 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 接收 cost curve 與 over-provision waste，從 <a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a> 接收成本 dashboard 需求，從 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a> 接收 owner、tag 與 attribution 規則。</p>
<h2 id="適用場景">適用場景</h2>
<p>多雲成本治理是 CloudHealth 的主要入口。大型企業常有不同 cloud provider、不同採購合約、不同 account 結構與不同團隊成熟度；CloudHealth 可以把成本、資產、policy 與權限治理收斂到 FinOps 工作流程。</p>
<p>Showback / chargeback 適合用 CloudHealth 建立財務語言。成本中心、部門、產品線、環境與專案需要穩定分攤規則，才能讓工程決策接到預算管理、採購承諾與年度規劃。</p>
<p>Optimization workflow 適合用 CloudHealth 管理組織節奏。Rightsizing、reserved capacity、idle resource、tag compliance 與 policy violation 都需要 owner、例外、核准、驗證與追蹤，enterprise 平台的價值在於流程一致。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>CloudHealth 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>組織治理</td>
          <td>支援多 account、多團隊、成本中心與 policy</td>
          <td>FinOps operating model、owner taxonomy</td>
      </tr>
      <tr>
          <td>成本分攤</td>
          <td>支援 showback / chargeback 與 shared cost rule</td>
          <td>tag hygiene、成本中心對照表</td>
      </tr>
      <tr>
          <td>最佳化流程</td>
          <td>支援 rightsizing、commitment 與 policy action</td>
          <td>工程驗證、變更排程、saving confirmation</td>
      </tr>
      <tr>
          <td>Enterprise 整合</td>
          <td>適合採購、財務、平台與工程共同使用</td>
          <td>權限模型、報表治理、例外處理</td>
      </tr>
  </tbody>
</table>
<p>組織治理價值來自一致流程。單一工程團隊可以靠雲端原生工具追成本；大型組織需要 policy、role、approval、exception 與 audit trail 才能讓成本治理長期運作。</p>
<p>成本分攤價值來自可對帳。Showback / chargeback 要能讓財務、平台與服務 owner 對同一筆費用得到相同解釋，shared platform cost、discount、support fee 與 commitment benefit 都要有分攤規則。</p>
<p>最佳化流程價值來自閉環管理。Rightsizing recommendation 只有在 owner 接手、服務驗證、變更落地與 saving confirmation 完成後，才會變成實際成本改善。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 CloudHealth deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Multi-cloud connector 完整性</strong>：AWS（CUR / billing role）、Azure（EA / MCA billing role）、GCP（BigQuery billing export）、Kubernetes（kube-state-metrics + Prometheus）連接器是否都接通、是否有 daily ingestion lag、是否漏 account / subscription</li>
<li><strong>FinOps team workflow 落地</strong>：policy queue、recommendation queue、approval flow 是否有實際 owner（不只是 dashboard 看一看）、weekly / monthly FinOps cadence 是否進到工程 sprint 跟財務 close cycle</li>
<li><strong>Chargeback 規則可對帳</strong>：business unit / cost center / application / environment 的分攤公式是否文件化、shared service（platform team / CI runner / observability stack）的 split rule 是否被各 BU 接受、月底財務 close 對得起來</li>
<li><strong>Reserved Instance / Savings Plan 管理</strong>：commitment coverage（已 commit 比例）、utilization（已用比例）、expiration alert、跨 account 的 commitment sharing 是否有 owner 主動經營、不是買完就放著</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 邊界的待補項目。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>CloudHealth</th>
          <th>Vantage</th>
          <th>AWS Cost Explorer</th>
          <th>Apptio Cloudability</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Multi-cloud</td>
          <td>強 — AWS / Azure / GCP / K8s</td>
          <td>強 — 加 Snowflake / Datadog 整合</td>
          <td>弱 — AWS-only</td>
          <td>強 — 三大雲 + on-prem</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>陡 — enterprise model 複雜</td>
          <td>緩 — engineer 友善 dashboard</td>
          <td>緩 — AWS console 內建</td>
          <td>陡 — TBM 模型門檻高</td>
      </tr>
      <tr>
          <td>Chargeback</td>
          <td>強 — policy + approval flow 完整</td>
          <td>中 — report-driven、流程靠外掛</td>
          <td>弱 — 報表為主、無 workflow</td>
          <td>強 — TBM 財務分攤是主場</td>
      </tr>
      <tr>
          <td>部署模型</td>
          <td>SaaS only</td>
          <td>SaaS only</td>
          <td>AWS console 內建</td>
          <td>SaaS only</td>
      </tr>
      <tr>
          <td>適合規模</td>
          <td>Enterprise（多 BU + 多雲）</td>
          <td>Startup ~ Mid（cloud-native）</td>
          <td>AWS single-account ~ Org</td>
          <td>Enterprise（重財務治理）</td>
      </tr>
      <tr>
          <td>計費模型</td>
          <td>% of cloud spend + minimum</td>
          <td>Per-cloud-account tier</td>
          <td>Free（AWS 內建）</td>
          <td>% of cloud spend + minimum</td>
      </tr>
      <tr>
          <td>Roadmap 風險</td>
          <td>Broadcom 收購後不確定</td>
          <td>獨立公司、roadmap 穩定</td>
          <td>AWS 自家、roadmap 跟雲同步</td>
          <td>IBM 收購後整合中</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>高 — chargeback rule + tag 量大</td>
          <td>低 — report 可重建</td>
          <td>無 — AWS-native 切換無痛</td>
          <td>高 — TBM 模型重 migrate</td>
      </tr>
  </tbody>
</table>
<p>選 CloudHealth 的核心訴求：<em>enterprise scale + 多雲 + 已有 VMware / Broadcom ecosystem</em>、且能投入 FinOps team 維護 chargeback rule、policy queue、commitment management lifecycle。中小型 cloud-native 走 Vantage 更快；AWS-only 直接用 Cost Explorer + Cost Anomaly Detection；重財務 TBM 整合走 Apptio Cloudability。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>CloudHealth 和 Vantage 的主要差異是治理深度。Vantage 偏工程友善報表與 Kubernetes cost visibility；CloudHealth 偏 enterprise FinOps operating model、policy 與大組織分攤流程。</p>
<p>CloudHealth 和 Akamas 的主要差異是最佳化方式。CloudHealth 偏成本治理與推薦流程；Akamas 偏把 SLO 約束與 configuration tuning 放進 optimization engine。</p>
<p>CloudHealth 和 AWS Cost Explorer 的主要差異是多雲與流程。Cost Explorer 適合 AWS-native 成本分析；CloudHealth 適合跨 provider、跨成本中心與跨團隊治理。</p>
<h2 id="操作成本">操作成本</h2>
<p>CloudHealth 的主要成本是組織模型維護。Business unit、cost center、application、environment、owner、account 與 tag policy 需要持續治理，平台才能提供穩定報表。</p>
<p>流程成本會高於單純報表工具。Recommendation 需要進入 approval、exception、change management、validation 與 financial close process；這些流程讓工具適合大型組織，也要求更高維運紀律。</p>
<p>資料品質成本會集中在標籤與 shared cost。未標記資源、跨團隊 shared service、commitment benefit 分攤與 marketplace charge 都會影響成本歸屬信任度。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Reserved Instance 與 Savings Plan management</strong>：CloudHealth 把 commitment 視為 portfolio、不是單筆採購。Coverage（已 commit 比例）、utilization（已用比例）、break-even（攤平時間）三個指標要持續追、跟業務 roadmap 對齊；新服務上線前先 model 預期用量、commit 太多反而 lock-in 浪費、太少又付 on-demand 溢價。跨 account / linked account 的 commitment sharing 要明確 owner、不然 platform team 買的 RI 被 product team 吃掉、財務分攤回不去。</p>
<p><strong>Chargeback / showback 流程</strong>：showback 是 <em>讓 BU 看到自己花多少</em>、chargeback 是 <em>讓 BU 帳本上真的扣這筆</em>。chargeback 需要財務簽核、需要每月 close cycle、需要 dispute 機制；CloudHealth 的 chargeback rule 改動要走 approval、不能 admin 自己改完就上線、會直接影響 BU 月結。</p>
<p><strong>Multi-cloud asset inventory</strong>：CloudHealth 不只是帳單工具、也作 asset inventory — EC2 / RDS / VM / GKE node / Azure SQL 等資源的 owner、tag、environment、policy state 在同一視角。這個能力是 enterprise CMDB integration 的入口、也能反向支援 <a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">7 security posture</a> 的 untagged / unauthorized resource 偵測。</p>
<p><strong>跟 Datadog / SIEM integration</strong>：CloudHealth 的 cost data 可以 export 到 <a href="/blog/backend/04-observability/vendors/datadog/" data-link-title="Datadog" data-link-desc="All-in-one SaaS 觀測平台、APM / Logs / Metrics / RUM / Security">Datadog</a> 作 SRE cost-aware alert（service 突然花費暴衝 → 通常是 retry storm / runaway job），也可送 SIEM 作 untagged resource / cross-account spend anomaly 偵測。整合的價值不是把 CloudHealth 當另一個 observability tool、而是讓 cost signal 進到工程值班的視野。</p>
<p><strong>Broadcom 收購後 product roadmap 變動風險</strong>：2023 Broadcom 完成 VMware 收購後、CloudHealth 經歷 license model 調整、partner program 變動、support tier 重整。對既有大客戶來說 license 漲幅、SLA 條款、roadmap 透明度都進入再評估期；新客戶選型時 <em>退場成本評估</em> 要先做、不能假設 platform 五年不變。Broadcom 對 enterprise 客戶仍會維持產品線、但中小客戶可能感受到 support 縮減。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Multi-cloud tag 不一致</strong>：AWS 用 <code>Environment=prod</code>、Azure 用 <code>env=production</code>、GCP 用 <code>env-tier=prod</code> — CloudHealth 報表看起來三套不同 — 統一 tag taxonomy（cost center / application / environment / owner）寫進 cloud governance policy、用 cloud-native enforcement（AWS Tag Policy / Azure Policy / GCP Org Policy）擋未標記資源</li>
<li><strong>Chargeback 對不上帳</strong>：BU 看到的金額 ≠ 財務 close 的金額 — shared service split rule 沒被簽核、commitment benefit attribution 跑掉、marketplace charge 沒分攤 — 走 monthly close reconciliation、把 rule 鎖定後才開 dispute window</li>
<li><strong>Reserved Instance 浪費</strong>：commit 買了沒用滿（utilization &lt; 80%）— 跨 account share 沒開、或業務 roadmap 改了沒同步 commitment team — 開 cross-account RI sharing、commitment review 進 monthly FinOps cadence</li>
<li><strong>新雲帳號接不進來</strong>：connector 一直 ingestion failure — IAM role / EA permission / BigQuery export 沒設好、或 organization 結構改了 CloudHealth 沒同步 — 走 onboarding checklist、新 account 自動化納管</li>
<li><strong>Recommendation 一直沒人 action</strong>：rightsizing queue 累積幾百筆沒處理 — 沒有 owner、或 recommendation 沒對應到實際 service team — 用 tag 反查 owner、把 recommendation 進 sprint backlog 而非 FinOps 自己追</li>
<li><strong>Broadcom 收購後 support / price 變動</strong>：renewal 漲幅突然 30-50%、support tier 被降級 — 早一年開始評估替代方案（Vantage / Apptio / 雲原生組合）、把 chargeback rule 跟 tag taxonomy 抽象到不綁 vendor 的格式</li>
</ul>
<h2 id="evidence-package">Evidence Package</h2>
<p>CloudHealth 結果應回寫到 FinOps governance evidence package。最小欄位包括 business unit、cost center、application、provider、account、policy、recommendation、expected saving、approval state、implementation state、verified saving 與 exception。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>CloudHealth 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>cost report、policy report、recommendation queue</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>billing period、review cycle、saving validation window</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>CloudHealth report、cloud billing query、policy detail</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>tag compliance、account coverage、allocation rule</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>owner mapping、approval status、verified saving</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>shared service rule、manual exception、provider delay</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是支援治理審查。CloudHealth report 要能回答「這筆成本屬於誰、哪條 policy 觸發、誰核准例外、變更是否真的帶來 savings」。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>CloudHealth 目前適合作為 enterprise FinOps 與多雲治理案例的工具承接點。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 的 7 個受監管市場跨地區治理與成本中心分攤需求、<a href="/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/" data-link-title="9.C33 Maersk &#43; Bosch：傳統產業在 Azure AKS 上的微服務治理" data-link-desc="全球海運 Maersk 跟 Bosch 智慧建築把 AKS 當微服務治理基礎、釋放工程資源做業務功能">9.C33 Maersk + Bosch on Azure AKS</a> 的傳統產業多 BU 治理一致性、<a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair hybrid burst</a> 的 on-prem + GCP 雙來源帳單合併、以及 <a href="/blog/backend/09-performance-capacity/cases/snap-gcp-keydb-cross-cloud/" data-link-title="9.C35 Snap：GCP &#43; KeyDB 在 multi-cloud 架構下的低延遲快取" data-link-desc="Snap 用 GCP 上的 KeyDB cluster 減少跨 cloud cache 延遲、用 TPU 訓練廣告推薦模型">9.C35 Snap multi-cloud</a> 的 GCP + AWS 跨雲成本對照。</p>
<p>這些案例的重點是組織能力。CloudHealth 頁引用案例時，要把案例拆成 governance model、owner taxonomy、policy action、engineering validation 與 financial reporting — 例如 Standard Chartered 的 7 市場分割要回到 per-market policy + 合規 tag、不是單一全球 report、而非停在雲端帳單下降。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a></li>
<li>官方：<a href="https://news.broadcom.com/apj/releases/broadcom-announces-new-cloudhealth-user-experience-for-greater-cloud-spend-management-across-enterprise-teams">Broadcom CloudHealth announcement</a></li>
</ul>
]]></content:encoded></item><item><title>9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/</guid><description>&lt;p>這個案例的核心責任是說明「hybrid cloud burst」模式 — 平日跑自家 data center、峰值事件靠雲端補容量。這跟全部上雲（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft&lt;/a>）或全部自管的兩種極端都不同、是大企業常見的折衷路徑。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Wayfair 在 GCP 的關鍵敘述（引自 &lt;a href="https://cloud.google.com/customers/wayfair">Wayfair Case Study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>商品數量&lt;/td>
 &lt;td>22 M+ 個 SKU&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>供應商數量&lt;/td>
 &lt;td>16,000+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>員工數&lt;/td>
 &lt;td>17,000&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>北美 + 歐洲&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>峰值事件&lt;/td>
 &lt;td>Way Day（年度大促）、Black Friday、Cyber Monday&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>COVID Q2 2020 業績&lt;/td>
 &lt;td>美國淨營收成長 +82.5%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>架構模式&lt;/td>
 &lt;td>Hybrid（on-prem + GCP burst）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：BigQuery（資料倉儲）、Cloud Dataproc（資料處理）、Cloud Pub/Sub（資料注入）、Looker（dashboard）、Cloud DLP（合規）、C2 processors（高性能 compute）。&lt;/p>
&lt;p>關鍵敘述：「Our automation systems signal the cloud to scale on demand」「We were able to reduce and eventually eliminate the need for change freezes leading up to big events」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Wayfair 揭露三個 hybrid cloud burst 模式的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Hybrid burst 是「容量規劃成本平衡」的折衷&lt;/strong>：自家 data center 平日跑得便宜、峰值事件不夠用；全部上雲峰值好辦但平日成本高。Hybrid 模式讓 baseline 用便宜的、峰值用彈性的、總成本曲線最平。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的長期 TCO 規劃。&lt;/li>
&lt;li>&lt;strong>「Change freeze 不再需要」是 burst 模式的真正價值&lt;/strong>：傳統零售 IT 為了 Black Friday 通常 2-3 個月前就 freeze code change、確保穩定。Wayfair 在 GCP burst 上線後、能在峰值前繼續正常 release — 因為新功能可以單獨 deploy 到 GCP、不影響 on-prem 主系統。對應 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate&lt;/a> 的非凍結式變更管理。&lt;/li>
&lt;li>&lt;strong>資料平面（BigQuery / Dataproc）是 hybrid 的主場、交易平面仍在 on-prem&lt;/strong>：Wayfair 把「分析、報表、推薦模型」放 GCP、「核心交易、訂單處理、庫存」仍在自家。這個切分是 hybrid 的常見做法 — 計算密集的工作上雲、業務核心保留自管。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的核心 OLTP 跟 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組&lt;/a> 的分析資料層分離。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p>
&lt;ul>
&lt;li>Wayfair 案例 &lt;em>沒有&lt;/em> 提具體 TPS、latency、capacity scale 數字 — 行銷敘述居多、工程細節較少。讀此類案例要對 &lt;em>策略&lt;/em> 做學習、不要套用具體數字。&lt;/li>
&lt;li>「82.5% 美國淨營收成長」是 &lt;em>業績&lt;/em>、不是 &lt;em>系統指標&lt;/em>。系統能撐業績、但兩者不是同一件事。&lt;/li>
&lt;/ul>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「hybrid cloud burst」模式 — 平日跑自家 data center、峰值事件靠雲端補容量。這跟全部上雲（<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>）或全部自管的兩種極端都不同、是大企業常見的折衷路徑。</p>
<h2 id="觀察">觀察</h2>
<p>Wayfair 在 GCP 的關鍵敘述（引自 <a href="https://cloud.google.com/customers/wayfair">Wayfair Case Study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>商品數量</td>
          <td>22 M+ 個 SKU</td>
      </tr>
      <tr>
          <td>供應商數量</td>
          <td>16,000+</td>
      </tr>
      <tr>
          <td>員工數</td>
          <td>17,000</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>北美 + 歐洲</td>
      </tr>
      <tr>
          <td>峰值事件</td>
          <td>Way Day（年度大促）、Black Friday、Cyber Monday</td>
      </tr>
      <tr>
          <td>COVID Q2 2020 業績</td>
          <td>美國淨營收成長 +82.5%</td>
      </tr>
      <tr>
          <td>架構模式</td>
          <td>Hybrid（on-prem + GCP burst）</td>
      </tr>
  </tbody>
</table>
<p>服務組合：BigQuery（資料倉儲）、Cloud Dataproc（資料處理）、Cloud Pub/Sub（資料注入）、Looker（dashboard）、Cloud DLP（合規）、C2 processors（高性能 compute）。</p>
<p>關鍵敘述：「Our automation systems signal the cloud to scale on demand」「We were able to reduce and eventually eliminate the need for change freezes leading up to big events」。</p>
<h2 id="判讀">判讀</h2>
<p>Wayfair 揭露三個 hybrid cloud burst 模式的工程重點。</p>
<ol>
<li><strong>Hybrid burst 是「容量規劃成本平衡」的折衷</strong>：自家 data center 平日跑得便宜、峰值事件不夠用；全部上雲峰值好辦但平日成本高。Hybrid 模式讓 baseline 用便宜的、峰值用彈性的、總成本曲線最平。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的長期 TCO 規劃。</li>
<li><strong>「Change freeze 不再需要」是 burst 模式的真正價值</strong>：傳統零售 IT 為了 Black Friday 通常 2-3 個月前就 freeze code change、確保穩定。Wayfair 在 GCP burst 上線後、能在峰值前繼續正常 release — 因為新功能可以單獨 deploy 到 GCP、不影響 on-prem 主系統。對應 <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate</a> 的非凍結式變更管理。</li>
<li><strong>資料平面（BigQuery / Dataproc）是 hybrid 的主場、交易平面仍在 on-prem</strong>：Wayfair 把「分析、報表、推薦模型」放 GCP、「核心交易、訂單處理、庫存」仍在自家。這個切分是 hybrid 的常見做法 — 計算密集的工作上雲、業務核心保留自管。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的核心 OLTP 跟 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 的分析資料層分離。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>Wayfair 案例 <em>沒有</em> 提具體 TPS、latency、capacity scale 數字 — 行銷敘述居多、工程細節較少。讀此類案例要對 <em>策略</em> 做學習、不要套用具體數字。</li>
<li>「82.5% 美國淨營收成長」是 <em>業績</em>、不是 <em>系統指標</em>。系統能撐業績、但兩者不是同一件事。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>Hybrid burst 適合「業務核心 on-prem 已穩定 + 季節性 / 事件型峰值」的企業</strong>：對於全新雲原生 startup、直接全上雲更簡單；對於有 15-20 年自建系統的大企業、hybrid 是穩妥路徑。</li>
<li><strong>資料平面先上雲、交易平面後上</strong>：BI、ML、推薦這類「計算密集 + 資料量大 + 容忍延遲」適合先上 GCP / AWS / Azure；OLTP 後續再評估。對應 <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a> 的資料層先行模式。</li>
<li><strong>automation signal + 雲端 burst 是「change freeze」的解法</strong>：監控訊號 → 自動 trigger 雲端容量 → 平滑釋放 → 不影響 on-prem 主系統的部署節奏。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a>。</li>
</ol>
<p>跨平台等效：AWS Outposts + AWS Direct Connect、Azure Arc + ExpressRoute、Equinix + 各雲商 PrivateLink 都是 hybrid burst 的基礎設施。差異是各家 hybrid 策略成熟度。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 hybrid cloud burst → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a></li>
<li>想做資料平面遷移 → <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>對照全雲原生 → <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></li>
<li>想取消 change freeze → <a href="/blog/backend/06-reliability/release-gate/" data-link-title="6.8 Release Gate 與變更節奏" data-link-desc="把驗證、migration、相容性納入放行判準">06.8 release gate</a> + <a href="/blog/backend/06-reliability/feature-flag-governance/" data-link-title="6.17 Feature Flag Governance" data-link-desc="把 feature flag 從上線開關升級為有角色分類、lifecycle 管理與 debt 治理的 runtime artifact">06.17 feature flag governance</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/customers/wayfair">Wayfair Case Study (Google Cloud)</a></li>
<li><a href="https://cloud.google.com/blog/topics/customers">Way Day 2019 burst capacity</a></li>
</ul>
]]></content:encoded></item><item><title>AWS Cost Explorer</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/</guid><description>&lt;p>AWS Cost Explorer 的核心責任是提供 AWS-native 的成本、用量、forecast、reservation 與 rightsizing 分析入口。它適合 AWS-first 團隊把帳單變化拆到 account、service、region、tag、usage type 與 time range，並把成本訊號接回容量規劃與服務 owner review。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>AWS Cost Explorer 適合做 AWS 成本分析的 baseline。當團隊需要回答「哪個服務、帳號、tag 或 usage type 造成成本變化」，Cost Explorer 可以直接使用 AWS billing data 產生圖表、report、forecast 與 API 查詢。&lt;/p>
&lt;p>這個定位讓 AWS Cost Explorer 接到三個主章。它從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 接收 cost per request 與 cost curve，從 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性&lt;/a> 接收成本 dashboard 需求，從 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因&lt;/a> 接收 tag 與 ownership 規則。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage&lt;/a> 等 multi-cloud FinOps 平台比、Cost Explorer 走 &lt;em>AWS-native + free&lt;/em>：不另收費（API 查詢按 request 收 USD 0.01）、跟 Billing Console + CUR + Budgets + Anomaly Detection 同一 IAM 邊界、tag 與 Cost Category 設定直接從 billing data 拉。換來的限制是 &lt;em>只看 AWS&lt;/em>、跨雲 / Kubernetes pod-level / SaaS license 都要外接。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Cost Explorer 是否健康發揮、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Cost Explorer view 是否有 saved report&lt;/strong>：team-level saved report（依 service / linked account / tag 拆）、月度 review checklist、有沒有人定期看 trend、view 是否進 dashboard share&lt;/li>
&lt;li>&lt;strong>CUR（Cost &amp;amp; Usage Report）設定&lt;/strong>：是否啟用 CUR 2.0 / Data Exports、S3 bucket 是否打開 Athena / QuickSight 查詢、hourly granularity 是否開、resource ID 是否開（沒開的話 tag-based allocation 拆不到 instance level）&lt;/li>
&lt;li>&lt;strong>Budgets + Anomaly Detection alert routing&lt;/strong>：service-level / account-level budget threshold、Cost Anomaly Detection monitor 是否分 service / linked account 設定、alert 接到 Slack / PagerDuty / email、誰負責 triage&lt;/li>
&lt;li>&lt;strong>Tag policy + Cost Category 治理&lt;/strong>：哪些 cost allocation tag 已啟用（在 Billing Console activate 才會進 CUR）、untagged resource 比例、Cost Category rule 是否覆蓋多帳號合併、誰維護 rule lifecycle&lt;/li>
&lt;/ul>
&lt;p>四件事任一缺失就是 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 邊界的待補項目 — CUR 沒開就只能看 console aggregated view、CUR 開了沒接 Athena / QuickSight 就只能看 Console 介面、不能跟 release / capacity 資料 join。&lt;/p></description><content:encoded><![CDATA[<p>AWS Cost Explorer 的核心責任是提供 AWS-native 的成本、用量、forecast、reservation 與 rightsizing 分析入口。它適合 AWS-first 團隊把帳單變化拆到 account、service、region、tag、usage type 與 time range，並把成本訊號接回容量規劃與服務 owner review。</p>
<h2 id="定位">定位</h2>
<p>AWS Cost Explorer 適合做 AWS 成本分析的 baseline。當團隊需要回答「哪個服務、帳號、tag 或 usage type 造成成本變化」，Cost Explorer 可以直接使用 AWS billing data 產生圖表、report、forecast 與 API 查詢。</p>
<p>這個定位讓 AWS Cost Explorer 接到三個主章。它從 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 接收 cost per request 與 cost curve，從 <a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a> 接收成本 dashboard 需求，從 <a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a> 接收 tag 與 ownership 規則。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a> / <a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a> 等 multi-cloud FinOps 平台比、Cost Explorer 走 <em>AWS-native + free</em>：不另收費（API 查詢按 request 收 USD 0.01）、跟 Billing Console + CUR + Budgets + Anomaly Detection 同一 IAM 邊界、tag 與 Cost Category 設定直接從 billing data 拉。換來的限制是 <em>只看 AWS</em>、跨雲 / Kubernetes pod-level / SaaS license 都要外接。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Cost Explorer 是否健康發揮、最少看四件事：</p>
<ul>
<li><strong>Cost Explorer view 是否有 saved report</strong>：team-level saved report（依 service / linked account / tag 拆）、月度 review checklist、有沒有人定期看 trend、view 是否進 dashboard share</li>
<li><strong>CUR（Cost &amp; Usage Report）設定</strong>：是否啟用 CUR 2.0 / Data Exports、S3 bucket 是否打開 Athena / QuickSight 查詢、hourly granularity 是否開、resource ID 是否開（沒開的話 tag-based allocation 拆不到 instance level）</li>
<li><strong>Budgets + Anomaly Detection alert routing</strong>：service-level / account-level budget threshold、Cost Anomaly Detection monitor 是否分 service / linked account 設定、alert 接到 Slack / PagerDuty / email、誰負責 triage</li>
<li><strong>Tag policy + Cost Category 治理</strong>：哪些 cost allocation tag 已啟用（在 Billing Console activate 才會進 CUR）、untagged resource 比例、Cost Category rule 是否覆蓋多帳號合併、誰維護 rule lifecycle</li>
</ul>
<p>四件事任一缺失就是 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 邊界的待補項目 — CUR 沒開就只能看 console aggregated view、CUR 開了沒接 Athena / QuickSight 就只能看 Console 介面、不能跟 release / capacity 資料 join。</p>
<h2 id="適用場景">適用場景</h2>
<p>AWS 月度成本 review 是 Cost Explorer 的主要入口。團隊可以依 service、linked account、region、tag、cost category、purchase option 或 usage type 檢視趨勢，找出 EC2、RDS、S3、NAT Gateway、Data Transfer 或 managed service 的成本變化。</p>
<p>Forecast 與 trend review 適合用 Cost Explorer 連到容量規劃。月中 forecast、daily cost trend、commitment utilization 與 reservation recommendation 可以讓平台團隊提前調整 autoscaling、instance family、reserved capacity 或 service 配置。</p>
<p>Programmatic cost query 適合接內部 dashboard。Cost Explorer API 可以把成本與用量資料拉到 release dashboard、capacity review、service scorecard 或 FinOps workflow，讓工程團隊在自己熟悉的介面看成本訊號。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>AWS Cost Explorer 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>AWS baseline</td>
          <td>直接使用 AWS billing data 與 Cost Management 入口</td>
          <td>Tag policy、Cost Category 設計</td>
      </tr>
      <tr>
          <td>Report</td>
          <td>支援 service、account、region、tag、usage type 分析</td>
          <td>owner mapping、business context</td>
      </tr>
      <tr>
          <td>Forecast</td>
          <td>支援成本預測與趨勢判讀</td>
          <td>release marker、event calendar</td>
      </tr>
      <tr>
          <td>API</td>
          <td>支援把 cost query 接到內部工具</td>
          <td>cache、權限控管、查詢成本治理</td>
      </tr>
  </tbody>
</table>
<p>AWS baseline 價值來自資料來源直接。Cost Explorer 使用 AWS 成本與用量資料，適合作為其他 FinOps 工具導入前的共同對帳入口。</p>
<p>Report 價值來自快速拆解。當某月成本上升，工程團隊可以先用 service、usage type、region 與 tag 找出最大變動，再決定是否需要更細的 workload-level 或 Kubernetes-level 工具。</p>
<p>API 價值來自流程整合。把 cost query 接到 release note、incident review 或 capacity planning dashboard，能讓成本變化跟部署、流量與容量決策同時被檢視。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>AWS Cost Explorer 和 Vantage 的主要差異是範圍。Cost Explorer 是 AWS-native 成本入口；Vantage 適合跨 provider、Kubernetes 成本與工程團隊自助報表。</p>
<p>AWS Cost Explorer 和 CloudHealth 的主要差異是治理層級。Cost Explorer 適合 AWS account 與 service-level 分析；CloudHealth 適合 enterprise FinOps policy、showback / chargeback 與多雲治理。</p>
<p>AWS Cost Explorer 和 Akamas 的主要差異是行動模型。Cost Explorer 提供成本與用量事實；Akamas 把成本、SLO 與配置調校接成 optimization loop。</p>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS Cost Explorer</th>
          <th>CloudHealth</th>
          <th>Vantage</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>範圍</td>
          <td>AWS-only</td>
          <td>Multi-cloud（AWS / Azure / GCP / SaaS）</td>
          <td>Multi-cloud + Kubernetes pod-level + SaaS</td>
      </tr>
      <tr>
          <td>計費</td>
          <td>Free（API 按 request 微收）</td>
          <td>Per-cloud-spend % 或 fixed tier</td>
          <td>Per-cloud-spend % 或 fixed tier</td>
      </tr>
      <tr>
          <td>治理層級</td>
          <td>Account / service / tag / usage type</td>
          <td>Enterprise FinOps policy、showback chargeback</td>
          <td>Engineering self-serve、業務團隊自助查詢</td>
      </tr>
      <tr>
          <td>Kubernetes</td>
          <td>EKS service-level、不到 pod / namespace</td>
          <td>Container module 補位</td>
          <td>內建 Kubernetes cost allocation</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>低 — 跟 AWS billing 同源、隨時可切</td>
          <td>中 — policy / showback rule 量多</td>
          <td>中 — query 跟 dashboard 量多</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-first、預算敏感、團隊小</td>
          <td>Enterprise、多雲、需要 chargeback</td>
          <td>Cloud-native、跨雲、engineering 自助 FinOps</td>
      </tr>
  </tbody>
</table>
<p>選 Cost Explorer 的核心訴求：<em>AWS-only + free + 跟 Billing / Budgets / Anomaly Detection 同 IAM 邊界</em>。當需求出現 <em>跨雲對帳</em> / <em>Kubernetes pod-level chargeback</em> / <em>SaaS license 整合</em>、就改走 CloudHealth / Vantage。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Cost Anomaly Detection</strong>：基於 ML 的 cost spike 偵測、按 service / linked account / cost category / tag 建 monitor、anomaly score 超 threshold 就 alert。實務治理：先用 <em>AWS services</em> monitor 全 service 跑 2-4 週看 baseline、再針對高變動 service（EC2 / Data Transfer / S3）建 dedicated monitor 拉緊 threshold、alert 接 SNS → Slack / PagerDuty。false positive 主要來自 release event 或 batch job、用 dimensional filter（exclude 特定 usage type / region）+ subscribe threshold 調 absolute USD + percentage 雙條件。</p>
<p><strong>Budgets + Forecast</strong>：Budget 可設 monthly / quarterly / annual、threshold 走 actual 跟 forecast 兩條 — forecast 達 80% 先 warn、actual 達 100% 才 page。Forecast 基於過去 historical pattern + linear extrapolation、新 workload / peak event 前要手動調整或關 forecast alert 避免噪音。Budget action 可以自動執行 IAM policy / SCP（例如 dev account 超預算自動 detach attach role）、但 production 別開、誤殺風險高。</p>
<p><strong>CUR (Cost &amp; Usage Report) + S3 + Athena / QuickSight</strong>：CUR 是 hourly granularity、含 resource ID、reserved instance / savings plan attribution、cost allocation tag 全欄位的 raw billing data、寫到 S3 bucket（Parquet 格式）。標準 pipeline：CUR → S3 → Glue Crawler → Athena → QuickSight dashboard、或直接拉到 BigQuery / Snowflake 跟其他維度 join（release calendar / SLO / traffic）。CUR 2.0 / Data Exports 是新版、欄位 schema 穩定、recommend 新部署直接走 CUR 2.0。</p>
<p><strong>Reserved Instance + Savings Plan recommendation</strong>：Cost Explorer 內建 RI / SP recommendation engine、看 past 7 / 30 / 60 day usage、推薦 commitment term（1yr / 3yr）+ payment option（All Upfront / Partial / No Upfront）+ break-even point。實務做法：先看 <em>Compute Savings Plan</em>（覆蓋 EC2 / Fargate / Lambda）的 baseline、再看 <em>EC2 Instance Savings Plan</em>（鎖 family + region）加深、最後看 RI 鎖 specific instance type — 三層疊加可達 60-70% saving、但 commitment 風險也疊加、要對齊 capacity planning。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Tag-based allocation 拆不到 instance / 比例異常</strong>：cost allocation tag 沒在 Billing Console activate（即使 EC2 tag 有設、billing 沒看到）— 進 Billing Console → Cost Allocation Tags → activate、要等 24hr CUR 才回填。Untagged resource 比例 &gt; 10% 直接代表 tag policy 沒落地、補 AWS Config rule 或 SCP 強制 tag。</li>
<li><strong>CUR delivery lag / 資料對不上 Console</strong>：CUR delivery 是 daily、月底結算後 finalized 還要等 1-3 天、月中看 CUR 跟 Console 有 % 差是正常 — 月中 review 用 Console、月底結算用 CUR finalized。如果 CUR 過了 48hr 還沒 delivery、檢查 S3 bucket policy 跟 CUR report status。</li>
<li><strong>Anomaly Detection false positive 多</strong>：threshold 設太嚴（absolute USD 太低 / percentage 太敏感）、或 monitor scope 太寬（包含 dev / sandbox account）— 拆 monitor 按 environment 分、production 抓 absolute USD + percentage 雙條件、dev 降低敏感度或關。</li>
<li><strong>Forecast 跳水 / 跳漲不合理</strong>：forecast 用 linear extrapolation、月中 spike / drop 會被放大、release 前 / peak event 前 forecast 不準 — 用 actual + Budget threshold 校正、別只看 forecast 決策。</li>
<li><strong>API rate limit / 查詢費用爆增</strong>：內部 dashboard 沒 cache 直接打 Cost Explorer API、每 request USD 0.01 月底結算 USD 數千 — cache 層 1hr TTL、time range 對齊 daily granularity、別 per-minute polling。</li>
<li><strong>Cost Category rule 衝突 / unallocated 過多</strong>：rule 設有 overlap 但 priority 沒設、或 rule 沒覆蓋新 service — Cost Category 走 explicit priority + default rule、新 service launch 進 owner checklist。</li>
</ul>
<h2 id="操作成本">操作成本</h2>
<p>Cost Explorer 的主要成本是資料治理。Tag、Cost Category、account structure、reservation sharing 與 owner mapping 要先整理，報表才會對工程團隊有行動意義。</p>
<p>API 整合需要查詢治理。程式化查詢要控制權限、頻率、cache、time range 與 paginated request 成本，避免內部 dashboard 造成額外查詢浪費。</p>
<p>成本解釋需要補業務 context。Cost Explorer 可以指出哪個 service 或 usage type 變貴；真正的工程判斷還要接 release、traffic、peak event、data retention、capacity policy 與 SLO 變化。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>AWS Cost Explorer 結果應回寫到 AWS cost evidence package。最小欄位包括 report name、group by、filter、time range、account、service、region、tag、usage type、forecast、recommendation、owner 與 action item。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>AWS Cost Explorer 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>Cost Explorer report、Cost Explorer API、RI / rightsizing recommendation</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>billing period、daily trend、forecast period</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>AWS Console report、API query、internal dashboard</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>tag coverage、Cost Category rule、data freshness</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>owner mapping、trend repeatability、billing delay</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>shared cost rule、multi-cloud gap、Kubernetes pod-level gap</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 AWS 成本 review 可以重跑。Cost Explorer report 要能回答「查詢條件是什麼、成本變化在哪個維度、誰負責處理、下次如何確認改善」。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>AWS Cost Explorer 目前適合作為 AWS-first 成本案例的 baseline 工具。它可回寫到 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的跨 DB 整併與 28% 成本下降驗證、<a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow modern data architecture</a> 的 80 TB 多副本 → 單一 source of truth + 80% 分析成本下降、<a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> 的 on-demand vs over-provisioned 對照、以及 <a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair GCP burst</a> 的 hybrid 模式 AWS-side baseline 釐清（即使是跨雲案例、AWS 側的 review 仍可用 Cost Explorer 跑）。</p>
<p>這些案例的重點是成本訊號到工程行動的轉換。Cost Explorer 頁引用案例時，要把 report 維度、變化原因、服務 owner、容量調整與驗證方式寫成可重跑流程 — Netflix 28% 下降要對應 Aurora cluster 數、IO-Optimized 切換時機與 reader replica 配比。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/cost-attribution/" data-link-title="4.15 Cost Attribution / Chargeback" data-link-desc="把 observability 成本拆到團隊、產品、環境維度">04 可觀測性成本歸因</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a></li>
<li>官方：<a href="https://docs.aws.amazon.com/cost-management/latest/userguide/ce-what-is.html">AWS Cost Explorer documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 +75%、成本 -28%</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/</guid><description>&lt;p>這個案例的核心責任是說明 Netflix 在 AWS 上的「資料庫統一」決策、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS 多集群&lt;/a> 形成對照。Riot 走「single-tenant per workload、246 個 cluster」、Netflix 走「跨 application 統一 Aurora、減少 DB 種類」 — 兩條路徑都是大規模平台的 &lt;em>合理&lt;/em> 選擇、但工程哲學完全不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Netflix 在 Aurora 整合的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/blogs/database/netflix-consolidates-relational-database-infrastructure-on-amazon-aurora-achieving-up-to-75-improved-performance/">Netflix consolidates relational database infrastructure on Amazon Aurora&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>效能提升&lt;/td>
 &lt;td>up to 75%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>成本下降&lt;/td>
 &lt;td>28%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>月串流時數&lt;/td>
 &lt;td>billions of hours&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>global&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>整合範圍&lt;/td>
 &lt;td>多套 relational DB → Aurora&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>微服務架構&lt;/td>
 &lt;td>全球分散式 microservices&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容器編排&lt;/td>
 &lt;td>Amazon EKS&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Netflix 整體 AWS 使用：「Netflix uses AWS to deliver billions of hours of content monthly and runs its analytics platform for optimum performance of its global service. AWS enables Netflix to quickly deploy thousands of servers and terabytes of storage within minutes.」&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Netflix Aurora 整合揭露三個大規模平台 DB 治理重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>「DB 種類太多」本身是規模化的成本&lt;/strong>：Netflix 過往用 PostgreSQL、MySQL、Oracle 等不同 RDB、每個都需要不同 DBA 知識、不同備份、不同 monitoring 流程。整合到 Aurora 不只是「換 DB」、是「降低運維 surface area」、釋放工程資源。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的人力成本工程化、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &amp;#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &amp;#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom&lt;/a> 同類訴求。&lt;/li>
&lt;li>&lt;strong>75% performance improvement 是 Aurora storage layer 的本質優勢&lt;/strong>：Aurora 把 storage 跟 compute 分離、storage 用分散式 log-based 設計、replication 在 storage 層處理、不在 compute 層 — 這讓 read replica 不會受 master 寫入壓力影響、性能曲線比傳統 RDB 平滑。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 的儲存層 vs 計算層分離。&lt;/li>
&lt;li>&lt;strong>Netflix 的 DB 工作負載大多是「微服務私有 store」&lt;/strong>：Netflix 微服務各自有自己的 Aurora cluster、不共用 — 跟 monolith 「一個大 DB 撐全部」相反。這層架構讓「DB 容量規劃」變成「每個微服務的容量規劃」、複雜度分散。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 service decomposition、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&amp;#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&amp;#43; 個微服務承載 8 倍峰值流量、跨 200&amp;#43; 城市">9.C7 Lyft 微服務&lt;/a>。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明 Netflix 在 AWS 上的「資料庫統一」決策、跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS 多集群</a> 形成對照。Riot 走「single-tenant per workload、246 個 cluster」、Netflix 走「跨 application 統一 Aurora、減少 DB 種類」 — 兩條路徑都是大規模平台的 <em>合理</em> 選擇、但工程哲學完全不同。</p>
<h2 id="觀察">觀察</h2>
<p>Netflix 在 Aurora 整合的關鍵敘述（引自 <a href="https://aws.amazon.com/blogs/database/netflix-consolidates-relational-database-infrastructure-on-amazon-aurora-achieving-up-to-75-improved-performance/">Netflix consolidates relational database infrastructure on Amazon Aurora</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>效能提升</td>
          <td>up to 75%</td>
      </tr>
      <tr>
          <td>成本下降</td>
          <td>28%</td>
      </tr>
      <tr>
          <td>月串流時數</td>
          <td>billions of hours</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>global</td>
      </tr>
      <tr>
          <td>整合範圍</td>
          <td>多套 relational DB → Aurora</td>
      </tr>
      <tr>
          <td>微服務架構</td>
          <td>全球分散式 microservices</td>
      </tr>
      <tr>
          <td>容器編排</td>
          <td>Amazon EKS</td>
      </tr>
  </tbody>
</table>
<p>Netflix 整體 AWS 使用：「Netflix uses AWS to deliver billions of hours of content monthly and runs its analytics platform for optimum performance of its global service. AWS enables Netflix to quickly deploy thousands of servers and terabytes of storage within minutes.」</p>
<h2 id="判讀">判讀</h2>
<p>Netflix Aurora 整合揭露三個大規模平台 DB 治理重點。</p>
<ol>
<li><strong>「DB 種類太多」本身是規模化的成本</strong>：Netflix 過往用 PostgreSQL、MySQL、Oracle 等不同 RDB、每個都需要不同 DBA 知識、不同備份、不同 monitoring 流程。整合到 Aurora 不只是「換 DB」、是「降低運維 surface area」、釋放工程資源。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的人力成本工程化、跟 <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a> 同類訴求。</li>
<li><strong>75% performance improvement 是 Aurora storage layer 的本質優勢</strong>：Aurora 把 storage 跟 compute 分離、storage 用分散式 log-based 設計、replication 在 storage 層處理、不在 compute 層 — 這讓 read replica 不會受 master 寫入壓力影響、性能曲線比傳統 RDB 平滑。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的儲存層 vs 計算層分離。</li>
<li><strong>Netflix 的 DB 工作負載大多是「微服務私有 store」</strong>：Netflix 微服務各自有自己的 Aurora cluster、不共用 — 跟 monolith 「一個大 DB 撐全部」相反。這層架構讓「DB 容量規劃」變成「每個微服務的容量規劃」、複雜度分散。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 service decomposition、跟 <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft 微服務</a>。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「effective 75% improvement」是 <em>跨多個 workload 的最大改善幅度</em>、不是「每個 workload 都 +75%」。實際每個 workload 改善幅度從 10% 到 75% 不等。</li>
<li>Netflix 數據層遠不止 Aurora — 還有 Cassandra（playback metadata）、EVCache（cache layer）、Iceberg（data warehouse）。Aurora 主要是「需要 ACID 的 OLTP 工作負載」、不是「all-purpose store」。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>DB 種類整合是規模化的必要工程</strong>：每多一種 DB 就多一套運維 surface。在能合理 consolidate 的時候整合、降低 ops 複雜度。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 vendor diversity 取捨。</li>
<li><strong>storage / compute 分離是 OLTP 擴容的關鍵</strong>：Aurora、Spanner、TiDB 都採類似設計、是現代 cloud DB 的共同特徵。對應 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> 的 storage layer 設計。</li>
<li><strong>微服務私有 store 比共用 DB 容量規劃簡單</strong>：每個服務各自管 DB 容量、跨服務 contention 變成 <em>network 議題</em> 而非 <em>DB lock 議題</em>。</li>
<li><strong>大規模平台必須區分「OLTP 用 Aurora」「analytics 用 data lake」「KV 用 DynamoDB」「cache 用 EVCache」</strong>：Netflix 用各種 DB、不是一招打天下。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 polyglot persistence。</li>
</ol>
<p>跨平台等效：GCP Spanner（替代 OLTP）+ Bigtable（替代 KV）+ BigQuery（替代 analytics）；Azure Cosmos DB（替代多 model）+ SQL Hyperscale + Synapse — 各雲商提供類似 stack。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他大規模平台 → <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS</a>（不同 consolidation 策略）</li>
<li>想理解 Aurora 設計 → <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora</a> + <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a></li>
<li>想做 polyglot persistence 選型 → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a></li>
<li>想做 DB consolidation 規劃 → <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a></li>
<li>想理解 +75% 的 storage / compute 解耦根因 → <a href="/blog/backend/01-database/vendors/aurora/storage-architecture/" data-link-title="Aurora Storage Architecture：quorum-based 分散式 log 與韌性即性能設計" data-link-desc="Aurora storage / compute 分離、6-way 跨 AZ replication、4-of-6 write / 3-of-6 read quorum、韌性投資自動 amortize 成 read 性能、DraftKings 6ms 寫 / &lt;1ms 讀 production reference">Aurora 儲存層架構</a></li>
<li>想規劃自管 PostgreSQL / MySQL 遷入 Aurora 的步驟 → <a href="/blog/backend/01-database/vendors/aurora/migrate-from-self-managed-pg-mysql/" data-link-title="從自管 PostgreSQL / MySQL 遷到 Aurora：operational redesign migration playbook" data-link-desc="PostgreSQL / MySQL → Aurora 的 Type C operational redesign hybrid playbook、6 規格面（Driver / Diff audit / Phase plan / Evidence / Cutover / Cleanup）、Standard Chartered 合規 lead time 模型、Netflix 非 all-purpose store 邊界">從自管 PostgreSQL/MySQL 遷入 Aurora</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/blogs/database/netflix-consolidates-relational-database-infrastructure-on-amazon-aurora-achieving-up-to-75-improved-performance/">Netflix consolidates relational database infrastructure on Amazon Aurora, achieving up to 75% improved performance</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/innovators/netflix/">Netflix on AWS</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/netflix-case-study/">Netflix Case Study</a></li>
</ul>
]]></content:encoded></item><item><title>9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/</guid><description>&lt;p>這個案例的核心責任是說明 B2B SaaS 平台的容量規劃跟 C2C 案例的本質差異。Genesys 服務的是 &lt;em>客戶服務中心&lt;/em> — 客戶停線 = 全終端使用者打不通電話、客戶會失去信任。99.999% 可用性（年停機 5 分鐘）對 B2B 客服 SaaS 是合約義務、不是行銷敘述。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Genesys Cloud 在 DynamoDB 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/genesys-dynamodb-case-study/">Genesys DynamoDB Case Study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>客戶組織&lt;/td>
 &lt;td>8,000+ 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務國家&lt;/td>
 &lt;td>100+ 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主 region&lt;/td>
 &lt;td>15 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>衛星 region&lt;/td>
 &lt;td>5 個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性&lt;/td>
 &lt;td>99.999%（截至 2024-07-31 的 12 個月）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>微服務數&lt;/td>
 &lt;td>數百個&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料層&lt;/td>
 &lt;td>DynamoDB 為預設、用其他要 justify&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵架構決策（引述 Chief Architect Rob Gevers）：「Amazon DynamoDB is our primary data layer by default, and teams have to justify the use of something else.」&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Genesys 案例揭露三個 B2B SaaS 平台容量規劃重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>B2B 可用性目標跟 C2C 不同&lt;/strong>：B2C 大型網站可能接受 99.9%（年停機 8.76 小時）、B2B SaaS 經常合約規定 99.95% 或 99.99%、客服平台類甚至要 99.999%（年停機 5 分鐘）。每多一個 9、容量規劃跟運維成本指數成長。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 SLO 等級設計。&lt;/li>
&lt;li>&lt;strong>「DynamoDB 為預設、用其他要 justify」是規模化平台的工程治理&lt;/strong>：跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix&lt;/a> 整合到 Aurora 是同樣訴求、不同實作 — Genesys 選 DynamoDB 為基準是因為「Multi-region active-active」+「自動 scaling」+「99.999% SLA」的組合最容易達成 5 個 9 目標。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 DB 預設選型。&lt;/li>
&lt;li>&lt;strong>15 主 region + 5 衛星 region = 全球客戶就近接入&lt;/strong>：客戶服務有強烈延遲敏感（agent 操作介面卡 1 秒、客服效率掉一半）、必須在客戶所在地有 region。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster&lt;/a> 的延遲驅動 region 部署同類思維。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的地理分散規劃。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p>
&lt;ul>
&lt;li>「99.999% over 12 months」是 &lt;em>截至特定時間點的歷史值&lt;/em>、不代表「未來持續達成」。可用性是滾動指標、不是恆久承諾。&lt;/li>
&lt;li>案例 &lt;em>沒有&lt;/em> 提具體 QPS / RPS、訊息量、延遲分布。讀者要對 &lt;em>策略&lt;/em> 學習、具體數字需要自己壓測。&lt;/li>
&lt;/ul>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明 B2B SaaS 平台的容量規劃跟 C2C 案例的本質差異。Genesys 服務的是 <em>客戶服務中心</em> — 客戶停線 = 全終端使用者打不通電話、客戶會失去信任。99.999% 可用性（年停機 5 分鐘）對 B2B 客服 SaaS 是合約義務、不是行銷敘述。</p>
<h2 id="觀察">觀察</h2>
<p>Genesys Cloud 在 DynamoDB 的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/genesys-dynamodb-case-study/">Genesys DynamoDB Case Study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>客戶組織</td>
          <td>8,000+ 個</td>
      </tr>
      <tr>
          <td>服務國家</td>
          <td>100+ 個</td>
      </tr>
      <tr>
          <td>主 region</td>
          <td>15 個</td>
      </tr>
      <tr>
          <td>衛星 region</td>
          <td>5 個</td>
      </tr>
      <tr>
          <td>可用性</td>
          <td>99.999%（截至 2024-07-31 的 12 個月）</td>
      </tr>
      <tr>
          <td>微服務數</td>
          <td>數百個</td>
      </tr>
      <tr>
          <td>資料層</td>
          <td>DynamoDB 為預設、用其他要 justify</td>
      </tr>
  </tbody>
</table>
<p>關鍵架構決策（引述 Chief Architect Rob Gevers）：「Amazon DynamoDB is our primary data layer by default, and teams have to justify the use of something else.」</p>
<h2 id="判讀">判讀</h2>
<p>Genesys 案例揭露三個 B2B SaaS 平台容量規劃重點。</p>
<ol>
<li><strong>B2B 可用性目標跟 C2C 不同</strong>：B2C 大型網站可能接受 99.9%（年停機 8.76 小時）、B2B SaaS 經常合約規定 99.95% 或 99.99%、客服平台類甚至要 99.999%（年停機 5 分鐘）。每多一個 9、容量規劃跟運維成本指數成長。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 SLO 等級設計。</li>
<li><strong>「DynamoDB 為預設、用其他要 justify」是規模化平台的工程治理</strong>：跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> 整合到 Aurora 是同樣訴求、不同實作 — Genesys 選 DynamoDB 為基準是因為「Multi-region active-active」+「自動 scaling」+「99.999% SLA」的組合最容易達成 5 個 9 目標。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 DB 預設選型。</li>
<li><strong>15 主 region + 5 衛星 region = 全球客戶就近接入</strong>：客戶服務有強烈延遲敏感（agent 操作介面卡 1 秒、客服效率掉一半）、必須在客戶所在地有 region。跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster</a> 的延遲驅動 region 部署同類思維。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的地理分散規劃。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「99.999% over 12 months」是 <em>截至特定時間點的歷史值</em>、不代表「未來持續達成」。可用性是滾動指標、不是恆久承諾。</li>
<li>案例 <em>沒有</em> 提具體 QPS / RPS、訊息量、延遲分布。讀者要對 <em>策略</em> 學習、具體數字需要自己壓測。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>B2B SaaS 平台優先選 multi-region active-active 資料層</strong>：DynamoDB Global Tables、Cosmos DB Multi-Region Write、Spanner multi-region 都是候選。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的全球一致性取捨。</li>
<li><strong>「預設 DB」原則簡化 onboarding</strong>：新團隊不用評估十種 DB、預設用 X、特殊需求再 justify。減少團隊認知負擔、加速產品開發。對應 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> 的 DB 整合。</li>
<li><strong>99.999% 必須有 redundancy 在每一層</strong>：DNS、load balancer、application、database、storage 都要跨 region active-active。任何一層 single-region 就破壞整體 SLO。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 跟 <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">06 可靠性驗證模組</a>。</li>
<li><strong>多 region 是成本 vs 可用性的硬取捨</strong>：15 個 region 的成本約是 1 個 region 的 15 倍 — 對 B2B SaaS 是合理投資、對 B2C 通常不划算。</li>
</ol>
<p>跨平台等效：Azure Cosmos DB Multi-Region Write、GCP Spanner multi-region、Cassandra multi-DC 都可實作對等架構。差異是 region 數量、SLA 承諾、跨 region 延遲。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計 B2B SaaS 可用性 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> + <a href="/blog/backend/06-reliability/slo-error-budget/" data-link-title="6.6 SLO 與 Error Budget 政策" data-link-desc="把可靠性目標轉成可驗證量測與凍結條件">06.6 SLO 與 Error Budget 政策</a></li>
<li>想設計多 region 資料層 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想做 DB 統一治理 → <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> + <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a></li>
<li>想規劃跨 region 容量 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a></li>
<li>想理解 DynamoDB 99.999% 背後的 partition / GSI 設計 → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a> + <a href="/blog/backend/01-database/vendors/dynamodb/gsi-lsi-design/" data-link-title="DynamoDB GSI 與 LSI 設計：access pattern 補位、projection、consistency 跟 DAX 補位" data-link-desc="GSI / LSI 是 single-table 沒覆蓋的 access pattern 補位、不是萬靈丹；本文涵蓋 projection 三型選擇、sparse index、GSI 自己會 hot partition、DAX 讀峰值補位的觸發條件（含 Capcom 是 derive vs Lemino 是 case fact 的分層）">DynamoDB GSI / LSI 設計</a></li>
<li>想對應 global tables 多 region 寫衝突 → <a href="/blog/backend/01-database/vendors/dynamodb/global-tables-conflict/" data-link-title="DynamoDB Global Tables：multi-region active-active、LWW conflict 與 cross-device sync 正向用例" data-link-desc="Global Tables 不只是 conflict 痛點、也是 cross-device sync / global read / DR failover 的正向工程方案；本文展開 B2B SaaS vs B2C 業務 driver、LWW conflict resolution、reconciliation pipeline，含 Genesys 99.999% 跨 15 region 跟 Disney&#43; 跨裝置同步的對照">DynamoDB global tables 寫衝突</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/genesys-dynamodb-case-study/">Genesys Achieves 99.999% Availability Using Amazon DynamoDB</a></li>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
</ul>
]]></content:encoded></item><item><title>9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/</guid><description>&lt;p>這個案例的核心責任是說明「ML feature store 的延遲敏感層」工程選型。即時推薦（首頁 carousel、播放後下一支）需要在 100ms 內生成、ML inference 之前的 feature lookup 通常吃 30-50ms — 把 lookup 壓到 10ms 以下、整個推薦延遲才有預算空間。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Tubi 在 ElastiCache 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/elasticache/customers/">ElastiCache Customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>工作負載&lt;/td>
 &lt;td>ML inference feature store&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>p99 延遲&lt;/td>
 &lt;td>&amp;lt; 10 ms&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移路徑&lt;/td>
 &lt;td>ScyllaDB → ElastiCache for Redis&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>業務場景&lt;/td>
 &lt;td>串流推薦（free streaming service）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Tubi 案例揭露三個 ML feature store 容量設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>feature store 是 ML inference 的 critical path&lt;/strong>：每個推薦請求都要查 N 個 feature（user_profile、item_metadata、recent_interactions、similar_users 等）、每個 feature 查詢都吃 latency budget。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的多 stage budget 分解。&lt;/li>
&lt;li>&lt;strong>ScyllaDB → ElastiCache 是「持久 KV → 純 cache」的權衡&lt;/strong>：ScyllaDB 是 Cassandra-compatible 高吞吐 KV、提供 durability；ElastiCache 是 in-memory cache、可以 cache miss。Tubi 選 cache 是判斷「feature 可以重新計算」、durability 不必、純 in-memory 更快。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 cache vs durable store 選型。&lt;/li>
&lt;li>&lt;strong>p99 才是 ML 系統的容量門檻&lt;/strong>：ML 系統的 user-perceived latency 是 &lt;em>最後完成的 inference&lt;/em>、不是平均。p50 快沒用、p99 慢用戶就看到 loading spinner。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery&lt;/a> 的 latency percentile 分析、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &amp;#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase&lt;/a> 的長尾延遲議題同類。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p>
&lt;ul>
&lt;li>「sub-10ms p99」沒指明 &lt;em>p999 / p9999&lt;/em>。p9999 通常比 p99 高一個量級、會出現在實際 user-perceived 體驗。&lt;/li>
&lt;li>ElastiCache 的 sub-10ms 是 &lt;em>cache hit 路徑&lt;/em> — cache miss 路徑會回到 ScyllaDB 或重新計算、延遲可能 100ms+。容量規劃要考慮 cache hit rate 跟 miss recovery 兩條路徑。&lt;/li>
&lt;/ul>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>ML feature store 用「兩層 cache」設計&lt;/strong>：L1 是 in-process cache（最熱的 features）、L2 是 ElastiCache / Memcached（次熱）、L3 才是持久 store（ScyllaDB / DynamoDB / S3 + Parquet）。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 cache hierarchy。&lt;/li>
&lt;li>&lt;strong>feature 可重算 → 用 cache、feature 必須持久 → 用 store&lt;/strong>：判斷依據是「重算成本」跟「資料一致性需求」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary&lt;/a>。&lt;/li>
&lt;li>&lt;strong>p99 / p999 反推單個 stage latency 上限&lt;/strong>：每個 stage（network、cache lookup、feature aggregation、model inference、response serialization）給一個 latency budget、總和等於整體 SLO。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a>、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &amp;#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase&lt;/a> 同樣的反推思維。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：AWS ElastiCache for Redis / Valkey / MemoryDB、GCP Memorystore for Redis、Azure Cache for Redis 都可實作對等架構。專為 ML feature store 設計的還有 Feast / Tecton / Hopsworks 等開源 + 商業方案、底層常用 Redis-compatible store。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「ML feature store 的延遲敏感層」工程選型。即時推薦（首頁 carousel、播放後下一支）需要在 100ms 內生成、ML inference 之前的 feature lookup 通常吃 30-50ms — 把 lookup 壓到 10ms 以下、整個推薦延遲才有預算空間。</p>
<h2 id="觀察">觀察</h2>
<p>Tubi 在 ElastiCache 的關鍵敘述（引自 <a href="https://aws.amazon.com/elasticache/customers/">ElastiCache Customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>工作負載</td>
          <td>ML inference feature store</td>
      </tr>
      <tr>
          <td>p99 延遲</td>
          <td>&lt; 10 ms</td>
      </tr>
      <tr>
          <td>遷移路徑</td>
          <td>ScyllaDB → ElastiCache for Redis</td>
      </tr>
      <tr>
          <td>業務場景</td>
          <td>串流推薦（free streaming service）</td>
      </tr>
  </tbody>
</table>
<h2 id="判讀">判讀</h2>
<p>Tubi 案例揭露三個 ML feature store 容量設計重點。</p>
<ol>
<li><strong>feature store 是 ML inference 的 critical path</strong>：每個推薦請求都要查 N 個 feature（user_profile、item_metadata、recent_interactions、similar_users 等）、每個 feature 查詢都吃 latency budget。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的多 stage budget 分解。</li>
<li><strong>ScyllaDB → ElastiCache 是「持久 KV → 純 cache」的權衡</strong>：ScyllaDB 是 Cassandra-compatible 高吞吐 KV、提供 durability；ElastiCache 是 in-memory cache、可以 cache miss。Tubi 選 cache 是判斷「feature 可以重新計算」、durability 不必、純 in-memory 更快。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 cache vs durable store 選型。</li>
<li><strong>p99 才是 ML 系統的容量門檻</strong>：ML 系統的 user-perceived latency 是 <em>最後完成的 inference</em>、不是平均。p50 快沒用、p99 慢用戶就看到 loading spinner。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a> 的 latency percentile 分析、跟 <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> 的長尾延遲議題同類。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「sub-10ms p99」沒指明 <em>p999 / p9999</em>。p9999 通常比 p99 高一個量級、會出現在實際 user-perceived 體驗。</li>
<li>ElastiCache 的 sub-10ms 是 <em>cache hit 路徑</em> — cache miss 路徑會回到 ScyllaDB 或重新計算、延遲可能 100ms+。容量規劃要考慮 cache hit rate 跟 miss recovery 兩條路徑。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>ML feature store 用「兩層 cache」設計</strong>：L1 是 in-process cache（最熱的 features）、L2 是 ElastiCache / Memcached（次熱）、L3 才是持久 store（ScyllaDB / DynamoDB / S3 + Parquet）。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 cache hierarchy。</li>
<li><strong>feature 可重算 → 用 cache、feature 必須持久 → 用 store</strong>：判斷依據是「重算成本」跟「資料一致性需求」。對應 <a href="/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary</a>。</li>
<li><strong>p99 / p999 反推單個 stage latency 上限</strong>：每個 stage（network、cache lookup、feature aggregation、model inference、response serialization）給一個 latency budget、總和等於整體 SLO。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a>、跟 <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> 同樣的反推思維。</li>
</ol>
<p>跨平台等效：AWS ElastiCache for Redis / Valkey / MemoryDB、GCP Memorystore for Redis、Azure Cache for Redis 都可實作對等架構。專為 ML feature store 設計的還有 Feast / Tecton / Hopsworks 等開源 + 商業方案、底層常用 Redis-compatible store。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 ML feature store → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a></li>
<li>想做 p99 / p999 反推 → <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.4 Saturation Discovery</a></li>
<li>對照其他 cache 案例 → <a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder ElastiCache</a>（配對引擎）</li>
<li>想理解 cache hierarchy → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/elasticache/customers/">Amazon ElastiCache Customers</a></li>
<li><a href="https://aws.amazon.com/blogs/database/build-an-ultra-low-latency-online-feature-store-for-real-time-inferencing-using-amazon-elasticache-for-redis/">Build an ultra-low latency online feature store for real-time inferencing using Amazon ElastiCache for Redis</a></li>
</ul>
]]></content:encoded></item><item><title>9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/</guid><description>&lt;p>這個案例的核心責任是說明「行動支付類 SaaS」的訊息工作負載特性。PayPay 是日本最大行動支付（pre-IPO 估值 70 億美金級）、訊息功能需要在每筆交易後即時通知（付款成功、收款、優惠券）、單一用戶每天可能收到數十條訊息、加總到平台級別就是每日上億訊息。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>PayPay 在 DynamoDB 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>每日訊息量&lt;/td>
 &lt;td>3 億訊息&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主要工作負載&lt;/td>
 &lt;td>行動支付通知 + 訊息功能&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可靠性敘述&lt;/td>
 &lt;td>「Super reliable and performed consistently」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>Amazon DynamoDB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>日本&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>PayPay 案例揭露三個行動支付訊息系統的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>支付通知是「不可丟失 + 不可延遲」雙重需求&lt;/strong>：用戶付完款 30 秒沒收到通知會懷疑系統壞了、會打客服 / 重複扣款。這層需求比 OTA 推播嚴格、必須有 durable queue + retry + 重複偵測。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> 的 idempotency 設計。&lt;/li>
&lt;li>&lt;strong>DynamoDB 在「訊息事件」這類負載特別適合&lt;/strong>：每則訊息有獨立 message_id（partition key 天然均勻）、TTL 機制可以自動清理過期訊息（避免 storage 爆炸）。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 的 partition 均勻優勢、跟 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary&lt;/a> 的 TTL 議題。&lt;/li>
&lt;li>&lt;strong>3 億 / 天 ≈ 3,500 訊息 / 秒平均&lt;/strong>：聽起來不大、但這是 &lt;em>平均&lt;/em>。月底、雙 11 類大促、新年紅包等場景、單秒峰值可能達 10x-50x。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling&lt;/a> 的峰均比評估。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「super reliable」是行銷語言、不是工程承諾。讀此類短篇案例要把行銷敘述折扣、重點看 &lt;em>服務組合&lt;/em> 與 &lt;em>規模量級&lt;/em>。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>訊息系統設計區分「通知」跟「訊息」&lt;/strong>：通知（payment received）是 transactional、不可丟失；訊息（marketing）可以丟失部分、重點是 throughput。兩者用不同 SLO、不同 storage。對應 &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> 的訊息分類。&lt;/li>
&lt;li>&lt;strong>TTL 自動清理避免 storage 成本爆炸&lt;/strong>：3 億 / 天 × 30 天 = 90 億筆記錄、不清理會撐死 storage 預算。對應 &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組&lt;/a> 的 TTL 設計。&lt;/li>
&lt;li>&lt;strong>訊息推送的下游（APNs、FCM、SMS gateway）是隱性瓶頸&lt;/strong>：DynamoDB 寫入可以撐 3K msg/sec、但 APNs 一天的 quota 是有限的。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a> 的依賴鏈分析。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：GCP Firestore + Cloud Messaging、Azure Cosmos DB + Notification Hubs 都是對等架構。差異是 vendor 整合度跟全球分發能力。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>想設計行動支付訊息 → &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a>&lt;/li>
&lt;li>對照其他 KV 高吞吐 → &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom&lt;/a>&lt;/li>
&lt;li>想做訊息系統容量規劃 → &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> + &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling&lt;/a>&lt;/li>
&lt;li>想避免訊息熱點打爆單一 partition → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &amp;#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式&lt;/a>&lt;/li>
&lt;li>想評估訊息系統的 capacity mode → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://aws.amazon.com/solutions/case-studies/paypay/">PayPay on AWS&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「行動支付類 SaaS」的訊息工作負載特性。PayPay 是日本最大行動支付（pre-IPO 估值 70 億美金級）、訊息功能需要在每筆交易後即時通知（付款成功、收款、優惠券）、單一用戶每天可能收到數十條訊息、加總到平台級別就是每日上億訊息。</p>
<h2 id="觀察">觀察</h2>
<p>PayPay 在 DynamoDB 的關鍵敘述（引自 <a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>每日訊息量</td>
          <td>3 億訊息</td>
      </tr>
      <tr>
          <td>主要工作負載</td>
          <td>行動支付通知 + 訊息功能</td>
      </tr>
      <tr>
          <td>可靠性敘述</td>
          <td>「Super reliable and performed consistently」</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>Amazon DynamoDB</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>日本</td>
      </tr>
  </tbody>
</table>
<h2 id="判讀">判讀</h2>
<p>PayPay 案例揭露三個行動支付訊息系統的工程重點。</p>
<ol>
<li><strong>支付通知是「不可丟失 + 不可延遲」雙重需求</strong>：用戶付完款 30 秒沒收到通知會懷疑系統壞了、會打客服 / 重複扣款。這層需求比 OTA 推播嚴格、必須有 durable queue + retry + 重複偵測。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 的 idempotency 設計。</li>
<li><strong>DynamoDB 在「訊息事件」這類負載特別適合</strong>：每則訊息有獨立 message_id（partition key 天然均勻）、TTL 機制可以自動清理過期訊息（避免 storage 爆炸）。對應 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 的 partition 均勻優勢、跟 <a href="/blog/backend/02-cache-redis/cache-copy-freshness-boundary/" data-link-title="2.7 Cache Copy Boundary 與 Freshness" data-link-desc="說明快取何時只是可重建副本，何時會影響交易、權限或配額正確性。">02.4 cache copy freshness boundary</a> 的 TTL 議題。</li>
<li><strong>3 億 / 天 ≈ 3,500 訊息 / 秒平均</strong>：聽起來不大、但這是 <em>平均</em>。月底、雙 11 類大促、新年紅包等場景、單秒峰值可能達 10x-50x。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a> 的峰均比評估。</li>
</ol>
<p>需要警惕：「super reliable」是行銷語言、不是工程承諾。讀此類短篇案例要把行銷敘述折扣、重點看 <em>服務組合</em> 與 <em>規模量級</em>。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>訊息系統設計區分「通知」跟「訊息」</strong>：通知（payment received）是 transactional、不可丟失；訊息（marketing）可以丟失部分、重點是 throughput。兩者用不同 SLO、不同 storage。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 的訊息分類。</li>
<li><strong>TTL 自動清理避免 storage 成本爆炸</strong>：3 億 / 天 × 30 天 = 90 億筆記錄、不清理會撐死 storage 預算。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的 TTL 設計。</li>
<li><strong>訊息推送的下游（APNs、FCM、SMS gateway）是隱性瓶頸</strong>：DynamoDB 寫入可以撐 3K msg/sec、但 APNs 一天的 quota 是有限的。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的依賴鏈分析。</li>
</ol>
<p>跨平台等效：GCP Firestore + Cloud Messaging、Azure Cosmos DB + Notification Hubs 都是對等架構。差異是 vendor 整合度跟全球分發能力。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想設計行動支付訊息 → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a></li>
<li>對照其他 KV 高吞吐 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> / <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a></li>
<li>想做訊息系統容量規劃 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.2 Workload Modeling</a></li>
<li>想避免訊息熱點打爆單一 partition → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a></li>
<li>想評估訊息系統的 capacity mode → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/paypay/">PayPay on AWS</a></li>
</ul>
]]></content:encoded></item><item><title>9.C27 Disney+：DynamoDB 撐每日數十億動作的觀看歷史</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/</guid><description>&lt;p>這個案例的核心責任是說明「串流平台 metadata 層」的工作負載 — 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&amp;#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL&lt;/a> 的「live streaming 直播容量」是同產業不同議題。Disney+ 的 metadata 層處理「播了什麼、看到哪、下次推薦什麼」、是串流平台的「control plane」、不是「data plane」。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Disney+ 在 DynamoDB 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>每日動作量&lt;/td>
 &lt;td>billions of actions daily&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主要工作負載&lt;/td>
 &lt;td>content metadata + watch list management&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>Amazon DynamoDB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>global&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>每個用戶動作（播放、暫停、跳過、加入 watchlist、評分）都是一次 DynamoDB 寫入。每次打開 app 又是多次讀（自己的 watchlist、最近播放、繼續觀看）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Disney+ 案例揭露三個串流平台 metadata 層的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>「每日數十億動作」= read + write 都要撐&lt;/strong>：跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads&lt;/a> 的 18:1 讀寫比不同、串流 metadata 通常接近 5:1 read-heavy（每動作 1 寫、每 session 5 讀）。partition key 設計通常用 user_id、天然均勻、不會 hot partition。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 schema design。&lt;/li>
&lt;li>&lt;strong>新片發布是 predictable-peak&lt;/strong>：Marvel / Star Wars / Disney 動畫 新片上線首日、metadata 流量可衝 3-5 倍 — 因為「全平台用戶同時打開該片頁面」。這比一般 Black Friday 集中、像 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&amp;#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL&lt;/a> 的集中型流量。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a> 的內容發布事件容量規劃。&lt;/li>
&lt;li>&lt;strong>watchlist + 播放進度需要跨裝置即時同步&lt;/strong>：用戶在手機看到一半、晚上回家用電視繼續、進度必須跨裝置同步。這層需求對 DynamoDB Global Tables（multi-region active-active）特別適合。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a> 的最終一致性可接受場景。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「billions of actions daily」沒指明具體數字（10 億、100 億 還是 數十億？）。讀此類短篇案例只能取「量級對標」、不能套用具體數字。&lt;/p>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>串流平台分「metadata 層」「content delivery 層」&lt;/strong>：metadata（watchlist、播放進度、推薦）用 DynamoDB / Cosmos DB；content（video file）用 CDN + S3 / object storage。兩者完全分開、互不影響。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 control plane vs data plane、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom&lt;/a> 的同類思維。&lt;/li>
&lt;li>&lt;strong>新片發布像 mini Black Friday、要 pre-scaling&lt;/strong>：發布時間已知、流量倍數可預估（根據前幾部）、可以提前 1-2 天 pre-scale DynamoDB capacity。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備&lt;/a>。&lt;/li>
&lt;li>&lt;strong>DynamoDB Global Tables 是跨裝置同步的有效方案&lt;/strong>：用戶在不同 region 登入同帳號、寫入會自動同步到其他 region。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &amp;#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys&lt;/a> 的 multi-region active-active。&lt;/li>
&lt;/ol>
&lt;p>跨平台等效：Netflix 同類 metadata 用 Cassandra + EVCache（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix&lt;/a> 提及）、HBO Max 用 Aurora、Apple TV+ 用 FoundationDB + Cassandra — 各家串流的 metadata 技術棧不同、但「分層解耦」的工程哲學一致。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「串流平台 metadata 層」的工作負載 — 跟 <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a> 的「live streaming 直播容量」是同產業不同議題。Disney+ 的 metadata 層處理「播了什麼、看到哪、下次推薦什麼」、是串流平台的「control plane」、不是「data plane」。</p>
<h2 id="觀察">觀察</h2>
<p>Disney+ 在 DynamoDB 的關鍵敘述（引自 <a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB Customers</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>每日動作量</td>
          <td>billions of actions daily</td>
      </tr>
      <tr>
          <td>主要工作負載</td>
          <td>content metadata + watch list management</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>Amazon DynamoDB</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>global</td>
      </tr>
  </tbody>
</table>
<p>每個用戶動作（播放、暫停、跳過、加入 watchlist、評分）都是一次 DynamoDB 寫入。每次打開 app 又是多次讀（自己的 watchlist、最近播放、繼續觀看）。</p>
<h2 id="判讀">判讀</h2>
<p>Disney+ 案例揭露三個串流平台 metadata 層的工程重點。</p>
<ol>
<li><strong>「每日數十億動作」= read + write 都要撐</strong>：跟 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> 的 18:1 讀寫比不同、串流 metadata 通常接近 5:1 read-heavy（每動作 1 寫、每 session 5 讀）。partition key 設計通常用 user_id、天然均勻、不會 hot partition。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema design。</li>
<li><strong>新片發布是 predictable-peak</strong>：Marvel / Star Wars / Disney 動畫 新片上線首日、metadata 流量可衝 3-5 倍 — 因為「全平台用戶同時打開該片頁面」。這比一般 Black Friday 集中、像 <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a> 的集中型流量。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 的內容發布事件容量規劃。</li>
<li><strong>watchlist + 播放進度需要跨裝置即時同步</strong>：用戶在手機看到一半、晚上回家用電視繼續、進度必須跨裝置同步。這層需求對 DynamoDB Global Tables（multi-region active-active）特別適合。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的最終一致性可接受場景。</li>
</ol>
<p>需要警惕：「billions of actions daily」沒指明具體數字（10 億、100 億 還是 數十億？）。讀此類短篇案例只能取「量級對標」、不能套用具體數字。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>串流平台分「metadata 層」「content delivery 層」</strong>：metadata（watchlist、播放進度、推薦）用 DynamoDB / Cosmos DB；content（video file）用 CDN + S3 / object storage。兩者完全分開、互不影響。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 control plane vs data plane、跟 <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a> 的同類思維。</li>
<li><strong>新片發布像 mini Black Friday、要 pre-scaling</strong>：發布時間已知、流量倍數可預估（根據前幾部）、可以提前 1-2 天 pre-scale DynamoDB capacity。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a>。</li>
<li><strong>DynamoDB Global Tables 是跨裝置同步的有效方案</strong>：用戶在不同 region 登入同帳號、寫入會自動同步到其他 region。對應 <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a> 的 multi-region active-active。</li>
</ol>
<p>跨平台等效：Netflix 同類 metadata 用 Cassandra + EVCache（<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> 提及）、HBO Max 用 Aurora、Apple TV+ 用 FoundationDB + Cassandra — 各家串流的 metadata 技術棧不同、但「分層解耦」的工程哲學一致。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他串流案例 → <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a>（live）/ <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 NTT DOCOMO Lemino</a></li>
<li>想理解 metadata 層 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a></li>
<li>想做內容發布 pre-scaling → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> + <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day</a></li>
<li>想做跨裝置同步設計 → <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys multi-region</a></li>
<li>想拆 metadata 的 single-table 與 GSI 設計 → <a href="/blog/backend/01-database/vendors/dynamodb/single-table-design-pattern/" data-link-title="DynamoDB Single-Table Design：從適用度前置判讀到 access pattern 反推 PK/SK" data-link-desc="DynamoDB single-table 設計不是「資料表越少越好」，而是 access pattern 反推 PK/SK 跟 GSI；本文先做 DynamoDB 適用度 4 軸前置判讀（PK 天然均勻 / control plane vs data plane / consistency / access pattern 穩定），再展開設計流程、failure modes 與 durable queue 正向用例">DynamoDB single-table design</a> + <a href="/blog/backend/01-database/vendors/dynamodb/gsi-lsi-design/" data-link-title="DynamoDB GSI 與 LSI 設計：access pattern 補位、projection、consistency 跟 DAX 補位" data-link-desc="GSI / LSI 是 single-table 沒覆蓋的 access pattern 補位、不是萬靈丹；本文涵蓋 projection 三型選擇、sparse index、GSI 自己會 hot partition、DAX 讀峰值補位的觸發條件（含 Capcom 是 derive vs Lemino 是 case fact 的分層）">DynamoDB GSI / LSI 設計</a></li>
<li>想做跨 region metadata 一致性 → <a href="/blog/backend/01-database/vendors/dynamodb/global-tables-conflict/" data-link-title="DynamoDB Global Tables：multi-region active-active、LWW conflict 與 cross-device sync 正向用例" data-link-desc="Global Tables 不只是 conflict 痛點、也是 cross-device sync / global read / DR failover 的正向工程方案；本文展開 B2B SaaS vs B2C 業務 driver、LWW conflict resolution、reconciliation pipeline，含 Genesys 99.999% 跨 15 region 跟 Disney&#43; 跨裝置同步的對照">DynamoDB global tables 寫衝突</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a></li>
<li><a href="https://aws.amazon.com/blogs/database/amazon-dynamodb-use-cases-for-media-and-entertainment-customers/">Amazon DynamoDB use cases for media and entertainment customers</a></li>
</ul>
]]></content:encoded></item><item><title>9.C28 FanDuel：體育直播 + 投注的雙重峰值</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/</guid><description>&lt;p>這個案例的核心責任是說明「雙重峰值對齊」的工程取捨。FanDuel 同時運營體育直播（live streaming）跟體育投注（betting）、兩個工作負載在 &lt;em>同一場 NFL Super Bowl&lt;/em> 同時達到峰值、但 SLO 完全不同 — 直播容忍 30 秒延遲、投注必須毫秒內成交。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>FanDuel 在 AWS 的關鍵敘述（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/fanduel-case-study/">FanDuel Case Study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>月活客戶&lt;/td>
 &lt;td>3.5 M+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>美國 20+ 州 + 加拿大&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>峰值擴容倍數&lt;/td>
 &lt;td>5-10x（NFL Super Bowl 等大型賽事）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>AWS Local Zones + Wavelength + Outposts&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>峰值類型&lt;/td>
 &lt;td>直播 + 投注雙峰&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵敘述：「seamlessly scale capacity 5–10 times as required for large sporting events, such as the NFL Super Bowl」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>FanDuel 案例揭露三個雙重峰值對齊的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>直播跟投注是兩種完全不同 SLO&lt;/strong>：直播容忍秒級延遲（用 CDN + ABR 串流）、投注必須毫秒級成交（Super Bowl 進球瞬間、賠率變動、用戶投注必須在賠率變化前完成）。兩個服務必須各自獨立擴容、各自獨立 SLO。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的多 SLO 對齊。&lt;/li>
&lt;li>&lt;strong>AWS Local Zones / Wavelength / Outposts 是地理 + 監管雙重需求&lt;/strong>：美國博彩受各州監管、資料必須留在州內 → 用 Local Zones 在每個州就近部署；4G/5G 用戶投注延遲敏感 → 用 Wavelength 在電信商機房內運算；on-prem 需求 → 用 Outposts。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered&lt;/a> 的受監管雙重需求、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games&lt;/a> 的延遲反推 region。&lt;/li>
&lt;li>&lt;strong>5-10x 是「同類事件中的最高倍率」&lt;/strong>：Super Bowl 是 NFL 賽季最大事件、不是常態。平日 baseline → 季後賽 2-3x → 季冠軍賽 4-5x → Super Bowl 5-10x。容量規劃要按事件級別分段、不是一律 10x。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的事件型容量分級。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p>
&lt;ul>
&lt;li>AWS 案例 &lt;em>沒有&lt;/em> 提具體 betting transaction TPS、concurrent streams、延遲分布。讀者要對 &lt;em>策略&lt;/em> 學習、不要套用具體數字。&lt;/li>
&lt;li>「5-10x」是 &lt;em>峰值倍數&lt;/em>、不是 &lt;em>peak 持續時間&lt;/em>。Super Bowl 的關鍵 30 分鐘可能 8-10x、其他 3 小時可能 3-5x。&lt;/li>
&lt;/ul>
&lt;h2 id="策略">策略&lt;/h2>
&lt;p>可重用的工程做法：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「雙重峰值對齊」的工程取捨。FanDuel 同時運營體育直播（live streaming）跟體育投注（betting）、兩個工作負載在 <em>同一場 NFL Super Bowl</em> 同時達到峰值、但 SLO 完全不同 — 直播容忍 30 秒延遲、投注必須毫秒內成交。</p>
<h2 id="觀察">觀察</h2>
<p>FanDuel 在 AWS 的關鍵敘述（引自 <a href="https://aws.amazon.com/solutions/case-studies/fanduel-case-study/">FanDuel Case Study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>月活客戶</td>
          <td>3.5 M+</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>美國 20+ 州 + 加拿大</td>
      </tr>
      <tr>
          <td>峰值擴容倍數</td>
          <td>5-10x（NFL Super Bowl 等大型賽事）</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>AWS Local Zones + Wavelength + Outposts</td>
      </tr>
      <tr>
          <td>峰值類型</td>
          <td>直播 + 投注雙峰</td>
      </tr>
  </tbody>
</table>
<p>關鍵敘述：「seamlessly scale capacity 5–10 times as required for large sporting events, such as the NFL Super Bowl」。</p>
<h2 id="判讀">判讀</h2>
<p>FanDuel 案例揭露三個雙重峰值對齊的工程重點。</p>
<ol>
<li><strong>直播跟投注是兩種完全不同 SLO</strong>：直播容忍秒級延遲（用 CDN + ABR 串流）、投注必須毫秒級成交（Super Bowl 進球瞬間、賠率變動、用戶投注必須在賠率變化前完成）。兩個服務必須各自獨立擴容、各自獨立 SLO。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的多 SLO 對齊。</li>
<li><strong>AWS Local Zones / Wavelength / Outposts 是地理 + 監管雙重需求</strong>：美國博彩受各州監管、資料必須留在州內 → 用 Local Zones 在每個州就近部署；4G/5G 用戶投注延遲敏感 → 用 Wavelength 在電信商機房內運算；on-prem 需求 → 用 Outposts。對應 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 的受監管雙重需求、跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a> 的延遲反推 region。</li>
<li><strong>5-10x 是「同類事件中的最高倍率」</strong>：Super Bowl 是 NFL 賽季最大事件、不是常態。平日 baseline → 季後賽 2-3x → 季冠軍賽 4-5x → Super Bowl 5-10x。容量規劃要按事件級別分段、不是一律 10x。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的事件型容量分級。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>AWS 案例 <em>沒有</em> 提具體 betting transaction TPS、concurrent streams、延遲分布。讀者要對 <em>策略</em> 學習、不要套用具體數字。</li>
<li>「5-10x」是 <em>峰值倍數</em>、不是 <em>peak 持續時間</em>。Super Bowl 的關鍵 30 分鐘可能 8-10x、其他 3 小時可能 3-5x。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>不同 SLO 的工作負載分開部署、不要混在同一 service</strong>：betting 跟 streaming 在 FanDuel 必然是兩個獨立微服務、各自有 dedicated infrastructure。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 service decomposition、跟 <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft</a> 同思維。</li>
<li><strong>多層 edge（Local Zone / Wavelength / Outposts）服務不同延遲需求</strong>：Local Zone 服務「州內合規」需求、Wavelength 服務「電信網內超低延遲」、Outposts 服務「on-prem 監管」需求。三者組合對應跨州博彩業務。</li>
<li><strong>事件型容量規劃分級</strong>：建立 event tier 體系（regular game / playoff / championship / super bowl），每 tier 對應不同 pre-scale 倍數。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 的容量分級。</li>
</ol>
<p>跨平台等效：Azure 提供類似 stack（Stack Edge + Edge Zones + Azure for Operators）、GCP 有 Network Edge + Distributed Cloud。差異是各家 edge 覆蓋深度跟電信商合作。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他事件型峰值 → <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a>（賽事高潮 AI 預測）/ <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a></li>
<li>想設計多 SLO 對齊 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a></li>
<li>想做受監管多地區部署 → <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> + <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a></li>
<li>想做 edge / Local Zone 規劃 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a></li>
<li>想理解雙峰下 Aurora storage / replica scaling → <a href="/blog/backend/01-database/vendors/aurora/storage-architecture/" data-link-title="Aurora Storage Architecture：quorum-based 分散式 log 與韌性即性能設計" data-link-desc="Aurora storage / compute 分離、6-way 跨 AZ replication、4-of-6 write / 3-of-6 read quorum、韌性投資自動 amortize 成 read 性能、DraftKings 6ms 寫 / &lt;1ms 讀 production reference">Aurora 儲存層架構</a> + <a href="/blog/backend/01-database/vendors/aurora/read-replica-scaling/" data-link-title="Aurora Read Replica Scaling：15 replica 上限、lag profile、headroom 預留與 fleet 治理" data-link-desc="Aurora 15 replica 上限、共享 storage 為什麼能養大量 replica、事件型容量分級表、DraftKings headroom 預留判讀、FanDuel 雙 SLO 並行、fleet 治理 3 條 driver（business sharding / microservice / 合規）">Aurora read replica scaling</a></li>
<li>想評估 distributed SQL 在 betting 場景的 fit → <a href="/blog/backend/01-database/vendors/cockroachdb/aurora-dsql-spanner-decision-tree/" data-link-title="CockroachDB vs Aurora DSQL vs Spanner：撞牆訊號分型 &#43; 七問題決策樹" data-link-desc="Distributed SQL 三選一決策樹。先用撞牆訊號分型識別 driver path（DoorDash 單主寫入撞牆 / Netflix Cassandra 缺口 / Hard Rock 合規驅動）、再走七問題（跨雲 / 雲商生態 / 風險預算 / PG 相容 / 管理負擔 / team size / vendor sizing barrier）。PostgreSQL 相容性 audit checklist 4 項、Spanner 100 pu sizing barrier、Hard Rock 「省 10-20 工程師」機會成本警示、Netflix Database Platform Team 規模">Aurora DSQL / Spanner / CockroachDB 決策樹</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/fanduel-case-study/">FanDuel Case Study</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/fanduel-cloudfront-case-study/">FanDuel CloudFront Case Study</a></li>
</ul>
]]></content:encoded></item><item><title>9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/</guid><description>&lt;p>這個案例的核心責任是說明「電信商級新串流服務」如何用雲端服務快速 launch + scale。Lemino 是 NTT DOCOMO 在 2023-04 推出的串流服務、3 個月達 5M MAU、工程工時下降 90% — 這個「不用大量工程師」的營運模式靠的是 managed services 組合、不是自建。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>NTT DOCOMO Lemino 在 AWS 的關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/ntt-docomo-lemino/">Lemino Case Study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>3 個月 MAU&lt;/td>
 &lt;td>500 萬&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>同時直播頻道&lt;/td>
 &lt;td>30 channels（規劃擴到 50）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DynamoDB 請求峰值&lt;/td>
 &lt;td>tens of thousands req/sec&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工程工時下降&lt;/td>
 &lt;td>90%（vs 自建）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>啟動年份&lt;/td>
 &lt;td>2023-04&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：AWS Media Services（Elemental Link、MediaConnect、MediaLive、MediaPackage）、Amazon Aurora、Amazon DynamoDB、DynamoDB Accelerator (DAX)、Amazon OpenSearch Service。&lt;/p>
&lt;p>關鍵敘述：採用 DynamoDB 的原因 — 「connection limits became bottlenecks when experiencing a rapid increase in access」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Lemino 案例揭露三個現代串流服務啟動的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>「connection limit 是 RDB 的隱性 bottleneck」是 OLTP 在 surge 下的典型問題&lt;/strong>：傳統 RDB（PostgreSQL、MySQL）每個連線吃記憶體跟 process / thread、connection pool 上限通常 1K-5K 個。當突發流量湧入、第一個爆的不是 CPU 也不是 disk、是 &lt;em>連線數量&lt;/em>。DynamoDB 的 HTTP API 模型沒有 connection state、天然解決這個問題。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 connection pool 議題、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato&lt;/a> 遷移動機同類。&lt;/li>
&lt;li>&lt;strong>AWS Media Services 是「電視台級」串流基礎設施&lt;/strong>：Elemental Link（encoding）、MediaConnect（transport）、MediaLive（live encoding）、MediaPackage（packaging + DRM）— 這套 stack 過往是電視台才買得起的硬體設備、AWS 把它變成 pay-per-use 服務。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 vendor-specific 串流服務評估。&lt;/li>
&lt;li>&lt;strong>90% 工程工時下降 = 走 managed 路線的真正價值&lt;/strong>：傳統電信商 launch 串流服務、要養 50-100 個 SRE + DBA + network 工程師、Lemino 用 managed 服務只需 5-10 個。差距不在「能不能 launch」、在「launch 後的維運成本」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &amp;#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &amp;#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom&lt;/a> 的同類訴求。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「tens of thousands req/sec」可能指 2 萬或 8 萬、差距 4 倍。「3 個月 5M MAU」很亮眼、但 NTT DOCOMO 自身有 8000 萬+ 電信用戶可以推、不是純自然成長。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「電信商級新串流服務」如何用雲端服務快速 launch + scale。Lemino 是 NTT DOCOMO 在 2023-04 推出的串流服務、3 個月達 5M MAU、工程工時下降 90% — 這個「不用大量工程師」的營運模式靠的是 managed services 組合、不是自建。</p>
<h2 id="觀察">觀察</h2>
<p>NTT DOCOMO Lemino 在 AWS 的關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/ntt-docomo-lemino/">Lemino Case Study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>3 個月 MAU</td>
          <td>500 萬</td>
      </tr>
      <tr>
          <td>同時直播頻道</td>
          <td>30 channels（規劃擴到 50）</td>
      </tr>
      <tr>
          <td>DynamoDB 請求峰值</td>
          <td>tens of thousands req/sec</td>
      </tr>
      <tr>
          <td>工程工時下降</td>
          <td>90%（vs 自建）</td>
      </tr>
      <tr>
          <td>啟動年份</td>
          <td>2023-04</td>
      </tr>
  </tbody>
</table>
<p>服務組合：AWS Media Services（Elemental Link、MediaConnect、MediaLive、MediaPackage）、Amazon Aurora、Amazon DynamoDB、DynamoDB Accelerator (DAX)、Amazon OpenSearch Service。</p>
<p>關鍵敘述：採用 DynamoDB 的原因 — 「connection limits became bottlenecks when experiencing a rapid increase in access」。</p>
<h2 id="判讀">判讀</h2>
<p>Lemino 案例揭露三個現代串流服務啟動的工程重點。</p>
<ol>
<li><strong>「connection limit 是 RDB 的隱性 bottleneck」是 OLTP 在 surge 下的典型問題</strong>：傳統 RDB（PostgreSQL、MySQL）每個連線吃記憶體跟 process / thread、connection pool 上限通常 1K-5K 個。當突發流量湧入、第一個爆的不是 CPU 也不是 disk、是 <em>連線數量</em>。DynamoDB 的 HTTP API 模型沒有 connection state、天然解決這個問題。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 connection pool 議題、跟 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> 遷移動機同類。</li>
<li><strong>AWS Media Services 是「電視台級」串流基礎設施</strong>：Elemental Link（encoding）、MediaConnect（transport）、MediaLive（live encoding）、MediaPackage（packaging + DRM）— 這套 stack 過往是電視台才買得起的硬體設備、AWS 把它變成 pay-per-use 服務。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 vendor-specific 串流服務評估。</li>
<li><strong>90% 工程工時下降 = 走 managed 路線的真正價值</strong>：傳統電信商 launch 串流服務、要養 50-100 個 SRE + DBA + network 工程師、Lemino 用 managed 服務只需 5-10 個。差距不在「能不能 launch」、在「launch 後的維運成本」。對應 <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a> 的同類訴求。</li>
</ol>
<p>需要警惕：「tens of thousands req/sec」可能指 2 萬或 8 萬、差距 4 倍。「3 個月 5M MAU」很亮眼、但 NTT DOCOMO 自身有 8000 萬+ 電信用戶可以推、不是純自然成長。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>新串流服務優先選 DynamoDB / Cosmos DB / Bigtable 撐 metadata 層</strong>：避免 connection limit、避免 schema migration、避免 DBA 維運成本。</li>
<li><strong>AWS Media Services / GCP Media CDN / Azure Media Services 是新進入者快速 launch 的捷徑</strong>：不要重造串流 stack、直接用 vendor 提供的。</li>
<li><strong>DAX 是 DynamoDB 讀 cache 的標準解法</strong>：當讀峰值持續高（例如熱門節目首播、Hotstar 等級）、加 DAX 減少 DynamoDB 讀次數、降低成本。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a>。</li>
<li><strong>小團隊 + managed services 是電信商雲端轉型的範本</strong>：傳統電信商過去靠人海戰術、現在改靠 managed + 工程紀律。</li>
</ol>
<p>跨平台等效：GCP 提供 Media CDN + Anvato，Azure 提供 Media Services + Azure Front Door — 各家都有完整串流 stack。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他串流案例 → <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a>（live 直播）/ <a href="/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">9.C27 Disney+</a>（VOD metadata）</li>
<li>想理解 connection limit 議題 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato 遷移</a></li>
<li>想做 DAX / cache 加速 → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> + <a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi ML feature store</a></li>
<li>想規劃 managed-only 串流 stack → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a></li>
<li>想做串流 metadata 的 partition / GSI 設計 → <a href="/blog/backend/01-database/vendors/dynamodb/partition-key-antipatterns/" data-link-title="DynamoDB Partition Key 反模式與 Write Sharding：composite key 修復跟 mode × partition 交叉判讀" data-link-desc="DynamoDB partition 上限 1000 WCU 是 hot partition 的根因；composite key（event_id &#43; shard suffix）跟 calculated shard（hash % N）兩種修法、mode × partition 在 provisioned / on-demand 不同表現，以及 9.C15 Tixcraft 6750x 擴展的工程細節">DynamoDB partition key 反模式</a> + <a href="/blog/backend/01-database/vendors/dynamodb/gsi-lsi-design/" data-link-title="DynamoDB GSI 與 LSI 設計：access pattern 補位、projection、consistency 跟 DAX 補位" data-link-desc="GSI / LSI 是 single-table 沒覆蓋的 access pattern 補位、不是萬靈丹；本文涵蓋 projection 三型選擇、sparse index、GSI 自己會 hot partition、DAX 讀峰值補位的觸發條件（含 Capcom 是 derive vs Lemino 是 case fact 的分層）">DynamoDB GSI / LSI 設計</a></li>
<li>想評估 on-demand vs provisioned 給直播 / VOD 用 → <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand vs provisioned</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/solutions/case-studies/ntt-docomo-lemino/">NTT Docomo Rebuilds Infrastructure for Lemino Streaming Service Launch</a></li>
<li><a href="https://aws.amazon.com/media/direct-to-consumer-d2c-streaming/">Direct to Consumer &amp; Streaming on AWS</a></li>
</ul>
]]></content:encoded></item><item><title>Datadog Continuous Profiler</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/</guid><description>&lt;p>Datadog Continuous Profiler 的核心責任是把 production profile 接到 SaaS APM、deployment marker、service tag 與 release regression workflow。它適合已經使用 Datadog APM / metrics / logs 的團隊，重點在讓 slow request、resource saturation、deploy version 與 profile diff 能在同一個操作介面中對齊。&lt;/p>
&lt;h2 id="定位">定位&lt;/h2>
&lt;p>Datadog Continuous Profiler 是 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/datadog/" data-link-title="Datadog" data-link-desc="All-in-one SaaS 觀測平台、APM / Logs / Metrics / RUM / Security">Datadog&lt;/a> APM 的 &lt;em>production profiling&lt;/em> add-on、跟 Datadog Logs / Metrics / Traces 同 plane、共用 service tag、env tag、version tag 與 query bar。它的核心責任是把 production profile 接到 SaaS APM、deployment marker、service tag 與 release regression workflow，讓 slow request、resource saturation、deploy version 與 profile diff 能在同一個操作介面中對齊。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca&lt;/a> 這類 OSS profiler 比、Datadog Continuous Profiler 走 &lt;em>ecosystem-bundled&lt;/em> 路線 — profiler 本身不獨立計費、跟 APM host 一起進 business unit 預算、profile data 直接跟 trace_id、deploy marker、log query 在同一介面 cross-link。OSS profiler 走 &lt;em>standalone deployment&lt;/em>、profile store 自管（ClickHouse / object storage）、跟 observability 其他 plane 要自己 wire（grafana correlation、自寫 trace_id mapping）。差異在 &lt;em>跨 signal 的 query continuity 跟組織計費歸屬&lt;/em>、flame graph 本身的視覺呈現相近。&lt;/p>
&lt;p>這個定位讓 Datadog Continuous Profiler 接到 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling&lt;/a>。它的價值在於降低 profile diff 的交接成本；它的代價在於 SaaS 成本、agent 設定、資料保留與 vendor 約束。&lt;/p></description><content:encoded><![CDATA[<p>Datadog Continuous Profiler 的核心責任是把 production profile 接到 SaaS APM、deployment marker、service tag 與 release regression workflow。它適合已經使用 Datadog APM / metrics / logs 的團隊，重點在讓 slow request、resource saturation、deploy version 與 profile diff 能在同一個操作介面中對齊。</p>
<h2 id="定位">定位</h2>
<p>Datadog Continuous Profiler 是 <a href="/blog/backend/04-observability/vendors/datadog/" data-link-title="Datadog" data-link-desc="All-in-one SaaS 觀測平台、APM / Logs / Metrics / RUM / Security">Datadog</a> APM 的 <em>production profiling</em> add-on、跟 Datadog Logs / Metrics / Traces 同 plane、共用 service tag、env tag、version tag 與 query bar。它的核心責任是把 production profile 接到 SaaS APM、deployment marker、service tag 與 release regression workflow，讓 slow request、resource saturation、deploy version 與 profile diff 能在同一個操作介面中對齊。</p>
<p>跟 <a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a> / <a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a> 這類 OSS profiler 比、Datadog Continuous Profiler 走 <em>ecosystem-bundled</em> 路線 — profiler 本身不獨立計費、跟 APM host 一起進 business unit 預算、profile data 直接跟 trace_id、deploy marker、log query 在同一介面 cross-link。OSS profiler 走 <em>standalone deployment</em>、profile store 自管（ClickHouse / object storage）、跟 observability 其他 plane 要自己 wire（grafana correlation、自寫 trace_id mapping）。差異在 <em>跨 signal 的 query continuity 跟組織計費歸屬</em>、flame graph 本身的視覺呈現相近。</p>
<p>這個定位讓 Datadog Continuous Profiler 接到 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 與 <a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a>。它的價值在於降低 profile diff 的交接成本；它的代價在於 SaaS 成本、agent 設定、資料保留與 vendor 約束。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Datadog Continuous Profiler deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Agent / SDK profiling 是否真的 enabled</strong>：Datadog Agent 跑著不等於 profiler 開了 — 各語言要在 SDK init 加 <code>profiling_enabled=true</code> 或環境變數 <code>DD_PROFILING_ENABLED=true</code>、Go / Java / Python / Node / Ruby / .NET 的開啟方式跟覆蓋的 profile type（CPU / heap / goroutine / lock / wall time）各不同</li>
<li><strong>Service / version / env tag 紀律</strong>：profile 沒有 <code>service</code> + <code>env</code> + <code>version</code> tag 就無法 diff、release marker 也對不上 — CI 要把 git SHA 或 release tag 注入 <code>DD_VERSION</code>、deploy pipeline 要打 deployment marker API</li>
<li><strong>Sampling rate 跟 production coverage</strong>：profiler 預設 60s 採一次、低流量服務或 short-lived 任務可能 sample 不到 hot path — 對 ultra-low latency / burst workload 要評估 sampling 是否還抓得到 regression signal</li>
<li><strong>Profile ingestion cost / retention</strong>：profile 是按 APM host 計費、但 profile event 量隨 service 數量 + sampling rate 漲、retention 預設 7 天（custom retention 另計）— 大型 deployment 要做 service-level enable/disable governance</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p>Release regression 定位適合 Datadog Continuous Profiler。當 canary 或 release candidate 的 p99、CPU、memory 或 cost per request 退化，團隊可以用 deployment marker 對比 release 前後 profile，找出變寬的 call stack。</p>
<p>APM-to-profile drilldown 適合 Datadog Continuous Profiler。慢 request 可以從 service、endpoint、trace 或 span 往下切到 profile，讓工程師知道 latency 是 DB、network、runtime、serialization、lock 還是 CPU hot path。</p>
<p>多語言 SaaS 團隊適合 Datadog Continuous Profiler。團隊如果同時維護 Go、Java、Python、Ruby、Node.js 或 .NET 服務，SaaS profiler 可以用統一 tag、dashboard 與權限模型管理。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Datadog 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>APM 整合</td>
          <td>trace、service、endpoint、profile 可串接</td>
          <td>service tag 與 deploy label 紀律</td>
      </tr>
      <tr>
          <td>Deployment marker</td>
          <td>release 前後 profile diff 容易建立</td>
          <td>release pipeline 與版本標記整合</td>
      </tr>
      <tr>
          <td>SaaS 操作</td>
          <td>低自管成本、跨團隊易查詢</td>
          <td>成本治理、資料保留與 vendor 約束</td>
      </tr>
      <tr>
          <td>多語言支援</td>
          <td>多 runtime 用同一套操作介面</td>
          <td>各語言 agent overhead 與覆蓋差異</td>
      </tr>
  </tbody>
</table>
<p>APM 整合價值來自上下文連續。Metrics 告訴你 CPU 上升，trace 告訴你 endpoint 變慢，profile 告訴你哪段 code path 變貴；Datadog 的優勢是把這些訊號放進同一個查詢與 dashboard 流程。</p>
<p>Deployment marker 價值來自 release gate。Profile diff 如果能對齊 commit、version、environment 與 canary cohort，就能成為 <a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a> 的 evidence。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Datadog Continuous Profiler</th>
          <th>Pyroscope</th>
          <th>Parca</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>SaaS only、跟 Datadog Agent / APM 綁</td>
          <td>OSS self-host / Grafana Cloud SaaS</td>
          <td>OSS self-host（Polar Signals SaaS 選）</td>
      </tr>
      <tr>
          <td>計費模型</td>
          <td>跟 APM host 計費（profile 不獨立 metering）</td>
          <td>OSS 免費 / Grafana Cloud 按 ingestion</td>
          <td>OSS 免費 / SaaS 按 host</td>
      </tr>
      <tr>
          <td>Profile 採集方式</td>
          <td>Language SDK（pull 採樣）</td>
          <td>SDK + eBPF agent</td>
          <td>eBPF-first、language-agnostic</td>
      </tr>
      <tr>
          <td>Trace correlation</td>
          <td>強 — trace_id 自動 link 到 flame graph</td>
          <td>中 — 要自己 wire OTel trace_id</td>
          <td>弱 — 偏 eBPF profile、trace 整合較淺</td>
      </tr>
      <tr>
          <td>視覺 / Workflow</td>
          <td>APM service view + Profile diff + Code Hotspot in IDE</td>
          <td>Grafana flame graph + diff、跟 Loki / Tempo 同 UI</td>
          <td>Parca UI 簡潔、偏單純 profile 探索</td>
      </tr>
      <tr>
          <td>多語言支援</td>
          <td>Go / Java / Python / Node / Ruby / .NET / PHP 官方 SDK</td>
          <td>同 + 社群 SDK；eBPF 補 native binary</td>
          <td>eBPF-only、不挑語言但 symbol 解析較吃力</td>
      </tr>
      <tr>
          <td>Vendor lock-in</td>
          <td>高 — profile 跟 APM workflow 綁、退場要重建 dashboard</td>
          <td>低 — OSS、profile 格式相對開放</td>
          <td>低 — OSS、pprof 格式相容</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Datadog-heavy org、APM / log / metric 已用</td>
          <td>Grafana stack 已用、要省 license</td>
          <td>eBPF-first、low-overhead always-on</td>
      </tr>
  </tbody>
</table>
<p>選 Datadog Continuous Profiler 的核心訴求：<em>Datadog 已是 observability backbone</em> + 要 <em>APM trace ↔ profile drilldown 是 first-class workflow</em> + 接受 SaaS 計費 + 接受 SDK overhead trade-off。如果 Datadog 不是既有平台、單純為了 profiling 引入 Datadog 通常成本不划算、改走 Pyroscope / Parca。</p>
<p>跟一次性 runtime profiler（<code>pprof</code>、<code>async-profiler</code> 手動跑）的差異是時間維度。一次性 profiler 適合本機或 incident 當下調查；continuous profiler 適合 baseline、release diff 與長期退化治理 — 兩者互補、不互斥。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>APM trace ↔ profile correlation</strong>：Datadog SDK 把 <code>trace_id</code> 注入 profile sample 的 label、APM trace view 上每個 span 可以直接點到「執行這段 span 時的 flame graph」。意義是 <em>p99 latency 異常 trace 不只看 span 等待時間、能直接看到該 span 期間 CPU / lock / allocation 真正花在哪段 code</em>。需要 SDK 版本支援 + trace context propagation 正確接上、舊版 SDK 或自寫 instrumentation 容易斷鏈。</p>
<p><strong>Endpoint profiling</strong>：profile 按 HTTP endpoint / RPC method 切片、不只看 service 整體 hot path。意義是 <em>新加的 endpoint 即便 traffic 小、也能單獨看它的 CPU / allocation cost</em>、不會被 service 主流量稀釋。對 multi-tenant API、A/B test endpoint、internal admin endpoint 的退化偵測特別有用。</p>
<p><strong>Code Hotspot in IDE</strong>：Datadog IDE plugin（IntelliJ / VS Code）把 production profile 的 hot line 直接 overlay 到 source code、工程師 review PR 時能看到「這個 function 在 production 佔 service CPU 12%」。降低 <em>看 flame graph → 找 source 對應行</em> 的 cognitive cost。對應 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 中「production signal → code change」的 feedback loop 縮短。</p>
<p><strong>Profile diff（baseline vs candidate）</strong>：Datadog 內建 diff view、選兩個 time window 或兩個 version tag、直接看 flame graph 哪些 frame 變寬 / 變窄。是 <a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a> 的核心 evidence — canary 跑完 30min、自動拉 baseline vs candidate diff 報告、超過 threshold 阻擋 promote。</p>
<p><strong>Notebooks correlation</strong>：Datadog Notebooks 可以把 profile flame graph、APM trace、metric chart、log query 排在同一份文件。incident post-mortem 跟 release review 寫一份 notebook 比散落多個 dashboard tab 更可追溯、也接 <a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">evidence package</a> 規範。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>SDK overhead 在 production 過高</strong>：profiler 預設 overhead &lt; 2% CPU、但 wall-time profiling / allocation profiling 全開可能到 5%+ — canary 一台量測、按 profile type 分別 enable、不要全部一次開</li>
<li><strong>Sampling rate 太低 / false negative</strong>：short-lived job（&lt; 60s）或 low-traffic service 可能整個生命週期沒被 sample 到、看不到 hot path — 改成事件觸發 profile（on-demand profiling API）或拉高該 service 的 sampling rate</li>
<li><strong>Profile 沒有 version tag / 無法 diff</strong>：deploy pipeline 沒注入 <code>DD_VERSION</code>、release marker 對不上 — 補 CI 環境變數、用 <code>dd-trace</code> SDK 自動讀 git commit SHA、跑 staging 驗證 diff view 能顯示 version</li>
<li><strong>Trace ↔ profile drilldown 斷鏈</strong>：SDK 版本太舊、或 trace context 在非同步 / queue handler 沒 propagate — 升 SDK + 補 trace context propagation、用一條已知慢 trace 驗證能不能跳到 flame graph</li>
<li><strong>Profiling cost spike</strong>：新 service 開啟 profiling、或某 service profile event 暴增（exception 路徑反覆採樣）— 看 Datadog usage dashboard 的 profile host hour、對嫌疑 service 暫關 profiling 觀察 cost 曲線、再 tune sampling rate</li>
<li><strong>Flame graph symbol 解析失敗 / 顯示 <code>?</code> frame</strong>：缺 debug symbol、stripped binary、或語言 runtime 版本不支援 — 補 build 時保留 symbol、確認 SDK 版本 vs runtime 版本對應表</li>
<li><strong>Lock profile 看不出 contention</strong>：某些語言（Go / Java）的 lock profiling 需要額外 flag（<code>DD_PROFILING_BLOCK_ENABLED</code> / <code>DD_PROFILING_LOCK_ENABLED</code>）— 預設沒開、要明確 enable 才看得到 lock contention flame graph</li>
</ul>
<h2 id="操作成本">操作成本</h2>
<p>Datadog Continuous Profiler 的主要成本是資料量與保留。Profile sample、tag cardinality、service 數量、environment 數量與 retention 都會影響費用與查詢體驗。</p>
<p>Agent 成本來自 runtime 差異。不同語言的 profiler 支援、overhead、可觀測維度與限制不同，導入時要用 canary service 量測 CPU、memory、latency 與 profile completeness。</p>
<p>Vendor 成本來自資料與 workflow 綁定。當 profile diff、release marker、APM drilldown 與 incident workflow 都在 Datadog 中，後續切換平台需要重新建立 tag schema、dashboard、retention 與 gate integration。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Datadog Continuous Profiler 結果應回寫到 evidence package。最小欄位包括 service、version、environment、deploy marker、profile type、time range、comparison baseline、profile diff link、overhead estimate、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Datadog 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>profiler view、profile diff、APM link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>baseline / candidate profile window</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>Datadog profile、trace、dashboard link</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>service tag、version tag、sampling status</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>production coverage、agent overhead</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>runtime coverage、tag drift、retention limit</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 release regression 可追溯。Reviewer 要能從 failed gate 直接打開 profile diff，看出哪個 service、version、endpoint 或 call stack 造成資源成本變化。</p>
<h2 id="案例回寫">案例回寫</h2>
<p>Datadog Continuous Profiler 適合回寫 release regression 與 APM 整合案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的 profile noise 降低、<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi feature store</a> 的 low-latency hot path 定位、<a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase ultra-low latency exchange</a> 的 z1d 單執行緒 hot path 分析、<a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft 100+ 微服務</a> 的 per-service profile diff，以及 <a href="/blog/backend/04-observability/cases/datadog-otel-migration-practice/" data-link-title="4.C7 Datadog：OTel 相容遷移實務" data-link-desc="APM 採集從專有代理轉向 OTel 相容模式的治理案例。">Datadog OTel migration practice</a> 的 observability pipeline 整合。</p>
<p>這些案例的重點是上下文對齊。Datadog Profiler 頁引用案例時，要把 case 轉成 service tag、deploy marker、profile diff、trace drilldown 與 release gate evidence — 例如 Coinbase sub-ms 目標下、profile 必須對齊 RAFT consensus 跟 placement group 拓樸、才能解釋 hot path 為何在某些 epoch 才出現。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a></li>
<li>官方：<a href="https://docs.datadoghq.com/profiler/">Datadog Continuous Profiler documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/</guid><description>&lt;p>這個案例的核心責任是填補 Azure data-architecture 維度缺口、並提供「MongoDB → Cosmos DB」這個跨產品遷移的官方範本。Microsoft 365 是全球最大 SaaS 之一（月活十億級）、其使用分析平台的容量需求是 planet-scale。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Microsoft 365 在 Cosmos DB 的關鍵敘述（引自 &lt;a href="https://azure.microsoft.com/en-us/blog/microsoft-365-boosts-usage-analytics-with-azure-cosmos-db/">Microsoft 365 boosts usage analytics with Azure Cosmos DB&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>用戶規模&lt;/td>
 &lt;td>Microsoft 365 全球用戶（十億級 MAU）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工作負載&lt;/td>
 &lt;td>使用分析（usage analytics）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷出技術&lt;/td>
 &lt;td>MongoDB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷入技術&lt;/td>
 &lt;td>Azure Cosmos DB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移動機&lt;/td>
 &lt;td>「globally-distributed, multi-model」「virtually unlimited elastic scalability」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵敘述：「The team decided to replace MongoDB with Azure Cosmos DB, a fully managed globally-distributed, multi-model database service designed for global distribution and virtually unlimited elastic scalability.」&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Microsoft 365 案例揭露三個全球 SaaS 分析平台的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>MongoDB → Cosmos DB 是「相容 API + 升級擴展性」的遷移路徑&lt;/strong>：Cosmos DB 提供 MongoDB API 相容、應用層程式幾乎不用改、但底層儲存改用 Cosmos DB 的分散式架構。這層遷移成本遠低於改寫 application 到 native Cosmos DB SQL API、適合大規模既有系統。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook&lt;/a>、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato&lt;/a> 形成對照。&lt;/li>
&lt;li>&lt;strong>分析平台 vs 交易平台的 DB 取捨不同&lt;/strong>：交易平台優先 latency + consistency（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner&lt;/a>）、分析平台優先 throughput + global distribution + cost。Cosmos DB 5 個 consistency level 讓分析場景可以選 weakest（eventual / session），換最大 throughput。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth&lt;/a> 同思維。&lt;/li>
&lt;li>&lt;strong>Microsoft 自家產品 dogfood Cosmos DB&lt;/strong>：跟 Amazon Prime Day 用自家 DynamoDB（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1&lt;/a>）、Google 自家用 Spanner（&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10&lt;/a>）一樣 — 雲商旗艦 DB 都會用在自家旗艦產品。讀此類 dogfood 案例的權重應該高、因為「雲商自己賭身家」。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是填補 Azure data-architecture 維度缺口、並提供「MongoDB → Cosmos DB」這個跨產品遷移的官方範本。Microsoft 365 是全球最大 SaaS 之一（月活十億級）、其使用分析平台的容量需求是 planet-scale。</p>
<h2 id="觀察">觀察</h2>
<p>Microsoft 365 在 Cosmos DB 的關鍵敘述（引自 <a href="https://azure.microsoft.com/en-us/blog/microsoft-365-boosts-usage-analytics-with-azure-cosmos-db/">Microsoft 365 boosts usage analytics with Azure Cosmos DB</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>用戶規模</td>
          <td>Microsoft 365 全球用戶（十億級 MAU）</td>
      </tr>
      <tr>
          <td>工作負載</td>
          <td>使用分析（usage analytics）</td>
      </tr>
      <tr>
          <td>遷出技術</td>
          <td>MongoDB</td>
      </tr>
      <tr>
          <td>遷入技術</td>
          <td>Azure Cosmos DB</td>
      </tr>
      <tr>
          <td>遷移動機</td>
          <td>「globally-distributed, multi-model」「virtually unlimited elastic scalability」</td>
      </tr>
  </tbody>
</table>
<p>關鍵敘述：「The team decided to replace MongoDB with Azure Cosmos DB, a fully managed globally-distributed, multi-model database service designed for global distribution and virtually unlimited elastic scalability.」</p>
<h2 id="判讀">判讀</h2>
<p>Microsoft 365 案例揭露三個全球 SaaS 分析平台的工程重點。</p>
<ol>
<li><strong>MongoDB → Cosmos DB 是「相容 API + 升級擴展性」的遷移路徑</strong>：Cosmos DB 提供 MongoDB API 相容、應用層程式幾乎不用改、但底層儲存改用 Cosmos DB 的分散式架構。這層遷移成本遠低於改寫 application 到 native Cosmos DB SQL API、適合大規模既有系統。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a>、跟 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> 形成對照。</li>
<li><strong>分析平台 vs 交易平台的 DB 取捨不同</strong>：交易平台優先 latency + consistency（<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a>）、分析平台優先 throughput + global distribution + cost。Cosmos DB 5 個 consistency level 讓分析場景可以選 weakest（eventual / session），換最大 throughput。對應 <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> 同思維。</li>
<li><strong>Microsoft 自家產品 dogfood Cosmos DB</strong>：跟 Amazon Prime Day 用自家 DynamoDB（<a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1</a>）、Google 自家用 Spanner（<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10</a>）一樣 — 雲商旗艦 DB 都會用在自家旗艦產品。讀此類 dogfood 案例的權重應該高、因為「雲商自己賭身家」。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>案例 <em>沒有</em> 提具體 throughput、latency、cost 數字。Microsoft 內部數字通常不公開、跟 AWS / GCP 案例的數字密度差很多。</li>
<li>「MongoDB 不夠用」是行銷話術。實際是 <em>MongoDB 在某些 workload pattern 下不夠用</em>、不是普遍結論。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>MongoDB-compatible Cosmos DB 是大規模遷移的捷徑</strong>：應用層改動少、底層擴展性升級。但要驗證 <em>特定 query pattern</em> 在兩邊行為一致。對應 <a href="/blog/backend/01-database/schema-migration-rollout-evidence/" data-link-title="1.7 Schema Migration Rollout 證據（Schema Migration Rollout Evidence）實作示範" data-link-desc="以訂單付款狀態欄位演進示範 schema migration 如何產出 evidence、release gate 與 incident decision log。">01.3 schema migration rollout evidence</a> 的 dual-write 驗證。</li>
<li><strong>分析平台用 weakest acceptable consistency</strong>：session consistency 或 eventual consistency 通常夠用、能換到 3-10x throughput。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的一致性取捨。</li>
<li><strong>dogfood 是 vendor selection 的重要訊號</strong>：vendor 自家是否用在 production-critical workload、能告訴你「他們對自己服務的信任度」。</li>
<li><strong>Multi-model 是 Cosmos DB 的差異化價值</strong>：同一個服務可以用 SQL API / MongoDB API / Cassandra API / Gremlin / Table API、避免多個 DB 服務並存。</li>
</ol>
<p>跨平台等效：AWS DynamoDB（KV）+ DocumentDB（MongoDB-compatible）、GCP Firestore（document）+ Spanner（SQL）+ Bigtable（KV）— 各家用不同產品覆蓋 multi-model、Cosmos DB 是少數「單一產品支援多 model」。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他 Cosmos DB 案例 → <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> / <a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS Black Friday</a></li>
<li>對照其他 dogfood 案例 → <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a> / <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想做 MongoDB-compatible 遷移 → <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a></li>
<li>想理解 multi-model 取捨 → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> + <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a></li>
<li>想對比 Cosmos DB MongoDB API vs SQL API 的選型 → <a href="/blog/backend/01-database/vendors/cosmosdb/mongodb-api-vs-sql-api/" data-link-title="Cosmos DB MongoDB API vs SQL API：遷移路徑、dogfood signal、multi-model、跨雲 hedging" data-link-desc="從『MongoDB API 跟 SQL API 哪個快』推進到 vendor selection 的四層問題：三型遷移路徑、dogfood signal 怎麼讀、multi-model 差異化、跨雲 hedging — 從 Microsoft 365 dogfood 案例切入">Cosmos DB MongoDB API vs SQL API</a></li>
<li>想做 RU 成本模型與容量 sizing → <a href="/blog/backend/01-database/vendors/cosmosdb/ru-cost-model-sizing/" data-link-title="Cosmos DB RU/s 成本模型 &#43; 容量規劃：RU 思維、payload、index、provisioned vs autoscale vs serverless" data-link-desc="從 CPU&#43;IOPS 思維轉到 RU 思維的學習曲線、依負載形狀選容量模式、payload &#43; index policy 對 RU 的影響、autoscale reactive 限制 — 從 ASOS Black Friday &#43; Minecraft Earth 1M RU/s 壓測切入">Cosmos DB RU 成本模型</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://azure.microsoft.com/en-us/blog/microsoft-365-boosts-usage-analytics-with-azure-cosmos-db/">Microsoft 365 boosts usage analytics with Azure Cosmos DB</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/a-technical-overview-of-azure-cosmos-db/">A technical overview of Azure Cosmos DB</a></li>
</ul>
]]></content:encoded></item><item><title>Aurora Serverless v2 適用判斷：ACU 自動擴縮、混合 cluster 與何時不該用</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/serverless-v2-scaling/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/serverless-v2-scaling/</guid><description>&lt;p>Aurora Serverless v2 把 instance 的容量從「開機時固定的 instance class」改成「按負載秒級伸縮的 ACU」。它解的問題很具體：固定 provisioned cluster 在離峰時段付滿整台機器的錢、卻只用一小部分；尖峰來時又被 instance class 上限卡住。但 serverless v2 不是「比較便宜的 Aurora」——穩定高負載下它反而比同等 provisioned 貴。要不要用，取決於 workload 的負載形狀是否間歇、是否難預測。&lt;/p>
&lt;p>本文不是 Aurora overview（請看 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&amp;#43;75% 效能改善的 production 證據">Aurora vendor 頁&lt;/a>）— 而是 Serverless v2 的容量機制、設定與適用邊界的實作層教學。&lt;/p>
&lt;h2 id="核心機制acu-與秒級擴縮">核心機制：ACU 與秒級擴縮&lt;/h2>
&lt;p>Serverless v2 的容量單位是 ACU（Aurora Capacity Unit），一個 ACU 對應一組固定比例的記憶體與運算資源。cluster 不再綁定一個 instance class，而是設一個 ACU 區間（min / max），Aurora 依即時負載在區間內伸縮：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>屬性&lt;/th>
 &lt;th>Provisioned&lt;/th>
 &lt;th>Serverless v2&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>容量設定&lt;/td>
 &lt;td>固定 instance class（如 db.r6g.xlarge）&lt;/td>
 &lt;td>min / max ACU 區間&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>計費&lt;/td>
 &lt;td>按 instance 開機時數&lt;/td>
 &lt;td>按實際消耗的 ACU-秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>擴縮&lt;/td>
 &lt;td>手動改 instance class（有中斷）&lt;/td>
 &lt;td>秒級自動伸縮、無中斷&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>離峰成本&lt;/td>
 &lt;td>付滿整台&lt;/td>
 &lt;td>縮到 min ACU、只付低水位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用負載&lt;/td>
 &lt;td>穩定、可預測&lt;/td>
 &lt;td>間歇、突發、難預測&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>擴縮行為&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>負載上升時 ACU 平滑增加、不需要切換 instance、無連線中斷&lt;/li>
&lt;li>負載下降時縮回低水位、但受 min ACU 下限約束&lt;/li>
&lt;li>min ACU 決定離峰的最低成本與「保留多少暖容量」；max ACU 決定尖峰的上限與成本天花板&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>&lt;strong>Scope warning&lt;/strong>：「ACU 對應的記憶體比例」「serverless v2 是否能縮到 0」「最小 ACU 粒度」這些屬 AWS vendor 規格、會隨版本演進（auto-pause 等能力陸續調整）、實作時 cross-verify 官方 doc 當前值。本文不含 production case 揭露的 ACU 配置數字。&lt;/p>&lt;/blockquote>
&lt;p>對應 knowledge card：&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">peak forecast&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">cost per request&lt;/a>。&lt;/p>
&lt;h2 id="min--max-acu-的設定權衡">min / max ACU 的設定權衡&lt;/h2>
&lt;p>min 與 max ACU 不是隨便設，兩端各自承擔不同風險。&lt;/p>
&lt;p>&lt;strong>min ACU 太低&lt;/strong>：離峰省錢，但流量回升時從很低的水位往上爬、爬升期間可能容量不足、且 buffer cache 在低 ACU 時被壓縮、回升後 cache 重新暖機、query latency 短暫升高。對延遲敏感、又有規律日週期的 workload，min ACU 不要壓到極限。&lt;/p>
&lt;p>&lt;strong>max ACU 太低&lt;/strong>：尖峰被天花板卡住、等同 provisioned 的 instance class 上限問題又回來。max ACU 要按「預期尖峰 + 餘量」設，並把它當成成本天花板來監控——max 設太高雖然不會平時就花錢，但失控 query（如缺索引的全表掃描）可能把 ACU 一路推到 max、帳單尖峰。&lt;/p>
&lt;p>&lt;strong>暖容量考量&lt;/strong>：min ACU 同時決定「保留多少隨時可用的暖容量」。完全不可預測、且要求第一個請求就低延遲的場景，min ACU 要留足暖機水位，不能為了省錢設到最低。&lt;/p>
&lt;h2 id="混合-clusterserverless--provisioned-並存">混合 cluster：serverless + provisioned 並存&lt;/h2>
&lt;p>Serverless v2 不是「整個 cluster 要嘛全 serverless、要嘛全 provisioned」。同一個 Aurora cluster 可以混用：writer 用 provisioned 保穩定、read replica 用 serverless v2 吸收讀取尖峰；或反過來。這讓 workload 的不同部分各取所需：&lt;/p></description><content:encoded><![CDATA[<p>Aurora Serverless v2 把 instance 的容量從「開機時固定的 instance class」改成「按負載秒級伸縮的 ACU」。它解的問題很具體：固定 provisioned cluster 在離峰時段付滿整台機器的錢、卻只用一小部分；尖峰來時又被 instance class 上限卡住。但 serverless v2 不是「比較便宜的 Aurora」——穩定高負載下它反而比同等 provisioned 貴。要不要用，取決於 workload 的負載形狀是否間歇、是否難預測。</p>
<p>本文不是 Aurora overview（請看 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor 頁</a>）— 而是 Serverless v2 的容量機制、設定與適用邊界的實作層教學。</p>
<h2 id="核心機制acu-與秒級擴縮">核心機制：ACU 與秒級擴縮</h2>
<p>Serverless v2 的容量單位是 ACU（Aurora Capacity Unit），一個 ACU 對應一組固定比例的記憶體與運算資源。cluster 不再綁定一個 instance class，而是設一個 ACU 區間（min / max），Aurora 依即時負載在區間內伸縮：</p>
<table>
  <thead>
      <tr>
          <th>屬性</th>
          <th>Provisioned</th>
          <th>Serverless v2</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>容量設定</td>
          <td>固定 instance class（如 db.r6g.xlarge）</td>
          <td>min / max ACU 區間</td>
      </tr>
      <tr>
          <td>計費</td>
          <td>按 instance 開機時數</td>
          <td>按實際消耗的 ACU-秒</td>
      </tr>
      <tr>
          <td>擴縮</td>
          <td>手動改 instance class（有中斷）</td>
          <td>秒級自動伸縮、無中斷</td>
      </tr>
      <tr>
          <td>離峰成本</td>
          <td>付滿整台</td>
          <td>縮到 min ACU、只付低水位</td>
      </tr>
      <tr>
          <td>適用負載</td>
          <td>穩定、可預測</td>
          <td>間歇、突發、難預測</td>
      </tr>
  </tbody>
</table>
<p><strong>擴縮行為</strong>：</p>
<ul>
<li>負載上升時 ACU 平滑增加、不需要切換 instance、無連線中斷</li>
<li>負載下降時縮回低水位、但受 min ACU 下限約束</li>
<li>min ACU 決定離峰的最低成本與「保留多少暖容量」；max ACU 決定尖峰的上限與成本天花板</li>
</ul>
<blockquote>
<p><strong>Scope warning</strong>：「ACU 對應的記憶體比例」「serverless v2 是否能縮到 0」「最小 ACU 粒度」這些屬 AWS vendor 規格、會隨版本演進（auto-pause 等能力陸續調整）、實作時 cross-verify 官方 doc 當前值。本文不含 production case 揭露的 ACU 配置數字。</p></blockquote>
<p>對應 knowledge card：<a href="/blog/backend/knowledge-cards/peak-forecast/" data-link-title="Peak Forecast" data-link-desc="說明預期峰值流量的預測方法 — 容量規劃的第一個輸入">peak forecast</a>、<a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">cost per request</a>。</p>
<h2 id="min--max-acu-的設定權衡">min / max ACU 的設定權衡</h2>
<p>min 與 max ACU 不是隨便設，兩端各自承擔不同風險。</p>
<p><strong>min ACU 太低</strong>：離峰省錢，但流量回升時從很低的水位往上爬、爬升期間可能容量不足、且 buffer cache 在低 ACU 時被壓縮、回升後 cache 重新暖機、query latency 短暫升高。對延遲敏感、又有規律日週期的 workload，min ACU 不要壓到極限。</p>
<p><strong>max ACU 太低</strong>：尖峰被天花板卡住、等同 provisioned 的 instance class 上限問題又回來。max ACU 要按「預期尖峰 + 餘量」設，並把它當成成本天花板來監控——max 設太高雖然不會平時就花錢，但失控 query（如缺索引的全表掃描）可能把 ACU 一路推到 max、帳單尖峰。</p>
<p><strong>暖容量考量</strong>：min ACU 同時決定「保留多少隨時可用的暖容量」。完全不可預測、且要求第一個請求就低延遲的場景，min ACU 要留足暖機水位，不能為了省錢設到最低。</p>
<h2 id="混合-clusterserverless--provisioned-並存">混合 cluster：serverless + provisioned 並存</h2>
<p>Serverless v2 不是「整個 cluster 要嘛全 serverless、要嘛全 provisioned」。同一個 Aurora cluster 可以混用：writer 用 provisioned 保穩定、read replica 用 serverless v2 吸收讀取尖峰；或反過來。這讓 workload 的不同部分各取所需：</p>
<ul>
<li>穩定的寫入路徑用 provisioned instance、成本可預測</li>
<li>間歇的讀取分析、報表副本用 serverless v2、平時縮到低水位</li>
<li>failover 目標可指定 provisioned 或 serverless，依可用性需求</li>
</ul>
<p>混合配置的判讀是把 cluster 內每個角色當獨立的負載形狀評估，而非整個 cluster 一刀切。</p>
<h2 id="操作流程">操作流程</h2>
<p>從負載形狀評估到上線的 6 步流程。</p>
<h4 id="step-1判斷負載形狀">Step 1：判斷負載形狀</h4>
<p>用 CloudWatch 過去 30 天的 CPU / connection / IOPS，看負載是穩定平緩、規律日週期、還是不規則突發：</p>
<ul>
<li>穩定高負載（平均使用率高、波動小）→ provisioned 通常更划算</li>
<li>間歇 / 突發 / 開發測試 / 多租戶各自小 DB → serverless v2 適合</li>
<li>規律日週期（白天高晚上低）→ serverless v2 或 provisioned + scheduled 都可，算成本 crossover</li>
</ul>
<h4 id="step-2估-min--max-acu">Step 2：估 min / max ACU</h4>
<p>min 依離峰最低負載 + 暖容量需求；max 依尖峰負載 + 餘量。第一次設保守一點、上線後依實際 ACU 曲線收斂。</p>
<h4 id="step-3建立或轉換">Step 3：建立或轉換</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 新 cluster 指定 serverless v2 capacity range</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">aws rds create-db-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --db-cluster-identifier my-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --engine aurora-postgresql <span class="se">\
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="se"></span>  --serverless-v2-scaling-configuration <span class="nv">MinCapacity</span><span class="o">=</span>2,MaxCapacity<span class="o">=</span><span class="m">32</span></span></span></code></pre></div><p>既有 provisioned cluster 可加 serverless v2 reader、逐步驗證再調整 writer。</p>
<h4 id="step-4觀察-acu-曲線">Step 4：觀察 ACU 曲線</h4>
<p>上線後盯 <code>ServerlessDatabaseCapacity</code>（即時 ACU）與 <code>ACUUtilization</code>，確認伸縮符合負載、min/max 設定合理。</p>
<h4 id="step-5成本對照">Step 5：成本對照</h4>
<p>把實際 ACU-秒換算的帳單，跟「同等 provisioned instance 全時段開機」對照。若 serverless 帳單接近或超過 provisioned，代表負載其實夠穩定、該回 provisioned。</p>
<h4 id="step-6驗證點">Step 6：驗證點</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl"># 驗證離峰真的縮到 min ACU（看 ServerlessDatabaseCapacity 低谷）
</span></span><span class="line"><span class="ln">2</span><span class="cl"># 驗證尖峰沒撞 max ACU 天花板（看是否長時間貼著 max）
</span></span><span class="line"><span class="ln">3</span><span class="cl"># 驗證回升期 latency 可接受（min ACU 暖容量是否足夠）</span></span></code></pre></div><p><strong>Rollback boundary</strong>：serverless v2 與 provisioned 可互轉、reader 先轉驗證再動 writer；轉換本身有短暫中斷，要排 maintenance window。</p>
<h2 id="失敗模式">失敗模式</h2>
<p>production 常見的 5 個踩雷：</p>
<h4 id="case-1穩定高負載用-serverless-反而更貴">Case 1：穩定高負載用 serverless 反而更貴</h4>
<p>把一個 7x24 高使用率的 cluster 改 serverless「以為省錢」，實際 ACU 幾乎全時段貼近高水位、按 ACU-秒計費比固定 instance 貴。修法：穩定高負載用 provisioned；serverless 的省錢前提是「有顯著的離峰可以縮」。</p>
<h4 id="case-2min-acu-設太低回升期-latency-尖刺">Case 2：min ACU 設太低、回升期 latency 尖刺</h4>
<p>離峰縮到極低、早上流量回來時 cache 冷、ACU 從低水位爬、前幾分鐘 query 變慢。修法：規律日週期的 workload，min ACU 留足暖容量；或用 provisioned + scheduled scaling 處理可預測的日週期。</p>
<h4 id="case-3max-acu-沒當成本天花板監控">Case 3：max ACU 沒當成本天花板監控</h4>
<p>缺索引的 query 觸發全表掃描、ACU 一路衝到 max、帳單尖峰才發現。修法：max ACU 設合理上限 + CloudWatch alarm 盯 ACU 長時間貼 max（那是 query 或容量問題的訊號，不是正常擴縮）。</p>
<h4 id="case-4把-serverless-當不用做容量規劃">Case 4：把 serverless 當「不用做容量規劃」</h4>
<p>以為 serverless 自動伸縮就不必估容量、min/max 隨便設。修法：serverless 改變的是「不用手動切 instance」，不是「不用理解負載形狀」；min/max 仍要基於負載曲線設定。</p>
<h4 id="case-5對延遲極敏感的-oltp-全-serverless">Case 5：對延遲極敏感的 OLTP 全 serverless</h4>
<p>核心交易路徑要求穩定低延遲、卻用會伸縮的 serverless writer、伸縮邊界期間 latency 抖動。修法：穩定低延遲的核心寫入用 provisioned writer，serverless 留給可容忍伸縮抖動的讀取 / 分析副本（混合 cluster）。</p>
<p><strong>Anti-recommendation</strong>：負載穩定、使用率長期偏高、或對延遲抖動零容忍的核心 OLTP → 用 provisioned；serverless v2 的價值在「間歇、突發、難預測、或有大量離峰」的負載，沒有離峰可縮就沒有省錢空間。</p>
<h2 id="容量與觀測">容量與觀測</h2>
<p>CloudWatch metric：</p>
<ul>
<li><code>ServerlessDatabaseCapacity</code>：即時 ACU、看伸縮曲線</li>
<li><code>ACUUtilization</code>：ACU 使用率、判斷 min/max 設定是否合理</li>
<li><code>CPUUtilization</code> / <code>DatabaseConnections</code>：底層負載、對照 ACU 是否跟得上</li>
</ul>
<p><strong>判讀</strong>：</p>
<ul>
<li>ACU 長時間貼近 max → max 設太低或有失控 query，要查</li>
<li>ACU 長時間貼近 min 且使用率低 → 負載其實很輕，min 可能可再降、或這個 cluster 適合更小配置</li>
<li>ACU 幾乎不波動且水位高 → 負載穩定，serverless 沒發揮價值，評估改 provisioned</li>
</ul>
<blockquote>
<p><strong>Scope warning</strong>：本文未引用 production case 的 ACU 數字；上述 metric 與判讀屬 vendor 規格 + 通用容量工程。</p></blockquote>
<p>接回 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora 容量規劃要點</a>。</p>
<h2 id="邊界與整合">邊界與整合</h2>
<h3 id="serverless-v2-vs-provisioned--scheduled-scaling">Serverless v2 vs provisioned + scheduled scaling</h3>
<p>兩者都能處理「負載隨時間變」，但適用場景不同：</p>
<ul>
<li><strong>scheduled scaling（provisioned）</strong>：負載 <em>可預測</em>（已知的日週期、已知大活動）→ 預先排程改容量，成本最可控</li>
<li><strong>serverless v2</strong>：負載 <em>不可預測</em>（突發、不規則）→ 自動伸縮吸收，不需預測</li>
</ul>
<p>可預測的尖峰用 scheduled、不可預測的用 serverless，這跟 <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB capacity mode</a> 的 predictable-peak vs flash-sale 判讀同源。</p>
<h3 id="sibling-與-cross-link">Sibling 與 cross-link</h3>
<ul>
<li><a href="/blog/backend/01-database/vendors/aurora/storage-architecture/" data-link-title="Aurora Storage Architecture：quorum-based 分散式 log 與韌性即性能設計" data-link-desc="Aurora storage / compute 分離、6-way 跨 AZ replication、4-of-6 write / 3-of-6 read quorum、韌性投資自動 amortize 成 read 性能、DraftKings 6ms 寫 / &lt;1ms 讀 production reference">storage-architecture</a> — serverless 只改 compute 層容量、storage 層 quorum 設計不變</li>
<li><a href="/blog/backend/01-database/vendors/aurora/read-replica-scaling/" data-link-title="Aurora Read Replica Scaling：15 replica 上限、lag profile、headroom 預留與 fleet 治理" data-link-desc="Aurora 15 replica 上限、共享 storage 為什麼能養大量 replica、事件型容量分級表、DraftKings headroom 預留判讀、FanDuel 雙 SLO 並行、fleet 治理 3 條 driver（business sharding / microservice / 合規）">read-replica-scaling</a> — serverless reader 吸收讀取尖峰、與 fleet 治理結合</li>
<li><a href="/blog/backend/01-database/vendors/postgresql/aurora-io-optimized-cost/" data-link-title="Aurora PostgreSQL I/O-Optimized Cost" data-link-desc="Aurora PostgreSQL Standard 與 I/O-Optimized 的成本模型、I/O 壓力、workload 判斷、遷移與回退條件">Aurora I/O-Optimized cost</a> — serverless 算的是 compute（ACU）成本、I/O-Optimized 算的是 storage I/O 成本，兩個成本軸獨立、要分開評估</li>
<li><a href="/blog/backend/01-database/vendors/aurora/rds-proxy-connection-pooling/" data-link-title="Aurora RDS Proxy 與連線管理：connection multiplexing、pinning 陷阱與 failover 加速" data-link-desc="RDS Proxy 不是「連上去就自動省連線」；本文展開 connection multiplexing 機制、哪些 session 操作會觸發 pinning 讓 multiplexing 失效、failover 期間 proxy 如何保持 client 連線縮短中斷，以及 RDS Proxy 與自管 pgbouncer 的責任切分">rds-proxy-connection-pooling</a> — serverless + Lambda 場景的連線管理</li>
<li>替代路由：負載穩定且高 → provisioned；KV access pattern → <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB</a></li>
<li>跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix 9.C23</a> 互引：polyglot 架構下不同 workload 用不同 Aurora 配置（穩定 OLTP provisioned、間歇副本 serverless）</li>
</ul>
]]></content:encoded></item><item><title>Pyroscope</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/</guid><description>&lt;p>Pyroscope 的核心責任是提供開源 continuous profiling backend，讓團隊用 Grafana 生態保存、查詢、比較與視覺化 production profile。它適合偏 OSS-first、已使用 Grafana / Prometheus / Tempo / Loki 的團隊，重點在把 CPU、memory、allocation 與 profile diff 放進可自管 observability stack。Pyroscope 原為獨立 OSS 專案、&lt;em>2023 年被 Grafana Labs 收購&lt;/em>、現分兩條產品線：&lt;em>Grafana Pyroscope&lt;/em>（OSS、Apache 2.0、self-host）與 &lt;em>Grafana Cloud Profiles&lt;/em>（商業 SaaS、走 Grafana Cloud 計費）。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Pyroscope 在 continuous profiling 賽道上的差異點是 &lt;em>Grafana Labs 整合 + 多語言 SDK 覆蓋&lt;/em>、而不是 profiling 演算法本身。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca&lt;/a> 比、Parca 走 &lt;em>pprof + Prometheus-style label&lt;/em> 的 CNCF / eBPF infrastructure profiling 路線、focus 在 system-wide 一次抓全機；Pyroscope 走 &lt;em>per-language SDK + Grafana stack 整合&lt;/em> 的 developer-facing 路線、focus 在 application-level flame graph 與 release diff。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler&lt;/a> 比、Datadog 走 &lt;em>SaaS all-in-one + APM 同 trace context&lt;/em>、profiling 自動跟 trace span 關聯；Pyroscope 走 &lt;em>self-host 可選 + Grafana 跨 signal&lt;/em>、整合靠 Grafana dashboard 跟 explore link 而非 product-level deep linking。&lt;/p>
&lt;p>這個定位讓 Pyroscope 接到 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop&lt;/a>。它的價值在於 OSS / Grafana 整合與可自管；它的代價在於 storage、retention、agent rollout 與營運責任要由團隊承擔。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Pyroscope deployment 是否健康、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Agent / SDK setup&lt;/strong>：是用 &lt;em>language SDK&lt;/em>（in-process profiler、跟 application code 一起部署）還是 &lt;em>Grafana Alloy / Pyroscope agent&lt;/em>（out-of-process、適合 binary-only 或無法改 code 的 workload）— 兩條路 overhead、覆蓋率、tag 注入方式都不同&lt;/li>
&lt;li>&lt;strong>Push or pull model&lt;/strong>：SDK 預設 &lt;em>push&lt;/em>（application 主動把 profile sample 推到 Pyroscope server）、Alloy / agent 可走 &lt;em>pull&lt;/em>（scrape pprof endpoint、跟 Prometheus 同模型）— push 適合 short-lived job / serverless、pull 適合 long-running service + Kubernetes service discovery&lt;/li>
&lt;li>&lt;strong>Grafana integration&lt;/strong>：是否在 Grafana datasource 設好 Pyroscope、explore 是否能跨 trace / log / profile 跳轉（Tempo trace → Pyroscope profile by service+span）、dashboard 是否內嵌 flame graph panel&lt;/li>
&lt;li>&lt;strong>Tag schema discipline&lt;/strong>：service / version / region / environment / pod 是否一致命名、deploy event 是否打 label 讓 baseline / candidate 比較可成立&lt;/li>
&lt;/ul>
&lt;p>四件事任一缺失、profile 就只是「能看 flame graph」而非「release gate evidence」、無法支撐 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop&lt;/a> 的 diff workflow。&lt;/p></description><content:encoded><![CDATA[<p>Pyroscope 的核心責任是提供開源 continuous profiling backend，讓團隊用 Grafana 生態保存、查詢、比較與視覺化 production profile。它適合偏 OSS-first、已使用 Grafana / Prometheus / Tempo / Loki 的團隊，重點在把 CPU、memory、allocation 與 profile diff 放進可自管 observability stack。Pyroscope 原為獨立 OSS 專案、<em>2023 年被 Grafana Labs 收購</em>、現分兩條產品線：<em>Grafana Pyroscope</em>（OSS、Apache 2.0、self-host）與 <em>Grafana Cloud Profiles</em>（商業 SaaS、走 Grafana Cloud 計費）。</p>
<h2 id="服務定位">服務定位</h2>
<p>Pyroscope 在 continuous profiling 賽道上的差異點是 <em>Grafana Labs 整合 + 多語言 SDK 覆蓋</em>、而不是 profiling 演算法本身。跟 <a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a> 比、Parca 走 <em>pprof + Prometheus-style label</em> 的 CNCF / eBPF infrastructure profiling 路線、focus 在 system-wide 一次抓全機；Pyroscope 走 <em>per-language SDK + Grafana stack 整合</em> 的 developer-facing 路線、focus 在 application-level flame graph 與 release diff。跟 <a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a> 比、Datadog 走 <em>SaaS all-in-one + APM 同 trace context</em>、profiling 自動跟 trace span 關聯；Pyroscope 走 <em>self-host 可選 + Grafana 跨 signal</em>、整合靠 Grafana dashboard 跟 explore link 而非 product-level deep linking。</p>
<p>這個定位讓 Pyroscope 接到 <a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a> 與 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a>。它的價值在於 OSS / Grafana 整合與可自管；它的代價在於 storage、retention、agent rollout 與營運責任要由團隊承擔。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Pyroscope deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Agent / SDK setup</strong>：是用 <em>language SDK</em>（in-process profiler、跟 application code 一起部署）還是 <em>Grafana Alloy / Pyroscope agent</em>（out-of-process、適合 binary-only 或無法改 code 的 workload）— 兩條路 overhead、覆蓋率、tag 注入方式都不同</li>
<li><strong>Push or pull model</strong>：SDK 預設 <em>push</em>（application 主動把 profile sample 推到 Pyroscope server）、Alloy / agent 可走 <em>pull</em>（scrape pprof endpoint、跟 Prometheus 同模型）— push 適合 short-lived job / serverless、pull 適合 long-running service + Kubernetes service discovery</li>
<li><strong>Grafana integration</strong>：是否在 Grafana datasource 設好 Pyroscope、explore 是否能跨 trace / log / profile 跳轉（Tempo trace → Pyroscope profile by service+span）、dashboard 是否內嵌 flame graph panel</li>
<li><strong>Tag schema discipline</strong>：service / version / region / environment / pod 是否一致命名、deploy event 是否打 label 讓 baseline / candidate 比較可成立</li>
</ul>
<p>四件事任一缺失、profile 就只是「能看 flame graph」而非「release gate evidence」、無法支撐 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 的 diff workflow。</p>
<h2 id="適用場景">適用場景</h2>
<p>自管 profiling backend 適合 Pyroscope。團隊若有資料主權、成本控制、內網部署或 OSS-first 要求，可以用 Pyroscope 保存 profile，降低 profile sample 外送帶來的治理成本。</p>
<p>Profile diff workflow 適合 Pyroscope。Release candidate、canary、baseline review 或 incident after-action 都可以用時間區間比較，找出 CPU、memory 或 allocation 的相對變化。</p>
<p>Grafana stack 整合適合 Pyroscope。若服務已經有 Grafana dashboard，profile link 可以放進 latency、CPU、memory、cost 或 release dashboard，讓 SRE 從聚合訊號跳到 callstack。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Pyroscope 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>OSS / self-host</td>
          <td>profile 資料可自管</td>
          <td>backend storage、retention、upgrade</td>
      </tr>
      <tr>
          <td>Grafana 整合</td>
          <td>dashboard、explore、profile link 容易串接</td>
          <td>tag schema 與 dashboard discipline</td>
      </tr>
      <tr>
          <td>Profile diff</td>
          <td>時間區間與版本對比直觀</td>
          <td>deploy label 與 baseline 管理</td>
      </tr>
      <tr>
          <td>多語言 agent</td>
          <td>常見 runtime 可導入</td>
          <td>agent overhead 與覆蓋差異量測</td>
      </tr>
  </tbody>
</table>
<p>OSS / self-host 價值來自控制權。Profile 可能包含 function name、package path、tenant-specific code path 或敏感 business logic，自管能讓資料保存與存取控制更貼近內部規範。</p>
<p>Grafana 整合價值來自操作連續性。當 CPU dashboard、latency dashboard 與 deploy annotation 都在 Grafana 中，Pyroscope 能讓工程師從圖表直接切到 flame graph。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Pyroscope 和 Datadog Continuous Profiler 的主要差異是平台責任。Pyroscope 偏 OSS / self-host / Grafana stack；Datadog 偏 SaaS all-in-one 與 APM product workflow。</p>
<p>Pyroscope 和 Parca 的主要差異是生態定位。Pyroscope 偏 Grafana profiling backend 與 developer-facing flame graph；Parca 偏 eBPF / infrastructure-wide profiling 與 CNCF 生態。</p>
<p>Pyroscope 和一次性 profiler 的主要差異是可比較性。一次性 profiler 擅長局部調查；Pyroscope 擅長讓 profile 成為 release baseline 與 incident evidence。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Pyroscope（Grafana）</th>
          <th>Parca</th>
          <th>Datadog Continuous Profiler</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>OSS self-host / Grafana Cloud Profiles SaaS</td>
          <td>OSS self-host（CNCF Sandbox）</td>
          <td>SaaS only</td>
      </tr>
      <tr>
          <td>Profile 來源</td>
          <td>language SDK + Alloy / agent（push 為主）</td>
          <td>pprof scrape（pull）+ Parca Agent（eBPF）</td>
          <td>Datadog Agent + language tracer 整合</td>
      </tr>
      <tr>
          <td>語言覆蓋</td>
          <td>Go / Python / Java / Ruby / .NET / Rust / Node</td>
          <td>任何能輸出 pprof 的 runtime + eBPF system-wide</td>
          <td>Go / Python / Java / Ruby / .NET / Node</td>
      </tr>
      <tr>
          <td>Tag / label</td>
          <td>Prometheus-style label + 自訂 tag</td>
          <td>Prometheus-style label</td>
          <td>Datadog tag（跟 APM 共用）</td>
      </tr>
      <tr>
          <td>Diff workflow</td>
          <td>時間區間 + label 對比 + flame graph diff UI</td>
          <td>時間區間 + label 對比</td>
          <td>自動跟 deploy event + trace span 關聯</td>
      </tr>
      <tr>
          <td>整合方向</td>
          <td>Grafana（Tempo / Loki / Mimir 互跳）</td>
          <td>Prometheus / Grafana（弱整合）</td>
          <td>Datadog APM / Logs / Metrics 同 plane</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Grafana-first、OSS-friendly、release diff 主流程</td>
          <td>infrastructure-wide eBPF profiling、CNCF 生態</td>
          <td>Datadog 已是主 observability、要 APM 連動</td>
      </tr>
  </tbody>
</table>
<p>選 Pyroscope 的核心訴求：<em>已用 Grafana stack + 多語言服務組合 + 要 OSS self-host 選項或預算敏感</em>、profile 主要用途是 release diff / incident hot-path 定位、不需要 APM-level 自動 trace 關聯。</p>
<h2 id="操作成本">操作成本</h2>
<p>Pyroscope 的主要成本是自管 backend。Profile ingest、storage、retention、compaction、backup、upgrade 與 dashboard ownership 都需要團隊負責。</p>
<p>Tag 成本來自查詢維度。service、version、region、environment、runtime、pod、tenant 這些 label 能提高定位能力，也會增加 cardinality、儲存與查詢成本。</p>
<p>Agent 成本來自 rollout 與 overhead。導入時要先選代表性服務，量測 profiler 對 CPU、memory、latency 的影響，再逐步擴大到 critical path。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Pyroscope 結果應回寫到 evidence package。最小欄位包括 service、version、environment、profile type、baseline window、candidate window、profile diff link、tag set、retention policy、overhead estimate、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Pyroscope 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>profile query、flame graph、diff link</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>baseline / candidate profile window</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>Grafana / Pyroscope explore link</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>tag completeness、sampling status</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>production coverage、agent overhead</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 runtime、tag drift、retention gap</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是讓 profile diff 成為 release artifact。Reviewer 要能從 release gate 打開 Pyroscope diff，確認變化來自 code path、runtime 行為、負載變化或 baseline drift。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Grafana Cloud Profiles</strong>：商業 SaaS 版本、走 Grafana Cloud 計費（per-series 或 per-profile bytes）、適合不想自管 storage / retention / compaction 的團隊。跟 OSS Pyroscope 共用 SDK 跟 query API、可在 OSS 起步、規模到一定程度再遷移到 Cloud、避免廠商一開始就鎖死。</p>
<p><strong>Flame graph diff</strong>：Pyroscope 的核心 release workflow — 選 baseline window（release 前 24hr）跟 candidate window（release 後 24hr）、UI 把兩張 flame graph 差異標紅綠、可直接看到哪個 function 變慢 / 變快。判讀要點是 <em>baseline window 要排除部署當下的 warm-up / cache miss spike</em>、否則 diff 噪音蓋過真實 regression。</p>
<p><strong>多語言 SDK 覆蓋</strong>：Pyroscope 官方 SDK 覆蓋 Go / Python / Java / Ruby / .NET / Rust / Node.js — Go SDK 用 <code>runtime/pprof</code> 包裝、Java 走 async-profiler、Python 走 <code>py-spy</code> 風格 sampling profiler、Node.js 走 V8 sampling。各 SDK overhead 不一致（Java async-profiler ~1%、Python py-spy ~3-5%）、選型時要看代表性服務量測再 rollout、不能假設「都很低」。</p>
<p><strong>Adhoc profiling</strong>：當 production SDK 沒裝、或想對 batch job / CLI tool 做一次性 profile、可用 Pyroscope CLI 上傳 <em>standalone pprof file</em>（<code>pyroscope adhoc</code> 或 <code>profilecli</code>）— 補位「標準 pprof endpoint 不夠用、但又不想長期 instrument」的情境。對 ad-hoc incident investigation 跟 batch job postmortem 特別有用。</p>
<p><strong>Grafana Alloy 整合</strong>：Grafana Alloy（前 Grafana Agent）內建 Pyroscope receiver、可同時 scrape Prometheus metrics + tail Loki log + push Tempo trace + scrape Pyroscope profile、單一 agent 跨 four signal、降低 sidecar 數量跟維運成本。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>SDK overhead 過高 / latency p99 上升</strong>：profile sample rate 太高、或 Java async-profiler 在低 CPU host 競爭 schedule — 降 sample rate、staging 量測 CPU / latency delta 確認 &lt; 3% 再 promote</li>
<li><strong>Push agent 跟 pull agent 取捨錯</strong>：short-lived job 用 pull 結果還沒被 scrape 就 exit、long-running service 用 push 結果 Pyroscope server 過載 — short-lived / serverless 走 SDK push、long-running + Kubernetes service discovery 走 Alloy pull</li>
<li><strong>Label cardinality 爆 / storage 跟查詢都慢</strong>：tag 加了 pod name / request ID / user ID 等高 cardinality 維度 — 限制 tag 為 service / version / region / environment / cluster 等低 cardinality、高基數維度走 trace / log 別放 profile</li>
<li><strong>Baseline / candidate diff 全是噪音</strong>：baseline window 沒對齊流量模式（off-peak vs peak）、或 deploy label 沒打 — 要求 release pipeline 自動寫 <code>version</code> / <code>deploy_id</code> label、diff window 跨完整流量週期（24hr or 7day）</li>
<li><strong>Grafana datasource 連不到 / explore 跳轉失敗</strong>：datasource URL 設錯、或 service / span tag 不一致 — Tempo trace 用的 <code>service.name</code> 要跟 Pyroscope <code>service</code> label 對齊、否則 cross-signal 跳轉斷裂</li>
<li><strong>Storage / retention 失控</strong>：profile 保留太久、SmartStore-like 冷儲存沒設 — Pyroscope OSS 支援 object storage（S3 / GCS）backend、長 retention 必開、不然 PV 會爆</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>已用 Datadog APM、要 trace ↔ profile 自動關聯</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a></td>
      </tr>
      <tr>
          <td>要 eBPF system-wide / infrastructure profiling</td>
          <td><a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a></td>
      </tr>
      <tr>
          <td>不想自管 backend、但要 Grafana stack</td>
          <td>Grafana Cloud Profiles（商業 SaaS、同 SDK）</td>
      </tr>
  </tbody>
</table>
<h2 id="案例回寫">案例回寫</h2>
<p>Pyroscope 適合回寫 OSS observability 與 release diff 案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的 profile noise 降低、<a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi feature store</a> 的 hot path 定位、<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS multi-cluster</a> 的 single-tenant per game profile 隔離、<a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom 遊戲後端</a> 的 30% 成本下降 hot path 分析，以及 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Improvement Loop</a> 的 baseline / candidate profile diff。</p>
<p>這些案例的重點是可比較 profile。Pyroscope 頁引用案例時，要把 case 轉成 tag schema、baseline window、candidate window、flame graph diff 與 release gate evidence — 例如 Riot Games 246 cluster 的 tag schema 必須涵蓋 game / region / cluster 三維、才能避免「跨遊戲混合 profile」的歸因錯誤。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 效能可觀測性</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a></li>
<li>官方：<a href="https://grafana.com/docs/pyroscope/latest/">Grafana Pyroscope documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/</guid><description>&lt;p>這個案例的核心責任是補強 GCP 案例庫的「商業應用」深度、並提供拉丁美洲電商規模對標。Mercado Libre 是拉丁美洲最大電商（市值 600 億美金級）、業務涵蓋 18 個國家、是區域型平台的容量規劃範本。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Mercado Libre 在 GCP 的關鍵敘述（引自 &lt;a href="https://cloud.google.com/customers/mercado-libre">Mercado Libre Customer Story&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>客戶數&lt;/td>
 &lt;td>1 億&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>商品數&lt;/td>
 &lt;td>1.5 億（3 個試點國家）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>業務影響&lt;/td>
 &lt;td>數百萬美金 incremental revenue（Vertex AI Search）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主要 GCP 服務&lt;/td>
 &lt;td>Vertex AI Search、BigQuery&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料即時性&lt;/td>
 &lt;td>near real-time&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務地理&lt;/td>
 &lt;td>拉丁美洲&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵能力：「Vertex AI Search across 150 million items in three pilot countries that is helping its 100 million customers find the products they love faster」、「BigQuery to design a robust data architecture that ensures the availability of data in near real-time」。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Mercado Libre 揭露三個區域電商容量規劃重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>區域電商 ≠ 全球電商&lt;/strong>：拉丁美洲 18 個國家、各自有獨立貨幣、稅務、物流、合規規則。容量規劃單位通常是「per country」、不是「per region」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered&lt;/a> 的市場分割、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow&lt;/a> 的跨國平台對照。&lt;/li>
&lt;li>&lt;strong>Vertex AI Search = 「搜尋」當作 ML 服務、不是 Elasticsearch&lt;/strong>：傳統電商搜尋靠 Elasticsearch / OpenSearch + 自訓 ranker、Mercado Libre 用 vendor managed Vertex AI Search、把「商品搜尋 + 推薦排序」當作 ML 黑盒。這個取捨用「不可調參」換「快速上線」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的 build vs buy、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify&lt;/a> 的 managed 轉向同類思維。&lt;/li>
&lt;li>&lt;strong>「數百萬美金 incremental revenue」是 ML 容量規劃的真實 ROI&lt;/strong>：搜尋改善 → 轉換率 → 訂單 → 收入、ML 投資的 cost 才能合理化。容量規劃不只看「能撐多大流量」、也要看「擴容能否帶業務 ROI」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency&lt;/a> 的成本工程化。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是補強 GCP 案例庫的「商業應用」深度、並提供拉丁美洲電商規模對標。Mercado Libre 是拉丁美洲最大電商（市值 600 億美金級）、業務涵蓋 18 個國家、是區域型平台的容量規劃範本。</p>
<h2 id="觀察">觀察</h2>
<p>Mercado Libre 在 GCP 的關鍵敘述（引自 <a href="https://cloud.google.com/customers/mercado-libre">Mercado Libre Customer Story</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>客戶數</td>
          <td>1 億</td>
      </tr>
      <tr>
          <td>商品數</td>
          <td>1.5 億（3 個試點國家）</td>
      </tr>
      <tr>
          <td>業務影響</td>
          <td>數百萬美金 incremental revenue（Vertex AI Search）</td>
      </tr>
      <tr>
          <td>主要 GCP 服務</td>
          <td>Vertex AI Search、BigQuery</td>
      </tr>
      <tr>
          <td>資料即時性</td>
          <td>near real-time</td>
      </tr>
      <tr>
          <td>服務地理</td>
          <td>拉丁美洲</td>
      </tr>
  </tbody>
</table>
<p>關鍵能力：「Vertex AI Search across 150 million items in three pilot countries that is helping its 100 million customers find the products they love faster」、「BigQuery to design a robust data architecture that ensures the availability of data in near real-time」。</p>
<h2 id="判讀">判讀</h2>
<p>Mercado Libre 揭露三個區域電商容量規劃重點。</p>
<ol>
<li><strong>區域電商 ≠ 全球電商</strong>：拉丁美洲 18 個國家、各自有獨立貨幣、稅務、物流、合規規則。容量規劃單位通常是「per country」、不是「per region」。對應 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 的市場分割、跟 <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a> 的跨國平台對照。</li>
<li><strong>Vertex AI Search = 「搜尋」當作 ML 服務、不是 Elasticsearch</strong>：傳統電商搜尋靠 Elasticsearch / OpenSearch + 自訓 ranker、Mercado Libre 用 vendor managed Vertex AI Search、把「商品搜尋 + 推薦排序」當作 ML 黑盒。這個取捨用「不可調參」換「快速上線」。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 build vs buy、跟 <a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a> 的 managed 轉向同類思維。</li>
<li><strong>「數百萬美金 incremental revenue」是 ML 容量規劃的真實 ROI</strong>：搜尋改善 → 轉換率 → 訂單 → 收入、ML 投資的 cost 才能合理化。容量規劃不只看「能撐多大流量」、也要看「擴容能否帶業務 ROI」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的成本工程化。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「1.5 億商品 in 3 pilot countries」是 <em>試點規模</em>、不是全平台。全平台商品總數應該更大、但案例沒揭露。</li>
<li>BigQuery「near real-time」沒指明 latency（秒級、分鐘級）。BigQuery 傳統是 minutes-level、不是 sub-second、對「即時」的定義要謹慎。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>區域電商的容量規劃是「per country × peak_factor」</strong>：不是「per region」聚合、要按國家分別規劃。每個國家自己的 Black Friday / Cyber Monday / 雙 11 / 6.18 等本地大促時間都不同。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a>。</li>
<li><strong>「商品搜尋」適合用 managed AI search</strong>：除非有自家強大的 ML team + 大量訓練資料、否則 Vertex AI Search / OpenSearch Service 等 managed 比自建 ranker 划算。</li>
<li><strong>BigQuery 是 LatAm / 新興市場數據平台的標配</strong>：能處理 PB 級資料、無需 cluster 管理、適合中等工程資源的團隊。對應 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 的 data 平台選型、跟 <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a> 的 Redshift + Athena 對照。</li>
<li><strong>ML ROI 直接 ＝ 業務指標</strong>：transaction conversion rate、AOV、recommendation CTR 都是 ML 容量規劃的下游 KPI。</li>
</ol>
<p>跨平台等效：AWS Personalize + Redshift + Glue、Azure AI Search + Synapse 都是對等候選。差異是 vendor 整合度跟模型的可調參空間。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他大規模電商 → <a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS Black Friday</a> / <a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair burst</a></li>
<li>想規劃跨國容量 → <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> + <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a></li>
<li>想做 ML feature serving → <a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi ML feature store</a></li>
<li>想做 build vs buy 決策 → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/customers/mercado-libre">Mercado Libre Customer Story</a></li>
<li><a href="https://cloud.google.com/blog/products/data-analytics/how-mercado-libre-uses-real-time-analytics-for-on-time-delivery">How Mercado Libre uses real-time analytics for on-time delivery</a></li>
</ul>
]]></content:encoded></item><item><title>Parca</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/parca/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/parca/</guid><description>&lt;p>Parca 的核心責任是用開源 continuous profiling 與 eBPF 路線建立 infrastructure-wide profile evidence。它適合需要低侵入、跨 process、跨 service、偏平台層的 profiling 團隊，重點在用 always-on profile 找出 CPU、memory、runtime 與 kernel / user space 的資源熱點。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Parca 是 Polar Signals 主導的 OSS continuous profiling、特色是 &lt;em>eBPF-based 採集 + pprof 標準格式 + Prometheus-style 拉取與 label 模型&lt;/em>。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope&lt;/a> 是 OSS 同類、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler&lt;/a> 則是 OSS / 自管 vs SaaS / APM 整合的差異。eBPF agent 直接從 kernel 採 stack trace、不需要 application 改 code 或注入 runtime agent；pprof 格式讓既有 Go / Java / Python 工具鏈可以直接讀；Prometheus-style scrape 讓 Parca server 跟 metrics 用同一套 service discovery 與 label。&lt;/p>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Parca 部署是否能撐起 platform-wide profiling、最少看四件事：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>eBPF agent deploy&lt;/strong>：Parca Agent 走 DaemonSet 跑在每個 node、需要 kernel ≥ 4.18（CO-RE / BTF）、&lt;code>SYS_ADMIN&lt;/code> 或 &lt;code>PERF_EVENT&lt;/code> capability、host PID namespace。受管 Kubernetes（GKE / EKS / AKS）的 worker node 是否允許這個權限是第一個判讀點&lt;/li>
&lt;li>&lt;strong>Parca server scrape&lt;/strong>：server 跟 agent 走 pull-based、Prometheus-style ServiceMonitor / scrape config、label 跟 metrics 同模型（namespace / pod / container / node）。scrape interval、retention、storage backend（FrostDB 內建 / object storage）要明確&lt;/li>
&lt;li>&lt;strong>pprof query&lt;/strong>：profile 以 pprof format 存、Parca UI 提供 flame graph 與 compare view、也可 export pprof file 給 &lt;code>go tool pprof&lt;/code> 或其他既有工具離線分析&lt;/li>
&lt;li>&lt;strong>Grafana integration&lt;/strong>：Parca 提供 datasource plugin、profile 可以跟 metrics / log / trace 在 Grafana 同一頁 correlate、配 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope&lt;/a> 或 Tempo 形成 observability 對齊&lt;/li>
&lt;/ul>
&lt;p>四件事任一缺失、就是 profiling control plane 還沒上線的待補項目。&lt;/p></description><content:encoded><![CDATA[<p>Parca 的核心責任是用開源 continuous profiling 與 eBPF 路線建立 infrastructure-wide profile evidence。它適合需要低侵入、跨 process、跨 service、偏平台層的 profiling 團隊，重點在用 always-on profile 找出 CPU、memory、runtime 與 kernel / user space 的資源熱點。</p>
<h2 id="服務定位">服務定位</h2>
<p>Parca 是 Polar Signals 主導的 OSS continuous profiling、特色是 <em>eBPF-based 採集 + pprof 標準格式 + Prometheus-style 拉取與 label 模型</em>。它跟 <a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a> 是 OSS 同類、跟 <a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a> 則是 OSS / 自管 vs SaaS / APM 整合的差異。eBPF agent 直接從 kernel 採 stack trace、不需要 application 改 code 或注入 runtime agent；pprof 格式讓既有 Go / Java / Python 工具鏈可以直接讀；Prometheus-style scrape 讓 Parca server 跟 metrics 用同一套 service discovery 與 label。</p>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Parca 部署是否能撐起 platform-wide profiling、最少看四件事：</p>
<ul>
<li><strong>eBPF agent deploy</strong>：Parca Agent 走 DaemonSet 跑在每個 node、需要 kernel ≥ 4.18（CO-RE / BTF）、<code>SYS_ADMIN</code> 或 <code>PERF_EVENT</code> capability、host PID namespace。受管 Kubernetes（GKE / EKS / AKS）的 worker node 是否允許這個權限是第一個判讀點</li>
<li><strong>Parca server scrape</strong>：server 跟 agent 走 pull-based、Prometheus-style ServiceMonitor / scrape config、label 跟 metrics 同模型（namespace / pod / container / node）。scrape interval、retention、storage backend（FrostDB 內建 / object storage）要明確</li>
<li><strong>pprof query</strong>：profile 以 pprof format 存、Parca UI 提供 flame graph 與 compare view、也可 export pprof file 給 <code>go tool pprof</code> 或其他既有工具離線分析</li>
<li><strong>Grafana integration</strong>：Parca 提供 datasource plugin、profile 可以跟 metrics / log / trace 在 Grafana 同一頁 correlate、配 <a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a> 或 Tempo 形成 observability 對齊</li>
</ul>
<p>四件事任一缺失、就是 profiling control plane 還沒上線的待補項目。</p>
<h2 id="定位">定位</h2>
<p>Parca 適合平台團隊建立 profiling control plane。當問題橫跨 Kubernetes cluster、node pool、multi-service path 或 shared runtime 成本，Parca 能從更接近 infrastructure 的角度收集 profile。</p>
<p>這個定位讓 Parca 接到 <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a> 與 <a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a>。它的價值在於低侵入與平台廣度；它的代價在於 eBPF 支援、symbolization、storage、權限與平台維運責任。</p>
<h2 id="適用場景">適用場景</h2>
<p>Infrastructure-wide profiling 適合 Parca。平台團隊可以觀察 cluster、node、namespace、service 與 process 的 CPU 熱點，找出共同 library、runtime、sidecar、agent 或 kernel path 的成本。</p>
<p>Kubernetes 平台適合 Parca。當服務在多 namespace、多 workload、多 node pool 上運作，Parca 可以把 profile 維度接到 pod、container、node、namespace 與 label。</p>
<p>低侵入 profiling 適合 Parca。eBPF-based profiling 可以降低 application instrumentation 成本，讓團隊先取得廣域視角，再對特定服務加更細的 runtime profiler 或 APM 整合。</p>
<h2 id="選型判準">選型判準</h2>
<table>
  <thead>
      <tr>
          <th>判準</th>
          <th>Parca 的價值</th>
          <th>需要補的能力</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>eBPF / low overhead</td>
          <td>低侵入取得廣域 profile</td>
          <td>kernel / runtime 支援與權限治理</td>
      </tr>
      <tr>
          <td>Platform-wide</td>
          <td>node、namespace、service 維度可對照</td>
          <td>Kubernetes label 與 ownership discipline</td>
      </tr>
      <tr>
          <td>Open source</td>
          <td>profiling platform 可自管</td>
          <td>storage、retention、upgrade</td>
      </tr>
      <tr>
          <td>Compare / diff</td>
          <td>profile compare 支援退化定位</td>
          <td>deploy label、baseline 與 symbolization</td>
      </tr>
  </tbody>
</table>
<p>eBPF / low overhead 價值來自平台廣度。團隊可以先觀察整個基礎設施的 CPU 熱點，再決定哪些服務需要更深入的 application-level profiling。</p>
<p>Platform-wide 價值來自共同成本治理。Sidecar、agent、logging library、serialization library 或 runtime upgrade 的成本可能散在多個服務中，Parca 這類工具能把分散成本聚合回平台決策。</p>
<h2 id="跟其他工具的取捨">跟其他工具的取捨</h2>
<p>Parca 和 Datadog Continuous Profiler 的主要差異是平台模型。Parca 偏開源、自管、eBPF 與 infra-wide profiling；Datadog 偏 SaaS、APM drilldown、deployment marker 與產品化 workflow。</p>
<p>Parca 和 Pyroscope 的主要差異是視角。Pyroscope 偏 Grafana / application profiling backend；Parca 偏 eBPF、Kubernetes / infrastructure-level profiling 與平台團隊治理。</p>
<p>Parca 和 language runtime profiler 的主要差異是導入方式。Runtime profiler 能提供語言特定維度；Parca 能先提供低侵入廣域 profile，但 symbolization 與語言細節需要額外治理。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>Parca</th>
          <th>Pyroscope</th>
          <th>Datadog Continuous Profiler</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>採集方式</td>
          <td>eBPF agent（kernel-level、unwound）</td>
          <td>eBPF + SDK 雙路、語言 SDK 較豐富</td>
          <td>APM agent 內建、語言 SDK 整合</td>
      </tr>
      <tr>
          <td>Profile format</td>
          <td>pprof（Google 標準）</td>
          <td>自家 + pprof export</td>
          <td>Datadog proprietary、可 export pprof</td>
      </tr>
      <tr>
          <td>採集模型</td>
          <td>Pull-based、Prometheus-style scrape</td>
          <td>Push or pull（Grafana Agent）</td>
          <td>Push to Datadog backend</td>
      </tr>
      <tr>
          <td>Label 模型</td>
          <td>Prometheus label（namespace / pod）</td>
          <td>Grafana label</td>
          <td>Datadog tag</td>
      </tr>
      <tr>
          <td>部署模型</td>
          <td>Self-hosted OSS + Polar Signals SaaS</td>
          <td>Self-hosted OSS + Grafana Cloud SaaS</td>
          <td>SaaS only</td>
      </tr>
      <tr>
          <td>Storage</td>
          <td>FrostDB 內建 / object storage</td>
          <td>自家 storage / Grafana backend</td>
          <td>Datadog managed</td>
      </tr>
      <tr>
          <td>APM 整合</td>
          <td>弱 — 走 Grafana correlation</td>
          <td>中 — Grafana stack 整合</td>
          <td>強 — trace ↔ profile drilldown 內建</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>Platform team 自管、Prometheus stack</td>
          <td>Grafana stack 已用、應用層 profiling</td>
          <td>已用 Datadog、APM-first、SaaS-only 可</td>
      </tr>
  </tbody>
</table>
<h2 id="進階主題">進階主題</h2>
<p><strong>Polar Signals Cloud</strong>：Parca 上游公司 Polar Signals 提供 managed SaaS — agent 一樣走 OSS、server / storage / UI 託管。適合不想養 Parca server 又要 OSS agent 路線的團隊。差異點是 ingestion cost 跟 retention 由 SaaS 計費、license / data residency 要看合約。</p>
<p><strong>Prometheus 同 label model</strong>：Parca 的 service discovery、scrape config 跟 label 跟 Prometheus 幾乎同形 — 既有 ServiceMonitor、relabel rule、Kubernetes SD 可以直接複用。意義是 profile 維度跟 metric 維度天然對齊、<code>namespace=foo, service=bar</code> 在兩邊都成立、cross-signal correlation 不需要再 mapping。</p>
<p><strong>Compare profiles（diff before/after deploy）</strong>：Parca UI 支援選 baseline window 跟 candidate window 做 flame graph diff、顏色標示哪個 stack frame 變胖變瘦。配 <a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a> 的 deploy marker、可以把「這次發版讓 CPU +15%」直接歸因到具體 frame。</p>
<p><strong>Continuous profiling vs sampling-only</strong>：傳統 profiler 是「出問題時手動跑 30 秒」、Parca 是「always-on、低頻率持續採」。差異是 <em>事後回溯能力</em> — incident 發生時直接拉時間區間的 profile、不用重現問題；sampling-only 工具在偶發 spike 時抓不到現場。代價是 storage 跟 agent overhead 要長期治理。</p>
<h2 id="操作成本">操作成本</h2>
<p>Parca 的主要成本是平台維運。Agent / scraper、server、storage、retention、symbolization、upgrade 與 Kubernetes 權限都需要平台團隊負責。</p>
<p>Symbolization 成本來自可讀性。Profile 如果缺 symbol、debug info、build ID 或 source mapping，flame graph 會變成難以行動的 address / binary offset，因此 build pipeline 要保留符號資訊策略。</p>
<p>權限成本來自 eBPF 與 node visibility。低層 profiling 需要足夠 host / kernel 權限，受管 Kubernetes、security policy、multi-tenant cluster 與 compliance 要先評估。</p>
<h2 id="evidence-package">Evidence Package</h2>
<p>Parca 結果應回寫到 evidence package。最小欄位包括 cluster、namespace、service、node pool、profile type、baseline window、candidate window、compare link、symbolization status、agent overhead、known gap 與 owner。</p>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>Parca 證據來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Source</td>
          <td>Parca query、compare view、flame graph</td>
      </tr>
      <tr>
          <td>Time range</td>
          <td>baseline / candidate profile window</td>
      </tr>
      <tr>
          <td>Query link</td>
          <td>Parca UI / dashboard / metrics link</td>
      </tr>
      <tr>
          <td>Data quality</td>
          <td>label completeness、symbolization status</td>
      </tr>
      <tr>
          <td>Confidence</td>
          <td>cluster coverage、agent overhead</td>
      </tr>
      <tr>
          <td>Known gap</td>
          <td>未覆蓋 node、symbol 缺失、kernel 限制</td>
      </tr>
  </tbody>
</table>
<p>Evidence package 的核心用途是把平台層 profile 變成容量決策。Reviewer 要能看到成本來自 application code、runtime、sidecar、kernel path 還是 shared library，並把結果回寫到 owner。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>eBPF agent 起不來 / kernel 不支援</strong>：舊 kernel（&lt; 4.18）或缺 BTF / CO-RE 支援、受管 Kubernetes 不開 <code>SYS_ADMIN</code> — 先確認 node OS image、必要時換 distribution 或升級 worker node pool</li>
<li><strong>Profile storage 暴增</strong>：scrape interval 太密 + retention 沒設 + label cardinality 爆炸（把 request-id 放進 label）— 降頻、限 retention window、把高 cardinality 維度移出 profile label</li>
<li><strong>Symbol resolution 失敗 / flame graph 全是 address</strong>：build pipeline 沒保留 debug info、stripped binary、容器 image 不含符號 — 在 build 階段保留 debug symbol、用 separate debuginfo 上傳 Parca debuginfod、或在 image 保留 unstripped binary</li>
<li><strong>JIT 語言（Java / Node.js）stack 不完整</strong>：eBPF 看到的是 native frame、JIT-compiled frame 需要額外 perf map / JVMTI agent — 補語言層 profiler 或開 JIT symbol dump</li>
<li><strong>Agent overhead 影響 production</strong>：sample rate 預設 19 Hz、特定 workload 可能仍敏感 — 在 noisy neighbor 敏感的 node pool 降頻或排除特定 namespace</li>
<li><strong>多 cluster scrape 中心化太重</strong>：單一 Parca server 拉 N 個 cluster 變瓶頸 — 改 federation 模型、每 cluster 一個 Parca server、上層做 query aggregation</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Parca 適合回寫平台層與 multi-service 成本案例。它可接 <a href="/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/" data-link-title="9.C34 GCP：130,000-node GKE cluster 的工程極限" data-link-desc="Google 用單一 GKE control plane 跑 13 萬個 node、AI workload &#43; 1000 Pods/sec 創建吞吐">9.C34 GCP 130K node GKE cluster</a> 的 cluster-scale profiling 需求、<a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS multi-cluster</a> 的 246 cluster 平台成本治理、<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的 shared platform noise 降低、<a href="/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/" data-link-title="9.C33 Maersk &#43; Bosch：傳統產業在 Azure AKS 上的微服務治理" data-link-desc="全球海運 Maersk 跟 Bosch 智慧建築把 AKS 當微服務治理基礎、釋放工程資源做業務功能">9.C33 Maersk + Bosch Azure AKS</a> 的傳統產業多 BU 平台層歸因，以及 <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom DynamoDB + EKS</a> 跨遊戲共用後端的 profile 切分。</p>
<p>這些案例的重點是平台視角。Parca 頁引用案例時，要把 case 轉成 cluster / namespace / service label、compare window、symbolization、shared library cost 與 owner routing — 例如 GCP 130K-node 規模下，Parca 自身的 storage / scrape capacity 也成為 profile target、不只是觀測 application。</p>
<p>兩個典型用途值得單獨點名：</p>
<ul>
<li><strong>Performance regression detection</strong>：發版前後拉 compare profile、把「這次 release 讓 P99 CPU +18%」歸因到具體 stack frame。配 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games EKS multi-cluster</a> 的 246 cluster 規模、單一 service rollout 在 always-on profile 下可秒級看出 hot path 變化、不需要等 SRE 跑手動 pprof</li>
<li><strong>Cost engineering</strong>：把 CPU profile 折算成 node 成本、找出 shared library / runtime / sidecar 的 hidden cost。配 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 的 platform consolidation 思路、profile 證據可以決定要不要重寫熱點、換 library、還是接受成本</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a></li>
<li>跨模組：<a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a></li>
<li>平行：<a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a></li>
<li>官方：<a href="https://www.parca.dev/docs/">Parca documentation</a></li>
</ul>
]]></content:encoded></item><item><title>9.C32 Clearent：Azure SQL Hyperscale 撐每年 5 億筆支付交易</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/</guid><description>&lt;p>這個案例的核心責任是補強 Azure DB-OLTP 維度缺口。Clearent 是美國的中型支付處理商、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered 跨市場銀行 OLTP&lt;/a> 形成對照 — 一個是合規驅動的跨市場分割、一個是單一規模的高吞吐處理。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Clearent 在 Azure SQL Hyperscale 的關鍵敘述（引自 &lt;a href="https://www.microsoft.com/en/customers/story/774969-clearent-banking-capital-markets-azure">Clearent Customer Story&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>年交易量&lt;/td>
 &lt;td>5 億筆&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>客戶基礎&lt;/td>
 &lt;td>各種規模 merchants（中小型為主）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>Azure SQL Database Hyperscale 服務級&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>架構模式&lt;/td>
 &lt;td>modern microservices architecture&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>擴展能力&lt;/td>
 &lt;td>「scale automatically and almost infinitely」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>並發特性&lt;/td>
 &lt;td>「tens of thousands of users 同時存取」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>業務驅動&lt;/td>
 &lt;td>「unite all its information in one place」+ 「faster insights」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵特性：Azure SQL Hyperscale 把 storage 跟 compute 分離、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora&lt;/a> 的 Aurora 是同類設計。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Clearent 案例揭露三個 Hyperscale 設計的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>5 億筆 / 年 ≈ 1500 筆 / 秒平均、但 peak 可能 10-50x&lt;/strong>：支付交易有日內 / 月內 / 季內節律。早上 9-11 點商家對帳高峰、下午 12-1 點消費高峰、晚上 6-8 點消費高峰、月底結算高峰。容量規劃必須按 peak 訂、不是平均。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> 的 peak/avg ratio 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型&lt;/a>。&lt;/li>
&lt;li>&lt;strong>Hyperscale = storage / compute 解耦&lt;/strong>：傳統 SQL Server primary 對 storage 跟 CPU / RAM 綁定、擴 storage 就要換更大 instance、不便。Hyperscale 把 storage 拉到分散式 log service、可以獨立擴 storage（最高 100 TB）、compute 獨立擴。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner&lt;/a> 的同類分離思維、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora&lt;/a>。&lt;/li>
&lt;li>&lt;strong>「unite all information in one place」是支付業的特殊需求&lt;/strong>：merchants 需要對帳、退款、清算、稅務報表都即時可查、不能 OLAP 分開。Hyperscale 的 read scale-out（最多 4 個 secondary replica）讓即時報表跑在 OLTP DB 上不影響交易吞吐。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：「scale automatically and almost infinitely」是行銷敘述。實際 Hyperscale 有上限（100 TB storage、Gen5 series 80 vCore）、超過要 sharding 應用層分散。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是補強 Azure DB-OLTP 維度缺口。Clearent 是美國的中型支付處理商、跟 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered 跨市場銀行 OLTP</a> 形成對照 — 一個是合規驅動的跨市場分割、一個是單一規模的高吞吐處理。</p>
<h2 id="觀察">觀察</h2>
<p>Clearent 在 Azure SQL Hyperscale 的關鍵敘述（引自 <a href="https://www.microsoft.com/en/customers/story/774969-clearent-banking-capital-markets-azure">Clearent Customer Story</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>年交易量</td>
          <td>5 億筆</td>
      </tr>
      <tr>
          <td>客戶基礎</td>
          <td>各種規模 merchants（中小型為主）</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>Azure SQL Database Hyperscale 服務級</td>
      </tr>
      <tr>
          <td>架構模式</td>
          <td>modern microservices architecture</td>
      </tr>
      <tr>
          <td>擴展能力</td>
          <td>「scale automatically and almost infinitely」</td>
      </tr>
      <tr>
          <td>並發特性</td>
          <td>「tens of thousands of users 同時存取」</td>
      </tr>
      <tr>
          <td>業務驅動</td>
          <td>「unite all its information in one place」+ 「faster insights」</td>
      </tr>
  </tbody>
</table>
<p>關鍵特性：Azure SQL Hyperscale 把 storage 跟 compute 分離、跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a> 的 Aurora 是同類設計。</p>
<h2 id="判讀">判讀</h2>
<p>Clearent 案例揭露三個 Hyperscale 設計的工程重點。</p>
<ol>
<li><strong>5 億筆 / 年 ≈ 1500 筆 / 秒平均、但 peak 可能 10-50x</strong>：支付交易有日內 / 月內 / 季內節律。早上 9-11 點商家對帳高峰、下午 12-1 點消費高峰、晚上 6-8 點消費高峰、月底結算高峰。容量規劃必須按 peak 訂、不是平均。對應 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> 的 peak/avg ratio 跟 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>。</li>
<li><strong>Hyperscale = storage / compute 解耦</strong>：傳統 SQL Server primary 對 storage 跟 CPU / RAM 綁定、擴 storage 就要換更大 instance、不便。Hyperscale 把 storage 拉到分散式 log service、可以獨立擴 storage（最高 100 TB）、compute 獨立擴。對應 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> 的同類分離思維、跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a>。</li>
<li><strong>「unite all information in one place」是支付業的特殊需求</strong>：merchants 需要對帳、退款、清算、稅務報表都即時可查、不能 OLAP 分開。Hyperscale 的 read scale-out（最多 4 個 secondary replica）讓即時報表跑在 OLTP DB 上不影響交易吞吐。</li>
</ol>
<p>需要警惕：「scale automatically and almost infinitely」是行銷敘述。實際 Hyperscale 有上限（100 TB storage、Gen5 series 80 vCore）、超過要 sharding 應用層分散。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>Hyperscale 跟 Aurora 是同類設計、選型按生態</strong>：Azure 生態用 Hyperscale、AWS 生態用 Aurora、GCP 用 AlloyDB / Spanner。三家底層工程哲學一致（log-structured storage、storage / compute 分離）、選哪家取決於 application 已在哪個 cloud。</li>
<li><strong>微服務 + 共用 OLTP 是支付業常見架構</strong>：服務拆細、但 OLTP 仍是 single source of truth、共用一個 Hyperscale cluster。這跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix microservice 各自 Aurora</a> 不同 — Netflix 每微服務 <em>自己</em> Aurora、Clearent 微服務共用 Hyperscale。取捨：Clearent 的「對帳一致性」需求讓共用更划算。</li>
<li><strong>支付業容量規劃以 peak 為主</strong>：不能用平均 RPS 規劃、要按單日 / 單秒 peak。歷史 peak × 預期成長 × headroom 是基本公式（<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>）。</li>
</ol>
<p>跨平台等效：AWS Aurora Serverless v2、GCP AlloyDB、Spanner、PostgreSQL 自管 + Patroni 都可實作對等架構。差異是 vendor managed 程度跟 OLAP / OLTP 統一視覺。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他 OLTP 案例 → <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora</a> / <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a> / <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></li>
<li>想設計支付業容量 → <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> + <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="活動、季節性流量、推廣事件的 capacity readiness 流程">9.11 高峰事件準備</a></li>
<li>想理解 storage / compute 分離 → <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.microsoft.com/en/customers/story/774969-clearent-banking-capital-markets-azure">Clearent scales its modern microservices architecture to handle 500 million payment transactions a year</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/announcing-azure-sql-database-hyperscale-public-preview/">Announcing Azure SQL Database Hyperscale</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/get-high-performance-scaling-for-your-azure-database-workloads-with-hyperscale/">Get high-performance scaling for your Azure database workloads with Hyperscale</a></li>
</ul>
]]></content:encoded></item><item><title>9.C33 Maersk + Bosch：傳統產業在 Azure AKS 上的微服務治理</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/</guid><description>&lt;p>這個案例的核心責任是補強 Azure compute / K8s 維度缺口。Maersk（全球最大貨櫃航運公司、每天處理百萬級貨櫃移動）跟 Bosch（德國工業集團、智慧建築 IoT）是 &lt;em>傳統產業上雲&lt;/em> 的代表 — 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 雲原生 EKS&lt;/a> 形成對比、傳統產業的 K8s 採用動機跟雲原生公司不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Maersk + Bosch 在 Azure AKS 的關鍵敘述（引自 &lt;a href="https://azure.microsoft.com/en-us/products/kubernetes-service/">AKS Customer Stories&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Maersk&lt;/th>
 &lt;th>Bosch Software Innovations&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>行業&lt;/td>
 &lt;td>全球海運&lt;/td>
 &lt;td>工業 IoT（Connected Building Solution）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>主要 workload&lt;/td>
 &lt;td>貨櫃追蹤、港口物流、行程規劃&lt;/td>
 &lt;td>樓宇感測、能源管理、設備運維&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AKS 用途&lt;/td>
 &lt;td>deployment + 運維 + 管理 Kubernetes API&lt;/td>
 &lt;td>microservices 監控、不同 release cycle&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工程訴求&lt;/td>
 &lt;td>「focus on things that makes the most business impact」&lt;/td>
 &lt;td>「simplify management of microservices released on different cycles」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務組合&lt;/td>
 &lt;td>AKS + Azure 管理工具&lt;/td>
 &lt;td>AKS + monitoring capabilities&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>其他常見 AKS 大客戶：Siemens Healthineers（醫療設備）、Finastra（金融軟體）、Hafslund（能源）。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Maersk 跟 Bosch 案例揭露三個傳統產業 K8s 治理的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>傳統產業上 K8s 的動機是「治理一致性」、不是「成長彈性」&lt;/strong>：
&lt;ul>
&lt;li>雲原生公司（Riot、Netflix）上 K8s 是為了 &lt;em>快速擴容&lt;/em> 跟 &lt;em>跨 region 部署&lt;/em>&lt;/li>
&lt;li>傳統產業上 K8s 是為了 &lt;em>統一 50+ 個應用團隊的部署流程&lt;/em>、降低 ops 複雜度&lt;/li>
&lt;li>訴求不同、配置不同 — 傳統產業可能用 &lt;em>較大 node、較少 cluster&lt;/em>、不是 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot 246 cluster&lt;/a> 那種多 cluster 策略&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>微服務 release cycle 多元化是傳統產業上 K8s 的核心需求&lt;/strong>：Bosch Connected Building 有「樓宇感測 daily release、能源計費 weekly release、設備運維 monthly release」、每個 release cycle 不同。K8s + GitOps（Argo CD、Flux）讓不同 cycle 共存於同一 cluster。對應 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組&lt;/a> 的 release governance。&lt;/li>
&lt;li>&lt;strong>「focus on business impact」是 managed K8s 的真正價值&lt;/strong>：Maersk 不是科技公司、是航運公司。工程資源從 &lt;em>維持 K8s 運維&lt;/em> 釋放到 &lt;em>貨櫃追蹤演算法、港口物流優化&lt;/em>、是商業 ROI 的關鍵。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &amp;#43; AWS Media Services 撐 30 channels live &amp;#43; 5M MAU、工程工時下降 90%">9.C29 Lemino 90% 工程工時下降&lt;/a> 的同類訴求、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 的人力成本工程化。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：Azure 官方對 Maersk / Bosch 的描述偏行銷、缺具體 throughput / latency 數字。讀此類案例要對 &lt;em>策略&lt;/em> 學習、不要套用數字。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是補強 Azure compute / K8s 維度缺口。Maersk（全球最大貨櫃航運公司、每天處理百萬級貨櫃移動）跟 Bosch（德國工業集團、智慧建築 IoT）是 <em>傳統產業上雲</em> 的代表 — 跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 雲原生 EKS</a> 形成對比、傳統產業的 K8s 採用動機跟雲原生公司不同。</p>
<h2 id="觀察">觀察</h2>
<p>Maersk + Bosch 在 Azure AKS 的關鍵敘述（引自 <a href="https://azure.microsoft.com/en-us/products/kubernetes-service/">AKS Customer Stories</a>）：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Maersk</th>
          <th>Bosch Software Innovations</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>行業</td>
          <td>全球海運</td>
          <td>工業 IoT（Connected Building Solution）</td>
      </tr>
      <tr>
          <td>主要 workload</td>
          <td>貨櫃追蹤、港口物流、行程規劃</td>
          <td>樓宇感測、能源管理、設備運維</td>
      </tr>
      <tr>
          <td>AKS 用途</td>
          <td>deployment + 運維 + 管理 Kubernetes API</td>
          <td>microservices 監控、不同 release cycle</td>
      </tr>
      <tr>
          <td>工程訴求</td>
          <td>「focus on things that makes the most business impact」</td>
          <td>「simplify management of microservices released on different cycles」</td>
      </tr>
      <tr>
          <td>服務組合</td>
          <td>AKS + Azure 管理工具</td>
          <td>AKS + monitoring capabilities</td>
      </tr>
  </tbody>
</table>
<p>其他常見 AKS 大客戶：Siemens Healthineers（醫療設備）、Finastra（金融軟體）、Hafslund（能源）。</p>
<h2 id="判讀">判讀</h2>
<p>Maersk 跟 Bosch 案例揭露三個傳統產業 K8s 治理的工程重點。</p>
<ol>
<li><strong>傳統產業上 K8s 的動機是「治理一致性」、不是「成長彈性」</strong>：
<ul>
<li>雲原生公司（Riot、Netflix）上 K8s 是為了 <em>快速擴容</em> 跟 <em>跨 region 部署</em></li>
<li>傳統產業上 K8s 是為了 <em>統一 50+ 個應用團隊的部署流程</em>、降低 ops 複雜度</li>
<li>訴求不同、配置不同 — 傳統產業可能用 <em>較大 node、較少 cluster</em>、不是 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot 246 cluster</a> 那種多 cluster 策略</li>
</ul>
</li>
<li><strong>微服務 release cycle 多元化是傳統產業上 K8s 的核心需求</strong>：Bosch Connected Building 有「樓宇感測 daily release、能源計費 weekly release、設備運維 monthly release」、每個 release cycle 不同。K8s + GitOps（Argo CD、Flux）讓不同 cycle 共存於同一 cluster。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 release governance。</li>
<li><strong>「focus on business impact」是 managed K8s 的真正價值</strong>：Maersk 不是科技公司、是航運公司。工程資源從 <em>維持 K8s 運維</em> 釋放到 <em>貨櫃追蹤演算法、港口物流優化</em>、是商業 ROI 的關鍵。對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino 90% 工程工時下降</a> 的同類訴求、跟 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 的人力成本工程化。</li>
</ol>
<p>需要警惕：Azure 官方對 Maersk / Bosch 的描述偏行銷、缺具體 throughput / latency 數字。讀此類案例要對 <em>策略</em> 學習、不要套用數字。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>傳統產業 K8s 採用先做「單一 cluster 多 namespace」、再考慮多 cluster</strong>：管理 1 個大 cluster 比管理 246 個小 cluster 容易。除非有 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 的隔離需求</a>、否則 single-cluster-multi-namespace 是 sane default。</li>
<li><strong>不同 release cycle 用 GitOps + namespace 隔離</strong>：每個團隊 own 自己的 namespace、配合 Argo CD / Flux 各自 release。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a>。</li>
<li><strong>AKS / EKS / GKE 的差異對傳統產業不關鍵</strong>：選哪家通常取決於企業已用哪家 cloud、不是 K8s feature 本身。重點是 <em>managed K8s ops 比自管划算</em>、不是哪家 managed 最好。</li>
<li><strong>監控訊號設計按業務 cycle</strong>：每天 release 的服務跟每月 release 的服務 monitoring 策略不同、alert 敏感度不同。對應 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a>。</li>
</ol>
<p>跨平台等效：AWS EKS、GCP GKE、自管 Kubernetes + Rancher 都可實作對等架構。Azure 在 enterprise 整合（Active Directory、Azure DevOps）有優勢、特別適合 Microsoft 生態企業。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照雲原生 K8s 策略 → <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster</a></li>
<li>對照其他 managed 服務釋放工程資源 → <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a> / <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a></li>
<li>想設計 K8s 治理 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://azure.microsoft.com/en-us/products/kubernetes-service/">Azure Kubernetes Service customer stories</a></li>
<li><a href="https://customers.microsoft.com/en-us/story/maersk-travel-transportation-azure">Maersk Azure case</a></li>
<li><a href="https://azure.microsoft.com/en-us/blog/product/azure-kubernetes-service-aks/">Bosch Software Innovations</a></li>
<li><a href="https://azure.microsoft.com/en-us/solutions/kubernetes-on-azure">Kubernetes on Azure - Enterprise Expertise</a></li>
</ul>
]]></content:encoded></item><item><title>9.C34 GCP：130,000-node GKE cluster 的工程極限</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/</guid><description>&lt;p>這個案例的核心責任是揭示「現代 AI workload 對 Kubernetes 規模極限的拉扯」。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster&lt;/a> 走「多小 cluster 隔離」相反 — GCP 內部驗證的是「單一巨大 cluster 集中管理」、為前沿 LLM 訓練的萬卡叢集需求設計。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>GCP 130K-node GKE cluster 實驗（引自 &lt;a href="https://cloud.google.com/blog/products/containers-kubernetes/how-we-built-a-130000-node-gke-cluster">How we built a 130,000-node GKE cluster&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>實驗節點數&lt;/td>
 &lt;td>130,000（vs 官方支援 65,000）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pod 創建峰值&lt;/td>
 &lt;td>1,000 Pods / 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Phase 1 deploy 時間&lt;/td>
 &lt;td>130,000 Pods in 3 分 40 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Phase 2 batch 創建&lt;/td>
 &lt;td>65,000 Pods in 81 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preemption 峰值&lt;/td>
 &lt;td>39,000 Pods preempted in 93 秒&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pod startup p99&lt;/td>
 &lt;td>~10 秒（inference workload）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>API server LIST p99&lt;/td>
 &lt;td>「well below defined thresholds」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Database objects&lt;/td>
 &lt;td>100 萬 +&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Lease 更新 QPS&lt;/td>
 &lt;td>13,000&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>客戶當前範圍&lt;/td>
 &lt;td>20-65K node range&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>預期 cluster size 穩定&lt;/td>
 &lt;td>100K node mark&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>工作負載類型：AI / ML 平台、三個 priority class：&lt;/p>
&lt;ul>
&lt;li>Low：preemptible batch（data prep）&lt;/li>
&lt;li>Medium：core model training（tolerant to queuing）&lt;/li>
&lt;li>High：latency-sensitive inference&lt;/li>
&lt;/ul>
&lt;p>關鍵 control plane 設計：&lt;/p>
&lt;ul>
&lt;li>Consistent Reads from Cache（KEP-2340）— 強一致 read 從 in-memory cache、不打 storage&lt;/li>
&lt;li>Snapshottable API Server Cache（KEP-4988）— B-tree snapshot 處理 LIST 請求&lt;/li>
&lt;li>Spanner-based key-value store 作為 K8s storage backend（撐 13K QPS lease 更新）&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>130K-node 案例揭露三個 hyperscale K8s 設計的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>單一 control plane 的極限取決於 storage backend、不是 nodes&lt;/strong>：130K node 不是「機器跑不動」、是「API server 跟 etcd 撐不撐住」。GCP 用 Spanner 替換 etcd、配上 cache-first read 設計、把 storage 從瓶頸變成「showed no signs of not being able to support higher scales」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程&lt;/a> 的「真實 bottleneck 在哪一層」。&lt;/li>
&lt;li>&lt;strong>AI workload 顛覆了 K8s 容量規劃&lt;/strong>：傳統 web workload 的 K8s 多在 1K-10K node、節點生命週期長。AI workload 短時間爆量創建跟銷毀 Pods（13 萬個 in 3 分 40 秒）、preempt 跟 schedule 頻繁、對 control plane 是完全不同壓力模式。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a> — workload 形狀完全不同、容量規劃也完全不同。&lt;/li>
&lt;li>&lt;strong>「power constraint &amp;gt; chip supply」是新瓶頸&lt;/strong>：單顆 NVIDIA GB200 GPU 吃 2700W、萬卡叢集 = 27MW 用電量。未來 mega cluster 必須跨多個 data center（一個 DC 電力撐不住）、需要 &lt;em>robust multi-cluster solutions&lt;/em>。這層瓶頸跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界&lt;/a> 對接 — 電力成本變成主要 cost driver。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是揭示「現代 AI workload 對 Kubernetes 規模極限的拉扯」。跟 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster</a> 走「多小 cluster 隔離」相反 — GCP 內部驗證的是「單一巨大 cluster 集中管理」、為前沿 LLM 訓練的萬卡叢集需求設計。</p>
<h2 id="觀察">觀察</h2>
<p>GCP 130K-node GKE cluster 實驗（引自 <a href="https://cloud.google.com/blog/products/containers-kubernetes/how-we-built-a-130000-node-gke-cluster">How we built a 130,000-node GKE cluster</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>實驗節點數</td>
          <td>130,000（vs 官方支援 65,000）</td>
      </tr>
      <tr>
          <td>Pod 創建峰值</td>
          <td>1,000 Pods / 秒</td>
      </tr>
      <tr>
          <td>Phase 1 deploy 時間</td>
          <td>130,000 Pods in 3 分 40 秒</td>
      </tr>
      <tr>
          <td>Phase 2 batch 創建</td>
          <td>65,000 Pods in 81 秒</td>
      </tr>
      <tr>
          <td>Preemption 峰值</td>
          <td>39,000 Pods preempted in 93 秒</td>
      </tr>
      <tr>
          <td>Pod startup p99</td>
          <td>~10 秒（inference workload）</td>
      </tr>
      <tr>
          <td>API server LIST p99</td>
          <td>「well below defined thresholds」</td>
      </tr>
      <tr>
          <td>Database objects</td>
          <td>100 萬 +</td>
      </tr>
      <tr>
          <td>Lease 更新 QPS</td>
          <td>13,000</td>
      </tr>
      <tr>
          <td>客戶當前範圍</td>
          <td>20-65K node range</td>
      </tr>
      <tr>
          <td>預期 cluster size 穩定</td>
          <td>100K node mark</td>
      </tr>
  </tbody>
</table>
<p>工作負載類型：AI / ML 平台、三個 priority class：</p>
<ul>
<li>Low：preemptible batch（data prep）</li>
<li>Medium：core model training（tolerant to queuing）</li>
<li>High：latency-sensitive inference</li>
</ul>
<p>關鍵 control plane 設計：</p>
<ul>
<li>Consistent Reads from Cache（KEP-2340）— 強一致 read 從 in-memory cache、不打 storage</li>
<li>Snapshottable API Server Cache（KEP-4988）— B-tree snapshot 處理 LIST 請求</li>
<li>Spanner-based key-value store 作為 K8s storage backend（撐 13K QPS lease 更新）</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>130K-node 案例揭露三個 hyperscale K8s 設計的工程重點。</p>
<ol>
<li><strong>單一 control plane 的極限取決於 storage backend、不是 nodes</strong>：130K node 不是「機器跑不動」、是「API server 跟 etcd 撐不撐住」。GCP 用 Spanner 替換 etcd、配上 cache-first read 設計、把 storage 從瓶頸變成「showed no signs of not being able to support higher scales」。對應 <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a> 的「真實 bottleneck 在哪一層」。</li>
<li><strong>AI workload 顛覆了 K8s 容量規劃</strong>：傳統 web workload 的 K8s 多在 1K-10K node、節點生命週期長。AI workload 短時間爆量創建跟銷毀 Pods（13 萬個 in 3 分 40 秒）、preempt 跟 schedule 頻繁、對 control plane 是完全不同壓力模式。對應 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a> — workload 形狀完全不同、容量規劃也完全不同。</li>
<li><strong>「power constraint &gt; chip supply」是新瓶頸</strong>：單顆 NVIDIA GB200 GPU 吃 2700W、萬卡叢集 = 27MW 用電量。未來 mega cluster 必須跨多個 data center（一個 DC 電力撐不住）、需要 <em>robust multi-cluster solutions</em>。這層瓶頸跟 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界</a> 對接 — 電力成本變成主要 cost driver。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>130K-node 是 <em>Google 內部實驗</em>、不是 <em>客戶能用的 production</em> 配置。目前 GKE 官方支援 65K node、客戶用到 100K+ 還很遠。</li>
<li>AI workload 跟 web workload 完全不同、把 AI 經驗套用到 web service 容量規劃是錯誤類比。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>K8s control plane 跟 data plane 分開規劃容量</strong>：data plane（worker nodes）擴容容易、control plane（API server、etcd / storage）擴容難。瓶頸通常在 control plane、不是 worker。</li>
<li><strong>storage backend 是 K8s 規模極限的關鍵</strong>：etcd 撐 5K-10K node 後開始吃力、要用 PostgreSQL / Spanner / 自家 KV 替換、才能擴到萬級節點。一般客戶用不到、但要知道「為什麼到某個規模 etcd 不夠」。</li>
<li><strong>AI workload 用 specialized scheduler</strong>（Kueue、Volcano）：默認 K8s scheduler 為 web workload 設計、AI 的 gang scheduling、fair-sharing、preemption 都不太適合。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 scheduler 選型。</li>
<li><strong>power-aware capacity planning 是未來方向</strong>：傳統按 CPU / RAM 規劃容量、未來要加上 <em>power budget</em>。data center 用電量是硬上限、不是錢的問題。</li>
<li><strong>multi-cluster 是萬卡訓練的必然</strong>：單一 cluster 撐不住、要 MultiKueue 等跨 cluster 排程方案。對應 <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games multi-cluster</a> 但目的完全不同。</li>
</ol>
<p>跨平台等效：AWS EKS 官方支援單 cluster 多至 100K pod / cluster、Azure AKS 支援 5K node / cluster。GCP 用 Spanner 替換 etcd 是最深的工程投資、目前其他兩家還沒到這個規模。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他大規模 K8s → <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games 246 cluster</a>（多 cluster 策略）</li>
<li>對照 AI workload → <a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokemon GO 50x surge</a>（非 AI 但同 GCP K8s）</li>
<li>想理解 control plane vs data plane → <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a> + <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>想設計 K8s 容量上限 → <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> + <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/blog/products/containers-kubernetes/how-we-built-a-130000-node-gke-cluster">How we built a 130,000-node GKE cluster</a></li>
<li><a href="https://cloud.google.com/blog/products/containers-kubernetes/gke-and-kubernetes-at-kubecon-2025">GKE and Kubernetes at KubeCon 2025</a></li>
<li><a href="https://cloud.google.com/blog/products/containers-kubernetes/whats-new-in-gke-at-next26">What&rsquo;s new in GKE at Next 26</a></li>
</ul>
]]></content:encoded></item><item><title>9.C35 Snap：GCP + KeyDB 在 multi-cloud 架構下的低延遲快取</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/snap-gcp-keydb-cross-cloud/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/snap-gcp-keydb-cross-cloud/</guid><description>&lt;p>這個案例的核心責任是補強 GCP cache 維度、並揭示 multi-cloud 架構的隱性 latency 議題。Snap（Snapchat 母公司、日活 4 億 +）2011 年從零起就在 GCP 上、是雲原生最早期客戶之一、但近年走 multi-cloud（GCP + AWS）。這個架構引出「跨 cloud cache latency 怎麼處理」的工程議題。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Snap 在 GCP 的關鍵敘述（引自 &lt;a href="https://cloud.google.com/blog/products/application-modernization/snap-deploys-keydb-on-google-cloud-to-reduce-cross-cloud-latency">Snap deploys KeyDB on Google Cloud&lt;/a>、&lt;a href="https://cloud.google.com/blog/products/ai-machine-learning/snap-inc-uses-google-cloud-tpu-for-deep-learning-recommendation-models">Snap TPU recommendation&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>內容&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>用戶基礎&lt;/td>
 &lt;td>4 億 + DAU、年增 18% YoY&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>開始在 GCP 時間&lt;/td>
 &lt;td>2011 年（產品早期）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Multi-cloud cache 方案&lt;/td>
 &lt;td>GCP 上部署 KeyDB cluster 減少 cross-cloud latency&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ML training&lt;/td>
 &lt;td>TPU（vs GPU 吞吐高 67%、成本低 52%）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>安全框架&lt;/td>
 &lt;td>BeyondCorp Enterprise（Zero Trust）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵架構決策：在 &lt;em>GCP&lt;/em> 上部署 KeyDB（Redis fork、multi-threaded）作為 cache layer、減少 cross-cloud latency。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Snap 案例揭露三個 multi-cloud 容量設計的工程重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>跨 cloud latency 是隱性容量瓶頸&lt;/strong>：當 application 在 AWS、cache 在 GCP（或反之）、每個 cache lookup 都吃跨 cloud 網路 latency（通常 5-30ms、視 region pair 而定）。對 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">Snap 這類「每次互動查多個 cache」&lt;/a> 的服務、5ms × 10 cache lookup = 50ms 額外 latency、用戶感受明顯。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget&lt;/a> 的 latency budget 反推。&lt;/li>
&lt;li>&lt;strong>KeyDB 是 Redis 的 multi-threaded 替代&lt;/strong>：Redis 7+ 之前是 single-threaded、單實例吞吐受限。KeyDB（Snap 等大型用戶採用）改成 multi-threaded、單實例 throughput 提升 5-10x、適合超高吞吐 cache 需求。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder ElastiCache&lt;/a> 的 cache layer 設計、但 Snap 規模更大要走專業 fork。&lt;/li>
&lt;li>&lt;strong>TPU vs GPU 是 ML training 的容量成本決策&lt;/strong>：Snap 算過 GPU 的「throughput -67% + cost +52%」就是 TPU 的反向 — TPU 的 throughput 高 67%、cost 低 52% — 對 ML-heavy 公司是巨大決策。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency&lt;/a> 的雲端硬體選型、跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &amp;#43; 1.5 億商品、用 GCP Vertex AI Search &amp;#43; BigQuery 提供近即時搜尋與分析">9.C31 Mercado Libre Vertex AI&lt;/a> 的 ML 容量規劃同類。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是補強 GCP cache 維度、並揭示 multi-cloud 架構的隱性 latency 議題。Snap（Snapchat 母公司、日活 4 億 +）2011 年從零起就在 GCP 上、是雲原生最早期客戶之一、但近年走 multi-cloud（GCP + AWS）。這個架構引出「跨 cloud cache latency 怎麼處理」的工程議題。</p>
<h2 id="觀察">觀察</h2>
<p>Snap 在 GCP 的關鍵敘述（引自 <a href="https://cloud.google.com/blog/products/application-modernization/snap-deploys-keydb-on-google-cloud-to-reduce-cross-cloud-latency">Snap deploys KeyDB on Google Cloud</a>、<a href="https://cloud.google.com/blog/products/ai-machine-learning/snap-inc-uses-google-cloud-tpu-for-deep-learning-recommendation-models">Snap TPU recommendation</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>用戶基礎</td>
          <td>4 億 + DAU、年增 18% YoY</td>
      </tr>
      <tr>
          <td>開始在 GCP 時間</td>
          <td>2011 年（產品早期）</td>
      </tr>
      <tr>
          <td>Multi-cloud cache 方案</td>
          <td>GCP 上部署 KeyDB cluster 減少 cross-cloud latency</td>
      </tr>
      <tr>
          <td>ML training</td>
          <td>TPU（vs GPU 吞吐高 67%、成本低 52%）</td>
      </tr>
      <tr>
          <td>安全框架</td>
          <td>BeyondCorp Enterprise（Zero Trust）</td>
      </tr>
  </tbody>
</table>
<p>關鍵架構決策：在 <em>GCP</em> 上部署 KeyDB（Redis fork、multi-threaded）作為 cache layer、減少 cross-cloud latency。</p>
<h2 id="判讀">判讀</h2>
<p>Snap 案例揭露三個 multi-cloud 容量設計的工程重點。</p>
<ol>
<li><strong>跨 cloud latency 是隱性容量瓶頸</strong>：當 application 在 AWS、cache 在 GCP（或反之）、每個 cache lookup 都吃跨 cloud 網路 latency（通常 5-30ms、視 region pair 而定）。對 <a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">Snap 這類「每次互動查多個 cache」</a> 的服務、5ms × 10 cache lookup = 50ms 額外 latency、用戶感受明顯。對應 <a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a> 的 latency budget 反推。</li>
<li><strong>KeyDB 是 Redis 的 multi-threaded 替代</strong>：Redis 7+ 之前是 single-threaded、單實例吞吐受限。KeyDB（Snap 等大型用戶採用）改成 multi-threaded、單實例 throughput 提升 5-10x、適合超高吞吐 cache 需求。對應 <a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder ElastiCache</a> 的 cache layer 設計、但 Snap 規模更大要走專業 fork。</li>
<li><strong>TPU vs GPU 是 ML training 的容量成本決策</strong>：Snap 算過 GPU 的「throughput -67% + cost +52%」就是 TPU 的反向 — TPU 的 throughput 高 67%、cost 低 52% — 對 ML-heavy 公司是巨大決策。對應 <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界與 efficiency</a> 的雲端硬體選型、跟 <a href="/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &#43; 1.5 億商品、用 GCP Vertex AI Search &#43; BigQuery 提供近即時搜尋與分析">9.C31 Mercado Libre Vertex AI</a> 的 ML 容量規劃同類。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>KeyDB 是 <em>fork-based</em> 軟體、有 vendor lock-in 風險（Snap 大規模採用後、KeyDB 公司被收購、未來 fork 走向不確定）</li>
<li>TPU 是 <em>Google 專屬硬體</em>、不能在其他 cloud 用、是 vendor lock-in 來源</li>
<li>「年增 18%」是用戶數、不是流量。流量成長通常超過用戶成長（per-user engagement 上升）</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>Multi-cloud 架構優先把 cache 跟 application 放同一 cloud</strong>：跨 cloud 的不該是 cache lookup（高頻、低 latency 容忍）、應該是 batch sync（低頻、高 latency 容忍）。對應 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 的部署策略。</li>
<li><strong>Redis 規模化遇到 single-threaded 限制時的選項</strong>：
<ul>
<li>拆 cluster（多個 Redis instance）— 應用層分散 key</li>
<li>換 KeyDB / Dragonfly（multi-threaded fork）</li>
<li>換 Redis 7+ I/O thread（保留 protocol）</li>
<li>換 Memcached（multi-threaded、但功能少）</li>
</ul>
</li>
<li><strong>ML training infrastructure 選型按 throughput / cost 而非品牌</strong>：GPU vs TPU vs Trainium 不是「哪家好」、是「在 <em>本 workload</em> 上哪個划算」。要實測 benchmark、不是看 vendor marketing。</li>
<li><strong>跨 cloud 部署的「資料引力」</strong>：data 在哪、application 通常會被 data 吸過去。Snap 把 cache 放 GCP 是因為 production data 在 GCP — 想搬 cache 到 AWS 同時要搬 data、成本高。</li>
</ol>
<p>跨平台等效：AWS ElastiCache + Cassandra / DynamoDB Global Tables、Azure Cache for Redis + Cosmos DB 都可實作 multi-region cache 但 single-cloud 內。multi-cloud cache 通常要自管（自管 KeyDB / Dragonfly / Redis Cluster）。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他 cache 案例 → <a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder ElastiCache</a> / <a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi ML feature store</a></li>
<li>想設計 multi-cloud cache → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> + <a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a></li>
<li>想做 ML training 容量規劃 → <a href="/blog/backend/09-performance-capacity/cost-engineering/" data-link-title="9.7 成本邊界與 efficiency" data-link-desc="cost per request、cost curve、降級成本、over-provisioning trade-off">9.7 成本邊界</a> + <a href="/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &#43; 1.5 億商品、用 GCP Vertex AI Search &#43; BigQuery 提供近即時搜尋與分析">9.C31 Mercado Libre</a></li>
<li>想理解 cross-cloud latency → <a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/blog/products/application-modernization/snap-deploys-keydb-on-google-cloud-to-reduce-cross-cloud-latency">Snap deploys KeyDB on Google Cloud to reduce cross-cloud latency</a></li>
<li><a href="https://cloud.google.com/blog/products/ai-machine-learning/snap-inc-uses-google-cloud-tpu-for-deep-learning-recommendation-models">Snap Inc. uses Google Cloud TPU for deep learning recommendation models</a></li>
<li><a href="https://cloud.google.com/blog/products/gcp/snap-maintains-uptime-with-mcs-from-google-cloud/">Snap maintains uptime with MCS from Google Cloud</a></li>
<li><a href="https://cloud.google.com/blog/products/identity-security/why-snap-chose-beyondcorp-enterprise-to-build-a-durable-zero-trust-framework">Why Snap chose BeyondCorp Enterprise</a></li>
</ul>
]]></content:encoded></item><item><title>9.C36 Coinbase：MongoDB 撐 Ruby 單體 + 1.5M reads/sec identity 服務</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-mongodb-document-platform/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-mongodb-document-platform/</guid><description>&lt;p>這個案例的核心責任是說明「document database 在大規模 OLTP 場景如何撐住」。Coinbase 從 Ruby on Rails 單體 + MongoDB 起家、八年後仍保留 MongoDB 作為主資料層、並把 connection pooling、ML 預測擴容、cache + freshness token 都疊在 document model 上。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365&lt;/a> 對照 — Microsoft 365 走「遷出 MongoDB、保留 document API」、Coinbase 走「保留 MongoDB、補周邊工具」。兩條路徑都揭露 MongoDB 在 production 主角位置會遇到什麼壓力。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Coinbase MongoDB 平台的關鍵數字（引自 &lt;a href="https://www.coinbase.com/blog/scaling-connections-with-ruby-and-mongodb">Coinbase Engineering Blog&lt;/a> 與 &lt;a href="https://www.mongodb.com/solutions/customer-case-studies/coinbase">MongoDB customer case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Users 服務尖峰讀取&lt;/td>
 &lt;td>1.5M reads / sec&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Deploy 時 MongoDB 連線尖峰&lt;/td>
 &lt;td>~60K connections / minute（單 cluster）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>mongobetween 後連線降幅&lt;/td>
 &lt;td>30K → ~2K（一個量級）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MongoDB cluster 數量&lt;/td>
 &lt;td>many clusters（多服務 federated）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>加密貨幣 surge 擴容時間&lt;/td>
 &lt;td>70 分鐘 → 25 分鐘（-64%）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ML 預測擴容領先窗&lt;/td>
 &lt;td>60 分鐘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cache 命中後跳過 DB&lt;/td>
 &lt;td>是（Memcached query-cache）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：MongoDB Atlas（主資料層）、DynamoDB（部分 workload 的 federated store）、Memcached（query result cache）、自研 mongobetween proxy（連線多工）、Ruby on Rails 單體 + 多個 Fragment APIs、ML 預測模型驅動 cluster auto-scaling。&lt;/p>
&lt;p>關鍵負載形狀：「加密貨幣價格突發 + 用戶交易需求湧入」雙峰疊加。價格 alert 觸發 read 爆量（users / portfolio 查詢）、下單觸發 write 爆量（order book / wallet 寫入）。兩種峰值不像 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &amp;#43;50% 不影響延遲">9.C4 DraftKings&lt;/a> 的 Super Bowl 事件型可預測、是隨外部市場波動的 &lt;em>low-latency-sustained 中夾雜 surge&lt;/em>。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Coinbase MongoDB 的工程選擇揭露三個 document database 在 production 主角位置的設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>MongoDB + Ruby 連線爆炸需要外部 connection pool&lt;/strong>：CRuby 因為 GVL 必須每 CPU core 起一個 process、blue-green 部署期間 instance 數量 ×2、連線數隨之 ×2、單一 cluster 看到 60K 連線/分鐘。原生 MongoDB driver 沒有跨 process 的 connection pool — 跟 PostgreSQL 走 pgbouncer 是同樣需求、所以 Coinbase 自建 &lt;a href="https://github.com/coinbase/mongobetween">mongobetween&lt;/a> 做多工。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取&lt;/a> 的 connection storm 問題、document database 不會自動解決、要主動補工具。&lt;/li>
&lt;li>&lt;strong>document model 撐 1.5M reads/sec 靠 cache + freshness token&lt;/strong>：直接打 MongoDB 不可能撐 1.5M reads/sec — Coinbase 在 users 服務前面加 Memcached query cache、單 document query 先查 cache。但 cache + write 會有一致性問題、所以引入 OCC version 跟 &lt;em>freshness token&lt;/em>：write 成功後給 client 一個 token、client 之後 read 帶 token、server 保證返回的資料版本 ≥ token、必要時 bypass cache 直接打 DB。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a> 的 read-after-write 設計。&lt;/li>
&lt;li>&lt;strong>加密貨幣 surge 用 ML 預測、不靠 reactive scaling&lt;/strong>：cluster 擴容要 70 分鐘、傳統 CPU / queue 觸發的 reactive scaling 在 surge 開始時才動、來不及。Coinbase 訓練 ML 模型分析價格資料、提前 60 分鐘預測流量、預先擴容。把擴容時間從 70 分鐘壓到 25 分鐘是 trigger 提前、不是擴容本身變快。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 的 predictive scaling。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「document database 在大規模 OLTP 場景如何撐住」。Coinbase 從 Ruby on Rails 單體 + MongoDB 起家、八年後仍保留 MongoDB 作為主資料層、並把 connection pooling、ML 預測擴容、cache + freshness token 都疊在 document model 上。跟 <a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a> 對照 — Microsoft 365 走「遷出 MongoDB、保留 document API」、Coinbase 走「保留 MongoDB、補周邊工具」。兩條路徑都揭露 MongoDB 在 production 主角位置會遇到什麼壓力。</p>
<h2 id="觀察">觀察</h2>
<p>Coinbase MongoDB 平台的關鍵數字（引自 <a href="https://www.coinbase.com/blog/scaling-connections-with-ruby-and-mongodb">Coinbase Engineering Blog</a> 與 <a href="https://www.mongodb.com/solutions/customer-case-studies/coinbase">MongoDB customer case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Users 服務尖峰讀取</td>
          <td>1.5M reads / sec</td>
      </tr>
      <tr>
          <td>Deploy 時 MongoDB 連線尖峰</td>
          <td>~60K connections / minute（單 cluster）</td>
      </tr>
      <tr>
          <td>mongobetween 後連線降幅</td>
          <td>30K → ~2K（一個量級）</td>
      </tr>
      <tr>
          <td>MongoDB cluster 數量</td>
          <td>many clusters（多服務 federated）</td>
      </tr>
      <tr>
          <td>加密貨幣 surge 擴容時間</td>
          <td>70 分鐘 → 25 分鐘（-64%）</td>
      </tr>
      <tr>
          <td>ML 預測擴容領先窗</td>
          <td>60 分鐘</td>
      </tr>
      <tr>
          <td>Cache 命中後跳過 DB</td>
          <td>是（Memcached query-cache）</td>
      </tr>
  </tbody>
</table>
<p>服務組合：MongoDB Atlas（主資料層）、DynamoDB（部分 workload 的 federated store）、Memcached（query result cache）、自研 mongobetween proxy（連線多工）、Ruby on Rails 單體 + 多個 Fragment APIs、ML 預測模型驅動 cluster auto-scaling。</p>
<p>關鍵負載形狀：「加密貨幣價格突發 + 用戶交易需求湧入」雙峰疊加。價格 alert 觸發 read 爆量（users / portfolio 查詢）、下單觸發 write 爆量（order book / wallet 寫入）。兩種峰值不像 <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 的 Super Bowl 事件型可預測、是隨外部市場波動的 <em>low-latency-sustained 中夾雜 surge</em>。</p>
<h2 id="判讀">判讀</h2>
<p>Coinbase MongoDB 的工程選擇揭露三個 document database 在 production 主角位置的設計重點。</p>
<ol>
<li><strong>MongoDB + Ruby 連線爆炸需要外部 connection pool</strong>：CRuby 因為 GVL 必須每 CPU core 起一個 process、blue-green 部署期間 instance 數量 ×2、連線數隨之 ×2、單一 cluster 看到 60K 連線/分鐘。原生 MongoDB driver 沒有跨 process 的 connection pool — 跟 PostgreSQL 走 pgbouncer 是同樣需求、所以 Coinbase 自建 <a href="https://github.com/coinbase/mongobetween">mongobetween</a> 做多工。對應 <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a> 的 connection storm 問題、document database 不會自動解決、要主動補工具。</li>
<li><strong>document model 撐 1.5M reads/sec 靠 cache + freshness token</strong>：直接打 MongoDB 不可能撐 1.5M reads/sec — Coinbase 在 users 服務前面加 Memcached query cache、單 document query 先查 cache。但 cache + write 會有一致性問題、所以引入 OCC version 跟 <em>freshness token</em>：write 成功後給 client 一個 token、client 之後 read 帶 token、server 保證返回的資料版本 ≥ token、必要時 bypass cache 直接打 DB。對應 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a> 的 read-after-write 設計。</li>
<li><strong>加密貨幣 surge 用 ML 預測、不靠 reactive scaling</strong>：cluster 擴容要 70 分鐘、傳統 CPU / queue 觸發的 reactive scaling 在 surge 開始時才動、來不及。Coinbase 訓練 ML 模型分析價格資料、提前 60 分鐘預測流量、預先擴容。把擴容時間從 70 分鐘壓到 25 分鐘是 trigger 提前、不是擴容本身變快。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的 predictive scaling。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「1.5M reads/sec」是 users 服務 <em>加上 cache</em> 的數字、不是 MongoDB cluster 純讀取數字。讀案例時要區分「應用層觀察到」跟「DB 層實際承擔」。</li>
<li>mongobetween 是 Coinbase 特殊環境（Ruby + GVL + blue-green）的產物。Go / Java / Node.js 應用因為原生支援連線多工、通常不需要這層 proxy。</li>
<li>ML 預測有 false positive / false negative — 預測錯時要嘛浪費容量、要嘛 surge 真來時擋不住。Coinbase 沒揭露準確率、所以仍保留 reactive scaling 作為 safety net。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>document database 撐大規模 OLTP 要主動補 connection pool</strong>：MongoDB 原生 connection 模式對「process 數多 + deploy 重」的環境會爆。應用層或 sidecar proxy 做多工是基線設計。對應 <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">01.10 KV / Document DB 容量規劃</a>。</li>
<li><strong>freshness token 是 read-after-write 一致性的可重用模式</strong>：比 strong consistency（性能差）跟 eventually consistent（read 不到剛寫的）更精細的中間路徑。token 機制可以推廣到任何「主要 eventually consistent、少數 read 要求最新」的場景。</li>
<li><strong>predictive scaling 適用於「外部訊號可預測流量」的服務</strong>：加密貨幣價格、賽事行程、票務開賣時間都是外部訊號。比 reactive scaling 早一個擴容週期出手。對應 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> 的 AI 預測式擴容。</li>
<li><strong>federated DB（MongoDB + DynamoDB）按 workload 分流</strong>：document-shaped 用 MongoDB、access pattern 固定的 KV 用 DynamoDB。不是「全用 MongoDB」也不是「全遷 DynamoDB」、是按 workload 形狀分。對應 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a> 的多 DB 整合反例（Netflix 走整合方向、Coinbase 走 federated）。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>AWS：MongoDB Atlas + ElastiCache + DynamoDB（Coinbase 配置）</li>
<li>GCP：MongoDB Atlas on GCP + Memorystore + Firestore（document API）</li>
<li>Azure：Cosmos DB MongoDB API + Cache for Redis、不需要 Atlas</li>
<li>mongobetween 風格的 proxy：PostgreSQL 走 pgbouncer / pgcat、MongoDB 走 mongobetween / mongoproxy</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 MongoDB 大規模 production → <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page</a> + <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">01.10 KV / Document DB 容量規劃</a></li>
<li>想做 read-after-write 一致性設計 → <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a></li>
<li>想做 predictive scaling → <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> + <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a></li>
<li>想對照 MongoDB 遷出 / 保留決策 → <a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a>（遷到 Cosmos DB MongoDB API）</li>
<li>想理解 connection storm 問題 → <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a></li>
<li>想深入 connection / proxy 治理與 cache 層 → <a href="/blog/backend/01-database/vendors/mongodb/connection-management-and-cache-layer/" data-link-title="MongoDB Connection Management and Cache Layer：driver × 部署模型 × cache × predictive scaling" data-link-desc="MongoDB 大規模 OLTP 撞牆不是單一 driver 議題、是 driver × 部署模型 × cache × scaling trigger 三層協作；含 Coinbase mongobetween / freshness token / ML 預測擴容三件套 &#43; 適用範圍紀律">MongoDB connection 管理與 cache 層</a></li>
<li>想做 replica set 讀寫分離設計 → <a href="/blog/backend/01-database/vendors/mongodb/replica-set-read-preference/" data-link-title="MongoDB Replica Set Read Preference：DB 層 causal session vs cache 層 freshness token" data-link-desc="MongoDB read preference 五擇一 &#43; read concern &#43; causal consistency session 機制；DB 層機制解 cluster 內 read-your-own-write、cache 層 freshness token 解跨層 read-after-write、大規模 OLTP 必須兩層合用">MongoDB replica set read preference</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.coinbase.com/blog/scaling-connections-with-ruby-and-mongodb">Coinbase：Scaling connections with Ruby and MongoDB</a></li>
<li><a href="https://www.coinbase.com/blog/scaling-identity-how-coinbase-serves-1.5M-reads-second">Coinbase：Scaling Identity - How Coinbase Serves 1.5M Reads/Second</a></li>
<li><a href="https://www.coinbase.com/blog/how-we-do-mongodb-migrations-at-coinbase">Coinbase：How We Do MongoDB Migrations at Coinbase</a></li>
<li><a href="https://www.mongodb.com/solutions/customer-case-studies/coinbase">MongoDB customer case study：Coinbase Decreases Scaling Time</a></li>
<li><a href="https://github.com/coinbase/mongobetween">mongobetween GitHub repository</a></li>
</ul>
]]></content:encoded></item><item><title>9.C37 Forbes：自管 MongoDB → Atlas on GCP、build 時間 25 → 9 分鐘</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/</guid><description>&lt;p>這個案例的核心責任是說明「從自管 MongoDB 遷到 Atlas managed」這條路徑的工程與成本對照。Forbes 自 2011 年起用 MongoDB 重寫 CMS、2020 年把 production 遷到 Atlas on Google Cloud、保留同一個 document model、轉移 DBA 責任跟跨雲彈性。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato&lt;/a> 的「跨 DB 種類遷移」對照 — Forbes 是 &lt;em>同 DB、換託管模式&lt;/em>、不需要重寫 schema 跟 access pattern。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Forbes 遷移到 MongoDB Atlas on Google Cloud 的關鍵數字（引自 &lt;a href="https://cloud.google.com/blog/products/databases/forbes-migrates-to-mongodb-atlas-on-google-cloud">Google Cloud Blog&lt;/a> 與 &lt;a href="https://www.mongodb.com/solutions/customer-case-studies/forbes">MongoDB customer case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>單月不重複訪客&lt;/td>
 &lt;td>120M（2020 年 5 月）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Build 時間&lt;/td>
 &lt;td>25 分鐘 → 9 分鐘（-64%）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Release 頻率提升&lt;/td>
 &lt;td>2x – 10x&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>微服務數量&lt;/td>
 &lt;td>50+（GKE 上）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移耗時&lt;/td>
 &lt;td>6 個月&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DB 總體擁有成本降幅&lt;/td>
 &lt;td>-25%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>電子報訂閱量&lt;/td>
 &lt;td>+92%（2020 全年）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Atlas 可用 region&lt;/td>
 &lt;td>70+（跨 AWS / GCP / Azure）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CMS MongoDB 起用年&lt;/td>
 &lt;td>2011（首版 CMS 兩個月內交付）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：MongoDB Atlas（managed document DB）、Google Cloud Platform（基礎設施）、Google Kubernetes Engine（50+ 微服務編排）、Google App Engine（部分 serverless 應用）、自建中介 abstraction layer（API 隔離 schema 變動）。&lt;/p>
&lt;p>關鍵負載形狀：「文章 publish 後突然爆量」是新聞媒體常態 — 熱門報導、人物專訪、財經事件都會在分鐘內把單篇文章拉到百萬讀者。這跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&amp;#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL&lt;/a> 的「賽事時段預期峰值」不同、Forbes 的爆量是事件驅動、難以精確預測、需要 Atlas auto-scaling 撐住臨時讀爆。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Forbes 的遷移選擇揭露三個「自管 → managed」路徑的判讀重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>同 DB 換託管模式比換 DB 種類風險低、但 ROI 也較窄&lt;/strong>：Forbes 6 個月完成遷移、保留同 document model、schema 不動、application 改動只在 connection string 跟運維邊界。這跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato 從 TiDB 遷到 DynamoDB&lt;/a> 對照、後者要重新設計 access pattern、ROI 大但風險高。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組&lt;/a> 的 schema migration playbook：「換 DB」跟「換託管」是兩個不同議題、不要混為一談。&lt;/li>
&lt;li>&lt;strong>跨雲彈性的價值在規避未來鎖定、不是當下省成本&lt;/strong>：Atlas 提供 AWS / GCP / Azure 跨雲部署。Forbes 選 GCP 是當下決策、但 Atlas 的跨雲能力讓未來雲商選型不再綁定特定 vendor。這跟 DynamoDB（AWS only）、Cosmos DB（Azure only）、Spanner（GCP only）的單雲鎖定形成對照。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的 vendor lock-in 評估。&lt;/li>
&lt;li>&lt;strong>Build 時間 25 → 9 分鐘 = 開發者效率改善、不是 DB 性能改善&lt;/strong>：Build 時間下降主因是 ephemeral test environment 用 Atlas API spin-up、不是 MongoDB query 變快。CMS 系統的 production read latency Atlas 跟自管 MongoDB 差距通常在 ±20% 內、真正贏的是「開發 / 部署 cycle 變短」。讀案例時要區分「開發者體驗 metric」跟「production 性能 metric」、兩者改善的杠桿完全不同。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「從自管 MongoDB 遷到 Atlas managed」這條路徑的工程與成本對照。Forbes 自 2011 年起用 MongoDB 重寫 CMS、2020 年把 production 遷到 Atlas on Google Cloud、保留同一個 document model、轉移 DBA 責任跟跨雲彈性。跟 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> 的「跨 DB 種類遷移」對照 — Forbes 是 <em>同 DB、換託管模式</em>、不需要重寫 schema 跟 access pattern。</p>
<h2 id="觀察">觀察</h2>
<p>Forbes 遷移到 MongoDB Atlas on Google Cloud 的關鍵數字（引自 <a href="https://cloud.google.com/blog/products/databases/forbes-migrates-to-mongodb-atlas-on-google-cloud">Google Cloud Blog</a> 與 <a href="https://www.mongodb.com/solutions/customer-case-studies/forbes">MongoDB customer case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>單月不重複訪客</td>
          <td>120M（2020 年 5 月）</td>
      </tr>
      <tr>
          <td>Build 時間</td>
          <td>25 分鐘 → 9 分鐘（-64%）</td>
      </tr>
      <tr>
          <td>Release 頻率提升</td>
          <td>2x – 10x</td>
      </tr>
      <tr>
          <td>微服務數量</td>
          <td>50+（GKE 上）</td>
      </tr>
      <tr>
          <td>遷移耗時</td>
          <td>6 個月</td>
      </tr>
      <tr>
          <td>DB 總體擁有成本降幅</td>
          <td>-25%</td>
      </tr>
      <tr>
          <td>電子報訂閱量</td>
          <td>+92%（2020 全年）</td>
      </tr>
      <tr>
          <td>Atlas 可用 region</td>
          <td>70+（跨 AWS / GCP / Azure）</td>
      </tr>
      <tr>
          <td>CMS MongoDB 起用年</td>
          <td>2011（首版 CMS 兩個月內交付）</td>
      </tr>
  </tbody>
</table>
<p>服務組合：MongoDB Atlas（managed document DB）、Google Cloud Platform（基礎設施）、Google Kubernetes Engine（50+ 微服務編排）、Google App Engine（部分 serverless 應用）、自建中介 abstraction layer（API 隔離 schema 變動）。</p>
<p>關鍵負載形狀：「文章 publish 後突然爆量」是新聞媒體常態 — 熱門報導、人物專訪、財經事件都會在分鐘內把單篇文章拉到百萬讀者。這跟 <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar IPL</a> 的「賽事時段預期峰值」不同、Forbes 的爆量是事件驅動、難以精確預測、需要 Atlas auto-scaling 撐住臨時讀爆。</p>
<h2 id="判讀">判讀</h2>
<p>Forbes 的遷移選擇揭露三個「自管 → managed」路徑的判讀重點。</p>
<ol>
<li><strong>同 DB 換託管模式比換 DB 種類風險低、但 ROI 也較窄</strong>：Forbes 6 個月完成遷移、保留同 document model、schema 不動、application 改動只在 connection string 跟運維邊界。這跟 <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato 從 TiDB 遷到 DynamoDB</a> 對照、後者要重新設計 access pattern、ROI 大但風險高。對應 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 的 schema migration playbook：「換 DB」跟「換託管」是兩個不同議題、不要混為一談。</li>
<li><strong>跨雲彈性的價值在規避未來鎖定、不是當下省成本</strong>：Atlas 提供 AWS / GCP / Azure 跨雲部署。Forbes 選 GCP 是當下決策、但 Atlas 的跨雲能力讓未來雲商選型不再綁定特定 vendor。這跟 DynamoDB（AWS only）、Cosmos DB（Azure only）、Spanner（GCP only）的單雲鎖定形成對照。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 vendor lock-in 評估。</li>
<li><strong>Build 時間 25 → 9 分鐘 = 開發者效率改善、不是 DB 性能改善</strong>：Build 時間下降主因是 ephemeral test environment 用 Atlas API spin-up、不是 MongoDB query 變快。CMS 系統的 production read latency Atlas 跟自管 MongoDB 差距通常在 ±20% 內、真正贏的是「開發 / 部署 cycle 變短」。讀案例時要區分「開發者體驗 metric」跟「production 性能 metric」、兩者改善的杠桿完全不同。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「25% TCO 降幅」是 <em>特定流量規模下</em> 的數字。Atlas managed 服務在小流量時 cost-per-GB 比自管低（不用養 DBA），但流量增長到一定規模後 self-hosted 反而便宜。Forbes 在 120M MAU 規模下選 managed 是合理判斷、但這個結論不是普適的。</li>
<li>「Build 25 → 9 分鐘」混合了「MongoDB Atlas API」、「GKE optimization」、「GCP CI/CD」三個變因。把全部歸功於 MongoDB Atlas 會誇大效益。</li>
<li>中介 abstraction layer 是 Forbes 主動加的設計、不是 Atlas 自帶。沒有這層 abstraction、schema 變動仍會直接打穿到所有 microservice、跨雲彈性也用不起來。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>自管 → managed 的遷移要先做 schema 跟 access pattern 盤點</strong>：確認沒有自管時的特殊 hack（自訂 plugin、特殊 storage engine、客製 oplog 處理）— 這些在 managed 服務上通常不支援。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a>。</li>
<li><strong>微服務 + abstraction layer 隔離 schema 變動</strong>：document database 的 schema flexibility 容易讓 production 出現 data inconsistency。中介 API 層把 schema 變動限制在 DB 邊界、microservice 看到的是穩定 API。對應 <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor 的 schema governance 段</a>。</li>
<li><strong>跨雲 managed 服務比單雲服務更適合長期不確定的雲商策略</strong>：Atlas（跨 AWS / GCP / Azure）vs DynamoDB / Cosmos DB / Spanner（單雲）的取捨。當雲商選擇尚未底定、跨雲服務的選項保留價值高。對應 <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor page</a> 跟 <a href="/blog/backend/01-database/vendors/cosmosdb/" data-link-title="Azure Cosmos DB" data-link-desc="全球分散式 multi-model DB、5 個 consistency levels、Microsoft 自家 dogfood 證據">Cosmos DB vendor page</a> 對比。</li>
<li><strong>遷移時間表跟團隊規模耦合</strong>：Forbes 6 個月完成、團隊規模未揭露但顯然是中型團隊 + 多個 squad 並行。1-2 人團隊做同類遷移通常要 12+ 個月。對應 <a href="/blog/backend/01-database/large-scale-db-migration/" data-link-title="1.12 大規模 DB 遷移實戰" data-link-desc="跨 DB 遷移的 dual-write、[shadow read](/backend/knowledge-cards/shadow-read/)、cutover、rollback 流程 — 從實戰案例提煉的工程做法">01.12 大規模 DB 遷移實戰</a> 的時間估計。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>自管 MongoDB → MongoDB Atlas（同 DB、換託管）：Forbes、SEGA HARDlight 路徑</li>
<li>自管 MongoDB → DocumentDB（AWS 自研、API 部分相容）：較多應用層改動、跨雲彈性失去</li>
<li>自管 MongoDB → Cosmos DB MongoDB API（Azure）：<a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a> 路徑、有 RU 模型差異</li>
<li>自管 PostgreSQL → Aurora / Cloud SQL：對等遷移、但 RDB 跟 document DB 的 schema 治理議題不同</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 MongoDB 遷移到 Atlas → <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page</a> + <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a></li>
<li>想評估跨雲 vs 單雲 DB 取捨 → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor page</a> 對比段</li>
<li>想做 microservice + abstraction layer 設計 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a></li>
<li>想對照同類遷移 → <a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a>（遷到 Cosmos DB MongoDB API）/ <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a>（換 DB 種類）</li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://cloud.google.com/blog/products/databases/forbes-migrates-to-mongodb-atlas-on-google-cloud">Forbes migrates from self-managed MongoDB to MongoDB Atlas on Google Cloud</a></li>
<li><a href="https://www.mongodb.com/solutions/customer-case-studies/forbes">New CMS and developer environment cuts build times to just nine minutes for Forbes</a></li>
<li><a href="https://www.mongodb.com/resources/solutions/use-cases/forbes-cloud-migration-helps-worlds-biggest-media-brand-continue-standard-digital-innovation">Forbes：MongoDB Cloud Migration Helps World&rsquo;s Biggest Media Brand</a></li>
</ul>
]]></content:encoded></item><item><title>9.C38 Toyota Connected：MongoDB Atlas 撐 900 萬車輛 telematics、月 180 億 transaction</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/toyota-connected-mongodb-telematics-iot/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/toyota-connected-mongodb-telematics-iot/</guid><description>&lt;p>這個案例的核心責任是說明「IoT / telematics 高頻 sensor 寫入」如何套在 document model 上、以及 MongoDB Atlas 在 mission-critical（生命安全）服務中的角色。Toyota Connected 把車輛 sensor、緊急通報（SOS / 撞擊偵測）、駕駛資料都寫進 20 個 MongoDB Atlas database、用 event-driven microservice 處理。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB&lt;/a> 對照 — Amazon Ads 用 KV 撐極高吞吐、Toyota 用 document model 撐「形狀變化頻繁的 sensor signal」、兩條路徑反映不同的工作負載決策。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Toyota Connected 平台關鍵數字（引自 &lt;a href="https://aws.amazon.com/solutions/case-studies/toyota-connected/">AWS case study&lt;/a> 與 &lt;a href="https://www.mongodb.com/solutions/customer-case-studies/toyota-connected">MongoDB customer case study&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>服務涵蓋車輛數&lt;/td>
 &lt;td>9M+（Toyota / Lexus 北美 Safety Connect）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>每月平台 transaction&lt;/td>
 &lt;td>18 Billion&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>流量擴展能力&lt;/td>
 &lt;td>18x usual 流量&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>緊急訊號處理延遲&lt;/td>
 &lt;td>3 秒內到 safety agent&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>可用性目標&lt;/td>
 &lt;td>99.99%（target、實測 99% 月達成）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MongoDB Atlas DB 數&lt;/td>
 &lt;td>20&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AWS 用量成長&lt;/td>
 &lt;td>3x（自 2018 啟動以來）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>自管成本降幅&lt;/td>
 &lt;td>70-80%（serverless 架構整體）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>車載 sensor 種類&lt;/td>
 &lt;td>數百個（occupant、seatbelt、fuel、air quality）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：MongoDB Atlas（document store，20 databases）、AWS Lambda（serverless 處理事件）、Amazon Kinesis Data Streams（即時資料攝取）、CloudAMQP（非同步訊息）、Redis（hot cache）、Kubernetes（microservice 編排）。&lt;/p>
&lt;p>關鍵負載形狀：「車輛 sensor 持續低頻 + 緊急事件高優先低延遲」雙模式並存。&lt;/p>
&lt;ul>
&lt;li>&lt;em>持續模式&lt;/em>：900 萬車輛、每車數百 sensor、定期上報遙測資料。這是「sustained-growth + 高 throughput」的形狀、document model 比 wide-column 更適合 — 因為不同車型 / 不同年份的 sensor schema 不一樣、document 自然演進、不需要每加 sensor 就 ALTER TABLE。&lt;/li>
&lt;li>&lt;em>緊急模式&lt;/em>：SOS 按鈕、自動撞擊通報、車輛安全異常。這是 &lt;em>life-critical low-latency&lt;/em> — 3 秒內 sensor 訊號要從車輛到 agent 螢幕、含網路傳輸、event routing、microservice 處理、agent UI rendering。這個 budget 倒推回 MongoDB 寫入要求是 sub-100ms。&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Toyota Connected 的 MongoDB 選擇揭露三個 IoT / telematics 工程決策的判讀重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>document model 適合「sensor schema 隨產品演進」的場景&lt;/strong>：車載 sensor 種類隨車型、年份、地區規範變化。RDB 走「每加 sensor 加 column」會讓 schema migration 變成發行週期的卡點；document model 走「polymorphic document」、新 sensor 只是新欄位、舊文件不需要 backfill。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page&lt;/a> 的 document shape 教學段。但這個彈性的成本是：production 必須做 schema governance（validation、版本欄位、application 層相容處理），否則「schema 自由」會變「production data inconsistency」。&lt;/li>
&lt;li>&lt;strong>20 個 Atlas database 不是技術上限、是業務邊界切分&lt;/strong>：18 Billion transactions / 月 ÷ 30 天 ÷ 86400 秒 ≈ 7K transactions / sec。這個數字單一 MongoDB cluster 可以撐、不需要 20 個 DB。Toyota 切 20 個 DB 是按 &lt;em>microservice ownership&lt;/em> 跟 &lt;em>blast radius&lt;/em> — 每個 microservice 擁有自己的 DB、單一 DB 故障不會影響其他服務。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程&lt;/a>、把「總吞吐」拆成「per-DB 邊界」。&lt;/li>
&lt;li>&lt;strong>99.99% target vs 99% 實測差距揭露 telematics 的可用性挑戰&lt;/strong>：99.99% 是 4 分鐘 / 月停機、99% 是 7.2 小時 / 月停機。差兩個 9 不是 MongoDB 自身可用性問題、是 &lt;em>end-to-end&lt;/em> 鏈路問題 — 車輛無線網路、cellular tower、AWS network、event bus、microservice、Atlas cluster 任一環節掉都會打掉可用性。MongoDB Atlas 自身的 SLA 通常是 99.95%、達到 99.99% 必須 multi-region + 跨雲冗餘。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &amp;#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys 99.999%&lt;/a> 的多 region active-active 設計。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「IoT / telematics 高頻 sensor 寫入」如何套在 document model 上、以及 MongoDB Atlas 在 mission-critical（生命安全）服務中的角色。Toyota Connected 把車輛 sensor、緊急通報（SOS / 撞擊偵測）、駕駛資料都寫進 20 個 MongoDB Atlas database、用 event-driven microservice 處理。跟 <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB</a> 對照 — Amazon Ads 用 KV 撐極高吞吐、Toyota 用 document model 撐「形狀變化頻繁的 sensor signal」、兩條路徑反映不同的工作負載決策。</p>
<h2 id="觀察">觀察</h2>
<p>Toyota Connected 平台關鍵數字（引自 <a href="https://aws.amazon.com/solutions/case-studies/toyota-connected/">AWS case study</a> 與 <a href="https://www.mongodb.com/solutions/customer-case-studies/toyota-connected">MongoDB customer case study</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>服務涵蓋車輛數</td>
          <td>9M+（Toyota / Lexus 北美 Safety Connect）</td>
      </tr>
      <tr>
          <td>每月平台 transaction</td>
          <td>18 Billion</td>
      </tr>
      <tr>
          <td>流量擴展能力</td>
          <td>18x usual 流量</td>
      </tr>
      <tr>
          <td>緊急訊號處理延遲</td>
          <td>3 秒內到 safety agent</td>
      </tr>
      <tr>
          <td>可用性目標</td>
          <td>99.99%（target、實測 99% 月達成）</td>
      </tr>
      <tr>
          <td>MongoDB Atlas DB 數</td>
          <td>20</td>
      </tr>
      <tr>
          <td>AWS 用量成長</td>
          <td>3x（自 2018 啟動以來）</td>
      </tr>
      <tr>
          <td>自管成本降幅</td>
          <td>70-80%（serverless 架構整體）</td>
      </tr>
      <tr>
          <td>車載 sensor 種類</td>
          <td>數百個（occupant、seatbelt、fuel、air quality）</td>
      </tr>
  </tbody>
</table>
<p>服務組合：MongoDB Atlas（document store，20 databases）、AWS Lambda（serverless 處理事件）、Amazon Kinesis Data Streams（即時資料攝取）、CloudAMQP（非同步訊息）、Redis（hot cache）、Kubernetes（microservice 編排）。</p>
<p>關鍵負載形狀：「車輛 sensor 持續低頻 + 緊急事件高優先低延遲」雙模式並存。</p>
<ul>
<li><em>持續模式</em>：900 萬車輛、每車數百 sensor、定期上報遙測資料。這是「sustained-growth + 高 throughput」的形狀、document model 比 wide-column 更適合 — 因為不同車型 / 不同年份的 sensor schema 不一樣、document 自然演進、不需要每加 sensor 就 ALTER TABLE。</li>
<li><em>緊急模式</em>：SOS 按鈕、自動撞擊通報、車輛安全異常。這是 <em>life-critical low-latency</em> — 3 秒內 sensor 訊號要從車輛到 agent 螢幕、含網路傳輸、event routing、microservice 處理、agent UI rendering。這個 budget 倒推回 MongoDB 寫入要求是 sub-100ms。</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>Toyota Connected 的 MongoDB 選擇揭露三個 IoT / telematics 工程決策的判讀重點。</p>
<ol>
<li><strong>document model 適合「sensor schema 隨產品演進」的場景</strong>：車載 sensor 種類隨車型、年份、地區規範變化。RDB 走「每加 sensor 加 column」會讓 schema migration 變成發行週期的卡點；document model 走「polymorphic document」、新 sensor 只是新欄位、舊文件不需要 backfill。對應 <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page</a> 的 document shape 教學段。但這個彈性的成本是：production 必須做 schema governance（validation、版本欄位、application 層相容處理），否則「schema 自由」會變「production data inconsistency」。</li>
<li><strong>20 個 Atlas database 不是技術上限、是業務邊界切分</strong>：18 Billion transactions / 月 ÷ 30 天 ÷ 86400 秒 ≈ 7K transactions / sec。這個數字單一 MongoDB cluster 可以撐、不需要 20 個 DB。Toyota 切 20 個 DB 是按 <em>microservice ownership</em> 跟 <em>blast radius</em> — 每個 microservice 擁有自己的 DB、單一 DB 故障不會影響其他服務。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a>、把「總吞吐」拆成「per-DB 邊界」。</li>
<li><strong>99.99% target vs 99% 實測差距揭露 telematics 的可用性挑戰</strong>：99.99% 是 4 分鐘 / 月停機、99% 是 7.2 小時 / 月停機。差兩個 9 不是 MongoDB 自身可用性問題、是 <em>end-to-end</em> 鏈路問題 — 車輛無線網路、cellular tower、AWS network、event bus、microservice、Atlas cluster 任一環節掉都會打掉可用性。MongoDB Atlas 自身的 SLA 通常是 99.95%、達到 99.99% 必須 multi-region + 跨雲冗餘。對應 <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys 99.999%</a> 的多 region active-active 設計。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>「18 Billion transactions / 月」是 <em>平台所有服務</em> 加總、不是 MongoDB 單一 cluster 數字。MongoDB 只承擔其中需要 document storage 的部分、其他走 Lambda 直接處理或寫到 Kinesis。</li>
<li>「3 秒延遲到 agent」包含車載、無線、雲端、UI、agent 操作多個環節。MongoDB 在這個延遲鏈裡通常分到 100-500ms 預算、不是整個 3 秒。</li>
<li>MongoDB 6.0+ 有 time series collection 對 IoT 寫入有專屬優化。Toyota 揭露的 20 個 DB 沒明確說有沒有用 time series collection — 對 IoT 案例這是重要區分、但 case study 沒揭露。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>IoT 高頻 sensor 寫入考慮 MongoDB time series collection（6.0+）</strong>：比 regular collection 寫入吞吐高 3-5x、storage 壓縮率更好。專為 timestamp + metadata + measurement 三段式資料優化。對應 <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page</a> 的容量規劃要點段。</li>
<li><strong>mission-critical IoT 系統要做 multi-region 跟多供應商備援</strong>：99.99% 不能只靠 MongoDB Atlas 本身、要靠 region 冗餘 + 多條 cellular network + 多個 event bus 路徑。對應 <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a> 的 multi-region active-active。</li>
<li><strong>按 microservice ownership 切 MongoDB cluster、不要單一巨型 cluster</strong>：blast radius 邊界 = 業務邊界、不是「能不能撐」的問題。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a>。</li>
<li><strong>event-driven 處理 IoT 資料、不用 request-response</strong>：sensor 寫到 Kinesis / Kafka / event bus、microservice 從 stream 消費、寫進 MongoDB。這條 path 避免「sensor 寫不進去 DB 就 retry storm」的問題。對應 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a>。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>AWS：MongoDB Atlas + Kinesis + Lambda（Toyota 配置）</li>
<li>GCP：MongoDB Atlas on GCP + Pub/Sub + Cloud Functions、或 Firestore + Pub/Sub（document API native）</li>
<li>Azure：Cosmos DB MongoDB API + Event Hubs + Azure Functions</li>
<li>跨雲：MongoDB Atlas 是 IoT 平台保留跨雲彈性的少數選項</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想規劃 IoT / telematics 資料層 → <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor page</a> + <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">01.10 KV / Document DB 容量規劃</a></li>
<li>想做 multi-region 高可用性 → <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys 99.999%</a></li>
<li>想對照不同 IoT 資料層選擇 → <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads DynamoDB</a>（KV）/ <a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26 PayPay</a>（高頻訊息）</li>
<li>想理解 event-driven IoT 架構 → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a></li>
<li>想做 IoT 寫入吞吐的 shard key 選型 → <a href="/blog/backend/01-database/vendors/mongodb/shard-key-selection/" data-link-title="MongoDB Shard Key Selection：hashed vs ranged、單 cluster 切 shard vs 多 cluster 切 blast radius" data-link-desc="MongoDB sharded cluster shard key 選型（hashed / ranged / compound）、單 cluster 分 shard vs 多 cluster 分 blast radius 對照、跟 DynamoDB / Cosmos DB partition key 可逆性的跨 vendor 紀律">MongoDB shard key 選型</a></li>
<li>想規劃 telemetry schema design → <a href="/blog/backend/01-database/vendors/mongodb/schema-design-pattern/" data-link-title="MongoDB Schema Design Pattern：contract layer 在哪 vs embedded / reference" data-link-desc="MongoDB document schema 真正的 production 議題不是 embedded vs reference 二選一、是 schema contract 該放 DB 層 validator 還是 app 層 abstraction；含 Toyota polymorphic governance、Forbes abstraction layer、time-series collection 邊界">MongoDB schema design pattern</a></li>
<li>想處理 IoT 高 client 數的 connection storm → <a href="/blog/backend/01-database/vendors/mongodb/connection-management-and-cache-layer/" data-link-title="MongoDB Connection Management and Cache Layer：driver × 部署模型 × cache × predictive scaling" data-link-desc="MongoDB 大規模 OLTP 撞牆不是單一 driver 議題、是 driver × 部署模型 × cache × scaling trigger 三層協作；含 Coinbase mongobetween / freshness token / ML 預測擴容三件套 &#43; 適用範圍紀律">MongoDB connection 管理與 cache 層</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.mongodb.com/solutions/customer-case-studies/toyota-connected">Toyota Connected Aims For At Least 99.99% Availability With MongoDB Assistance</a></li>
<li><a href="https://aws.amazon.com/solutions/case-studies/toyota-connected/">Toyota Connected Reimagines Mobility on AWS</a></li>
<li><a href="https://digitalcxo.com/article/mongodb-aws-help-toyota-connected-move-past-legacy-database-challenges/">MongoDB, AWS Help Toyota Connected Move Past Legacy Database Challenges</a></li>
<li><a href="https://www.just-auto.com/news/toyota-connected-hails-efficiencies-from-migration-of-data-services-to-mongodb-atlas/">Toyota Connected hails efficiencies from migration of data services to MongoDB Atlas</a></li>
<li><a href="https://www.mongodb.com/company/blog/innovation/data-modeling-strategies-connected-vehicle-signal-data-in-mongodb">Data Modeling Strategies For Connected Vehicle Signal Data In MongoDB</a></li>
</ul>
]]></content:encoded></item><item><title>9.C39 DoorDash：Aurora Postgres 寫入瓶頸 → CockroachDB 多主寫入</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/doordash-cockroachdb-orders-platform/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/doordash-cockroachdb-orders-platform/</guid><description>&lt;p>這個案例的核心責任是說明「single-primary OLTP 撞到寫入天花板」如何用 distributed SQL 拆解。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &amp;#43;50% 不影響延遲">9.C4 DraftKings&lt;/a> 對比 — DraftKings 在 Aurora 上靠「業務切 200 個獨立 cluster」橫向擴展、DoorDash 是「保留 PostgreSQL wire 介面、但底層換成多主寫入的 CockroachDB」。兩條路徑都在解「Aurora 單主寫入容量上限」、走法不同。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>DoorDash 從 Aurora Postgres 遷到 CockroachDB 的關鍵敘述（引自 &lt;a href="https://www.cockroachlabs.com/blog/aurora-postgres-to-cockroachdb/">Why DoorDash migrated from Aurora Postgres to CockroachDB&lt;/a> / &lt;a href="https://thenewstack.io/how-doordash-migrated-from-aurora-postgres-to-cockroachdb/">The New Stack 報導&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>2020-04-17 高峰 QPS&lt;/td>
 &lt;td>&amp;gt; 1.636 million QPS&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>事件結果&lt;/td>
 &lt;td>multi-hour outage&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>事件背景&lt;/td>
 &lt;td>疫情封鎖、外送需求暴增&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>遷移啟動&lt;/td>
 &lt;td>事件後幾週、先把 table 從主 cluster 拆出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>第一階段移轉量&lt;/td>
 &lt;td>一個月內把 dozens of tables 拆到獨立 Aurora cluster&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>第二階段&lt;/td>
 &lt;td>自動化工具把 Aurora Postgres → CockroachDB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>後續結果&lt;/td>
 &lt;td>跑更多 cluster、incident alert volume 反而下降&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：Aurora Postgres（遷移前主要 OLTP）、CockroachDB self-hosted、自製 table extraction tool、自製 lossless migration pipeline。&lt;/p>
&lt;p>關鍵負載形狀：DoorDash 是 &lt;em>規模化外送平台&lt;/em> — 訂單、Dasher 派遣、餐廳 menu、新業務（grocery / convenience）並存。寫入壓力來自訂單成立、status 變更、地圖位置更新等多種 hot write path。2020 疫情前流量已大、疫情後再翻倍、且高峰集中在週末晚餐 / 週日早午餐時段。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>DoorDash 的工程選擇揭露三個 OLTP 寫入容量設計重點。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Aurora 的「single-primary 寫入」是規模化的天花板&lt;/strong>：Aurora 把 storage 跟 compute 分離、read replica 容易擴、&lt;em>但寫入仍走唯一 primary&lt;/em>。1.636 M QPS 不是均勻分佈、是 hot table 集中寫爆。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取&lt;/a> 的寫入容量規劃。CockroachDB 改成 Raft per range、每個 node 都能服務寫入、容量隨節點線性擴。&lt;/li>
&lt;li>&lt;strong>Migration 工具自製是先決條件、不是 nice-to-have&lt;/strong>：DoorDash 沒「一次性遷整套」、而是先寫工具把 table 從主 cluster 拆到獨立 Aurora cluster（紓壓）、再寫第二套工具把 Aurora → CockroachDB（換引擎）。兩階段都要 &lt;em>lossless&lt;/em> + &lt;em>可回退&lt;/em>。對應 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook&lt;/a> 的「先建工具、再遷資料」原則。&lt;/li>
&lt;li>&lt;strong>Cluster 數量增加、alert volume 卻下降&lt;/strong>：直覺反過來、cluster 多 = 維運面變大、應該更多 alert。但每個 CockroachDB cluster 內建 Raft 自動容錯、單節點 fail 不會 page on-call、Aurora 時代的「primary failover alert」消失。對應 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組&lt;/a> 的「告警 surface 設計」與 &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">06.x reliability&lt;/a> 的 graceful degradation。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：1.636 M QPS 是 &lt;em>主 cluster 峰值&lt;/em>、不是「DoorDash 全部寫入 QPS」。case 沒揭露遷移後單一 CockroachDB cluster 的峰值、只說「跑更多 cluster」。讀案例時不要把這個數字當成「CockroachDB 撐 1.6 M QPS」的證據、它是 &lt;em>Aurora 在那個時間點撞牆的痛點&lt;/em>。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「single-primary OLTP 撞到寫入天花板」如何用 distributed SQL 拆解。跟 <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 對比 — DraftKings 在 Aurora 上靠「業務切 200 個獨立 cluster」橫向擴展、DoorDash 是「保留 PostgreSQL wire 介面、但底層換成多主寫入的 CockroachDB」。兩條路徑都在解「Aurora 單主寫入容量上限」、走法不同。</p>
<h2 id="觀察">觀察</h2>
<p>DoorDash 從 Aurora Postgres 遷到 CockroachDB 的關鍵敘述（引自 <a href="https://www.cockroachlabs.com/blog/aurora-postgres-to-cockroachdb/">Why DoorDash migrated from Aurora Postgres to CockroachDB</a> / <a href="https://thenewstack.io/how-doordash-migrated-from-aurora-postgres-to-cockroachdb/">The New Stack 報導</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>2020-04-17 高峰 QPS</td>
          <td>&gt; 1.636 million QPS</td>
      </tr>
      <tr>
          <td>事件結果</td>
          <td>multi-hour outage</td>
      </tr>
      <tr>
          <td>事件背景</td>
          <td>疫情封鎖、外送需求暴增</td>
      </tr>
      <tr>
          <td>遷移啟動</td>
          <td>事件後幾週、先把 table 從主 cluster 拆出</td>
      </tr>
      <tr>
          <td>第一階段移轉量</td>
          <td>一個月內把 dozens of tables 拆到獨立 Aurora cluster</td>
      </tr>
      <tr>
          <td>第二階段</td>
          <td>自動化工具把 Aurora Postgres → CockroachDB</td>
      </tr>
      <tr>
          <td>後續結果</td>
          <td>跑更多 cluster、incident alert volume 反而下降</td>
      </tr>
  </tbody>
</table>
<p>服務組合：Aurora Postgres（遷移前主要 OLTP）、CockroachDB self-hosted、自製 table extraction tool、自製 lossless migration pipeline。</p>
<p>關鍵負載形狀：DoorDash 是 <em>規模化外送平台</em> — 訂單、Dasher 派遣、餐廳 menu、新業務（grocery / convenience）並存。寫入壓力來自訂單成立、status 變更、地圖位置更新等多種 hot write path。2020 疫情前流量已大、疫情後再翻倍、且高峰集中在週末晚餐 / 週日早午餐時段。</p>
<h2 id="判讀">判讀</h2>
<p>DoorDash 的工程選擇揭露三個 OLTP 寫入容量設計重點。</p>
<ol>
<li><strong>Aurora 的「single-primary 寫入」是規模化的天花板</strong>：Aurora 把 storage 跟 compute 分離、read replica 容易擴、<em>但寫入仍走唯一 primary</em>。1.636 M QPS 不是均勻分佈、是 hot table 集中寫爆。對應 <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a> 的寫入容量規劃。CockroachDB 改成 Raft per range、每個 node 都能服務寫入、容量隨節點線性擴。</li>
<li><strong>Migration 工具自製是先決條件、不是 nice-to-have</strong>：DoorDash 沒「一次性遷整套」、而是先寫工具把 table 從主 cluster 拆到獨立 Aurora cluster（紓壓）、再寫第二套工具把 Aurora → CockroachDB（換引擎）。兩階段都要 <em>lossless</em> + <em>可回退</em>。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> 的「先建工具、再遷資料」原則。</li>
<li><strong>Cluster 數量增加、alert volume 卻下降</strong>：直覺反過來、cluster 多 = 維運面變大、應該更多 alert。但每個 CockroachDB cluster 內建 Raft 自動容錯、單節點 fail 不會 page on-call、Aurora 時代的「primary failover alert」消失。對應 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 的「告警 surface 設計」與 <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">06.x reliability</a> 的 graceful degradation。</li>
</ol>
<p>需要警惕：1.636 M QPS 是 <em>主 cluster 峰值</em>、不是「DoorDash 全部寫入 QPS」。case 沒揭露遷移後單一 CockroachDB cluster 的峰值、只說「跑更多 cluster」。讀案例時不要把這個數字當成「CockroachDB 撐 1.6 M QPS」的證據、它是 <em>Aurora 在那個時間點撞牆的痛點</em>。</p>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>single-primary 撞牆前、先評估 multi-primary 選項</strong>：Aurora / RDS Postgres 是 single-primary 為主、寫入量持續成長最終會撞天花板。轉折點不是 IOPS、是 <em>primary CPU + WAL flush rate</em>。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的瓶頸辨識。</li>
<li><strong>遷 OLTP 引擎要走「兩階段紓壓」</strong>：先在原引擎內把 hot table 拆出（降低主 cluster 壓力、爭取時間）、再規劃換引擎（架構級改造）。直接「一次性換引擎」風險過高。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a>。</li>
<li><strong>PostgreSQL wire protocol 相容性是降低遷移成本的關鍵</strong>：DoorDash 保留 PostgreSQL driver / ORM、應用層改動小。CockroachDB 不是 PostgreSQL fork、是 <em>protocol-level 相容</em>、實際 SQL 行為（serializable default、retry semantics、partial index）仍要驗證。對應 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a> 的 PostgreSQL 相容性 audit 段。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>AWS Aurora DSQL（2024）解同類「multi-primary 寫入」問題、但 AWS-only</li>
<li>Spanner（GCP）同類設計、GCP-only</li>
<li>TiDB（MySQL wire）解同類問題、亞洲生態深</li>
<li>自管 PostgreSQL + Citus（sharded extension）走 application 層 sharding、operation burden 較高</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想理解 single-primary 寫入天花板訊號 → <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> + <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">01.6 高併發資料存取</a></li>
<li>想規劃 PostgreSQL → CockroachDB migration → <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> + <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a></li>
<li>對照其他 OLTP 規模化案例 → <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings Aurora</a>（按業務切 cluster）/ <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a>（DB 種類整合）</li>
<li>想對照其他 distributed SQL 案例 → <a href="/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/" data-link-title="9.C40 Netflix：380&#43; CockroachDB cluster 的 multi-active 拓樸艦隊" data-link-desc="Netflix 把 Cassandra 不夠用的 transactional workload 移到 CockroachDB、380&#43; cluster / 60&#43; 跨 region、含 Open Connect、studio cloud drive、gaming control plane">9.C40 Netflix CockroachDB fleet</a> / <a href="/blog/backend/09-performance-capacity/cases/hard-rock-digital-cockroachdb-sports-betting/" data-link-title="9.C41 Hard Rock Digital：CockroachDB on AWS Outposts、Wire Act 合規 &#43; 跨州單一邏輯 DB" data-link-desc="Hard Rock Digital 用 CockroachDB 跨 AWS Outposts &#43; US-East-1、Wire Act 強制資料留州、單一邏輯 DB 解多州 sportsbook、100 node 32 vCPU 撐 Super Bowl">9.C41 Hard Rock Digital</a></li>
<li>想理解全球一致性 OLTP 選型 → <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
<li>想拆 CockroachDB transaction retry 與 contention 模式 → <a href="/blog/backend/01-database/vendors/cockroachdb/transaction-retry-pattern/" data-link-title="CockroachDB Transaction Retry Pattern：serializable default 與 application contract 重塑" data-link-desc="CockroachDB default SERIALIZABLE、application 必須包 retry loop 處理 40001 serialization_failure。本文走 PG → CockroachDB application contract 重塑視角、SAVEPOINT cockroach_restart 語法、5 種失敗模式（retry storm / 非冪等 / cross-statement state / hot row / long-running transaction）。**整篇是跨 case 合成 frame**：DoorDash case 沒揭露 retry pattern、只揭露 PG wire protocol 相容 &#43; SQL 行為仍要 audit、本章 retry contract 重塑屬通用工程議題從 Cockroach Labs 官方 docs 合成">CockroachDB transaction retry pattern</a></li>
<li>想對比 Aurora DSQL / Spanner / CockroachDB 的選型 → <a href="/blog/backend/01-database/vendors/cockroachdb/aurora-dsql-spanner-decision-tree/" data-link-title="CockroachDB vs Aurora DSQL vs Spanner：撞牆訊號分型 &#43; 七問題決策樹" data-link-desc="Distributed SQL 三選一決策樹。先用撞牆訊號分型識別 driver path（DoorDash 單主寫入撞牆 / Netflix Cassandra 缺口 / Hard Rock 合規驅動）、再走七問題（跨雲 / 雲商生態 / 風險預算 / PG 相容 / 管理負擔 / team size / vendor sizing barrier）。PostgreSQL 相容性 audit checklist 4 項、Spanner 100 pu sizing barrier、Hard Rock 「省 10-20 工程師」機會成本警示、Netflix Database Platform Team 規模">Aurora DSQL / Spanner / CockroachDB 決策樹</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.cockroachlabs.com/blog/aurora-postgres-to-cockroachdb/">Why DoorDash migrated from Aurora Postgres to CockroachDB</a></li>
<li><a href="https://thenewstack.io/how-doordash-migrated-from-aurora-postgres-to-cockroachdb/">How DoorDash Migrated from Aurora Postgres to CockroachDB（The New Stack）</a></li>
<li><a href="https://careersatdoordash.com/blog/how-we-scaled-new-verticals-fulfillment-backend-with-cockroachdb/">How We Scaled New Verticals Fulfillment Backend with CockroachDB（DoorDash Engineering Blog）</a></li>
<li><a href="https://www.infoq.com/news/2024/02/doordash-config-cockroachdb/">DoorDash Uses CockroachDB to Create Config Management Platform for Microservices（InfoQ）</a></li>
</ul>
]]></content:encoded></item><item><title>9.C40 Netflix：380+ CockroachDB cluster 的 multi-active 拓樸艦隊</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/</guid><description>&lt;p>這個案例的核心責任是說明「Cassandra 撐不住 transactional 一致性」如何用 distributed SQL 補位。Netflix &lt;em>用 CockroachDB 補 Cassandra 缺的那塊&lt;/em>、全面替換從來不是策略：需要 rich transaction + global secondary index + multi-active 寫入的場景。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation&lt;/a> 對照 — Aurora 整合的是 OLTP single-region workload、CockroachDB 解的是「跨 region 強一致 + 跨 cluster 高彈性」。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Netflix CockroachDB 艦隊的關鍵數字（引自 &lt;a href="https://www.cockroachlabs.com/customers/netflix/">Now Streaming: Why Netflix Runs a Fleet of 380+ CockroachDB Clusters&lt;/a> / &lt;a href="https://www.cockroachlabs.com/blog/netflix-at-cockroachdb/">The history of databases at Netflix&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>總 cluster 數&lt;/td>
 &lt;td>380+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production cluster&lt;/td>
 &lt;td>160+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Multi-region cluster&lt;/td>
 &lt;td>60+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>最大單區 cluster&lt;/td>
 &lt;td>60 nodes / 26.5 TB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Gaming 平台 cluster&lt;/td>
 &lt;td>48 nodes、跨 4 個 region&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>首個 prod cluster&lt;/td>
 &lt;td>2020 上線&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production cluster&lt;/td>
 &lt;td>2022 已達 100、近年擴至 160+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>部署拓樸常態&lt;/td>
 &lt;td>多數 single-region、3 個 AZ&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：CockroachDB self-managed（Netflix Database Platform Team 自運維）、跨 AWS region、與 Cassandra / EVCache / RDS 並存（polyglot persistence）。&lt;/p>
&lt;p>關鍵 workload：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Studio Cloud Drive&lt;/strong>：影視製作資產的 file-system 風格服務、需要強一致 metadata + 全球可寫&lt;/li>
&lt;li>&lt;strong>Open Connect 控制平面&lt;/strong>：Netflix 自有 CDN、控制全球網路設備、需要跨 region 一致 control state&lt;/li>
&lt;li>&lt;strong>Spinnaker（持續交付平台）&lt;/strong>：deployment workflow state 需要 transactional 一致&lt;/li>
&lt;li>&lt;strong>Maestro（ML / 資料 workflow orchestration）&lt;/strong>：scheduling 與 state machine 不容許 eventual consistency&lt;/li>
&lt;li>&lt;strong>Gaming control plane&lt;/strong>：metadata 跨 4 region、region failure 不能 downtime&lt;/li>
&lt;/ul>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Netflix CockroachDB 艦隊揭露三個「補 Cassandra 缺口」的 OLTP 工程選擇。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Cassandra 不是 transactional 引擎、補位需求是工程現實&lt;/strong>：Netflix 2014 全面採用 Cassandra 解 global replication、但 &lt;em>lightweight transaction&lt;/em> 跟 unreliable secondary index 在 studio / control plane 等場景出問題。2019 評估後選 CockroachDB 是因為它同時滿足 multi-active topology、global consistent secondary index、global transaction、open source、SQL — 五個條件 Cassandra 在 transactional 場景下湊不齊。對應 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組&lt;/a> 的 polyglot persistence 與 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary&lt;/a>。&lt;/li>
&lt;li>&lt;strong>380+ cluster ≠ 「一個巨型 DB」&lt;/strong>：Netflix 是 &lt;em>artery of small DBs&lt;/em> 模型 — 每個微服務 / 應用配自己的 cluster、cluster sizing 從幾個 node 到 60 nodes 不等。容量規劃變成「每個 cluster 各自規劃」、不是「全公司一個容量曲線」。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora&lt;/a> 的「微服務私有 store」哲學。&lt;/li>
&lt;li>&lt;strong>Multi-region 是「region failure 0 downtime」、不是「更快」&lt;/strong>：Netflix 60+ multi-region cluster 主要動機是 region-level survival、不是降 latency（跨 region quorum 反而會增 latency）。Gaming cluster 48-node 跨 4 region 就是為了「region failover 不停服」、不是讓玩家延遲變低。對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget&lt;/a> 的 latency vs availability 取捨。&lt;/li>
&lt;/ol>
&lt;p>需要警惕：&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「Cassandra 撐不住 transactional 一致性」如何用 distributed SQL 補位。Netflix <em>用 CockroachDB 補 Cassandra 缺的那塊</em>、全面替換從來不是策略：需要 rich transaction + global secondary index + multi-active 寫入的場景。跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a> 對照 — Aurora 整合的是 OLTP single-region workload、CockroachDB 解的是「跨 region 強一致 + 跨 cluster 高彈性」。</p>
<h2 id="觀察">觀察</h2>
<p>Netflix CockroachDB 艦隊的關鍵數字（引自 <a href="https://www.cockroachlabs.com/customers/netflix/">Now Streaming: Why Netflix Runs a Fleet of 380+ CockroachDB Clusters</a> / <a href="https://www.cockroachlabs.com/blog/netflix-at-cockroachdb/">The history of databases at Netflix</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>總 cluster 數</td>
          <td>380+</td>
      </tr>
      <tr>
          <td>Production cluster</td>
          <td>160+</td>
      </tr>
      <tr>
          <td>Multi-region cluster</td>
          <td>60+</td>
      </tr>
      <tr>
          <td>最大單區 cluster</td>
          <td>60 nodes / 26.5 TB</td>
      </tr>
      <tr>
          <td>Gaming 平台 cluster</td>
          <td>48 nodes、跨 4 個 region</td>
      </tr>
      <tr>
          <td>首個 prod cluster</td>
          <td>2020 上線</td>
      </tr>
      <tr>
          <td>Production cluster</td>
          <td>2022 已達 100、近年擴至 160+</td>
      </tr>
      <tr>
          <td>部署拓樸常態</td>
          <td>多數 single-region、3 個 AZ</td>
      </tr>
  </tbody>
</table>
<p>服務組合：CockroachDB self-managed（Netflix Database Platform Team 自運維）、跨 AWS region、與 Cassandra / EVCache / RDS 並存（polyglot persistence）。</p>
<p>關鍵 workload：</p>
<ul>
<li><strong>Studio Cloud Drive</strong>：影視製作資產的 file-system 風格服務、需要強一致 metadata + 全球可寫</li>
<li><strong>Open Connect 控制平面</strong>：Netflix 自有 CDN、控制全球網路設備、需要跨 region 一致 control state</li>
<li><strong>Spinnaker（持續交付平台）</strong>：deployment workflow state 需要 transactional 一致</li>
<li><strong>Maestro（ML / 資料 workflow orchestration）</strong>：scheduling 與 state machine 不容許 eventual consistency</li>
<li><strong>Gaming control plane</strong>：metadata 跨 4 region、region failure 不能 downtime</li>
</ul>
<h2 id="判讀">判讀</h2>
<p>Netflix CockroachDB 艦隊揭露三個「補 Cassandra 缺口」的 OLTP 工程選擇。</p>
<ol>
<li><strong>Cassandra 不是 transactional 引擎、補位需求是工程現實</strong>：Netflix 2014 全面採用 Cassandra 解 global replication、但 <em>lightweight transaction</em> 跟 unreliable secondary index 在 studio / control plane 等場景出問題。2019 評估後選 CockroachDB 是因為它同時滿足 multi-active topology、global consistent secondary index、global transaction、open source、SQL — 五個條件 Cassandra 在 transactional 場景下湊不齊。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 polyglot persistence 與 <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a>。</li>
<li><strong>380+ cluster ≠ 「一個巨型 DB」</strong>：Netflix 是 <em>artery of small DBs</em> 模型 — 每個微服務 / 應用配自己的 cluster、cluster sizing 從幾個 node 到 60 nodes 不等。容量規劃變成「每個 cluster 各自規劃」、不是「全公司一個容量曲線」。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 跟 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a> 的「微服務私有 store」哲學。</li>
<li><strong>Multi-region 是「region failure 0 downtime」、不是「更快」</strong>：Netflix 60+ multi-region cluster 主要動機是 region-level survival、不是降 latency（跨 region quorum 反而會增 latency）。Gaming cluster 48-node 跨 4 region 就是為了「region failover 不停服」、不是讓玩家延遲變低。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.12 SLO 與 Performance Budget</a> 的 latency vs availability 取捨。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>case study 沒揭露單一 cluster QPS / latency 具體數字、只揭露 <em>艦隊規模</em> 跟 <em>最大 cluster 容量</em>。讀案例時不要把「380 cluster」直接換算成「Netflix CockroachDB QPS 上限」。</li>
<li>Netflix 是 <em>self-managed</em>、不是 Cockroach Cloud — 需要專屬 Database Platform Team 養 380+ cluster。沒這量級團隊的組織直接 self-host 380 cluster 是 ops 自殺、Cockroach Cloud 才是合理路徑。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>不要試圖一個 DB 撐全部</strong>：Netflix 同時用 Cassandra（高吞吐 eventual）、CockroachDB（transactional + global）、Aurora（單區 ACID）、EVCache（cache）。每種 DB 對應不同 workload 類型、不混用。對應 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 的 polyglot persistence。</li>
<li><strong>每個 cluster 對應一個 application boundary</strong>：避免 multi-tenant 大 cluster、改用「per-app cluster」— 容量規劃顆粒對齊 application、爆掉時 blast radius 限縮在單一 app。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.5 瓶頸定位流程</a> 的 blast radius 設計。</li>
<li><strong>Multi-region 用於 survival、不是 latency 優化</strong>：跨 region quorum 物理上必然增 latency。把 multi-region 動機釐清成 <em>region failure 容忍</em>、不要混淆「跨 region = 更快」。對應 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 的 survival goal vs latency budget 取捨。</li>
<li><strong>Self-managed 規模化需要專屬平台團隊</strong>：Netflix 有 Database Platform Team 養 380+ cluster — 包含 backup、upgrade、incident response、capacity review。沒這量級團隊就走 managed service。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的人力成本權衡。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>Spanner（GCP）解同類「global transaction + secondary index」、GCP-only</li>
<li>DynamoDB Global Tables 走 eventual consistency、不是 Netflix 想要的 strong consistency</li>
<li>Yugabyte / TiDB 是 distributed SQL 對等候選、生態深度與 PostgreSQL wire 相容度有差</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>想理解 polyglot persistence 選型 → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> + <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a></li>
<li>想規劃 multi-region survival goal → <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> + <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a></li>
<li>對照其他 distributed SQL 案例 → <a href="/blog/backend/09-performance-capacity/cases/doordash-cockroachdb-orders-platform/" data-link-title="9.C39 DoorDash：Aurora Postgres 寫入瓶頸 → CockroachDB 多主寫入" data-link-desc="DoorDash 從 Aurora Postgres 遷到 CockroachDB、解 1.6 M QPS 單主寫入瓶頸、外送平台爆量壓力下重做 OLTP 拓樸">9.C39 DoorDash</a> / <a href="/blog/backend/09-performance-capacity/cases/hard-rock-digital-cockroachdb-sports-betting/" data-link-title="9.C41 Hard Rock Digital：CockroachDB on AWS Outposts、Wire Act 合規 &#43; 跨州單一邏輯 DB" data-link-desc="Hard Rock Digital 用 CockroachDB 跨 AWS Outposts &#43; US-East-1、Wire Act 強制資料留州、單一邏輯 DB 解多州 sportsbook、100 node 32 vCPU 撐 Super Bowl">9.C41 Hard Rock Digital</a> / <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想理解 transaction vs eventual consistency 邊界 → <a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">01.5 transaction boundary</a></li>
<li>想深入 CockroachDB survival goal 與 region failure 取捨 → <a href="/blog/backend/01-database/vendors/cockroachdb/survival-goals/" data-link-title="CockroachDB Survival Goals：zone 級 vs region 級配置與業務 SLO 倒推流程" data-link-desc="CockroachDB 用 SURVIVE ZONE FAILURE / SURVIVE REGION FAILURE 兩種 survival goal 宣告式控制 Raft replica 分佈、決定 RTO / RPO。本文走 Hard Rock Digital bet placement RPO=0 倒推流程、Netflix Gaming 48-node 跨 4 region 「為求 survival 而非 latency」的反直覺判讀、配置語法、寫入 latency 暴漲跟 cost 暴漲兩條失敗模式、合規邊界對比">CockroachDB survival goals</a></li>
<li>想規劃跨 region schema 與資料本地化 → <a href="/blog/backend/01-database/vendors/cockroachdb/locality-aware-schema/" data-link-title="CockroachDB Locality-Aware Schema：跨州合規 &#43; 邏輯一個 cluster 的 region placement 策略" data-link-desc="Hard Rock Digital 跨 8 州 sportsbook、用 AWS Outposts &#43; region placement 把運算釘在州內、邏輯上仍是一個 CockroachDB cluster。本文走 REGIONAL BY ROW / REGIONAL BY TABLE / GLOBAL 三種 locality、Hard Rock 拓樸創新對比 Standard Chartered Aurora 7 cluster fleet、AWS Outposts 是合規工具不是 latency 工具的反直覺判讀">CockroachDB locality-aware schema</a></li>
<li>想對比 Aurora DSQL / Spanner / CockroachDB → <a href="/blog/backend/01-database/vendors/cockroachdb/aurora-dsql-spanner-decision-tree/" data-link-title="CockroachDB vs Aurora DSQL vs Spanner：撞牆訊號分型 &#43; 七問題決策樹" data-link-desc="Distributed SQL 三選一決策樹。先用撞牆訊號分型識別 driver path（DoorDash 單主寫入撞牆 / Netflix Cassandra 缺口 / Hard Rock 合規驅動）、再走七問題（跨雲 / 雲商生態 / 風險預算 / PG 相容 / 管理負擔 / team size / vendor sizing barrier）。PostgreSQL 相容性 audit checklist 4 項、Spanner 100 pu sizing barrier、Hard Rock 「省 10-20 工程師」機會成本警示、Netflix Database Platform Team 規模">Aurora DSQL / Spanner / CockroachDB 決策樹</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://assets.ctfassets.net/00voh0j35590/7qBPsA0FKKTuAK4JhK27uu/1b30b2015f32878874bd0873a2a54361/CockroachLabs-NETFLIX-Case-Study.pdf">Now Streaming: Why Netflix Runs a Fleet of 380+ CockroachDB Clusters（PDF）</a></li>
<li><a href="https://www.cockroachlabs.com/customers/netflix/">Now Streaming: Why Netflix Runs a Fleet of 380+ CockroachDB Clusters（cockroachlabs.com Netflix customer page）</a></li>
<li><a href="https://www.cockroachlabs.com/blog/netflix-at-cockroachdb/">The history of databases at Netflix: From Cassandra to CockroachDB</a></li>
<li><a href="https://www.cockroachlabs.com/blog/netflix-dbaas-roachfest24-recap/">A Netflix RoachFest24 Original: The Case for Multi-Region Clusters</a></li>
<li><a href="https://www.cockroachlabs.com/blog/persistence-as-a-service-at-netflix/">How Netflix engineers choose their tech stack</a></li>
</ul>
]]></content:encoded></item><item><title>9.C41 Hard Rock Digital：CockroachDB on AWS Outposts、Wire Act 合規 + 跨州單一邏輯 DB</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hard-rock-digital-cockroachdb-sports-betting/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hard-rock-digital-cockroachdb-sports-betting/</guid><description>&lt;p>這個案例的核心責任是說明「合規強制資料留地理邊界 + 想要單一邏輯 DB」如何用 distributed SQL + 邊緣硬體解。跟 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered&lt;/a> 對比 — Standard Chartered 走「Aurora 多 region、each region 一個 cluster」、Hard Rock Digital 走「跨 AWS Outposts + AWS region 一個邏輯 cluster」。兩條都解受監管金融類業務、結構差異反映法規顆粒不同：銀行是國家層級、美國運動博彩是 &lt;em>州&lt;/em> 層級。&lt;/p>
&lt;h2 id="觀察">觀察&lt;/h2>
&lt;p>Hard Rock Digital sportsbook 部署的關鍵數字（引自 &lt;a href="https://www.cockroachlabs.com/customers/hard-rock-digital/">Hard Rock Digital customer page&lt;/a> / &lt;a href="https://www.cockroachlabs.com/blog/highly-available-sports-betting-app/">How Hard Rock Digital built a highly available and compliant sports betting app&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>數字&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>營運州數&lt;/td>
 &lt;td>8（AZ / IN / TN / FL / OH / IL / NJ / VA）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>高峰節點數&lt;/td>
 &lt;td>~100 nodes、each 32 vCPU&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>淡季節點數&lt;/td>
 &lt;td>scales down ~33 nodes（約 1/3）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>基礎設施組合&lt;/td>
 &lt;td>AWS Regions + AWS Local Zones + AWS Outposts（按州合規要求布局）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料庫拓樸&lt;/td>
 &lt;td>跨所有 region 一個 logical database&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Survival goal&lt;/td>
 &lt;td>單一 Outpost 或 AWS AZ 失敗不丟資料&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>顯著測試失敗事件&lt;/td>
 &lt;td>node crash / EC2 instance fail / single state loss — 對使用者無感&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>重大事件流量&lt;/td>
 &lt;td>Super Bowl / World Cup 等高峰、無效能退化紀錄&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Engineering 團隊&lt;/td>
 &lt;td>tech team ~50 人；若用 PostgreSQL 估計需多加 10-20 工程師&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>服務組合：CockroachDB self-managed、AWS US-East-1（共用 control plane）、AWS Outposts（部分州合規要求設備位於州內）、AWS Local Zones（特定都會區延遲補強）。&lt;/p>
&lt;p>關鍵 workload：bet placement、bet settlement、account management、cache loading、sports metadata import。&lt;/p>
&lt;p>關鍵負載形狀：sports betting 是 &lt;em>event-driven peak&lt;/em> — Super Bowl / World Cup 等賽事是已知時間點、流量在開賽前 30-60 分鐘飆升、賽中持續高水位、賽後 settlement 集中爆發。「100 → 33 → 100」的 scale up / down 反映賽季 vs 淡季的容量需求差。&lt;/p>
&lt;h2 id="判讀">判讀&lt;/h2>
&lt;p>Hard Rock Digital 的工程選擇揭露三個受監管 OLTP 的設計重點。&lt;/p></description><content:encoded><![CDATA[<p>這個案例的核心責任是說明「合規強制資料留地理邊界 + 想要單一邏輯 DB」如何用 distributed SQL + 邊緣硬體解。跟 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 對比 — Standard Chartered 走「Aurora 多 region、each region 一個 cluster」、Hard Rock Digital 走「跨 AWS Outposts + AWS region 一個邏輯 cluster」。兩條都解受監管金融類業務、結構差異反映法規顆粒不同：銀行是國家層級、美國運動博彩是 <em>州</em> 層級。</p>
<h2 id="觀察">觀察</h2>
<p>Hard Rock Digital sportsbook 部署的關鍵數字（引自 <a href="https://www.cockroachlabs.com/customers/hard-rock-digital/">Hard Rock Digital customer page</a> / <a href="https://www.cockroachlabs.com/blog/highly-available-sports-betting-app/">How Hard Rock Digital built a highly available and compliant sports betting app</a>）：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>數字</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>營運州數</td>
          <td>8（AZ / IN / TN / FL / OH / IL / NJ / VA）</td>
      </tr>
      <tr>
          <td>高峰節點數</td>
          <td>~100 nodes、each 32 vCPU</td>
      </tr>
      <tr>
          <td>淡季節點數</td>
          <td>scales down ~33 nodes（約 1/3）</td>
      </tr>
      <tr>
          <td>基礎設施組合</td>
          <td>AWS Regions + AWS Local Zones + AWS Outposts（按州合規要求布局）</td>
      </tr>
      <tr>
          <td>資料庫拓樸</td>
          <td>跨所有 region 一個 logical database</td>
      </tr>
      <tr>
          <td>Survival goal</td>
          <td>單一 Outpost 或 AWS AZ 失敗不丟資料</td>
      </tr>
      <tr>
          <td>顯著測試失敗事件</td>
          <td>node crash / EC2 instance fail / single state loss — 對使用者無感</td>
      </tr>
      <tr>
          <td>重大事件流量</td>
          <td>Super Bowl / World Cup 等高峰、無效能退化紀錄</td>
      </tr>
      <tr>
          <td>Engineering 團隊</td>
          <td>tech team ~50 人；若用 PostgreSQL 估計需多加 10-20 工程師</td>
      </tr>
  </tbody>
</table>
<p>服務組合：CockroachDB self-managed、AWS US-East-1（共用 control plane）、AWS Outposts（部分州合規要求設備位於州內）、AWS Local Zones（特定都會區延遲補強）。</p>
<p>關鍵 workload：bet placement、bet settlement、account management、cache loading、sports metadata import。</p>
<p>關鍵負載形狀：sports betting 是 <em>event-driven peak</em> — Super Bowl / World Cup 等賽事是已知時間點、流量在開賽前 30-60 分鐘飆升、賽中持續高水位、賽後 settlement 集中爆發。「100 → 33 → 100」的 scale up / down 反映賽季 vs 淡季的容量需求差。</p>
<h2 id="判讀">判讀</h2>
<p>Hard Rock Digital 的工程選擇揭露三個受監管 OLTP 的設計重點。</p>
<ol>
<li><strong>法規顆粒決定基礎設施拓樸、不是反過來</strong>：美國 Wire Act 要求 <em>betting data 必須在下注州內處理</em>、所以每個營運州都要有州內運算資源。傳統路徑是「每州一個獨立 silo」— 但 silo 之間的玩家統一帳戶、跨州 reporting、欺詐偵測會撞牆。Hard Rock Digital 用 AWS Outposts 把運算放進州內、但邏輯上仍是 <em>一個</em> CockroachDB cluster — region placement 配置決定哪些 range 釘在哪個 Outpost、合規與單一邏輯 DB 同時成立。對應 <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a> 的合規 boundary 設計與 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 的 region placement。</li>
<li><strong>Survival goal 「Outpost 或 AZ 失敗不丟」對應業務 SLO</strong>：sports betting 中 <em>bet placement</em> 不能 lose — 玩家下注後系統 crash 沒紀錄、對博彩牌照是合規事故。CockroachDB Raft 3-replica + 跨 AZ 配置讓 Outpost 失敗時其他 replica 還在、自動 failover。對應 <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">06 reliability</a> 的 RPO=0 設計與 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a> 的 Survival Goals。</li>
<li><strong>Scale up / down 是賽季常態、不是異常事件</strong>：100 → 33 → 100 的擺盪在 sportsbook 業務是 <em>年度循環</em> — NFL 季結束 / NBA 季初切換、流量結構性下降。CockroachDB 加減節點靠 range rebalance、不停服。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 的 seasonality 與 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 的 event-driven scaling。</li>
</ol>
<p>需要警惕：</p>
<ul>
<li>case study 沒揭露 QPS、p99 latency 具體數字。100 node × 32 vCPU 是硬體規模、不是 throughput。讀案例時要區分 <em>容量 sizing</em>（節點數）跟 <em>workload throughput</em>（每秒處理量）。</li>
<li>「省了 10-20 工程師」是 <em>估計差距</em>、不是已 hire 後解雇。對應的是「沒選 PostgreSQL 所以沒招那麼多 DBA」、是機會成本不是節省支出。</li>
<li>Wire Act 是 <em>美國聯邦法</em>、各州還有獨立法規（NJ DGE、NV NGC 等）。Hard Rock Digital 模型適合 <em>跨州</em> 合規、不是 <em>跨國</em> — 跨國牌照差異更大、不能直接套。</li>
</ul>
<h2 id="策略">策略</h2>
<p>可重用的工程做法：</p>
<ol>
<li><strong>合規 boundary 用 region placement 表達、不是 cluster fragmentation</strong>：當法規要求資料留某地理邊界、優先看 distributed SQL 的 region placement / pin-to-region 能力、不要直接開獨立 cluster。獨立 cluster 解了合規但破壞了業務邏輯（跨州統一帳戶、欺詐偵測、reporting）。對應 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a> 的 multi-region table 與 <a href="/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Spanner vendor</a> 的 placement。</li>
<li><strong>邊緣硬體（AWS Outposts / Local Zones）是合規工具、不是 latency 工具</strong>：Outposts 主要為「資料留某地理邊界」而存在、latency 改善是副作用。決策時先看合規驅動力、latency 改善列為 bonus。對應 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 的 hybrid cloud 設計。</li>
<li><strong>賽季型擴縮容寫進 baseline 容量模型</strong>：Hard Rock Digital 100 ↔ 33 的擺盪不是「臨時 scale up」、是計畫內年度循環。容量規劃要直接把 NFL / NBA / 國際賽事曆塞進預測模型、不要當 surprise。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> 與 <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech 體育博彩 AI 預測</a>。</li>
<li><strong>distributed SQL 的 ops 槓桿：team 小、cluster 大</strong>：Hard Rock Digital 50 人 tech team 養全部運維、估省了 10-20 個 DBA。distributed SQL 把「DBA 養單區、跨區 sync 養運維」的工作量壓進 <em>系統內建</em> 的 Raft / placement、人月支出降。對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.7 成本邊界與 efficiency</a> 的人力成本工程化。</li>
</ol>
<p>跨平台等效：</p>
<ul>
<li>Spanner（GCP）也支援 region placement、但 GCP-only、無 Outposts 等效</li>
<li>Aurora DSQL（AWS 2024）支援跨 region 強一致、但 Outpost 部署現階段未完整覆蓋</li>
<li>自管 PostgreSQL + application 層 sharding：理論可行、operation burden 跟人力需求大幅上升、Hard Rock Digital 評估後選 CockroachDB 的主因之一</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>對照其他受監管金融 / 博彩 OLTP → <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a>（銀行國家層級）/ <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a>（fantasy sports）</li>
<li>對照 event-driven peak 設計 → <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> / <a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a></li>
<li>想規劃 multi-region OLTP survival goal → <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> + <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a></li>
<li>對照其他 distributed SQL 案例 → <a href="/blog/backend/09-performance-capacity/cases/doordash-cockroachdb-orders-platform/" data-link-title="9.C39 DoorDash：Aurora Postgres 寫入瓶頸 → CockroachDB 多主寫入" data-link-desc="DoorDash 從 Aurora Postgres 遷到 CockroachDB、解 1.6 M QPS 單主寫入瓶頸、外送平台爆量壓力下重做 OLTP 拓樸">9.C39 DoorDash</a> / <a href="/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/" data-link-title="9.C40 Netflix：380&#43; CockroachDB cluster 的 multi-active 拓樸艦隊" data-link-desc="Netflix 把 Cassandra 不夠用的 transactional workload 移到 CockroachDB、380&#43; cluster / 60&#43; 跨 region、含 Open Connect、studio cloud drive、gaming control plane">9.C40 Netflix</a> / <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></li>
<li>想理解合規驅動的拓樸設計 → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> + <a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">01.4 database migration playbook</a></li>
<li>想拆 CockroachDB survival goal 與合規拓樸對齊 → <a href="/blog/backend/01-database/vendors/cockroachdb/survival-goals/" data-link-title="CockroachDB Survival Goals：zone 級 vs region 級配置與業務 SLO 倒推流程" data-link-desc="CockroachDB 用 SURVIVE ZONE FAILURE / SURVIVE REGION FAILURE 兩種 survival goal 宣告式控制 Raft replica 分佈、決定 RTO / RPO。本文走 Hard Rock Digital bet placement RPO=0 倒推流程、Netflix Gaming 48-node 跨 4 region 「為求 survival 而非 latency」的反直覺判讀、配置語法、寫入 latency 暴漲跟 cost 暴漲兩條失敗模式、合規邊界對比">CockroachDB survival goals</a></li>
<li>想做 region pinning 與在地化 schema → <a href="/blog/backend/01-database/vendors/cockroachdb/locality-aware-schema/" data-link-title="CockroachDB Locality-Aware Schema：跨州合規 &#43; 邏輯一個 cluster 的 region placement 策略" data-link-desc="Hard Rock Digital 跨 8 州 sportsbook、用 AWS Outposts &#43; region placement 把運算釘在州內、邏輯上仍是一個 CockroachDB cluster。本文走 REGIONAL BY ROW / REGIONAL BY TABLE / GLOBAL 三種 locality、Hard Rock 拓樸創新對比 Standard Chartered Aurora 7 cluster fleet、AWS Outposts 是合規工具不是 latency 工具的反直覺判讀">CockroachDB locality-aware schema</a></li>
<li>想對比 Aurora DSQL / Spanner / CockroachDB 給博彩 OLTP → <a href="/blog/backend/01-database/vendors/cockroachdb/aurora-dsql-spanner-decision-tree/" data-link-title="CockroachDB vs Aurora DSQL vs Spanner：撞牆訊號分型 &#43; 七問題決策樹" data-link-desc="Distributed SQL 三選一決策樹。先用撞牆訊號分型識別 driver path（DoorDash 單主寫入撞牆 / Netflix Cassandra 缺口 / Hard Rock 合規驅動）、再走七問題（跨雲 / 雲商生態 / 風險預算 / PG 相容 / 管理負擔 / team size / vendor sizing barrier）。PostgreSQL 相容性 audit checklist 4 項、Spanner 100 pu sizing barrier、Hard Rock 「省 10-20 工程師」機會成本警示、Netflix Database Platform Team 規模">Aurora DSQL / Spanner / CockroachDB 決策樹</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://www.cockroachlabs.com/customers/hard-rock-digital/">Hard Rock Digital: scaling a performant sports betting platform（cockroachlabs.com customer page）</a></li>
<li><a href="https://downloads.ctfassets.net/00voh0j35590/7dKNWhsW4RjpUlFgzHB8qw/752a22c833c879bca503bbffb2b584c7/CockroachLabs-Hard-Rock-Digital-Case-Study-v2.pdf">Hard Rock, anytime, anywhere: scaling a performant sports betting platform（PDF case study）</a></li>
<li><a href="https://www.cockroachlabs.com/blog/highly-available-sports-betting-app/">How Hard Rock Digital built a highly available and compliant sports betting app</a></li>
<li><a href="https://www.cockroachlabs.com/blog/real-money-gaming-reference-architecture/">Building a sports betting application to handle &lsquo;Big Game&rsquo; traffic</a></li>
<li><a href="https://www.cockroachlabs.com/solutions/verticals/gambling/">CockroachDB for Gambling solutions page</a></li>
</ul>
]]></content:encoded></item><item><title>Aurora Read Replica Scaling：15 replica 上限、lag profile、headroom 預留與 fleet 治理</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/read-replica-scaling/</link><pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/read-replica-scaling/</guid><description>&lt;p>Aurora 「最多 15 read replica」是文件數字、實際 production 部署常常更早遇到拆 cluster 的決策點 — 不是 15 replica 不夠用、是 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius&lt;/a>、業務 sharding、微服務 ownership、合規 boundary 早在 15 replica 之前就推動拆 cluster。本文同時展開兩個議題：(1) 單 cluster 內 read replica 怎麼用、容量怎麼規劃、lag 怎麼管；(2) Aurora fleet 治理的 3 條 driver、什麼條件下拆 cluster vs 加 replica。後者是 Aurora 系列的 &lt;em>fleet 治理 SSoT&lt;/em> — &lt;a href="../storage-architecture/">Aurora storage architecture&lt;/a> / &lt;a href="../cross-az-failover-rto/">Aurora cross-AZ failover RTO&lt;/a> / &lt;a href="../global-database-multi-region/">Aurora Global Database&lt;/a> / &lt;a href="../migrate-from-self-managed-pg-mysql/">Aurora migration playbook&lt;/a> 都 cross-link 到本篇、不重複展開。&lt;/p>
&lt;p>本文不是 Aurora overview（請看 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&amp;#43;75% 效能改善的 production 證據">Aurora vendor 頁&lt;/a>）— 而是 read replica 跟 fleet 拓樸的實作層教學。前置閱讀建議 &lt;a href="../storage-architecture/">Aurora storage architecture&lt;/a>（理解共享 storage 為什麼能養大量 replica）。&lt;/p>
&lt;h2 id="問題情境">問題情境&lt;/h2>
&lt;p>典型觸發場景：FanDuel Super Bowl / DraftKings 比賽日、流量 5-10 倍尖峰、read query（用戶查 balance、投注紀錄、odds）打爆 primary、需要快速擴 read replica 但又怕 lag 把 stale read 推到 user-facing。&lt;/p>
&lt;p>讀者常見的具體疑問：&lt;/p>
&lt;ul>
&lt;li>「加 read replica 後 primary CPU 沒降、為什麼？」&lt;/li>
&lt;li>「Auto-scaling 加 replica 要幾分鐘、來不及接尖峰怎麼辦？」&lt;/li>
&lt;li>「Reader endpoint round-robin 把 query 打到 lag 大的 replica、用戶看到舊 balance」&lt;/li>
&lt;li>「業務跨 200 個 cluster、單個 cluster 才 5-10 個 replica、為什麼不集中？」&lt;/li>
&lt;/ul>
&lt;p>進一步問題：讀寫雙峰錯位是 Aurora 讀寫分流的核心 driver。&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &amp;#43;50% 不影響延遲">9.C4 DraftKings&lt;/a> 揭露「write workloads spike up significantly around payout events, but opening the app during the game also activates a lot of balance queries」— 比賽進行時讀爆量、payout event 時寫爆量、兩個峰不在同一時刻。這代表 read replica 容量規劃不是「分散負載」、而是「為讀峰專門配置 capacity」。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &amp;#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &amp;#43; Wavelength &amp;#43; Outposts 處理 20&amp;#43; 州的雙重峰值">9.C28 FanDuel&lt;/a> 揭露事件型容量分級：平日 baseline → 季後賽 2-3x → 季冠軍賽 4-5x → Super Bowl 5-10x。容量規劃要按事件級別分段、不是一律 10x。&lt;/p></description><content:encoded><![CDATA[<p>Aurora 「最多 15 read replica」是文件數字、實際 production 部署常常更早遇到拆 cluster 的決策點 — 不是 15 replica 不夠用、是 <a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius</a>、業務 sharding、微服務 ownership、合規 boundary 早在 15 replica 之前就推動拆 cluster。本文同時展開兩個議題：(1) 單 cluster 內 read replica 怎麼用、容量怎麼規劃、lag 怎麼管；(2) Aurora fleet 治理的 3 條 driver、什麼條件下拆 cluster vs 加 replica。後者是 Aurora 系列的 <em>fleet 治理 SSoT</em> — <a href="../storage-architecture/">Aurora storage architecture</a> / <a href="../cross-az-failover-rto/">Aurora cross-AZ failover RTO</a> / <a href="../global-database-multi-region/">Aurora Global Database</a> / <a href="../migrate-from-self-managed-pg-mysql/">Aurora migration playbook</a> 都 cross-link 到本篇、不重複展開。</p>
<p>本文不是 Aurora overview（請看 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor 頁</a>）— 而是 read replica 跟 fleet 拓樸的實作層教學。前置閱讀建議 <a href="../storage-architecture/">Aurora storage architecture</a>（理解共享 storage 為什麼能養大量 replica）。</p>
<h2 id="問題情境">問題情境</h2>
<p>典型觸發場景：FanDuel Super Bowl / DraftKings 比賽日、流量 5-10 倍尖峰、read query（用戶查 balance、投注紀錄、odds）打爆 primary、需要快速擴 read replica 但又怕 lag 把 stale read 推到 user-facing。</p>
<p>讀者常見的具體疑問：</p>
<ul>
<li>「加 read replica 後 primary CPU 沒降、為什麼？」</li>
<li>「Auto-scaling 加 replica 要幾分鐘、來不及接尖峰怎麼辦？」</li>
<li>「Reader endpoint round-robin 把 query 打到 lag 大的 replica、用戶看到舊 balance」</li>
<li>「業務跨 200 個 cluster、單個 cluster 才 5-10 個 replica、為什麼不集中？」</li>
</ul>
<p>進一步問題：讀寫雙峰錯位是 Aurora 讀寫分流的核心 driver。<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 揭露「write workloads spike up significantly around payout events, but opening the app during the game also activates a lot of balance queries」— 比賽進行時讀爆量、payout event 時寫爆量、兩個峰不在同一時刻。這代表 read replica 容量規劃不是「分散負載」、而是「為讀峰專門配置 capacity」。</p>
<p><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a> 揭露事件型容量分級：平日 baseline → 季後賽 2-3x → 季冠軍賽 4-5x → Super Bowl 5-10x。容量規劃要按事件級別分段、不是一律 10x。</p>
<p>對 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 這種受監管金融、不能用單一巨型 cluster — 7 個受監管市場 = 7 個獨立 cluster、合規 boundary 比運維成本優先。</p>
<h2 id="核心機制15-replica-上限共享-storagereader-endpoint">核心機制：15 replica 上限、共享 storage、reader endpoint</h2>
<p>Aurora read replica 的 first-class concept 是 <em>共享 storage + DNS-based reader endpoint</em>。傳統 PostgreSQL streaming replication 靠 primary push WAL 給 replica、replica 自己 apply；Aurora replica 直接從共享 storage 讀已 apply 的 page、不需要 catch-up。</p>
<p><strong>15 replica 上限</strong>：</p>
<ul>
<li>每個 Aurora cluster 最多 15 個 read replica（跨 AZ）</li>
<li>跨 region replica 走 <a href="../global-database-multi-region/">Aurora Global Database</a>（不算這 15 個）</li>
<li>文件上限不是 production 真實上限 — 多數 production 部署在 5-10 replica 之間遇到拆 cluster 訊號</li>
</ul>
<p><strong>共享 storage 對 lag 的影響</strong>：</p>
<ul>
<li>Replica 不靠 logical replication catch-up、直接從共享 storage 讀</li>
<li>Lag 來源是 <em>compute node 的 buffer cache 同步</em>、不是 WAL replay</li>
<li>Typical 10-30ms、heavy write 期間可能 100ms+、但 <em>不會像 PostgreSQL 那樣 unbounded</em></li>
</ul>
<p><strong>DraftKings 揭露的「lag 可預測」frame</strong>（<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">case「判讀」段第 2 點</a>）：</p>
<p>「30 秒降到 10-30 ms」的工程意義不只是「快」、而是「讓 read-after-write 變得可預測」。30 秒 lag 的世界裡、application 端做 read-after-write 要 cache 用戶最後寫入 30 秒以上、實務上做不到；10-30ms lag 的世界裡、application 可以做「寫操作後 100ms 內走 primary、之後可走 replica」的可規劃策略。</p>
<p><strong>Reader endpoint 行為</strong>：</p>
<ul>
<li>DNS-based round-robin、不感知 replica 健康狀態</li>
<li>Application 想要 lag-aware routing 要自己實作或用 RDS Proxy</li>
<li>Failover 期間短暫包含 promoted replica（已升 primary）、見 <a href="../cross-az-failover-rto/">Aurora cross-AZ failover RTO</a></li>
</ul>
<p><strong>Auto-scaling policy</strong>：</p>
<ul>
<li>CloudWatch metric（CPU / connection）trigger</li>
<li>Replica creation 2-5 分鐘</li>
<li><em>無法用於秒級尖峰</em> — 是 DraftKings「+50% no sweat」誤讀的關鍵點</li>
</ul>
<p><strong>跟通用 read replica 差在哪</strong>：Aurora replica 不用 catch-up WAL、lag 上限可預測；vs PostgreSQL streaming replication lag 是 unbounded（取決於 primary 寫速度）。可預測 lag 是 read-after-write 場景變得可規劃的前提。</p>
<p>對應 knowledge card：<a href="/blog/backend/knowledge-cards/replication-lag/" data-link-title="Replication Lag" data-link-desc="說明資料副本落後正式來源多久，以及它如何影響讀取正確性">replication-lag</a>、<a href="/blog/backend/knowledge-cards/stale-read/" data-link-title="Stale Read" data-link-desc="讀取到落後於最新寫入版本的舊資料">stale-read</a>。</p>
<h2 id="step-by-step-配置--reader-endpoint-設計">Step-by-step 配置 / Reader endpoint 設計</h2>
<p><strong>建 read replica</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">aws rds create-db-instance <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --db-cluster-identifier my-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --db-instance-identifier my-replica-01 <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --db-instance-class db.r6g.4xlarge <span class="se">\
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="se"></span>  --engine aurora-postgresql <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>  --availability-zone us-east-1b <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>  --promotion-tier <span class="m">1</span></span></span></code></pre></div><p><strong>Reader endpoint vs Custom endpoint</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 預設 reader endpoint：所有 replica round-robin</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"># 訪問 url: my-cluster.cluster-ro-xxx.us-east-1.rds.amazonaws.com</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># Custom endpoint：group 特定 replica</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">aws rds create-db-cluster-endpoint <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>  --db-cluster-identifier my-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>  --db-cluster-endpoint-identifier my-cluster-analytics <span class="se">\
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="se"></span>  --endpoint-type READER <span class="se">\
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="se"></span>  --static-members my-replica-analytics-01 my-replica-analytics-02</span></span></code></pre></div><p>Custom endpoint 適用場景：</p>
<ul>
<li>分析 query 走獨立 endpoint、不影響 OLTP read replica</li>
<li>Read-after-write session 走 primary endpoint、其他 read 走 reader endpoint</li>
<li>不同 SLO 的 read traffic 分流（high-priority vs batch）</li>
</ul>
<p><strong>Auto-scaling policy</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl">aws application-autoscaling register-scalable-target <span class="se">\
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="se"></span>  --service-namespace rds <span class="se">\
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="se"></span>  --resource-id cluster:my-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="se"></span>  --scalable-dimension rds:cluster:ReadReplicaCount <span class="se">\
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="se"></span>  --min-capacity <span class="m">2</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="se"></span>  --max-capacity <span class="m">10</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">aws application-autoscaling put-scaling-policy <span class="se">\
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="se"></span>  --service-namespace rds <span class="se">\
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="se"></span>  --resource-id cluster:my-cluster <span class="se">\
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="se"></span>  --scalable-dimension rds:cluster:ReadReplicaCount <span class="se">\
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="se"></span>  --policy-name my-cluster-cpu-scaling <span class="se">\
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="se"></span>  --policy-type TargetTrackingScaling <span class="se">\
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="se"></span>  --target-tracking-scaling-policy-configuration file://scaling-config.json</span></span></code></pre></div><p><strong>預配 vs auto-scale</strong>：</p>
<ul>
<li>Peak workload 預知（賽事、促銷、季節事件）→ 提前 1 小時預配</li>
<li>Unpredictable burst → auto-scale（接受 2-5 分鐘 lead time）</li>
<li>兩者混合：baseline 預配 + auto-scale 處理 baseline 之上的浮動</li>
</ul>
<p><strong>驗證點</strong>：</p>
<ul>
<li><code>AuroraReplicaLag</code> &lt; 100ms（per replica）</li>
<li>Reader endpoint CPU 分布均勻（不是某 replica 過熱）</li>
<li>Application stale-read error rate &lt; 0.1%</li>
</ul>
<p><strong>Rollback boundary</strong>：移除 replica 即時生效、無 data loss；但 reader endpoint DNS cache 仍可能短暫 routing 到已移除 replica（5-30 秒）。</p>
<h2 id="故障模式--邊界-case">故障模式 / 邊界 case</h2>
<h3 id="case-1加-replica-後-primary-cpu-沒降">Case 1：加 replica 後 primary CPU 沒降</h3>
<p>徵兆：明明加了 3 個 read replica、primary CPU 仍然 90%、reader endpoint CPU 才 10%。</p>
<p>原因：application 沒把 read query routing 到 reader endpoint、所有 query 仍打 primary。Aurora reader endpoint 不會自動分流 — 必須 application 端拆 read / write data source。</p>
<p>修：</p>
<ul>
<li>Application 端 ORM / data source layer 拆 read / write connection pool</li>
<li>寫操作用 writer endpoint、純讀走 reader endpoint</li>
<li>雙峰錯位是這層拆分的 driver（<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">DraftKings case 揭露</a> 讀寫資源規劃要分開）</li>
</ul>
<h3 id="case-2reader-endpoint-round-robin-推-stale-read">Case 2：Reader endpoint round-robin 推 stale read</h3>
<p>徵兆：read-after-write 場景（用戶下注後立刻查 balance）打到 lagging replica、看到舊 balance、客訴。</p>
<p>原因：reader endpoint DNS-based round-robin、不感知 lag。Application 假設 read 永遠 fresh、但 typical 10-30ms lag 期間用戶操作就會踩到。</p>
<p>修：</p>
<ul>
<li>Sticky session：寫操作後 N 秒內同 session 走 primary（N = lag p99、typical 100ms）</li>
<li>Application 端做「下注後 N 秒走 primary」邏輯（DraftKings「可預測 lag」frame 讓 N 秒可規劃）</li>
<li>或用 RDS Proxy 提供 lag-aware routing（managed alternative）</li>
</ul>
<h3 id="case-3auto-scaling-來不及接秒級尖峰--headroom-預留判讀">Case 3：Auto-scaling 來不及接秒級尖峰 — headroom 預留判讀</h3>
<p>徵兆：賽事開賽 30 秒內流量 +50%、auto-scaling 觸發但 2-5 分鐘後才有新 replica、開賽尖峰已過、用戶在最關鍵時段看到 timeout。</p>
<p>機制限制：replica creation 2-5 分鐘、秒級尖峰過去了 replica 才上線。</p>
<p><strong>DraftKings「Super Bowl +50% no sweat」的工程意義</strong>（<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">case「判讀」段第 3 點原文</a>）：「這句話的工程意義是 <em>提前做好容量規劃</em>、不是『Aurora 神奇』。寫 workload 預期可能 +50%、整個 system headroom 預留至少 50%、加上 read replica 動態加減、才能讓 50% 增幅變成『不流汗』」。</p>
<p>工程含義：</p>
<ul>
<li>Peak workload 預知（賽事 / 促銷）用 <em>headroom 預留 + <a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">scheduled scaling</a> 提前預配</em>、不靠 auto-scale 接秒級</li>
<li>Auto-scale 是 unpredictable burst 才用（突發新聞、KOL 推廣、未預期事件）</li>
<li>DraftKings 的「不流汗」是 <em>系統設計</em> 結果、不是 Aurora 特殊能力</li>
</ul>
<p>修：</p>
<ul>
<li>賽事日曆建模：賽前 1 小時自動加 replica、賽後 2 小時減</li>
<li>Primary instance class 升級提前一週、不是賽前升（升級期間 failover 風險）</li>
<li>Headroom 預算：read replica 預留 50%、primary CPU baseline &lt; 50%</li>
</ul>
<h3 id="case-415-replica-上限--拆-cluster-訊號">Case 4：15 replica 上限 — 拆 cluster 訊號</h3>
<p>徵兆：read traffic 持續成長、加到 15 replica 仍接近 CPU 瓶頸、想加第 16 個被 API 拒絕。</p>
<p>原因：Aurora 硬上限 15 replica / cluster、超過要拆 cluster。但實務上更常在 5-10 replica 就遇到其他拆 cluster 訊號（blast radius、ownership boundary、業務 sharding）。</p>
<p>修：見下方「邊界與整合：fleet 治理 SSoT」段、按 3 條 driver 判讀拆 cluster vs 加 replica。</p>
<h3 id="case-5heavy-write-期間-replica-lag-spike">Case 5：Heavy write 期間 replica lag spike</h3>
<p>徵兆：bulk insert / DDL 期間 replica lag 從 10-30ms 跳到 100-500ms、application 假設 typical lag 永遠成立、stale read 比例大幅上升。</p>
<p>原因：heavy write 期間 replica buffer cache invalidate 速度跟不上、lag 暫時拉大。Aurora 的「可預測 lag」不等於「lag 永遠 10-30ms」。</p>
<p>修：</p>
<ul>
<li>bulk insert / DDL 期間 application 端切到全 primary 模式（避開 stale read 風險）</li>
<li>重要 DDL 用 <a href="https://github.com/reorg/pg_repack">pg_repack</a> 或 logical migration、避免長時間 table lock</li>
<li>監測 <code>AuroraReplicaLagMaximum</code>、spike 超過 p99 threshold trigger application 端 fallback</li>
</ul>
<h3 id="case-6fanduel-雙-slo-並行--不要壓成單一數字">Case 6：FanDuel 雙 SLO 並行 — 不要壓成單一數字</h3>
<p>徵兆：team 看 FanDuel「5-10x peak」直接套到自家 streaming workload、結果 Aurora 撐不住、發現 FanDuel streaming 根本不走 Aurora。</p>
<p><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a> case「判讀」段第 1 點原文：「直播跟投注是兩種完全不同 SLO：直播容忍秒級延遲（用 CDN + ABR 串流）、投注必須毫秒級成交。兩個服務必須各自獨立擴容、各自獨立 SLO」。</p>
<p><strong>scope warning（必明示）</strong>：</p>
<ul>
<li>FanDuel 5-10x 是 <em>betting 服務的 Aurora 擴容倍數</em>、不是 streaming</li>
<li>Streaming 走 CDN、不走 Aurora</li>
<li>不能把兩種 SLO 壓縮成「Aurora 撐 5-10x」單一數字</li>
</ul>
<p><strong>case 自承的進一步 scope warning</strong>：「AWS 案例 <em>沒有</em> 提具體 betting transaction TPS、concurrent streams、延遲分布」（case「需要警惕」段）。引用 FanDuel 時不能寫「Aurora 在 betting 路徑撐 X TPS」這類細節 — case 沒提的數字不能擴寫。</p>
<p>修：</p>
<ul>
<li>不同 SLO workload 拆獨立 cluster 或拆 read / write data source</li>
<li>容量規劃看自家 workload TPS、不要套用未公開的 case 數字</li>
</ul>
<h2 id="事件型容量分級表">事件型容量分級表</h2>
<p><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a> 揭露事件型 scaling 不是一律 10x — <em>事件級別</em> 是容量分級單位：</p>
<table>
  <thead>
      <tr>
          <th>事件級別</th>
          <th>倍數</th>
          <th>來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>平日 baseline</td>
          <td>1x</td>
          <td>FanDuel case「判讀」段第 3 點</td>
      </tr>
      <tr>
          <td>季後賽 playoff</td>
          <td>2-3x</td>
          <td>FanDuel case 揭露事件分級</td>
      </tr>
      <tr>
          <td>季冠軍賽 championship</td>
          <td>4-5x</td>
          <td>FanDuel case 揭露事件分級</td>
      </tr>
      <tr>
          <td>Super Bowl</td>
          <td>5-10x</td>
          <td>FanDuel case 揭露事件分級</td>
      </tr>
  </tbody>
</table>
<p><strong>Frame 8 event-driven scaling 5 模式（跨 vendor 共寫）</strong>：本表是 Aurora 端從讀峰視角切入的事件分級、跟 <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand-vs-provisioned</a> 的 5 模式分類（flash-sale spike / predictable peak / sustained growth / surge baseline permanent shift / B2B sustained + 高可用）共軸。Aurora 端的 FanDuel 季賽 cycle 在 5 模式分類中對應 <em>predictable peak</em> 的時間序列展開 — 事件 tier 已知（賽季 → 季後賽 → 季冠軍賽 → Super Bowl）、按 tier 預配 read replica 數量、本質是「峰值已知 + 重複出現」的 predictable peak 在多 tier 結構下的延伸。</p>
<p><strong>KV 層 vs SQL 層的 mode 決策差異</strong>：DynamoDB 端的 on-demand vs provisioned mode 是 KV vendor 的容量抽象（軸 1 peak/avg ratio / 軸 4 predictable-peak vs flash-sale）、詳見 <a href="/blog/backend/01-database/vendors/dynamodb/on-demand-vs-provisioned/" data-link-title="DynamoDB On-Demand vs Provisioned：6 軸決策、auto-scaling 邊界與 cost crossover" data-link-desc="capacity mode 選擇不是單軸 peak/avg ratio；本文展開 6 軸決策（peak/avg / 讀寫比 trend / surge 暫時 vs 永久 baseline / predictable-peak vs flash-sale / DBA 工時釋放 / vendor vs 自管 cost crossover），含 Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload 等 case 分軸 anchor">DynamoDB on-demand-vs-provisioned 6 軸決策</a>、本篇不展開。Aurora 端對應的決策是 <em>read replica 數量 + auto-scaling vs scheduled scaling vs headroom 預留</em>、靠的是 replica fleet size 而非 mode 切換。</p>
<p>兩 vendor 在 Frame 8 各自承擔：</p>
<ul>
<li><strong>DynamoDB on-demand-vs-provisioned</strong>：5 模式分類 SSoT、mode × 事件型分類的合成判讀</li>
<li><strong>Aurora read-replica-scaling（本篇）</strong>：read 峰值的 headroom 預留 + 雙 SLO 並行（FanDuel 分級 + DraftKings 讀寫雙峰錯位）+ fleet 治理</li>
</ul>
<p><strong>case 自帶警示（scope warning 必保留）</strong>：</p>
<ul>
<li>「5-10x」是 <em>峰值倍數</em>、不是 <em>peak 持續時間</em>。Super Bowl 的關鍵 30 分鐘可能 8-10x、其他 3 小時可能 3-5x（case「需要警惕」段）</li>
<li>分級 driver 是「同類事件中的最高倍率」、不是恆定數字 — 引用時要保留事件 tier 對應、不是一律「Super Bowl = 10x」單一閾值</li>
<li>跨業務 transfer 判讀：本表 <em>只代表體育博彩賽季 cycle</em>、不能直接套到 e-commerce flash-sale（後者倍數結構是「秒級數千倍」、跟事件 tier 結構不同）</li>
</ul>
<p><strong>容量規劃做法</strong>：</p>
<ul>
<li>建立 event tier 體系、每 tier 對應不同 pre-scale 倍數跟 lead time（賽前 N 小時預配）</li>
<li>事件型分級的關鍵是「峰值是已知的」、不是「峰值多大」</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> 的容量分級</li>
</ul>
<h2 id="邊界與整合fleet-治理-ssot--何時拆-cluster-vs-加-replica">邊界與整合：Fleet 治理 SSoT — 何時拆 cluster vs 加 replica</h2>
<p>本段是 Aurora fleet 治理軸 SSoT — <a href="../storage-architecture/">Aurora storage architecture</a> / <a href="../cross-az-failover-rto/">Aurora cross-AZ failover RTO</a> / <a href="../global-database-multi-region/">Aurora Global Database</a> / <a href="../migrate-from-self-managed-pg-mysql/">Aurora migration playbook</a> cross-link 不重複展開。</p>
<p><strong>跨 case 合成 frame</strong>：production scale 不是「單一巨型 cluster」而是 <em>fleet of clusters</em>、但 <em>driver 各異</em>。</p>
<table>
  <thead>
      <tr>
          <th>Driver</th>
          <th>Case anchor</th>
          <th>Fleet 規模</th>
          <th>拆分判讀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Business sharding</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a></td>
          <td>200 cluster</td>
          <td>業務本身可切分（每體育類別 / 每地理 / 每產品線各自 cluster）、blast radius 隔離</td>
      </tr>
      <tr>
          <td>Microservice ownership</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></td>
          <td>多 cluster</td>
          <td>每微服務私有 store、不共用 cluster — 容量規劃分散到 service owner</td>
      </tr>
      <tr>
          <td>合規市場 boundary</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></td>
          <td>7 cluster</td>
          <td>受監管市場資料 <em>不能跨境複製</em>、每市場獨立 cluster — Global Database 在合規場景反指標</td>
      </tr>
  </tbody>
</table>
<h3 id="driver-1business-shardingdraftkings-200-cluster">Driver 1：Business sharding（DraftKings 200 cluster）</h3>
<p>DraftKings 不用一個巨型 cluster 撐 100 萬 ops/min、而是 <em>按業務切 200 cluster</em>。每體育類別、每地理、每產品線各自 cluster、blast radius 自然隔離。</p>
<p>工程含義：</p>
<ul>
<li>業務本身就有 sharding key（sport type / region / product line）— 拆 cluster 不需要 schema redesign</li>
<li>單 cluster 故障只影響該業務、不影響全平台</li>
<li>容量規劃變成「每 cluster 的容量規劃」、單機極限不重要</li>
</ul>
<p><strong>容易誤判的邊界</strong>：<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">DraftKings 100 萬 ops/min ≈ 17K ops/sec</a> 是 <em>200 cluster 加總</em>、平均每 cluster 約 80 ops/sec（case「需要警惕」段）— 不是「單一 cluster 撐 100 萬 ops」、案例對照不能擴寫成單 cluster 容量。</p>
<h3 id="driver-2microservice-ownershipnetflix">Driver 2：Microservice ownership（Netflix）</h3>
<p>Netflix 每微服務各自有 private Aurora cluster、不共用 — 跟 monolith「一個大 DB 撐全部」相反。</p>
<p>工程含義：</p>
<ul>
<li>DB 容量規劃變成「每微服務的容量規劃」、複雜度分散到 service owner</li>
<li>跨服務 contention 變成 <em>network 議題</em> 而非 <em>DB lock 議題</em></li>
<li>每多一個微服務就多一個 cluster、operational surface area × N</li>
</ul>
<p><strong>case 自帶 scope 警示</strong>：<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">Netflix 數據層遠不止 Aurora</a> — 還有 Cassandra（playback metadata）、EVCache（cache layer）、Iceberg（data warehouse）。Aurora 主要是「需要 ACID 的 OLTP 工作負載」、不是「all-purpose store」（case「需要警惕」段第 2 點）。讀者引用 Netflix consolidation 時、不能誤推論「Aurora 可以替所有 store」。</p>
<h3 id="driver-3合規市場-boundarystandard-chartered-7-cluster">Driver 3：合規市場 boundary（Standard Chartered 7 cluster）</h3>
<p>Standard Chartered 7 個受監管市場 = 7 個獨立 cluster。<a href="/blog/backend/knowledge-cards/data-residency/" data-link-title="Data Residency" data-link-desc="合規要求資料留在特定地理邊界內、跨境複製違反合規、推動 fleet 拓樸決策">Data Residency</a> 規範資料 <em>不能跨境複製</em>、<a href="../global-database-multi-region/">Aurora Global Database</a> 在這種場景違反合規。</p>
<p>工程含義：</p>
<ul>
<li>容量規劃變成「7 個獨立規劃 × 各自合規門檻」</li>
<li>跨市場 DR 不靠 Global Database、靠應用層市場切換</li>
<li>合規 lead time 是時程主項（見 <a href="../migrate-from-self-managed-pg-mysql/">migration playbook</a> 合規時程段）</li>
</ul>
<p><strong>case 自承 scope 警示</strong>：Standard Chartered case 未公開是 PostgreSQL 還是 MySQL、未公開具體 cost 數字、屬「相關 case study」匿名對照。</p>
<h3 id="何時拆-vs-加-replica-的判讀順序">何時拆 vs 加 replica 的判讀順序</h3>
<p>按以下順序判斷、第一個成立的就是拆 cluster 的訊號：</p>
<ol>
<li><strong>&gt; 15 replica 需求</strong> → 拆 cluster（Aurora 硬上限）</li>
<li><strong>Blast radius 隔離需求</strong> → 拆 cluster（單 cluster 故障影響範圍太大、業務不能接受）</li>
<li><strong>業務本身可切分</strong>（user shard / 產品線 / 地理）→ 拆 cluster（DraftKings 拓樸）</li>
<li><strong>微服務私有 store 拓樸</strong> → 拆 cluster（Netflix 拓樸、跟服務生命週期綁定）</li>
<li><strong>合規禁止跨境複製</strong> → 拆 cluster（Standard Chartered 拓樸、Global Database 反指標）</li>
<li><strong>以上都不成立</strong> → 加 replica（最便宜的容量槓桿）</li>
</ol>
<p><strong>容易誤判的邊界</strong>：</p>
<ul>
<li>Fleet 治理本身有 ops surface area 成本（parameter group / backup / IAM / observability fan-out × N cluster）— 不是免費；driver 不夠強時不該拆</li>
<li>「fleet 看起來大」不是 driver — driver 是業務本身有 boundary、不是運維美觀</li>
<li>拆 cluster 後再合併比拆更難（資料遷移成本高）— driver 不確定時先加 replica</li>
</ul>
<h2 id="容量與觀測">容量與觀測</h2>
<p><strong>核心 metric</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">AuroraReplicaLag           # per replica lag
</span></span><span class="line"><span class="ln">2</span><span class="cl">AuroraReplicaLagMaximum    # cluster max lag
</span></span><span class="line"><span class="ln">3</span><span class="cl">CPUUtilization             # per replica CPU
</span></span><span class="line"><span class="ln">4</span><span class="cl">DatabaseConnections        # per replica connection</span></span></code></pre></div><p><strong>Application 端 metric</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">read_query_latency_p99       # per endpoint (writer vs reader)
</span></span><span class="line"><span class="ln">2</span><span class="cl">stale_read_error_count       # read-after-write 失敗訊號
</span></span><span class="line"><span class="ln">3</span><span class="cl">read_replica_routing_ratio   # writer vs reader 流量比例</span></span></code></pre></div><p><strong>容量上限</strong>：</p>
<ul>
<li>15 replica / cluster（硬上限）</li>
<li>Cross-region replica 走 <a href="../global-database-multi-region/">Aurora Global Database</a>（不算 15）</li>
</ul>
<p><strong>容量公式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">read replica count = (read QPS / replica throughput) × (1 + lag buffer) × (1 + event tier headroom)
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">lag buffer        = 30%（典型）
</span></span><span class="line"><span class="ln">4</span><span class="cl">event tier headroom = 0% (平日) / 50% (playoff) / 100% (championship) / 200% (Super Bowl)</span></span></code></pre></div><p><strong>回路徑</strong>：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a> 判斷 read-bound vs write-bound、<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> peak workload 預配 vs auto-scale 決策。</p>
<h2 id="邊界與整合--下一步">邊界與整合 / 下一步</h2>
<p><strong>Sibling deep articles</strong>：</p>
<ul>
<li><a href="../storage-architecture/">Aurora storage architecture</a> — 共享 storage 為什麼能養 15 replica + 雙峰錯位 application 邊界</li>
<li><a href="../cross-az-failover-rto/">Aurora cross-AZ failover RTO</a> — replica 升 primary 流程</li>
<li><a href="../global-database-multi-region/">Aurora Global Database</a> — 跨 region replica 配置 + 合規 anti-pattern</li>
</ul>
<p><strong>Migration playbook</strong>：</p>
<ul>
<li><a href="../migrate-from-self-managed-pg-mysql/">PostgreSQL / MySQL → Aurora</a> — fleet 拓樸是 migration 規劃的維度之一</li>
</ul>
<p><strong>1.x 章節互引</strong>：</p>
<ul>
<li><a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取</a> — read replica 是 OLTP 擴容的基本槓桿</li>
</ul>
<p><strong>RDS Proxy 整合</strong>：lag-aware routing、connection pool 共享、Lambda 場景；managed alternative。</p>
<p><strong>何時不用本文</strong>：single replica + cross-AZ failover 已滿足、read traffic 不是 bottleneck 時可跳過、看 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor overview</a> 即可。</p>
<h2 id="相關連結">相關連結</h2>
<ul>
<li><a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor overview</a> — 服務定位、適用 / 不適用場景</li>
<li><a href="/blog/backend/knowledge-cards/replication-lag/" data-link-title="Replication Lag" data-link-desc="說明資料副本落後正式來源多久，以及它如何影響讀取正確性">Replication Lag 卡片</a> — 概念基底</li>
<li><a href="/blog/backend/knowledge-cards/stale-read/" data-link-title="Stale Read" data-link-desc="讀取到落後於最新寫入版本的舊資料">Stale Read 卡片</a> — read-after-write 容忍度</li>
<li><a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> — 200 cluster business sharding 跟 headroom 預留</li>
<li><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> — 微服務私有 store + Aurora 非 all-purpose store 邊界</li>
<li><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> — 合規驅動 fleet 拓樸</li>
<li><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a> — 雙 SLO 並行 + 事件型容量分級</li>
<li><a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">Vendor 深度技術文章方法論</a> — 本文遵循的 6 規格面寫作模板</li>
<li>官方：<a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Replication.html">Aurora replication</a></li>
</ul>
]]></content:encoded></item><item><title>效能與容量工具清單</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/</guid><description>&lt;p>效能與容量工具清單的核心責任是把工具名稱放回 workload model、saturation discovery、capacity planning 與 production validation 的服務責任。工具頁先回答它降低哪一種風險，再討論 scenario scripting、distributed load、結果保存、CI 整合、成本與案例回寫。&lt;/p>
&lt;h2 id="讀法">讀法&lt;/h2>
&lt;p>效能工具要從問題節點進入。團隊如果缺 workload model，先讀 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling&lt;/a>；如果缺 saturation 邊界，先讀 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery&lt;/a>；如果缺 production 驗證，先讀 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證&lt;/a>。&lt;/p>
&lt;p>工具頁的任務是承接這些問題節點。k6、JMeter、Gatling、Locust 與 Vegeta 都能產生負載，但它們在腳本語言、protocol 覆蓋、分散式執行、CI integration、報表與團隊學習成本上不同；production replay、profiling 與 cost analysis 工具則承擔不同的證據責任。&lt;/p>
&lt;h2 id="教學順序同步">教學順序同步&lt;/h2>
&lt;p>效能與容量工具頁的教學順序是先建立 load test，再進入 replay / mirroring、profiling、optimization 與 FinOps。這個順序對齊 checkout E7：讀者先理解 workload model、saturation evidence 與 capacity gate，再比較 production traffic evidence、profile evidence、rightsizing 建議與成本 owner 如何形成改善閉環。&lt;/p>
&lt;h2 id="t1-工具頁">T1 工具頁&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>工具&lt;/th>
 &lt;th>類型&lt;/th>
 &lt;th>核心責任&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6&lt;/a>&lt;/td>
 &lt;td>Load test&lt;/td>
 &lt;td>用 scriptable scenario 建立 API / protocol 負載&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter&lt;/a>&lt;/td>
 &lt;td>Load test&lt;/td>
 &lt;td>用 GUI、plugin 與多 protocol sampler 承接企業測試資產&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling&lt;/a>&lt;/td>
 &lt;td>Load test&lt;/td>
 &lt;td>用 JVM DSL 與 injection profile 表達複雜 scenario&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust&lt;/a>&lt;/td>
 &lt;td>Load test&lt;/td>
 &lt;td>用 Python user behavior 與 distributed worker 表達高自訂負載&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta&lt;/a>&lt;/td>
 &lt;td>HTTP probe&lt;/td>
 &lt;td>用固定 rate HTTP attack 快速探測 endpoint saturation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay&lt;/a>&lt;/td>
 &lt;td>Traffic replay&lt;/td>
 &lt;td>捕捉 production HTTP traffic 並重播到 shadow target&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring&lt;/a>&lt;/td>
 &lt;td>Traffic mirror&lt;/td>
 &lt;td>用 proxy route policy mirror production traffic&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring&lt;/a>&lt;/td>
 &lt;td>Traffic mirror&lt;/td>
 &lt;td>用 VPC 網路層封包鏡像建立低侵入 production evidence&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler&lt;/a>&lt;/td>
 &lt;td>Profiling&lt;/td>
 &lt;td>用 SaaS APM 整合與 deploy marker 支援 profile diff&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope&lt;/a>&lt;/td>
 &lt;td>Profiling&lt;/td>
 &lt;td>用 Grafana / OSS profiling backend 建立可自管 profile diff&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca&lt;/a>&lt;/td>
 &lt;td>Profiling&lt;/td>
 &lt;td>用 eBPF 與平台視角建立 infrastructure-wide profile evidence&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/akamas/" data-link-title="Akamas" data-link-desc="用 AI-driven optimization 把效能、可靠性與雲端成本放進同一個容量調校閉環">Akamas&lt;/a>&lt;/td>
 &lt;td>Optimization&lt;/td>
 &lt;td>用 SLO constraint 與配置實驗建立 capacity / cost 調校閉環&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage&lt;/a>&lt;/td>
 &lt;td>FinOps&lt;/td>
 &lt;td>用 cost reports、Kubernetes cost 與 forecast 建立成本可見性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth&lt;/a>&lt;/td>
 &lt;td>FinOps&lt;/td>
 &lt;td>用 enterprise governance、policy 與 allocation 管理雲端成本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer&lt;/a>&lt;/td>
 &lt;td>AWS FinOps&lt;/td>
 &lt;td>用 AWS-native cost / usage report 建立成本分析 baseline&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>這批工具頁已完成 load test、production traffic replay、continuous profiling 與 capacity / cost analysis 的主要分流。k6 承接 scriptable scenario，JMeter 承接企業測試資產，Gatling 承接 JVM simulation，Locust 承接 Python custom behavior，Vegeta 承接快速 HTTP probe；GoReplay、Service Mesh Mirroring 與 AWS VPC Traffic Mirroring 承接不同層級的 production traffic evidence；Datadog Continuous Profiler、Pyroscope 與 Parca 承接不同操作模型的 profile evidence；Akamas、Vantage、CloudHealth 與 AWS Cost Explorer 承接 cost visibility、optimization 與 FinOps governance。&lt;/p></description><content:encoded><![CDATA[<p>效能與容量工具清單的核心責任是把工具名稱放回 workload model、saturation discovery、capacity planning 與 production validation 的服務責任。工具頁先回答它降低哪一種風險，再討論 scenario scripting、distributed load、結果保存、CI 整合、成本與案例回寫。</p>
<h2 id="讀法">讀法</h2>
<p>效能工具要從問題節點進入。團隊如果缺 workload model，先讀 <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a>；如果缺 saturation 邊界，先讀 <a href="/blog/backend/09-performance-capacity/saturation-discovery/" data-link-title="9.4 Saturation Discovery" data-link-desc="找出 throughput plateau 與 latency knee 的方法">9.4 Saturation Discovery</a>；如果缺 production 驗證，先讀 <a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a>。</p>
<p>工具頁的任務是承接這些問題節點。k6、JMeter、Gatling、Locust 與 Vegeta 都能產生負載，但它們在腳本語言、protocol 覆蓋、分散式執行、CI integration、報表與團隊學習成本上不同；production replay、profiling 與 cost analysis 工具則承擔不同的證據責任。</p>
<h2 id="教學順序同步">教學順序同步</h2>
<p>效能與容量工具頁的教學順序是先建立 load test，再進入 replay / mirroring、profiling、optimization 與 FinOps。這個順序對齊 checkout E7：讀者先理解 workload model、saturation evidence 與 capacity gate，再比較 production traffic evidence、profile evidence、rightsizing 建議與成本 owner 如何形成改善閉環。</p>
<h2 id="t1-工具頁">T1 工具頁</h2>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>類型</th>
          <th>核心責任</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a></td>
          <td>Load test</td>
          <td>用 scriptable scenario 建立 API / protocol 負載</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a></td>
          <td>Load test</td>
          <td>用 GUI、plugin 與多 protocol sampler 承接企業測試資產</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a></td>
          <td>Load test</td>
          <td>用 JVM DSL 與 injection profile 表達複雜 scenario</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></td>
          <td>Load test</td>
          <td>用 Python user behavior 與 distributed worker 表達高自訂負載</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a></td>
          <td>HTTP probe</td>
          <td>用固定 rate HTTP attack 快速探測 endpoint saturation</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/goreplay/" data-link-title="GoReplay" data-link-desc="用 production HTTP traffic capture 與 replay 驗證真實請求形狀的效能工程工具">GoReplay</a></td>
          <td>Traffic replay</td>
          <td>捕捉 production HTTP traffic 並重播到 shadow target</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/service-mesh-mirroring/" data-link-title="Service Mesh Mirroring" data-link-desc="用 sidecar / proxy 層 mirror production traffic 到新版本或 shadow service 的 production validation 方式">Service Mesh Mirroring</a></td>
          <td>Traffic mirror</td>
          <td>用 proxy route policy mirror production traffic</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/aws-vpc-traffic-mirroring/" data-link-title="AWS VPC Traffic Mirroring" data-link-desc="用 VPC 網路層封包鏡像觀察 production traffic 的低侵入 production validation 方式">AWS VPC Traffic Mirroring</a></td>
          <td>Traffic mirror</td>
          <td>用 VPC 網路層封包鏡像建立低侵入 production evidence</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a></td>
          <td>Profiling</td>
          <td>用 SaaS APM 整合與 deploy marker 支援 profile diff</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a></td>
          <td>Profiling</td>
          <td>用 Grafana / OSS profiling backend 建立可自管 profile diff</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a></td>
          <td>Profiling</td>
          <td>用 eBPF 與平台視角建立 infrastructure-wide profile evidence</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/akamas/" data-link-title="Akamas" data-link-desc="用 AI-driven optimization 把效能、可靠性與雲端成本放進同一個容量調校閉環">Akamas</a></td>
          <td>Optimization</td>
          <td>用 SLO constraint 與配置實驗建立 capacity / cost 調校閉環</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/vantage/" data-link-title="Vantage" data-link-desc="用 cloud cost reports、Kubernetes cost allocation 與 forecast 建立工程可用的成本可見性">Vantage</a></td>
          <td>FinOps</td>
          <td>用 cost reports、Kubernetes cost 與 forecast 建立成本可見性</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/cloudhealth/" data-link-title="CloudHealth" data-link-desc="用 enterprise FinOps governance、policy 與多雲成本管理支援大型組織的容量成本治理">CloudHealth</a></td>
          <td>FinOps</td>
          <td>用 enterprise governance、policy 與 allocation 管理雲端成本</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/vendors/aws-cost-explorer/" data-link-title="AWS Cost Explorer" data-link-desc="用 AWS-native 成本與用量分析建立 account、service、tag 與 usage type 的成本判讀入口">AWS Cost Explorer</a></td>
          <td>AWS FinOps</td>
          <td>用 AWS-native cost / usage report 建立成本分析 baseline</td>
      </tr>
  </tbody>
</table>
<p>這批工具頁已完成 load test、production traffic replay、continuous profiling 與 capacity / cost analysis 的主要分流。k6 承接 scriptable scenario，JMeter 承接企業測試資產，Gatling 承接 JVM simulation，Locust 承接 Python custom behavior，Vegeta 承接快速 HTTP probe；GoReplay、Service Mesh Mirroring 與 AWS VPC Traffic Mirroring 承接不同層級的 production traffic evidence；Datadog Continuous Profiler、Pyroscope 與 Parca 承接不同操作模型的 profile evidence；Akamas、Vantage、CloudHealth 與 AWS Cost Explorer 承接 cost visibility、optimization 與 FinOps governance。</p>
<h2 id="內容覆蓋進度">內容覆蓋進度</h2>
<p>每個工具頁下會擴充兩類文章：deep article（工具自身的配置、故障、容量、走 <a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">6-section 模板</a>）跟 migration playbook（跨工具遷移流程、走 <a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6-type 結構</a>）。「← X」代表從 X 遷入。</p>
<table>
  <thead>
      <tr>
          <th>Vendor</th>
          <th>Deep article</th>
          <th>Migration playbook</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="k6/">k6</a></td>
          <td>—</td>
          <td><a href="k6/migrate-from-jmeter/">← JMeter (Type E)</a></td>
      </tr>
      <tr>
          <td><a href="datadog-continuous-profiler/">Datadog Continuous Profiler</a></td>
          <td>—</td>
          <td><a href="datadog-continuous-profiler/migrate-from-pyroscope/">← Pyroscope (Type C)</a></td>
      </tr>
  </tbody>
</table>
<p>其他 T1 工具（JMeter / Gatling / Locust / Vegeta / GoReplay / Service Mesh Mirroring / AWS VPC Traffic Mirroring / Pyroscope / Parca / Akamas / Vantage / CloudHealth / AWS Cost Explorer）尚未開始。跟 <a href="/blog/backend/06-reliability/vendors/" data-link-title="可靠性 Vendor 清單" data-link-desc="規劃 CI、壓測、chaos engineering 與 SLO 工具的服務頁撰寫順序與判準">06 vendors</a> 共用部分工具（k6 / JMeter / Gatling / Locust），未來寫 deep article 時需明確區分「驗證流程的工具鏈」（06）跟「效能工程的工具鏈」（09）的角度。對應的 backlog 議題見上方「T1 工具頁」段每個工具頁要回答的核心責任、跟各工具 <code>_index.md</code> 的「預計實作話題」段。</p>
<h2 id="後續候選">後續候選</h2>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>候選工具</th>
          <th>寫作重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Load test</td>
          <td>Artillery、wrk、hey、Grafana k6 Cloud、AWS Distributed Load Testing、BlazeMeter、LoadRunner</td>
          <td>managed runner、跨 region、報表與費用</td>
      </tr>
      <tr>
          <td>Production traffic replay</td>
          <td>shadow traffic pattern、Diffy 類 response diff、proxy mirror variants</td>
          <td>response diff、資料遮罩、side effect 邊界</td>
      </tr>
      <tr>
          <td>Profiling</td>
          <td>GCP Cloud Profiler、AWS CodeGuru Profiler、Azure Application Insights Profiler、New Relic Profiler、Dynatrace Profiling</td>
          <td>雲端整合、採樣成本、profile diff</td>
      </tr>
      <tr>
          <td>Capacity / cost analysis</td>
          <td>Kubecost / OpenCost、CloudZero、CAST AI、Infracost、Harness Cloud Cost Management</td>
          <td>workload-level 成本、rightsizing、IaC cost</td>
      </tr>
      <tr>
          <td>Benchmark / workload model</td>
          <td>YCSB、JMH、pgbench、sysbench</td>
          <td>component benchmark、DB workload、micro vs system boundary</td>
      </tr>
  </tbody>
</table>
<p>Load test 工具頁要保留 workload model 語言。JMeter 適合 protocol 覆蓋與 GUI 驅動團隊，Gatling 適合程式化 scenario 與 JVM 生態，Locust 適合 Python 團隊，Vegeta 適合簡單 HTTP 壓測與 CLI workflow。</p>
<p>Production replay 工具頁要保留安全與副作用邊界。Replay production traffic 會碰到 PII、credential、payment callback、idempotency 與下游配額，因此文章要先定義遮罩、隔離、rate limit 與 stop condition。</p>
<p>Profiling 工具頁要保留長期成本。Continuous profiling 能降低退化定位時間，但會增加採樣成本、儲存成本、敏感資訊治理、symbolization 與 baseline 維護責任。</p>
<p>Capacity / cost analysis 工具頁要保留 owner 與行動閉環。成本報表只有在 tag、label、cost center、service owner、release marker 與 action workflow 對齊後，才會變成容量規劃與成本改善的工程證據。</p>
<p>主流覆蓋檢查的重點是分開 scenario load、quick probe、managed runner、traffic replay、profiling、FinOps 與 component benchmark。k6 / Gatling / Locust 解 scenario；Vegeta / wrk / hey 解 quick HTTP probe；Grafana k6 Cloud / AWS Distributed Load Testing / BlazeMeter 解 managed runner；Pyroscope / Parca / Datadog / cloud profiler 解 profiling；Kubecost / CloudZero / CAST AI 解 workload cost。</p>
<h2 id="工具頁標準章節">工具頁標準章節</h2>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>效能與容量工具頁要補的內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>工具定位</td>
          <td>它是 load test、replay、traffic mirror、profiler、optimizer 還是 FinOps 工具</td>
      </tr>
      <tr>
          <td>本章目標</td>
          <td>讀者能判斷它降低容量未知、production gap、瓶頸定位或成本歸因哪種風險</td>
      </tr>
      <tr>
          <td>最短判讀路徑</td>
          <td>用「缺 workload、缺 saturation、缺 production evidence、缺 cost owner」快速定位</td>
      </tr>
      <tr>
          <td>日常操作與決策形狀</td>
          <td>scenario、runner、threshold、sampling、dashboard、recommendation、owner</td>
      </tr>
      <tr>
          <td>核心取捨表</td>
          <td>同類工具與相鄰工具的機會成本，例如 k6 vs JMeter、Vantage vs Cost Explorer</td>
      </tr>
      <tr>
          <td>進階主題</td>
          <td>distributed runner、shadow traffic、continuous profiling、optimization guardrail</td>
      </tr>
      <tr>
          <td>排錯與失敗快速判讀</td>
          <td>runner bottleneck、side effect、sampling bias、tag gap、forecast drift</td>
      </tr>
      <tr>
          <td>何時改走其他服務</td>
          <td>驗證流程回 06、觀測資料回 04、部署控制回 05、事故處理回 08</td>
      </tr>
      <tr>
          <td>不在本頁內的主題</td>
          <td>完整工具 CLI 教學、供應商 pricing 細節、所有 dashboard 設定</td>
      </tr>
      <tr>
          <td>案例回寫與下一步路由</td>
          <td>回到 09 cases、6.13 regression gate、4.20 evidence package</td>
      </tr>
  </tbody>
</table>
<h2 id="跨-vendor-議題對照">跨 vendor 議題對照</h2>
<p>本模組 15 個 vendor 跨 5 個 sub-category（load test / production replay / continuous profiling / optimization / FinOps）、解不同效能與容量工程問題、不是同類選一。</p>
<table>
  <thead>
      <tr>
          <th>Sub-category</th>
          <th>典型 vendor</th>
          <th>輸出證據</th>
          <th>Production 風險</th>
          <th>操作成本</th>
          <th>Owner</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Load test</td>
          <td>k6 / JMeter / Gatling / Locust / Vegeta</td>
          <td>threshold pass/fail / p95 p99 / throughput</td>
          <td>低（測試環境）</td>
          <td>scenario 維護 / runner 規模 / 測試資料</td>
          <td>Engineering / QA</td>
      </tr>
      <tr>
          <td>Production replay</td>
          <td>GoReplay / Service Mesh Mirroring / AWS VPC</td>
          <td>response diff / shadow load</td>
          <td>高（PII / side effect / 配額）</td>
          <td>masking / isolation / rate limit</td>
          <td>SRE + Security</td>
      </tr>
      <tr>
          <td>Continuous profiling</td>
          <td>Datadog Profiler / Pyroscope / Parca</td>
          <td>flame graph diff / regression detection</td>
          <td>中（採樣 overhead）</td>
          <td>symbolization / storage / baseline 維護</td>
          <td>Engineering</td>
      </tr>
      <tr>
          <td>Optimization</td>
          <td>Akamas</td>
          <td>recommendation / SLO-constrained config</td>
          <td>中（autopilot rollout）</td>
          <td>objective model / approval workflow</td>
          <td>SRE + FinOps</td>
      </tr>
      <tr>
          <td>FinOps</td>
          <td>Vantage / CloudHealth / AWS Cost Explorer</td>
          <td>cost report / forecast / rightsizing</td>
          <td>無(reporting)</td>
          <td>tag governance / owner mapping / cadence</td>
          <td>FinOps + Eng lead</td>
      </tr>
  </tbody>
</table>
<p>對照表的用途有三：</p>
<ul>
<li>對齊 sub-category 跟問題節點：缺 saturation → load test；缺 production gap → replay；缺 瓶頸定位 → profiler；缺 capacity / cost 閉環 → optimizer + FinOps</li>
<li>評估 production 風險：load test 安全、replay / mirror 要明示 side effect 邊界、profiler 要看採樣 overhead、FinOps reporting 無風險</li>
<li>對齊 owner：load test 多 Engineering / QA、replay 多 SRE + Security、optimization + FinOps 跨團隊</li>
</ul>
<p>下面 5 段把對照表的 sub-category 展開、每段帶 vendor 選型判讀。</p>
<h3 id="load-testk6--jmeter--gatling--locust--vegeta">Load test（k6 / JMeter / Gatling / Locust / Vegeta）</h3>
<p>Load test 是 09 模組的主要 saturation 探測工具、跟 <a href="/blog/backend/06-reliability/vendors/" data-link-title="可靠性 Vendor 清單" data-link-desc="規劃 CI、壓測、chaos engineering 與 SLO 工具的服務頁撰寫順序與判準">06 reliability load test 章節</a> 同 vendor 但角度不同 — 06 看 CI gate / regression evidence、09 看 capacity planning / saturation discovery / peak event readiness。</p>
<p>選型判讀：CI-first JS → <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a>；JVM + 複雜 scenario → <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a>；既有 .jmx 資產 → <a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a>；Python custom behavior → <a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a>；快速 HTTP probe / fixed rate → <a href="/blog/backend/09-performance-capacity/vendors/vegeta/" data-link-title="Vegeta" data-link-desc="用簡潔 CLI 與固定 rate HTTP attack 快速探測 latency、throughput 與 saturation 的效能工程工具">Vegeta</a>（單一 HTTP attack 模式、不適合多 step scenario）。</p>
<h3 id="production-replaygoreplay--service-mesh-mirroring--aws-vpc-traffic-mirroring">Production replay（GoReplay / Service Mesh Mirroring / AWS VPC Traffic Mirroring）</h3>
<p>Production replay 把實際流量重播到 shadow target、補 load test 的「人工 scenario 跟真實流量差距」缺口。<strong>GoReplay</strong> 應用層 HTTP traffic capture + replay；<strong>Service Mesh Mirroring</strong> 用 Envoy / Istio proxy mirror、適合 K8s 內部；<strong>AWS VPC Traffic Mirroring</strong> L4 封包鏡像、適合非 HTTP / 低侵入。</p>
<p>選型判讀：HTTP application 層 → GoReplay；K8s 內 service mesh → Service Mesh Mirroring；非 HTTP / 跨 VPC / 低侵入 → AWS VPC。共同議題：PII 遮罩、idempotency boundary、downstream 配額 — 不可省。</p>
<h3 id="continuous-profilingdatadog-continuous-profiler--pyroscope--parca">Continuous profiling（Datadog Continuous Profiler / Pyroscope / Parca）</h3>
<p>Continuous profiling 在 production 持續採樣、退化時可 profile diff 找瓶頸。<strong>Datadog Continuous Profiler</strong> SaaS APM 整合、deploy marker 自動關聯；<strong>Pyroscope</strong> OSS / Grafana 生態、可自管或 Grafana Cloud；<strong>Parca</strong> eBPF-based、infrastructure-wide profile（不需 application instrumentation）。</p>
<p>選型判讀：已用 Datadog APM → Datadog Profiler；Grafana 生態 / OSS → Pyroscope；不想 instrument application + eBPF 友善 → Parca。共同議題：採樣 overhead（CPU / memory）、symbolization、storage cost、敏感資訊。</p>
<h3 id="optimizationakamas">Optimization（Akamas）</h3>
<p>Optimization 把 workload + SLO + cost 放進同一閉環、產出 configuration recommendation。<strong>Akamas</strong> 是 09 模組唯一 optimizer vendor、適合已有可量測 workload 跟成本壓力的服務。</p>
<p>選型判讀：Kubernetes rightsizing + runtime tuning + cost target → Akamas；純 FinOps reporting 不夠（要主動建議）→ Akamas。Akamas 不替代 FinOps tool — Vantage / CloudHealth 看歷史成本、Akamas 提產出未來 recommendation。</p>
<h3 id="finopsvantage--cloudhealth--aws-cost-explorer">FinOps（Vantage / CloudHealth / AWS Cost Explorer）</h3>
<p>FinOps 提供 cost visibility + forecast + allocation。<strong>Vantage</strong> Kubernetes cost + forecast 友善的 startup-friendly 平台；<strong>CloudHealth</strong> enterprise FinOps governance + policy + chargeback；<strong>AWS Cost Explorer</strong> AWS-native cost analysis baseline（免費、限 AWS）。</p>
<p>選型判讀：純 AWS 啟動 → Cost Explorer；多雲 + startup / mid-size → Vantage；enterprise + 多 BU chargeback → CloudHealth；K8s workload cost → Kubecost / OpenCost（不在本表、後續候選）。共同議題：tag governance、cost center mapping、cadence。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a></li>
<li>上游：<a href="/blog/backend/09-performance-capacity/production-validation/" data-link-title="9.10 Production-Side 驗證" data-link-desc="shadow traffic、dark launch、canary、production-like load test">9.10 Production-Side 驗證</a></li>
<li>服務路徑：<a href="/blog/backend/#%e8%b2%ab%e7%a9%bf%e5%bc%8f%e6%a1%88%e4%be%8bcheckout-%e6%9c%8d%e5%8b%99%e6%bc%94%e9%80%b2" data-link-title="Backend 服務實務指南" data-link-desc="用跨語言教學路線整理資料庫、快取、訊息佇列、觀測、部署、可靠性、資安、事故與容量等後端服務能力">Checkout 服務演進</a></li>
<li>平行：<a href="/blog/backend/06-reliability/vendors/" data-link-title="可靠性 Vendor 清單" data-link-desc="規劃 CI、壓測、chaos engineering 與 SLO 工具的服務頁撰寫順序與判準">06 Reliability vendors</a> — 06 從驗證流程看工具，09 從容量量化與效能工程看工具</li>
</ul>
]]></content:encoded></item><item><title>模組九案例正文</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/</guid><description>&lt;p>這個資料夾的核心責任是把雲端服務商公開的高併發實戰案例轉成可回寫主章判讀的案例正文。資料來源以 &lt;a href="https://aws.amazon.com/solutions/case-studies/">AWS Customer Success Stories&lt;/a>、&lt;a href="https://cloud.google.com/customers">Google Cloud Customer Stories&lt;/a> 與 &lt;a href="https://customers.microsoft.com/">Azure Customer Case Studies&lt;/a> 為主，因為這層案例同時提供具體流量數字、實際使用的服務組合與工程決策路徑，比一般 engineering blog 更接近實戰判讀。&lt;/p>
&lt;p>跟模組七案例庫一樣、本資料夾不只服務 09 主章閱讀、也是 01-05 模組寫作時的證據來源。當寫 01 資料庫章節需要說明「Aurora 真實流量下能撐多少」、當寫 02 快取章節需要說明「ElastiCache 在持續成長服務的角色」時、可以直接回查本資料夾相應案例。&lt;/p>
&lt;h2 id="跟-06-案例庫的差異">跟 06 案例庫的差異&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>&lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/cases/" data-link-title="可靠性服務案例庫" data-link-desc="按服務組織的 SRE 實踐案例庫，累積架構脈絡與工程文化">06 cases&lt;/a>&lt;/th>
 &lt;th>09 cases（本資料夾）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>來源&lt;/td>
 &lt;td>大企業工程部落格（Google SRE Book、Netflix Tech Blog、Shopify 等）&lt;/td>
 &lt;td>AWS / GCP / Azure 官方 customer case studies&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>證據型態&lt;/td>
 &lt;td>方法論敘事（SLO 政策、chaos hypothesis、failure mode）&lt;/td>
 &lt;td>具體流量、實例、延遲、成本數字（QPS、msg/sec、p95、cost ratio）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>讀法&lt;/td>
 &lt;td>失敗模式如何被驗證&lt;/td>
 &lt;td>容量量化實踐：什麼配置撐多少、加多少、成本曲線怎麼走&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>教學責任&lt;/td>
 &lt;td>把驗證流程制度化&lt;/td>
 &lt;td>把容量地圖具體化、把成本邊界量化&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>兩層案例互補。06 教讀者「怎麼預先驗證失敗會被擋住」、09 教讀者「實際配置在實際流量下會怎麼跑」。同一個服務可以同時出現在兩處、但讀法不同。&lt;/p>
&lt;h2 id="案例列表">案例列表&lt;/h2>
&lt;p>每個案例標 tag 讓多個主章可以反查。tag 維度：&lt;strong>雲商&lt;/strong>（aws / gcp / azure）、&lt;strong>服務維度&lt;/strong>（db-oltp / db-kv / cache / mq-stream / compute / global-edge / latency / data-architecture）、&lt;strong>負載形狀&lt;/strong>（predictable-peak / event-peak / surge / flash-sale-spike / low-latency-sustained / sustained-growth）。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>章節&lt;/th>
 &lt;th>主題&lt;/th>
 &lt;th>雲商&lt;/th>
 &lt;th>服務維度&lt;/th>
 &lt;th>負載形狀&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1&lt;/a>&lt;/td>
 &lt;td>AWS Prime Day 2025 dogfood&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>multi&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &amp;#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2&lt;/a>&lt;/td>
 &lt;td>GR8 Tech 體育博彩 AI 預測式擴容&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>event-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &amp;#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3&lt;/a>&lt;/td>
 &lt;td>Coinbase 超低延遲交易&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>latency&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &amp;#43;50% 不影響延遲">9.C4&lt;/a>&lt;/td>
 &lt;td>DraftKings Aurora 100 萬 ops/min&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-oltp&lt;/td>
 &lt;td>event-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &amp;#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5&lt;/a>&lt;/td>
 &lt;td>Amazon Ads DynamoDB 9000 萬 RPS&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6&lt;/a>&lt;/td>
 &lt;td>Tinder ElastiCache 配對引擎&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>cache&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&amp;#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&amp;#43; 個微服務承載 8 倍峰值流量、跨 200&amp;#43; 城市">9.C7&lt;/a>&lt;/td>
 &lt;td>Lyft 100+ 微服務 8x 峰值&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>event-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8&lt;/a>&lt;/td>
 &lt;td>Niantic Pokémon GO 50x 突發&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>surge&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9&lt;/a>&lt;/td>
 &lt;td>Spotify Kafka → Pub/Sub 遷移&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>mq-stream&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10&lt;/a>&lt;/td>
 &lt;td>Cloud Spanner 10 億 req/sec&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>db-oltp&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11&lt;/a>&lt;/td>
 &lt;td>Minecraft Earth Cosmos DB 全球&lt;/td>
 &lt;td>azure&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>surge&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12&lt;/a>&lt;/td>
 &lt;td>Riot Games 246 EKS clusters&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&amp;#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13&lt;/a>&lt;/td>
 &lt;td>Hotstar IPL 1860 萬同時觀看&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>global-edge&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14&lt;/a>&lt;/td>
 &lt;td>Standard Chartered Aurora 4000 TPS&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-oltp&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &amp;#43; 傳統伺服器當慢速消費者、承受 100K&amp;#43; 同時選位 &amp;#43; 30 秒從 6 台擴到 800 台">9.C15&lt;/a>&lt;/td>
 &lt;td>拓元 Tixcraft 售票搶購&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>flash-sale-spike&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &amp;#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &amp;#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16&lt;/a>&lt;/td>
 &lt;td>SeatGeek Virtual Waiting Room&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>flash-sale-spike&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17&lt;/a>&lt;/td>
 &lt;td>BookMyShow 印度年售 2 億張票&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>data-architecture&lt;/td>
 &lt;td>flash-sale-spike&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18&lt;/a>&lt;/td>
 &lt;td>Zoom COVID 30x DAU 突發&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>surge&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &amp;#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &amp;#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19&lt;/a>&lt;/td>
 &lt;td>Capcom 遊戲後端 DynamoDB + EKS&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20&lt;/a>&lt;/td>
 &lt;td>Zomato TiDB → DynamoDB 4x 吞吐&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21&lt;/a>&lt;/td>
 &lt;td>ASOS Cosmos DB Black Friday&lt;/td>
 &lt;td>azure&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&amp;#43; 商品 &amp;#43; 16,000&amp;#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22&lt;/a>&lt;/td>
 &lt;td>Wayfair GCP burst capacity&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>data-architecture&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23&lt;/a>&lt;/td>
 &lt;td>Netflix Aurora 統一 +75% 效能&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-oltp&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &amp;#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24&lt;/a>&lt;/td>
 &lt;td>Genesys 99.999% 跨 15 region&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25&lt;/a>&lt;/td>
 &lt;td>Tubi ML feature store sub-10ms p99&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>cache&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26&lt;/a>&lt;/td>
 &lt;td>PayPay 行動支付每日 3 億訊息&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&amp;#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&amp;#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">9.C27&lt;/a>&lt;/td>
 &lt;td>Disney+ 觀看歷史每日數十億動作&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &amp;#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &amp;#43; Wavelength &amp;#43; Outposts 處理 20&amp;#43; 州的雙重峰值">9.C28&lt;/a>&lt;/td>
 &lt;td>FanDuel 直播 + 投注雙重峰值&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>event-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &amp;#43; AWS Media Services 撐 30 channels live &amp;#43; 5M MAU、工程工時下降 90%">9.C29&lt;/a>&lt;/td>
 &lt;td>NTT DOCOMO Lemino 5M MAU / 3 個月&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-kv&lt;/td>
 &lt;td>predictable-peak&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30&lt;/a>&lt;/td>
 &lt;td>Microsoft 365 MongoDB → Cosmos DB&lt;/td>
 &lt;td>azure&lt;/td>
 &lt;td>data-architecture&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &amp;#43; 1.5 億商品、用 GCP Vertex AI Search &amp;#43; BigQuery 提供近即時搜尋與分析">9.C31&lt;/a>&lt;/td>
 &lt;td>Mercado Libre LatAm Vertex + BigQuery&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>data-architecture&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/" data-link-title="9.C32 Clearent：Azure SQL Hyperscale 撐每年 5 億筆支付交易" data-link-desc="Clearent 在 Azure SQL Hyperscale 上處理每年 5 億筆支付交易、autoscale &amp;#43; 微服務架構">9.C32&lt;/a>&lt;/td>
 &lt;td>Clearent Azure SQL Hyperscale 5 億 txn/年&lt;/td>
 &lt;td>azure&lt;/td>
 &lt;td>db-oltp&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/" data-link-title="9.C33 Maersk &amp;#43; Bosch：傳統產業在 Azure AKS 上的微服務治理" data-link-desc="全球海運 Maersk 跟 Bosch 智慧建築把 AKS 當微服務治理基礎、釋放工程資源做業務功能">9.C33&lt;/a>&lt;/td>
 &lt;td>Maersk + Bosch Azure AKS&lt;/td>
 &lt;td>azure&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/" data-link-title="9.C34 GCP：130,000-node GKE cluster 的工程極限" data-link-desc="Google 用單一 GKE control plane 跑 13 萬個 node、AI workload &amp;#43; 1000 Pods/sec 創建吞吐">9.C34&lt;/a>&lt;/td>
 &lt;td>GCP 130K-node GKE cluster (AI)&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>compute&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/snap-gcp-keydb-cross-cloud/" data-link-title="9.C35 Snap：GCP &amp;#43; KeyDB 在 multi-cloud 架構下的低延遲快取" data-link-desc="Snap 用 GCP 上的 KeyDB cluster 減少跨 cloud cache 延遲、用 TPU 訓練廣告推薦模型">9.C35&lt;/a>&lt;/td>
 &lt;td>Snap GCP KeyDB cross-cloud cache&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>cache&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/coinbase-mongodb-document-platform/" data-link-title="9.C36 Coinbase：MongoDB 撐 Ruby 單體 &amp;#43; 1.5M reads/sec identity 服務" data-link-desc="Coinbase 以 MongoDB 為主資料層、自建 mongobetween connection proxy、users 服務在加密貨幣 surge 時撐 1.5M reads/sec">9.C36&lt;/a>&lt;/td>
 &lt;td>Coinbase MongoDB 1.5M reads/sec&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-document&lt;/td>
 &lt;td>low-latency-sustained&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/" data-link-title="9.C37 Forbes：自管 MongoDB → Atlas on GCP、build 時間 25 → 9 分鐘" data-link-desc="Forbes 把自管 MongoDB 遷到 Atlas on Google Cloud、6 個月完成、build 25 → 9 分鐘、120M 不重複訪客單月承接">9.C37&lt;/a>&lt;/td>
 &lt;td>Forbes 自管 MongoDB → Atlas on GCP&lt;/td>
 &lt;td>gcp&lt;/td>
 &lt;td>db-document&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/toyota-connected-mongodb-telematics-iot/" data-link-title="9.C38 Toyota Connected：MongoDB Atlas 撐 900 萬車輛 telematics、月 180 億 transaction" data-link-desc="Toyota Connected 用 MongoDB Atlas 撐 Safety Connect 900 萬車、月 180 億 transaction、緊急訊號 3 秒內到 agent">9.C38&lt;/a>&lt;/td>
 &lt;td>Toyota Connected MongoDB 月 180 億 txn&lt;/td>
 &lt;td>aws&lt;/td>
 &lt;td>db-document&lt;/td>
 &lt;td>sustained-growth&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="主章寫作時的反查路由">主章寫作時的反查路由&lt;/h2>
&lt;p>當寫 01-05 模組的具體服務章節需要援引「真實流量下會發生什麼」、查下表找對應案例。&lt;/p></description><content:encoded><![CDATA[<p>這個資料夾的核心責任是把雲端服務商公開的高併發實戰案例轉成可回寫主章判讀的案例正文。資料來源以 <a href="https://aws.amazon.com/solutions/case-studies/">AWS Customer Success Stories</a>、<a href="https://cloud.google.com/customers">Google Cloud Customer Stories</a> 與 <a href="https://customers.microsoft.com/">Azure Customer Case Studies</a> 為主，因為這層案例同時提供具體流量數字、實際使用的服務組合與工程決策路徑，比一般 engineering blog 更接近實戰判讀。</p>
<p>跟模組七案例庫一樣、本資料夾不只服務 09 主章閱讀、也是 01-05 模組寫作時的證據來源。當寫 01 資料庫章節需要說明「Aurora 真實流量下能撐多少」、當寫 02 快取章節需要說明「ElastiCache 在持續成長服務的角色」時、可以直接回查本資料夾相應案例。</p>
<h2 id="跟-06-案例庫的差異">跟 06 案例庫的差異</h2>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th><a href="/blog/backend/06-reliability/cases/" data-link-title="可靠性服務案例庫" data-link-desc="按服務組織的 SRE 實踐案例庫，累積架構脈絡與工程文化">06 cases</a></th>
          <th>09 cases（本資料夾）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>來源</td>
          <td>大企業工程部落格（Google SRE Book、Netflix Tech Blog、Shopify 等）</td>
          <td>AWS / GCP / Azure 官方 customer case studies</td>
      </tr>
      <tr>
          <td>證據型態</td>
          <td>方法論敘事（SLO 政策、chaos hypothesis、failure mode）</td>
          <td>具體流量、實例、延遲、成本數字（QPS、msg/sec、p95、cost ratio）</td>
      </tr>
      <tr>
          <td>讀法</td>
          <td>失敗模式如何被驗證</td>
          <td>容量量化實踐：什麼配置撐多少、加多少、成本曲線怎麼走</td>
      </tr>
      <tr>
          <td>教學責任</td>
          <td>把驗證流程制度化</td>
          <td>把容量地圖具體化、把成本邊界量化</td>
      </tr>
  </tbody>
</table>
<p>兩層案例互補。06 教讀者「怎麼預先驗證失敗會被擋住」、09 教讀者「實際配置在實際流量下會怎麼跑」。同一個服務可以同時出現在兩處、但讀法不同。</p>
<h2 id="案例列表">案例列表</h2>
<p>每個案例標 tag 讓多個主章可以反查。tag 維度：<strong>雲商</strong>（aws / gcp / azure）、<strong>服務維度</strong>（db-oltp / db-kv / cache / mq-stream / compute / global-edge / latency / data-architecture）、<strong>負載形狀</strong>（predictable-peak / event-peak / surge / flash-sale-spike / low-latency-sustained / sustained-growth）。</p>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>主題</th>
          <th>雲商</th>
          <th>服務維度</th>
          <th>負載形狀</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1</a></td>
          <td>AWS Prime Day 2025 dogfood</td>
          <td>aws</td>
          <td>multi</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2</a></td>
          <td>GR8 Tech 體育博彩 AI 預測式擴容</td>
          <td>aws</td>
          <td>compute</td>
          <td>event-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3</a></td>
          <td>Coinbase 超低延遲交易</td>
          <td>aws</td>
          <td>latency</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4</a></td>
          <td>DraftKings Aurora 100 萬 ops/min</td>
          <td>aws</td>
          <td>db-oltp</td>
          <td>event-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5</a></td>
          <td>Amazon Ads DynamoDB 9000 萬 RPS</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6</a></td>
          <td>Tinder ElastiCache 配對引擎</td>
          <td>aws</td>
          <td>cache</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7</a></td>
          <td>Lyft 100+ 微服務 8x 峰值</td>
          <td>aws</td>
          <td>compute</td>
          <td>event-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8</a></td>
          <td>Niantic Pokémon GO 50x 突發</td>
          <td>gcp</td>
          <td>compute</td>
          <td>surge</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9</a></td>
          <td>Spotify Kafka → Pub/Sub 遷移</td>
          <td>gcp</td>
          <td>mq-stream</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10</a></td>
          <td>Cloud Spanner 10 億 req/sec</td>
          <td>gcp</td>
          <td>db-oltp</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11</a></td>
          <td>Minecraft Earth Cosmos DB 全球</td>
          <td>azure</td>
          <td>db-kv</td>
          <td>surge</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12</a></td>
          <td>Riot Games 246 EKS clusters</td>
          <td>aws</td>
          <td>compute</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13</a></td>
          <td>Hotstar IPL 1860 萬同時觀看</td>
          <td>aws</td>
          <td>global-edge</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14</a></td>
          <td>Standard Chartered Aurora 4000 TPS</td>
          <td>aws</td>
          <td>db-oltp</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15</a></td>
          <td>拓元 Tixcraft 售票搶購</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>flash-sale-spike</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16</a></td>
          <td>SeatGeek Virtual Waiting Room</td>
          <td>aws</td>
          <td>compute</td>
          <td>flash-sale-spike</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17</a></td>
          <td>BookMyShow 印度年售 2 億張票</td>
          <td>aws</td>
          <td>data-architecture</td>
          <td>flash-sale-spike</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18</a></td>
          <td>Zoom COVID 30x DAU 突發</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>surge</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19</a></td>
          <td>Capcom 遊戲後端 DynamoDB + EKS</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20</a></td>
          <td>Zomato TiDB → DynamoDB 4x 吞吐</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21</a></td>
          <td>ASOS Cosmos DB Black Friday</td>
          <td>azure</td>
          <td>db-kv</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22</a></td>
          <td>Wayfair GCP burst capacity</td>
          <td>gcp</td>
          <td>data-architecture</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23</a></td>
          <td>Netflix Aurora 統一 +75% 效能</td>
          <td>aws</td>
          <td>db-oltp</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24</a></td>
          <td>Genesys 99.999% 跨 15 region</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25</a></td>
          <td>Tubi ML feature store sub-10ms p99</td>
          <td>aws</td>
          <td>cache</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/paypay-mobile-payment-messaging/" data-link-title="9.C26 PayPay：行動支付每日 3 億訊息的 DynamoDB 後端" data-link-desc="日本最大行動支付 PayPay 每日 3 億訊息、用 DynamoDB 處理通知與訊息功能、支撐次秒級反應">9.C26</a></td>
          <td>PayPay 行動支付每日 3 億訊息</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/disney-plus-content-metadata/" data-link-title="9.C27 Disney&#43;：DynamoDB 撐每日數十億動作的觀看歷史" data-link-desc="Disney&#43; 用 DynamoDB 撐每日數十億動作的觀看歷史、watchlist、播放進度等串流 metadata">9.C27</a></td>
          <td>Disney+ 觀看歷史每日數十億動作</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28</a></td>
          <td>FanDuel 直播 + 投注雙重峰值</td>
          <td>aws</td>
          <td>compute</td>
          <td>event-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29</a></td>
          <td>NTT DOCOMO Lemino 5M MAU / 3 個月</td>
          <td>aws</td>
          <td>db-kv</td>
          <td>predictable-peak</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30</a></td>
          <td>Microsoft 365 MongoDB → Cosmos DB</td>
          <td>azure</td>
          <td>data-architecture</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/mercado-libre-latam-bigquery-vertex/" data-link-title="9.C31 Mercado Libre：LatAm 電商在 GCP 上用 Vertex AI 搜尋 1.5 億商品" data-link-desc="Mercado Libre 1 億客戶 &#43; 1.5 億商品、用 GCP Vertex AI Search &#43; BigQuery 提供近即時搜尋與分析">9.C31</a></td>
          <td>Mercado Libre LatAm Vertex + BigQuery</td>
          <td>gcp</td>
          <td>data-architecture</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/" data-link-title="9.C32 Clearent：Azure SQL Hyperscale 撐每年 5 億筆支付交易" data-link-desc="Clearent 在 Azure SQL Hyperscale 上處理每年 5 億筆支付交易、autoscale &#43; 微服務架構">9.C32</a></td>
          <td>Clearent Azure SQL Hyperscale 5 億 txn/年</td>
          <td>azure</td>
          <td>db-oltp</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/maersk-bosch-azure-aks/" data-link-title="9.C33 Maersk &#43; Bosch：傳統產業在 Azure AKS 上的微服務治理" data-link-desc="全球海運 Maersk 跟 Bosch 智慧建築把 AKS 當微服務治理基礎、釋放工程資源做業務功能">9.C33</a></td>
          <td>Maersk + Bosch Azure AKS</td>
          <td>azure</td>
          <td>compute</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/gcp-130k-node-gke-cluster/" data-link-title="9.C34 GCP：130,000-node GKE cluster 的工程極限" data-link-desc="Google 用單一 GKE control plane 跑 13 萬個 node、AI workload &#43; 1000 Pods/sec 創建吞吐">9.C34</a></td>
          <td>GCP 130K-node GKE cluster (AI)</td>
          <td>gcp</td>
          <td>compute</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/snap-gcp-keydb-cross-cloud/" data-link-title="9.C35 Snap：GCP &#43; KeyDB 在 multi-cloud 架構下的低延遲快取" data-link-desc="Snap 用 GCP 上的 KeyDB cluster 減少跨 cloud cache 延遲、用 TPU 訓練廣告推薦模型">9.C35</a></td>
          <td>Snap GCP KeyDB cross-cloud cache</td>
          <td>gcp</td>
          <td>cache</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-mongodb-document-platform/" data-link-title="9.C36 Coinbase：MongoDB 撐 Ruby 單體 &#43; 1.5M reads/sec identity 服務" data-link-desc="Coinbase 以 MongoDB 為主資料層、自建 mongobetween connection proxy、users 服務在加密貨幣 surge 時撐 1.5M reads/sec">9.C36</a></td>
          <td>Coinbase MongoDB 1.5M reads/sec</td>
          <td>aws</td>
          <td>db-document</td>
          <td>low-latency-sustained</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/" data-link-title="9.C37 Forbes：自管 MongoDB → Atlas on GCP、build 時間 25 → 9 分鐘" data-link-desc="Forbes 把自管 MongoDB 遷到 Atlas on Google Cloud、6 個月完成、build 25 → 9 分鐘、120M 不重複訪客單月承接">9.C37</a></td>
          <td>Forbes 自管 MongoDB → Atlas on GCP</td>
          <td>gcp</td>
          <td>db-document</td>
          <td>sustained-growth</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/toyota-connected-mongodb-telematics-iot/" data-link-title="9.C38 Toyota Connected：MongoDB Atlas 撐 900 萬車輛 telematics、月 180 億 transaction" data-link-desc="Toyota Connected 用 MongoDB Atlas 撐 Safety Connect 900 萬車、月 180 億 transaction、緊急訊號 3 秒內到 agent">9.C38</a></td>
          <td>Toyota Connected MongoDB 月 180 億 txn</td>
          <td>aws</td>
          <td>db-document</td>
          <td>sustained-growth</td>
      </tr>
  </tbody>
</table>
<h2 id="主章寫作時的反查路由">主章寫作時的反查路由</h2>
<p>當寫 01-05 模組的具體服務章節需要援引「真實流量下會發生什麼」、查下表找對應案例。</p>
<h3 id="寫-01-資料庫模組-時">寫 <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">01 資料庫模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>OLTP 高 TPS 容量</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> / <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> / <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></td>
      </tr>
      <tr>
          <td>KV 極高吞吐</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> / <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> / <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a> / <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a> / <a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS</a></td>
      </tr>
      <tr>
          <td>全球一致性 OLTP</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> / <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a>（multi-region active-active）</td>
      </tr>
      <tr>
          <td>Transaction boundary</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a>（RAFT、強順序）</td>
      </tr>
      <tr>
          <td>Hot partition / 分片</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> / <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> / <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a></td>
      </tr>
      <tr>
          <td>DB 作為寫入緩衝</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（DynamoDB 緩衝 + 傳統 server 慢速消費）</td>
      </tr>
      <tr>
          <td>DB 種類整合 / consolidation</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora</a> / <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys DynamoDB 為預設</a></td>
      </tr>
      <tr>
          <td>Migration 與合規</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> / <a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a> / <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato TiDB → DynamoDB</a> / <a href="/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/" data-link-title="9.C37 Forbes：自管 MongoDB → Atlas on GCP、build 時間 25 → 9 分鐘" data-link-desc="Forbes 把自管 MongoDB 遷到 Atlas on Google Cloud、6 個月完成、build 25 → 9 分鐘、120M 不重複訪客單月承接">9.C37 Forbes 自管 MongoDB → Atlas</a></td>
      </tr>
      <tr>
          <td>多事件 ticketing 資料層</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a> / <a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair</a></td>
      </tr>
      <tr>
          <td>Document database / MongoDB</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-mongodb-document-platform/" data-link-title="9.C36 Coinbase：MongoDB 撐 Ruby 單體 &#43; 1.5M reads/sec identity 服務" data-link-desc="Coinbase 以 MongoDB 為主資料層、自建 mongobetween connection proxy、users 服務在加密貨幣 surge 時撐 1.5M reads/sec">9.C36 Coinbase</a>（1.5M reads/sec、connection proxy）/ <a href="/blog/backend/09-performance-capacity/cases/forbes-mongodb-atlas-multi-cloud-migration/" data-link-title="9.C37 Forbes：自管 MongoDB → Atlas on GCP、build 時間 25 → 9 分鐘" data-link-desc="Forbes 把自管 MongoDB 遷到 Atlas on Google Cloud、6 個月完成、build 25 → 9 分鐘、120M 不重複訪客單月承接">9.C37 Forbes</a>（自管 → Atlas）/ <a href="/blog/backend/09-performance-capacity/cases/toyota-connected-mongodb-telematics-iot/" data-link-title="9.C38 Toyota Connected：MongoDB Atlas 撐 900 萬車輛 telematics、月 180 億 transaction" data-link-desc="Toyota Connected 用 MongoDB Atlas 撐 Safety Connect 900 萬車、月 180 億 transaction、緊急訊號 3 秒內到 agent">9.C38 Toyota Connected</a>（IoT telematics）/ <a href="/blog/backend/09-performance-capacity/cases/microsoft-365-cosmos-db-analytics/" data-link-title="9.C30 Microsoft 365：從 MongoDB 遷移到 Cosmos DB 的分析平台" data-link-desc="Microsoft 365 把使用分析平台從 MongoDB 遷移到 Cosmos DB、planet-scale 全球分散式分析">9.C30 Microsoft 365</a>（遷到 Cosmos DB）</td>
      </tr>
  </tbody>
</table>
<h3 id="寫-02-快取模組-時">寫 <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">02 快取模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>高吞吐 cache layer</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder</a></td>
      </tr>
      <tr>
          <td>Cache as SoT</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder</a>（配對快取為主要服務面）</td>
      </tr>
      <tr>
          <td>ML feature store</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a>（sub-10ms p99）</td>
      </tr>
      <tr>
          <td>Sub-ms latency 需求</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a>（不只 cache、整體 sub-ms 設計）</td>
      </tr>
      <tr>
          <td>Cache stampede</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokémon GO surge</a>（50x 突發必觸 stampede 風險）</td>
      </tr>
      <tr>
          <td>Cache hierarchy / 多層 cache</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a>（L1 in-process + L2 cache + L3 store）</td>
      </tr>
      <tr>
          <td>Cache vs durable store 取捨</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a>（從 ScyllaDB 遷到 ElastiCache）</td>
      </tr>
  </tbody>
</table>
<h3 id="寫-03-訊息佇列模組-時">寫 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 訊息佇列模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>大規模事件交付</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a></td>
      </tr>
      <tr>
          <td>Broker 自管 vs managed</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a></td>
      </tr>
      <tr>
          <td>極端 message volume</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 AWS Prime Day</a>（SQS 1.66 億 msg/sec）</td>
      </tr>
      <tr>
          <td>Queue 作為緩衝吸收洪峰</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（DynamoDB 模仿 queue 行為）</td>
      </tr>
      <tr>
          <td>Migration playbook</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a></td>
      </tr>
  </tbody>
</table>
<h3 id="寫-04-可觀測性模組-時">寫 <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">04 可觀測性模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SLO 量測 baseline</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a>（99.999% availability）/ <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a>（99.999% 12 個月達成）</td>
      </tr>
      <tr>
          <td>Latency budget 反推</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> / <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot</a> / <a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a>（ML p99 分解）</td>
      </tr>
      <tr>
          <td>Saturation 訊號</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a>（25ms p95 是業務 KPI）</td>
      </tr>
      <tr>
          <td>多地區 metric 治理</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar</a> / <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot</a> / <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a>（15 主 region）</td>
      </tr>
      <tr>
          <td>SLO 演進 / surge 後校準</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a>（30x 後 baseline 永久上移）</td>
      </tr>
  </tbody>
</table>
<h3 id="寫-05-部署平台模組-時">寫 <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">05 部署平台模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>K8s multi-cluster</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a> / <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a>（多遊戲共用 vs 多 cluster）</td>
      </tr>
      <tr>
          <td>Container vs VM</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokémon GO</a></td>
      </tr>
      <tr>
          <td>微服務切分</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft</a> / <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a>（微服務私有 store）</td>
      </tr>
      <tr>
          <td>Autoscaling 策略</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day</a> / <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> / <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（30 分鐘擴 130 倍）</td>
      </tr>
      <tr>
          <td>Global edge / CDN</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar</a> / <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（CloudFront 卸載靜態）</td>
      </tr>
      <tr>
          <td>限流 / Virtual Waiting Room</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a>（明確排隊）/ <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（隱性緩衝）</td>
      </tr>
      <tr>
          <td>Hybrid cloud / burst</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair</a>（on-prem + GCP burst）</td>
      </tr>
      <tr>
          <td>Control plane vs Data plane</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a>（DynamoDB 撐 metadata、影音另走 edge）</td>
      </tr>
  </tbody>
</table>
<h3 id="寫-00-服務選型模組-時">寫 <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">00 服務選型模組</a> 時</h3>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>對應案例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Traffic / data scale</td>
          <td>全部案例都可作對標、特別是 <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1</a> / <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5</a> / <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10</a></td>
      </tr>
      <tr>
          <td>合規 / 受監管</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></td>
      </tr>
      <tr>
          <td>Vendor 戰略支援</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokémon GO</a>（Google CRE）</td>
      </tr>
      <tr>
          <td>成本曲線</td>
          <td><a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot Games</a>（$10M 年省）</td>
      </tr>
  </tbody>
</table>
<h2 id="按負載形狀的讀法引導">按負載形狀的讀法引導</h2>
<p>當讀者遇到具體容量問題卡住時、先判斷負載屬於哪一種形狀、再選對應案例。</p>
<ol>
<li><strong>可預期極端峰值</strong>（年度活動、預售、賽事決賽）→ <a href="/blog/backend/09-performance-capacity/cases/aws-prime-day-extreme-scale-2025/" data-link-title="9.C1 AWS Prime Day 2025：可預期極端峰值的 dogfood" data-link-desc="Amazon 自家服務在 Prime Day 2025 的峰值數字 — 一年一次可預期峰值的容量設計參考">9.C1 Prime Day</a> / <a href="/blog/backend/09-performance-capacity/cases/hotstar-ipl-eighteen-million-concurrent/" data-link-title="9.C13 Disney&#43; Hotstar：IPL 板球決賽 1860 萬人同時直播" data-link-desc="Hotstar 在 IPL 板球決賽創下 1860 萬同時觀看的全球直播紀錄、CDN 與全球邊緣容量極限">9.C13 Hotstar</a> / <a href="/blog/backend/09-performance-capacity/cases/asos-cosmos-db-black-friday/" data-link-title="9.C21 ASOS：Cosmos DB 在 Black Friday 撐 1.67 億請求" data-link-desc="ASOS 在 2016 Black Friday 用 Azure Cosmos DB 撐 24 小時 1.67 億請求、3500 req/sec、48ms 平均延遲">9.C21 ASOS Black Friday</a> / <a href="/blog/backend/09-performance-capacity/cases/wayfair-gcp-burst-capacity/" data-link-title="9.C22 Wayfair：用 GCP 提供 Way Day / Black Friday 的 burst capacity" data-link-desc="Wayfair 22M&#43; 商品 &#43; 16,000&#43; 供應商、用 GCP 補充 on-prem data center 在峰值事件的 burst capacity">9.C22 Wayfair</a></li>
<li><strong>事件型不可預期峰值</strong>（賽事高潮、突發新聞、KOL 推廣）→ <a href="/blog/backend/09-performance-capacity/cases/gr8-tech-ai-predicted-betting-peak/" data-link-title="9.C2 GR8 Tech：AI 預測式自動擴容下的體育博彩高峰" data-link-desc="AI 預測 &#43; EKS 自動擴容怎麼在 25ms p95 下承載 54000 TPS 體育博彩峰值流量">9.C2 GR8 Tech</a> / <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> / <a href="/blog/backend/09-performance-capacity/cases/lyft-microservice-eight-x-peak/" data-link-title="9.C7 Lyft：100&#43; 微服務在 8 倍峰值下的 Auto Scaling" data-link-desc="Lyft 用 AWS Auto Scaling 跨 100&#43; 個微服務承載 8 倍峰值流量、跨 200&#43; 城市">9.C7 Lyft</a></li>
<li><strong>突發遠超預期的 surge</strong>（產品爆紅、病毒式擴散、結構性外部事件）→ <a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokémon GO</a>（產品爆紅、暫時）/ <a href="/blog/backend/09-performance-capacity/cases/minecraft-earth-cosmos-db-global/" data-link-title="9.C11 Minecraft Earth：Azure Cosmos DB 上的全球分散式 AR 遊戲" data-link-desc="Minecraft Earth 用 Cosmos DB 跨地區分散、測試到 100 萬 RU/s 仍維持承諾延遲">9.C11 Minecraft Earth</a> / <a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom</a>（COVID 結構性永久）</li>
<li><strong>flash-sale 瞬間爆量</strong>（售票開賣、報名活動、限量搶購）→ <a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">9.C15 Tixcraft</a>（隱性緩衝）/ <a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">9.C16 SeatGeek</a>（明確排隊）/ <a href="/blog/backend/09-performance-capacity/cases/bookmyshow-indian-ticketing-platform/" data-link-title="9.C17 BookMyShow：印度年售 2 億張票的資料架構現代化" data-link-desc="BookMyShow 從 15 年自建 analytics 遷移到 AWS modern data architecture、4 個月完成、分析成本下降 80%">9.C17 BookMyShow</a>（規模化平台資料層）</li>
<li><strong>持續成長 sustained</strong>（用戶月增、業務擴張）→ <a href="/blog/backend/09-performance-capacity/cases/amazon-ads-dynamodb-extreme-kv/" data-link-title="9.C5 Amazon Ads：DynamoDB 9000 萬 reads/sec 的廣告事件量測" data-link-desc="Amazon Ads 在 DynamoDB 上跑 9000 萬 reads/sec &#43; 500 萬 writes/sec、99.999% 可用性的廣告事件量測">9.C5 Amazon Ads</a> / <a href="/blog/backend/09-performance-capacity/cases/tinder-elasticache-valkey-matching/" data-link-title="9.C6 Tinder：ElastiCache for Valkey 撐 4700 萬月活的配對引擎" data-link-desc="Tinder 用 Amazon ElastiCache for Valkey 提供配對引擎所需的次毫秒延遲快取層">9.C6 Tinder</a> / <a href="/blog/backend/09-performance-capacity/cases/spotify-kafka-to-pubsub-migration-gcp/" data-link-title="9.C9 Spotify：從自管 Kafka 遷移到 GCP Pub/Sub 的事件交付系統" data-link-desc="Spotify 把自管 Kafka 事件系統遷移到 Google Cloud Pub/Sub、避免自管 broker 的容量規劃成本">9.C9 Spotify</a> / <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> / <a href="/blog/backend/09-performance-capacity/cases/capcom-gaming-dynamodb-eks/" data-link-title="9.C19 Capcom：Resident Evil / Monster Hunter 在 DynamoDB &#43; EKS 上的遊戲後端" data-link-desc="Capcom 把 Resident Evil、Street Fighter、Monster Hunter 遊戲後端跑在 DynamoDB &#43; EKS、單一秒位數延遲、營運成本降 30%">9.C19 Capcom</a> / <a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato</a> / <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></li>
<li><strong>低延遲持續需求</strong>（金融交易、即時配對、廣告競價、ML inference）→ <a href="/blog/backend/09-performance-capacity/cases/coinbase-ultra-low-latency-exchange-2023/" data-link-title="9.C3 Coinbase International Exchange：超低延遲交易的逆向容量設計" data-link-desc="為什麼 Coinbase 國際交易所選 Cluster Placement Group &#43; z1d 而不是自動擴容 — 延遲敏感型負載的容量取捨">9.C3 Coinbase</a> / <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> / <a href="/blog/backend/09-performance-capacity/cases/riot-games-eks-multi-cluster/" data-link-title="9.C12 Riot Games：246 個 EKS cluster 的多遊戲多地區治理" data-link-desc="Riot Games 從 Mesos 遷移到 EKS、用 246 個 cluster 跨遊戲跨地區治理、年省 1000 萬美金">9.C12 Riot</a> / <a href="/blog/backend/09-performance-capacity/cases/genesys-dynamodb-99999-availability/" data-link-title="9.C24 Genesys：用 DynamoDB 在 15 region 跑出 99.999% 可用性" data-link-desc="Genesys 客服平台用 DynamoDB 為預設資料層、跨 15 主 region &#43; 5 衛星 region、達成 12 個月 99.999% 可用性">9.C24 Genesys</a> / <a href="/blog/backend/09-performance-capacity/cases/tubi-elasticache-ml-feature-store/" data-link-title="9.C25 Tubi：從 ScyllaDB 遷到 ElastiCache、ML feature store 達 sub-10ms p99" data-link-desc="Tubi 把 ML 推薦的 feature store 從 ScyllaDB 遷到 ElastiCache for Redis、99 百分位延遲降到 10ms 以下">9.C25 Tubi</a></li>
</ol>
<h3 id="surge-形狀的兩種次分類">surge 形狀的兩種次分類</h3>
<p>surge（突發遠超預期）內部還可分兩種、設計回應完全不同：</p>
<ul>
<li><strong>產品爆紅 surge</strong>（<a href="/blog/backend/09-performance-capacity/cases/niantic-pokemon-go-fifty-x-surge-gcp/" data-link-title="9.C8 Niantic Pokémon GO：在 GCP 上承載 50 倍突發流量" data-link-desc="Pokémon GO 上線時實際流量達原始預估 50 倍、Google CRE 怎麼即時補容量">9.C8 Pokémon GO</a>）：流量隨熱度消退、是「暫時偏離 baseline 又回歸」。容量規劃焦點是「撐過熱度高峰、避免在最忙時掛」。</li>
<li><strong>結構性 surge</strong>（<a href="/blog/backend/09-performance-capacity/cases/zoom-covid-surge-dynamodb/" data-link-title="9.C18 Zoom：COVID 期間從 1000 萬到 3 億 DAU 的 30 倍突發" data-link-desc="Zoom 在 2020 年 COVID 爆發時、日活從 1000 萬衝到 3 億、用 DynamoDB 撐住會議後端">9.C18 Zoom COVID</a>）：baseline 永久上移、是「新常態」。容量規劃焦點是「30x 後 SLO baseline 重新校準、長期成本曲線重算」。</li>
</ul>
<h3 id="flash-sale-spike-形狀的特殊性">flash-sale-spike 形狀的特殊性</h3>
<p>售票搶購 / 報名活動 / 限量搶購跟其他「峰值」案例有本質差異：</p>
<ul>
<li><strong>時間點精確、可秒級預測</strong>：開賣時刻 = 公告時刻、跟 GR8 Tech 的「賽事高潮」不一樣（賽事高潮在何時 + 多大都未知）</li>
<li><strong>持續時間極短</strong>：5-30 分鐘賣完、跟 Prime Day（48 小時）/ Hotstar IPL（4 小時）量級差很多</li>
<li><strong>峰值倍數極端</strong>：t=0 前流量近 0、t=0 瞬間衝到 10K-100K 倍、平均流量沒意義、只有峰值</li>
<li><strong>後端不容易跟上</strong>：高流量湧入時、付款 / 簽證 / 庫存後端通常是 legacy 系統、無法等比擴容、必須靠 buffer / queue / waiting room 解耦</li>
</ul>
<p>這個負載形狀的兩個主要設計模式：<strong>隱性緩衝</strong>（<a href="/blog/backend/09-performance-capacity/cases/tixcraft-ticketing-flash-sale-spike/" data-link-title="9.C15 拓元 Tixcraft：售票搶購的瞬間爆量架構" data-link-desc="拓元用 DynamoDB 當寫入緩衝 &#43; 傳統伺服器當慢速消費者、承受 100K&#43; 同時選位 &#43; 30 秒從 6 台擴到 800 台">Tixcraft 模式</a>：用 DynamoDB / Kafka 吸收洪峰、後端慢消費）跟<strong>明確排隊</strong>（<a href="/blog/backend/09-performance-capacity/cases/seatgeek-virtual-waiting-room/" data-link-title="9.C16 SeatGeek：DynamoDB &#43; Lambda 打造的虛擬等候室" data-link-desc="SeatGeek 用 DynamoDB 4 張表 &#43; Lambda Bouncer 實作 flash-sale 限流排隊機制、取代第三方 waiting room 服務">SeatGeek 模式</a>：Virtual Waiting Room + token-based queue）。實務常見組合使用 — 入口先排隊、進入後仍用 buffer。</p>
<h2 id="案例覆蓋矩陣">案例覆蓋矩陣</h2>
<p>下表顯示 38 個案例在 <em>服務維度 × 雲商</em> 的覆蓋情況、空格代表待補。</p>
<table>
  <thead>
      <tr>
          <th>服務維度</th>
          <th>AWS</th>
          <th>GCP</th>
          <th>Azure</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DB-OLTP</td>
          <td>C4, C14, C23</td>
          <td>C10</td>
          <td>C32</td>
      </tr>
      <tr>
          <td>DB-KV</td>
          <td>C5, C15, C18, C19, C20, C24, C26, C27, C29</td>
          <td>（待補）</td>
          <td>C11, C21</td>
      </tr>
      <tr>
          <td>DB-Document</td>
          <td>C36, C38</td>
          <td>C37</td>
          <td>（透過 C30 對照）</td>
      </tr>
      <tr>
          <td>Cache</td>
          <td>C6, C25</td>
          <td>C35</td>
          <td>（待補）</td>
      </tr>
      <tr>
          <td>MQ-Stream</td>
          <td>C1 (SQS), C7 (Kinesis)</td>
          <td>C9</td>
          <td>（待補）</td>
      </tr>
      <tr>
          <td>Compute / K8s</td>
          <td>C2, C7, C12, C16, C19, C28</td>
          <td>C8, C34</td>
          <td>C33</td>
      </tr>
      <tr>
          <td>Global Edge</td>
          <td>C13</td>
          <td>（待補）</td>
          <td>（待補）</td>
      </tr>
      <tr>
          <td>Latency 敏感</td>
          <td>C3, C25, C36</td>
          <td>C10, C35</td>
          <td>（待補）</td>
      </tr>
      <tr>
          <td>Data Architecture</td>
          <td>C17</td>
          <td>C22, C31</td>
          <td>C30</td>
      </tr>
  </tbody>
</table>
<p>AWS 25 個 case、GCP 8 個 case（補了 130K-node GKE + Snap KeyDB + Forbes）、Azure 5 個 case。三家覆蓋更平衡。新增 DB-Document 維度後、MongoDB 作為主角的案例（C36 Coinbase / C37 Forbes / C38 Toyota Connected）跟原本 C30 Microsoft 365（MongoDB 遷出 → Cosmos DB）形成完整 document model 案例組。剩餘缺口：Azure cache / global edge / latency、GCP DB-KV / MQ-Stream 加深、GCP / Azure global edge。</p>
<h3 id="負載形狀--雲商-覆蓋">負載形狀 × 雲商 覆蓋</h3>
<table>
  <thead>
      <tr>
          <th>負載形狀</th>
          <th>AWS</th>
          <th>GCP</th>
          <th>Azure</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>predictable-peak</td>
          <td>C1, C13, C27, C29</td>
          <td>C22</td>
          <td>C21</td>
      </tr>
      <tr>
          <td>event-peak</td>
          <td>C2, C4, C7, C28</td>
          <td>-</td>
          <td>-</td>
      </tr>
      <tr>
          <td>surge</td>
          <td>C18</td>
          <td>C8</td>
          <td>C11</td>
      </tr>
      <tr>
          <td>flash-sale-spike</td>
          <td>C15, C16, C17</td>
          <td>-</td>
          <td>-</td>
      </tr>
      <tr>
          <td>low-latency-sustained</td>
          <td>C3, C12, C24, C25, C36</td>
          <td>C10, C34, C35</td>
          <td>-</td>
      </tr>
      <tr>
          <td>sustained-growth</td>
          <td>C5, C6, C14, C19, C20, C23, C26, C38</td>
          <td>C9, C31, C37</td>
          <td>C30, C32, C33</td>
      </tr>
  </tbody>
</table>
<p>flash-sale-spike 是 09 案例庫的核心 differentiator — 雲商案例庫對這個負載形狀的著墨遠勝一般 engineering blog。surge 維度補了 Zoom 之後、跟 Pokemon GO（暫時 surge）跟 Minecraft Earth（地理 surge）形成三種次分類對照。後續若有 GCP / Azure 同類售票案例可補。</p>
<h2 id="規劃中案例第二批">規劃中案例（第二批）</h2>
<p>待 09 主章寫作推進、第二批案例可從下列候選補齊。</p>
<table>
  <thead>
      <tr>
          <th>候選案例</th>
          <th>預期教學重點</th>
          <th>來源</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Disney+ DynamoDB</td>
          <td>每日數十億動作、watch list metadata</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>PayPay 30 億訊息/日</td>
          <td>行動支付的持續高頻 message</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>Capcom DynamoDB</td>
          <td>遊戲業數十億請求、single-digit ms</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>Zomato 90% 延遲下降</td>
          <td>帳務處理、跨資料庫遷移效益</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>Zoom COVID 30x 成長</td>
          <td>1000 萬 → 3 億 DAU、突發長期 sustained</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>FanFight 100 萬寫入/秒</td>
          <td>印度 fantasy sports 體育博彩</td>
          <td><a href="https://aws.amazon.com/dynamodb/customers/">DynamoDB customers</a></td>
      </tr>
      <tr>
          <td>Tubi ScyllaDB → ElastiCache</td>
          <td>ML feature store sub-10ms p99</td>
          <td><a href="https://aws.amazon.com/elasticache/customers/">ElastiCache customers</a></td>
      </tr>
      <tr>
          <td>FanDuel 直播 + 投注</td>
          <td>雙重峰值對齊</td>
          <td><a href="https://aws.amazon.com/solutions/case-studies/fanduel-case-study/">FanDuel case study</a></td>
      </tr>
      <tr>
          <td>Blockchain.com Spanner</td>
          <td>Crypto 高頻交易、強一致全球</td>
          <td><a href="https://cloud.google.com/blog/products/databases/using-cloud-spanner-to-handle-high-throughput-writes/">Spanner blog</a></td>
      </tr>
      <tr>
          <td>Walmart Cosmos DB</td>
          <td>全球零售 KV、跨地區一致性策略</td>
          <td><a href="https://azure.microsoft.com/en-us/blog/azure-cosmos-db-pushing-the-frontier-of-globally-distributed-databases/">Cosmos DB blog</a></td>
      </tr>
      <tr>
          <td>Microsoft 365 Cosmos</td>
          <td>MongoDB → Cosmos 遷移、planet-scale 分析</td>
          <td><a href="https://azure.microsoft.com/en-us/blog/microsoft-365-boosts-usage-analytics-with-azure-cosmos-db/">Cosmos DB Microsoft 365 blog</a></td>
      </tr>
  </tbody>
</table>
<h2 id="engineering-blog-補充候選">Engineering Blog 補充候選</h2>
<p>當 AWS / GCP / Azure 案例缺乏某些工程紀律的深度（例如 chaos hypothesis、cell-based architecture 細節），補引 engineering blog 作為交叉驗證。候選來源：Shopify BFCM、Netflix Tech Blog、Amazon Builders&rsquo; Library、Google SRE Book、LinkedIn Engineering、Stripe Engineering、Cloudflare Blog、Discord Engineering、Uber Engineering、Pinterest Engineering 等。這層不另開資料夾、補在主章「案例對照」段。</p>
<h2 id="案例正文格式">案例正文格式</h2>
<p>每篇案例使用統一結構、方便快速比對。</p>
<ol>
<li><strong>觀察</strong>：客觀數字與事件序列。流量規模、實例配置、延遲分布、成本變化都用引用源的原始數字、不四捨五入。</li>
<li><strong>判讀</strong>：把案例的工程決策翻成主章的問題節點。</li>
<li><strong>策略</strong>：可重用的工程做法、去掉雲端 vendor 特異性。EKS、Auto Scaling、DynamoDB on-demand 等翻成跨平台等效概念。</li>
<li><strong>下一步路由</strong>：往哪個主章或前置案例延伸閱讀。</li>
<li><strong>引用源</strong>：雲端服務商官方 case study URL + 相關 Architecture Blog 連結。</li>
</ol>
<h2 id="tripwire">Tripwire</h2>
<ul>
<li>同一服務維度的 case 超過 5 個時、暫停擴張、改補其他維度。</li>
<li>AWS 案例數字過於行銷、缺工程細節 → 補 AWS Architecture Blog 同主題文章作為交叉驗證。</li>
<li>案例只是「我們用了 X 服務」、沒有具體量化結果 → 不收進案例庫、作為候選參考即可。</li>
<li>同一公司多個案例（例如 Coinbase 還有遷移案例）→ 拆 sub-case 而不是合成單一檔。</li>
<li>GCP / Azure 覆蓋持續落後 AWS 超過 2 倍時 → 主動補 GCP / Azure 案例、不要讓案例庫變成 AWS-only。</li>
</ul>
]]></content:encoded></item><item><title>JMeter → k6：k6 不是 JMeter 的「script 版本」、是 VU model 取代 thread model</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/migrate-from-jmeter/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/k6/migrate-from-jmeter/</guid><description>&lt;p>k6 不是 JMeter 的 &lt;em>「script 版本」&lt;/em>。&lt;/p>
&lt;p>這個誤解是 JMeter → k6 migration 第一週最常見的事故來源。Migration 啟動會議常聽到「JMeter 的 thread group 翻成 k6 的 VU 就好了吧」、然後團隊把 &lt;code>.jmx&lt;/code> 內 100 thread → k6 &lt;code>vus: 100&lt;/code>、跑下去發現 RPS 差三倍、p95 延遲表完全不同形狀、以為 k6 壞了。&lt;/p>
&lt;p>實際上 k6 的 &lt;em>Virtual User (VU)&lt;/em> 跟 JMeter 的 &lt;em>Thread&lt;/em> 是 &lt;em>兩種不同的使用者行為建模方式&lt;/em>：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>JMeter Thread&lt;/strong>：一個 OS thread = 一個 user、&lt;code>numThreads=100&lt;/code> 就 &lt;em>固定 100 個 concurrent 使用者一直跑&lt;/em>、ramp-up period 控制怎麼啟動、無 explicit arrival rate 概念&lt;/li>
&lt;li>&lt;strong>k6 VU&lt;/strong>：一個 goroutine-like execution context、預設 &lt;code>vus&lt;/code> 是 &lt;em>concurrent VU pool&lt;/em>、但 k6 更推薦用 &lt;code>arrival-rate executor&lt;/code> — 直接表達 &lt;em>每秒進來幾個 request&lt;/em>、VU 是 &lt;em>為了達到 arrival rate 動態起的 worker&lt;/em>&lt;/li>
&lt;/ul>
&lt;p>差別在 &lt;em>測量視角&lt;/em>：JMeter 預設視角是 &lt;em>「我有 100 個使用者在用系統」&lt;/em>、k6 預設視角是 &lt;em>「我每秒有 N 個請求進來」&lt;/em>。兩種視角下 &lt;em>同一個系統的瓶頸結果完全不同&lt;/em>：100 concurrent user 模型在 server 慢時 throughput 會自動降（user 等回應）、100 RPS arrival rate 模型在 server 慢時 queue 會累積、暴露 &lt;em>真實 production behavior&lt;/em>（user 不會體諒、會繼續送請求）。&lt;/p>
&lt;p>這篇 migration playbook 不是 schema translation 文（&lt;code>.jmx&lt;/code> 翻成 &lt;code>.js&lt;/code> 只是表面）、是 &lt;em>paradigm shift&lt;/em> — 從 closed-system model（thread）到 open-system model（arrival rate）的視角轉換。&lt;/p>
&lt;h2 id="為什麼是-type-eschema--paradigm-同-high">為什麼是 Type E（schema + paradigm 同 High）&lt;/h2>
&lt;p>跑 &lt;a href="https://tarrragon.github.io/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/#6-%e7%b6%ad-diff-dimension-audit" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6 維 diff dimension audit&lt;/a>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>評&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Schema&lt;/td>
 &lt;td>High&lt;/td>
 &lt;td>&lt;code>.jmx&lt;/code> XML vs JavaScript scenario、test plan 完全不同 file format / DSL&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Operational&lt;/td>
 &lt;td>Medium&lt;/td>
 &lt;td>CLI / distributed run 接近、CI integration 差別大、distributed runner 模型不同&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Paradigm&lt;/td>
 &lt;td>High&lt;/td>
 &lt;td>thread group closed model → arrival rate open model、測試思維不同&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Components&lt;/td>
 &lt;td>Low&lt;/td>
 &lt;td>都是 load test runner、no multi-tool decomposition&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>App change&lt;/td>
 &lt;td>N/A&lt;/td>
 &lt;td>是 test code、不是 production code&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Topology&lt;/td>
 &lt;td>Low&lt;/td>
 &lt;td>都是 CLI / runner 跑、無 sharding&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Schema High + Paradigm High 兩軸 High。按優先序 Schema &amp;gt; Paradigm、預設選 Type A。但對 JMeter → k6 的讀者來說、&lt;em>paradigm shift 才是難關&lt;/em> — schema translation 是工作量、但搞錯 paradigm 會讓 migration 後的測試結果 &lt;em>跟 production 不對應&lt;/em>。所以選 &lt;strong>Type E paradigm shift&lt;/strong> 結構、schema translation 抽出 Phase 1-2 補充。&lt;/p></description><content:encoded><![CDATA[<p>k6 不是 JMeter 的 <em>「script 版本」</em>。</p>
<p>這個誤解是 JMeter → k6 migration 第一週最常見的事故來源。Migration 啟動會議常聽到「JMeter 的 thread group 翻成 k6 的 VU 就好了吧」、然後團隊把 <code>.jmx</code> 內 100 thread → k6 <code>vus: 100</code>、跑下去發現 RPS 差三倍、p95 延遲表完全不同形狀、以為 k6 壞了。</p>
<p>實際上 k6 的 <em>Virtual User (VU)</em> 跟 JMeter 的 <em>Thread</em> 是 <em>兩種不同的使用者行為建模方式</em>：</p>
<ul>
<li><strong>JMeter Thread</strong>：一個 OS thread = 一個 user、<code>numThreads=100</code> 就 <em>固定 100 個 concurrent 使用者一直跑</em>、ramp-up period 控制怎麼啟動、無 explicit arrival rate 概念</li>
<li><strong>k6 VU</strong>：一個 goroutine-like execution context、預設 <code>vus</code> 是 <em>concurrent VU pool</em>、但 k6 更推薦用 <code>arrival-rate executor</code> — 直接表達 <em>每秒進來幾個 request</em>、VU 是 <em>為了達到 arrival rate 動態起的 worker</em></li>
</ul>
<p>差別在 <em>測量視角</em>：JMeter 預設視角是 <em>「我有 100 個使用者在用系統」</em>、k6 預設視角是 <em>「我每秒有 N 個請求進來」</em>。兩種視角下 <em>同一個系統的瓶頸結果完全不同</em>：100 concurrent user 模型在 server 慢時 throughput 會自動降（user 等回應）、100 RPS arrival rate 模型在 server 慢時 queue 會累積、暴露 <em>真實 production behavior</em>（user 不會體諒、會繼續送請求）。</p>
<p>這篇 migration playbook 不是 schema translation 文（<code>.jmx</code> 翻成 <code>.js</code> 只是表面）、是 <em>paradigm shift</em> — 從 closed-system model（thread）到 open-system model（arrival rate）的視角轉換。</p>
<h2 id="為什麼是-type-eschema--paradigm-同-high">為什麼是 Type E（schema + paradigm 同 High）</h2>
<p>跑 <a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/#6-%e7%b6%ad-diff-dimension-audit" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6 維 diff dimension audit</a>：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>評</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Schema</td>
          <td>High</td>
          <td><code>.jmx</code> XML vs JavaScript scenario、test plan 完全不同 file format / DSL</td>
      </tr>
      <tr>
          <td>Operational</td>
          <td>Medium</td>
          <td>CLI / distributed run 接近、CI integration 差別大、distributed runner 模型不同</td>
      </tr>
      <tr>
          <td>Paradigm</td>
          <td>High</td>
          <td>thread group closed model → arrival rate open model、測試思維不同</td>
      </tr>
      <tr>
          <td>Components</td>
          <td>Low</td>
          <td>都是 load test runner、no multi-tool decomposition</td>
      </tr>
      <tr>
          <td>App change</td>
          <td>N/A</td>
          <td>是 test code、不是 production code</td>
      </tr>
      <tr>
          <td>Topology</td>
          <td>Low</td>
          <td>都是 CLI / runner 跑、無 sharding</td>
      </tr>
  </tbody>
</table>
<p>Schema High + Paradigm High 兩軸 High。按優先序 Schema &gt; Paradigm、預設選 Type A。但對 JMeter → k6 的讀者來說、<em>paradigm shift 才是難關</em> — schema translation 是工作量、但搞錯 paradigm 會讓 migration 後的測試結果 <em>跟 production 不對應</em>。所以選 <strong>Type E paradigm shift</strong> 結構、schema translation 抽出 Phase 1-2 補充。</p>
<h2 id="driverdeveloper-ergonomic--ci-gate-friendly">Driver：developer ergonomic + CI gate friendly</h2>
<p>從 JMeter 遷出 k6 的核心拉力是 <em>developer ergonomic + CI 友善</em>：</p>
<ul>
<li><strong><code>.jmx</code> XML 在 git 內 diff 不可讀</strong>：兩個 <code>.jmx</code> PR 的 diff 是 XML attribute reorder noise、reviewer 看不出來實際邏輯改了什麼；JavaScript 是純文字 + AST、PR diff 直接可讀</li>
<li><strong>GUI 學習曲線</strong>：JMeter GUI 不是現代 IDE、不熟的工程師寫一個 scenario 要花半天找對的 sampler 跟 listener；JavaScript 用既有 IDE（VS Code / IntelliJ）、autocomplete + lint + format 全有</li>
<li><strong>CI integration 步驟差</strong>：JMeter 在 CI 跑要 packaging plugin + non-GUI mode + result XML parser；k6 直接 <code>k6 run script.js</code>、result 是 JSON / Prometheus metrics、threshold pass/fail 直接 exit code</li>
<li><strong>單機 VU 容量</strong>：JMeter 單機通常 ~500-1000 thread（受 JVM 跟 OS thread limit）、k6 單機可跑 30K-50K VU（Go runtime + goroutine）、distributed runner 需求降低</li>
<li><strong>Workload model expressiveness</strong>：k6 <code>arrival-rate executor</code> + <code>ramping-vus</code> + <code>constant-vus</code> 三種 executor 直接對應 <em>open system / ramping / closed system</em> 三種測量視角、不像 JMeter 需要組合 Constant Throughput Timer + Synchronizing Timer + thread group 才達到</li>
</ul>
<p>這條 driver 在 <em>QA 團隊 GUI 維護 .jmx asset</em> 的 org 沒拉力（GUI 反而是優勢）、但對 <em>dev / SRE 寫 performance test 進 CI</em> 的 org 是強拉力。Audience 不同、migration value 完全不同。</p>
<h2 id="4-phase-partial-migration不收斂">4-phase partial migration（不收斂）</h2>
<p>Type E 的特徵是 <em>不收斂</em> — 多數 org 不會把 <code>.jmx</code> 全退役、會停在某個 phase 變成 hybrid：</p>
<h3 id="phase-1學會-k6-paradigm不寫實際-test">Phase 1：學會 k6 paradigm（不寫實際 test）</h3>
<p>寫一個 throwaway script 跑當前 production-like API、不為了 migrate、為了搞清楚 k6 paradigm：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">import</span> <span class="nx">http</span> <span class="nx">from</span> <span class="s1">&#39;k6/http&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">check</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;k6&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  <span class="c1">// 不要用 vus: 100、用 arrival rate
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>  <span class="nx">scenarios</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="nx">open_model</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">      <span class="nx">executor</span><span class="o">:</span> <span class="s1">&#39;constant-arrival-rate&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">      <span class="nx">rate</span><span class="o">:</span> <span class="mi">100</span><span class="p">,</span>           <span class="c1">// 每秒 100 request
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span>      <span class="nx">timeUnit</span><span class="o">:</span> <span class="s1">&#39;1s&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">      <span class="nx">duration</span><span class="o">:</span> <span class="s1">&#39;5m&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">      <span class="nx">preAllocatedVUs</span><span class="o">:</span> <span class="mi">200</span><span class="p">,</span> <span class="c1">// 預先準備 VU 數
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>      <span class="nx">maxVUs</span><span class="o">:</span> <span class="mi">500</span><span class="p">,</span>          <span class="c1">// 上限
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="c1"></span>    <span class="p">},</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">  <span class="nx">thresholds</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="nx">http_req_duration</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;p(95)&lt;500&#39;</span><span class="p">],</span> <span class="c1">// p95 &lt; 500ms
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>    <span class="nx">http_req_failed</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;rate&lt;0.01&#39;</span><span class="p">],</span>   <span class="c1">// 失敗率 &lt; 1%
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span>  <span class="p">},</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">  <span class="kr">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="nx">http</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;https://api.example.com/orders&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">  <span class="nx">check</span><span class="p">(</span><span class="nx">res</span><span class="p">,</span> <span class="p">{</span> <span class="s1">&#39;status 200&#39;</span><span class="o">:</span> <span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">r</span><span class="p">.</span><span class="nx">status</span> <span class="o">===</span> <span class="mi">200</span> <span class="p">});</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>對比同一個 test 用 <code>.jmx</code> 寫的形狀、思考 <em>為什麼 arrival rate 跟 thread group 測出來不一樣</em>。這 phase 的目標是 <em>paradigm internalization</em>、不是產出 migration artifact。團隊每個寫 performance test 的人都要過這一關、不能跳。</p>
<p>完成標準：寫的人能講清楚「arrival rate 100 / 5 分鐘」跟「100 thread / 5 分鐘 ramp-up」的 production behavior 差異。</p>
<h3 id="phase-2高價值-critical-path-改-k6gui-留-jmeter">Phase 2：高價值 critical path 改 k6（GUI 留 JMeter）</h3>
<p>選 <em>最常跑 + 最重要</em> 的 1-3 條 scenario 改寫 k6、不全部一次轉。典型候選：</p>
<ul>
<li>Pre-release smoke test（核心 API 的 baseline check）</li>
<li>Nightly regression（per-commit performance gate）</li>
<li>Peak readiness rehearsal scenario（活動前 T-7 跑的 stress test）</li>
</ul>
<p>GUI / QA 團隊維護的 <code>.jmx</code> <em>不動</em> — 那些通常是 multi-protocol（JDBC / JMS / FTP）、不在 k6 適合 scope。</p>
<p>工作主要塊：</p>
<ul>
<li><code>.jmx</code> thread group → k6 scenario executor 的 <em>paradigm-correct</em> 翻譯（不是欄位翻譯）</li>
<li>HTTP request 跟 assertion 翻譯（payload / header / cookies）</li>
<li>CSV data source（JMeter CSV Data Set Config）→ k6 <code>SharedArray</code> from JSON</li>
<li>結果輸出 schema 改變（XML / JTL → JSON / Prometheus / k6 Cloud）</li>
<li>CI integration 重做（GitHub Actions / GitLab CI 直接 <code>k6 run</code>、不需要 packaging）</li>
</ul>
<p>完成標準：critical path 的 k6 baseline 跟 <code>.jmx</code> baseline 數據對比一致（p50 / p95 / throughput 在 10% 誤差內、行為不一致時知道是 paradigm 差還是 bug）。</p>
<h3 id="phase-3qa-團隊雙工具技能hybrid-穩定形態">Phase 3：QA 團隊雙工具技能（hybrid 穩定形態）</h3>
<p>很多 org 停在這個 phase：QA 團隊用 GUI 維護 multi-protocol .jmx（covering JDBC / JMS / LDAP / SOAP / FTP）、dev / SRE 用 k6 維護 HTTP / gRPC / WebSocket performance test in CI。Two-tool stack 不是 broken state、是 <em>not-converged-by-design</em>。</p>
<p>這個 phase 的工作主要塊：</p>
<ul>
<li>文件化：哪類 test 用 k6、哪類用 JMeter、決策樹寫在 team handbook</li>
<li>結果整合：兩個工具的 metrics 都進同一個 Grafana dashboard（k6 → Prometheus 直接、JMeter → InfluxDB / Prometheus exporter）</li>
<li>Release gate 用 k6 為主（CI 整合直接）、JMeter 用於 manual QA campaign / multi-protocol 場景</li>
</ul>
<p>多數 org 不進 Phase 4。</p>
<h3 id="phase-4jmeter-退役少見">Phase 4：JMeter 退役（少見）</h3>
<p>只有當 <em>所有 protocol 都換到 k6 extension</em> 或 <em>捨棄了 multi-protocol coverage</em> 時、才 fully 退役 JMeter。常見路徑：</p>
<ul>
<li>用 k6 xk6 extensions 補 protocol（xk6-sql for JDBC、xk6-kafka for Kafka、xk6-amqp for RabbitMQ、xk6-mqtt for MQTT）</li>
<li>評估每個 extension 的 maturity / community support — xk6 ecosystem 比 JMeter plugin 小很多</li>
<li>接受 part of legacy <code>.jmx</code> test 直接 deprecate（covered by integration test 而非 load test）</li>
</ul>
<p>完成標準：所有 protocol 都在 k6 + xk6 內可表達、<code>.jmx</code> 全部 archive。</p>
<h2 id="5-個-production-踩雷">5 個 production 踩雷</h2>
<h3 id="1-thread-group--vu-直接翻譯最常見phase-2-必踩">1. Thread group → VU 直接翻譯（最常見、Phase 2 必踩）</h3>
<p>把 <code>numThreads=100</code> 翻成 <code>vus: 100</code> 就完事 — 結果 RPS 跟 JMeter 不一致、p95 完全不同形狀。原因：JMeter 100 thread 是 <em>closed model</em>（thread 等回應才送下一個）、k6 <code>vus: 100</code> 預設也是 closed model、但 <em>iteration 結束就立刻送下一個</em>（無 think time）— 兩者的 <em>throughput 行為</em> 差異來自 think time / response time。</p>
<p>修法：</p>
<ul>
<li>不用 <code>vus: N</code>、用 <code>constant-arrival-rate</code> 或 <code>ramping-arrival-rate</code>、直接表達 <em>每秒幾個請求</em></li>
<li>如果一定要 closed model（pre-existing JMeter scenario 對比）、在 default function 內加 <code>sleep(thinkTime)</code> 模擬 JMeter Think Time</li>
</ul>
<h3 id="2-arrival-rate-vs-concurrent-vu-混淆">2. Arrival rate vs concurrent VU 混淆</h3>
<p><code>arrival-rate</code> executor 的 <code>rate: 100</code> 意思是 <em>每秒進來 100 request</em>、<code>preAllocatedVUs: 200</code> 是 <em>預先準備 200 個 VU worker pool</em>。如果 service 變慢（p95 從 100ms 飄到 500ms）、需要的 VU 數會從 100/sec * 0.1s = 10 暴增到 100/sec * 0.5s = 50、<code>preAllocatedVUs</code> 不夠就會 warning「ran out of VUs」、實際 arrival rate 達不到 spec。</p>
<p>修法：</p>
<ul>
<li><code>preAllocatedVUs</code> 設為 <code>maxVUs / 2</code></li>
<li><code>maxVUs</code> 設為 <code>rate * worst_case_response_time_seconds * 5</code>（5x safety margin）</li>
<li>Monitor <code>dropped_iterations</code> metric — 不該 &gt; 0、&gt; 0 表示 worker pool 不夠</li>
</ul>
<h3 id="3-protocol-gapk6-沒原生對應-jmeter-的部分">3. Protocol gap（k6 沒原生對應 JMeter 的部分）</h3>
<p>k6 原生支援 HTTP/1.1 / HTTP/2 / gRPC / WebSocket / SSE。<strong>沒有</strong>原生支援：</p>
<ul>
<li>JDBC（要 xk6-sql extension）</li>
<li>JMS（要 xk6-amqp / xk6-kafka extension）</li>
<li>LDAP（無 extension、要外接 LDAP client）</li>
<li>FTP（無 extension）</li>
<li>SMTP / IMAP / POP3（無 extension）</li>
<li>SOAP（HTTP module 內手寫 XML body、無 helper）</li>
</ul>
<p>如果 <code>.jmx</code> 用了這些 protocol、評估 xk6 extension 成熟度（GitHub stars、recent commit、issue volume）、不成熟就把這些 test 留在 JMeter。</p>
<h3 id="4-結果輸出-schema-改變result-post-processing-全部要重寫">4. 結果輸出 schema 改變（result post-processing 全部要重寫）</h3>
<p>JMeter 預設輸出 JTL XML（per-sample 一行）、有 listener 後處理。k6 預設輸出 stdout summary + optional JSON / CSV / Prometheus / k6 Cloud。如果有既有 <em>result analysis pipeline</em>（從 JTL 拉 data 進 BI tool、產 trend chart）、Phase 2 必須重寫。</p>
<p>修法：</p>
<ul>
<li>評估直接接 Prometheus + Grafana（k6 native）取代既有 BI dashboard</li>
<li>或寫 k6 JSON output → 自家 BI 的 transformation script</li>
</ul>
<h3 id="5-ci-integration-重做distributed-runner-模型不同">5. CI integration 重做（distributed runner 模型不同）</h3>
<p>JMeter 在 CI 跑要：JVM provision、plugin install、<code>.jmx</code> upload、non-GUI mode 跑、JTL 結果 parse、exit code 對應 threshold。k6 在 CI 跑：<code>k6 run script.js</code>、threshold pass / fail 直接 exit code、result 進 Prometheus / k6 Cloud。</p>
<p>看起來 k6 簡單、但有踩雷：</p>
<ul>
<li>Distributed run model 不同：JMeter 用 master-slave、k6 OSS 不內建 distributed、要 Grafana Cloud k6 或自建 k6-operator on Kubernetes</li>
<li>大規模負載（&gt; 50K VU）必須 distributed、Phase 2 評估時要先確認 distributed setup 不是 blocker</li>
<li>CI runner 資源：k6 是 native binary、CPU / memory 用量比 JMeter（JVM）低、但 runner spec 要按 max VU 估</li>
</ul>
<h2 id="protocol-gap-詳表">Protocol gap 詳表</h2>
<table>
  <thead>
      <tr>
          <th>Protocol</th>
          <th>JMeter sampler</th>
          <th>k6 對應</th>
          <th>成熟度 / 替代方案</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HTTP/1.1</td>
          <td>HTTP Request</td>
          <td><code>k6/http</code></td>
          <td>原生、成熟</td>
      </tr>
      <tr>
          <td>HTTP/2</td>
          <td>HTTP/2 sampler</td>
          <td><code>k6/http</code>（auto）</td>
          <td>原生、成熟</td>
      </tr>
      <tr>
          <td>gRPC</td>
          <td>（無原生、要 plugin）</td>
          <td><code>k6/net/grpc</code></td>
          <td>原生、成熟</td>
      </tr>
      <tr>
          <td>WebSocket</td>
          <td>WebSocket sampler（plugin）</td>
          <td><code>k6/ws</code></td>
          <td>原生、成熟</td>
      </tr>
      <tr>
          <td>SSE</td>
          <td>（無原生）</td>
          <td>xk6-sse</td>
          <td>extension、中等</td>
      </tr>
      <tr>
          <td>JDBC</td>
          <td>JDBC Request</td>
          <td>xk6-sql</td>
          <td>extension、不成熟、留 JMeter</td>
      </tr>
      <tr>
          <td>JMS</td>
          <td>JMS sampler</td>
          <td>xk6-amqp / xk6-kafka</td>
          <td>extension、protocol-specific</td>
      </tr>
      <tr>
          <td>LDAP</td>
          <td>LDAP Request</td>
          <td>（無）</td>
          <td>外接 / 留 JMeter</td>
      </tr>
      <tr>
          <td>FTP</td>
          <td>FTP Request</td>
          <td>（無）</td>
          <td>留 JMeter</td>
      </tr>
      <tr>
          <td>SMTP / IMAP</td>
          <td>Mail sampler</td>
          <td>（無）</td>
          <td>留 JMeter</td>
      </tr>
      <tr>
          <td>SOAP / XML-RPC</td>
          <td>SOAP / XML-RPC Request</td>
          <td><code>k6/http</code> 手寫 XML body</td>
          <td>工作量大、留 JMeter</td>
      </tr>
      <tr>
          <td>TCP socket</td>
          <td>TCP sampler</td>
          <td><code>k6/net/tcp</code></td>
          <td>原生但簡單、複雜 protocol 留 JMeter</td>
      </tr>
  </tbody>
</table>
<h2 id="容量與成本對照">容量與成本對照</h2>
<table>
  <thead>
      <tr>
          <th>項目</th>
          <th>JMeter</th>
          <th>k6 OSS</th>
          <th>Grafana Cloud k6</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cost</td>
          <td>Free (Apache)</td>
          <td>Free (Apache 2.0)</td>
          <td>$49+ / mo (Pro)</td>
      </tr>
      <tr>
          <td>單機 VU 容量</td>
          <td>~500-1000 thread</td>
          <td>30K-50K VU</td>
          <td>unlimited（cloud runner）</td>
      </tr>
      <tr>
          <td>Distributed</td>
          <td>master-slave 內建</td>
          <td>不內建、需 k6-operator</td>
          <td>cloud-native</td>
      </tr>
      <tr>
          <td>Result store</td>
          <td>JTL XML（local）</td>
          <td>stdout / JSON / Prom</td>
          <td>cloud retained</td>
      </tr>
      <tr>
          <td>CI integration</td>
          <td>需 packaging</td>
          <td>native CLI</td>
          <td>native + cloud</td>
      </tr>
      <tr>
          <td>Multi-protocol coverage</td>
          <td>廣</td>
          <td>窄（HTTP/gRPC/WS）+ xk6</td>
          <td>同 OSS</td>
      </tr>
  </tbody>
</table>
<p>對 dev-driven CI gate use case：k6 OSS 已經夠用、Grafana Cloud k6 在 <em>跨 region runner + result retention + dashboard 整合</em> 時才有 ROI。對既有 multi-protocol .jmx asset：考慮 Phase 3 hybrid stable state、不要強推 Phase 4。</p>
<h2 id="何時不要切">何時不要切</h2>
<ul>
<li><strong>multi-protocol coverage 是核心需求</strong>：JDBC + JMS + LDAP + FTP 必要、xk6 extension 不夠成熟、留 JMeter</li>
<li><strong>QA 團隊維護 GUI .jmx</strong>：QA 不寫 code、<code>.jmx</code> GUI 是團隊資產、貿然轉 k6 等於 throwaway QA team</li>
<li><strong>既有 multi-year .jmx asset 大量</strong>：500+ scenario 全部翻譯成本 &gt; k6 ergonomic 收益、考慮 Phase 3 stable hybrid</li>
<li><strong>Distributed run 需求極大（&gt; 100K VU）但 ops budget 緊</strong>：k6-operator on Kubernetes 不便宜、Grafana Cloud k6 對應 tier 也不便宜、JMeter master-slave 仍是 cost-effective 選項</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>平行 batch：<a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/migrate-from-pyroscope/" data-link-title="Pyroscope → Datadog Continuous Profiler：profiling deployment lifecycle 各階段 operational ownership 轉手" data-link-desc="Pyroscope → Datadog Continuous Profiler 是 Type C operational hybrid migration — pprof data model 接近、profile lifecycle 五階段（install / instrument / ingest / query / cost）的 ops ownership 從 self-host 轉到 SaaS。本文走 6 維 audit（Operational High 其他 Low）、4-phase migration（operational audit &#43; agent parallel &#43; tag reconcile &#43; cutover）、5 production 踩雷（agent 重複 overhead / tag schema 不一致 / trace_id correlation 斷 / cost 突增 / retention 政策變動）、何時保留 Pyroscope（資料主權 / 內網 / OSS-first / cost sensitive）">Pyroscope → Datadog Profiler</a>（Type C operational hybrid）</li>
<li>同 batch Type E：<a href="/blog/backend/08-incident-response/vendors/pagerduty/migrate-to-incident-io/" data-link-title="PagerDuty → incident.io：「On-call」是個 retconned word、同名不同 contract" data-link-desc="PagerDuty → incident.io 不是 schema translation — 兩家的「on-call」字面相同、contract 不同（alert routing vs IR coordination &#43; Slack-native &#43; retrospective）。本文走 Type E paradigm shift、6 維 audit 顯示 paradigm / schema / operational 三軸 High、用 4-phase partial migration（不收斂、Phase 1-2 多數 org 停留）、5 個 production 踩雷（雙系統 state drift / severity 翻譯失真 / schedule layer 漏 / Slack channel 過載 / retrospective 斷層）、跟 PagerDuty Process Automation / AIOps 沒對應的 capability gap">PagerDuty → incident.io</a>（IR paradigm shift）</li>
<li>上游：<a href="/blog/backend/09-performance-capacity/load-test-tooling/" data-link-title="9.3 壓測工具選型" data-link-desc="k6 / JMeter / Gatling / Locust / Vegeta / Production Replay 的工程選型">9.3 壓測工具選型</a> / <a href="/blog/backend/09-performance-capacity/workload-modeling/" data-link-title="9.2 Workload Modeling" data-link-desc="把 production traffic shape 翻成可重播的壓測模型">9.2 Workload Modeling</a></li>
<li>下游：<a href="/blog/backend/06-reliability/performance-regression-gate/" data-link-title="6.13 Performance Regression Gate" data-link-desc="把效能 baseline 從一次性壓測變成持續對齊的 release gate，涵蓋 baseline 設定、判讀方法、variance 控制與退化定位">6.13 Performance Regression Gate</a>（CI gate integration）</li>
<li>vendor 對照：<a href="/blog/backend/09-performance-capacity/vendors/jmeter/" data-link-title="Apache JMeter" data-link-desc="用 GUI、plugin 與多 protocol sampler 承接企業壓測資產的效能工程工具">JMeter</a> / <a href="/blog/backend/09-performance-capacity/vendors/k6/" data-link-title="k6" data-link-desc="用 scriptable scenario 建立 API、protocol 與 CI 友善壓測的效能工程工具">k6</a> / <a href="/blog/backend/09-performance-capacity/vendors/gatling/" data-link-title="Gatling" data-link-desc="用 JVM DSL、simulation 與 injection profile 表達複雜 scenario 的效能工程工具">Gatling</a> / <a href="/blog/backend/09-performance-capacity/vendors/locust/" data-link-title="Locust" data-link-desc="用 Python user behavior 與 distributed worker 表達高自訂負載模型的效能工程工具">Locust</a></li>
<li>方法論：<a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">Migration Playbook Methodology</a>（Type E paradigm shift 結構說明）</li>
</ul>
]]></content:encoded></item><item><title>Pyroscope → Datadog Continuous Profiler：profiling deployment lifecycle 各階段 operational ownership 轉手</title><link>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/migrate-from-pyroscope/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/migrate-from-pyroscope/</guid><description>&lt;p>Continuous profiling deployment 的 lifecycle 有五階段：&lt;strong>install&lt;/strong>（agent / SDK 部署） → &lt;strong>instrument&lt;/strong>（service / env / version tag 注入） → &lt;strong>ingest&lt;/strong>（profile sample 進 backend store） → &lt;strong>query&lt;/strong>（flame graph / diff / explore） → &lt;strong>cost&lt;/strong>（storage retention / billing）。Pyroscope 跟 Datadog Continuous Profiler 在這五階段的 &lt;em>ops ownership 分布完全不同&lt;/em>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>階段&lt;/th>
 &lt;th>Pyroscope（self-host）&lt;/th>
 &lt;th>Datadog Continuous Profiler&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Install&lt;/td>
 &lt;td>Grafana Alloy / Pyroscope agent / per-language SDK、自己部署&lt;/td>
 &lt;td>Datadog Agent（多半 APM 已部署）、SDK 加 flag&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Instrument&lt;/td>
 &lt;td>tag schema 自己設計&lt;/td>
 &lt;td>用 Datadog 既有 &lt;code>service&lt;/code> / &lt;code>env&lt;/code> / &lt;code>version&lt;/code> tag&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Ingest&lt;/td>
 &lt;td>Pyroscope server（自管 storage / scaling）&lt;/td>
 &lt;td>Datadog SaaS（vendor 管）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Query&lt;/td>
 &lt;td>Grafana datasource explore / flame graph panel&lt;/td>
 &lt;td>Datadog APM 介面、跟 trace / log / metrics deep link&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cost&lt;/td>
 &lt;td>self-host TCO（storage + ops + on-call）&lt;/td>
 &lt;td>按 APM host 計費（profiling 是 add-on）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>從 Pyroscope 遷出 Datadog Continuous Profiler 的本質是 &lt;em>operational ownership 從 self-host 轉手到 SaaS&lt;/em> — pprof data model 跟 flame graph 視覺幾乎一樣、profile diff workflow 接近、&lt;em>差異 90% 在 ops 跟 ecosystem integration&lt;/em>。schema / paradigm 差距小、operational 差距大、就是 Type C operational hybrid 的 signature。&lt;/p>
&lt;h2 id="為什麼是-type-coperational-為主">為什麼是 Type C（operational 為主）&lt;/h2>
&lt;p>跑 &lt;a href="https://tarrragon.github.io/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/#6-%e7%b6%ad-diff-dimension-audit" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6 維 diff dimension audit&lt;/a>：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>評&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Schema&lt;/td>
 &lt;td>Low-Medium&lt;/td>
 &lt;td>pprof 是 industry standard、profile types (CPU / heap / etc) 接近&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Operational&lt;/td>
 &lt;td>High&lt;/td>
 &lt;td>self-host backend storage / retention / scaling → SaaS 全託管&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Paradigm&lt;/td>
 &lt;td>Low&lt;/td>
 &lt;td>都是 pprof-based continuous profiling、diff workflow 接近&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Components&lt;/td>
 &lt;td>Low-Medium&lt;/td>
 &lt;td>都需要 agent + backend、元件數量接近&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>App change&lt;/td>
 &lt;td>Low&lt;/td>
 &lt;td>agent / SDK config 改、code instrumentation 接近&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Topology&lt;/td>
 &lt;td>Low&lt;/td>
 &lt;td>都是 agent → backend 單向 ingest&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Operational = High（其他 Low） → &lt;strong>Type C operational hybrid&lt;/strong>。Type C 結構是 &lt;em>operational audit prefix + 4-phase drop-in cutover&lt;/em> — operational diff 集中在 ingest / cost / retention 三階段、其他階段是 schema-level drop-in。&lt;/p></description><content:encoded><![CDATA[<p>Continuous profiling deployment 的 lifecycle 有五階段：<strong>install</strong>（agent / SDK 部署） → <strong>instrument</strong>（service / env / version tag 注入） → <strong>ingest</strong>（profile sample 進 backend store） → <strong>query</strong>（flame graph / diff / explore） → <strong>cost</strong>（storage retention / billing）。Pyroscope 跟 Datadog Continuous Profiler 在這五階段的 <em>ops ownership 分布完全不同</em>：</p>
<table>
  <thead>
      <tr>
          <th>階段</th>
          <th>Pyroscope（self-host）</th>
          <th>Datadog Continuous Profiler</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Install</td>
          <td>Grafana Alloy / Pyroscope agent / per-language SDK、自己部署</td>
          <td>Datadog Agent（多半 APM 已部署）、SDK 加 flag</td>
      </tr>
      <tr>
          <td>Instrument</td>
          <td>tag schema 自己設計</td>
          <td>用 Datadog 既有 <code>service</code> / <code>env</code> / <code>version</code> tag</td>
      </tr>
      <tr>
          <td>Ingest</td>
          <td>Pyroscope server（自管 storage / scaling）</td>
          <td>Datadog SaaS（vendor 管）</td>
      </tr>
      <tr>
          <td>Query</td>
          <td>Grafana datasource explore / flame graph panel</td>
          <td>Datadog APM 介面、跟 trace / log / metrics deep link</td>
      </tr>
      <tr>
          <td>Cost</td>
          <td>self-host TCO（storage + ops + on-call）</td>
          <td>按 APM host 計費（profiling 是 add-on）</td>
      </tr>
  </tbody>
</table>
<p>從 Pyroscope 遷出 Datadog Continuous Profiler 的本質是 <em>operational ownership 從 self-host 轉手到 SaaS</em> — pprof data model 跟 flame graph 視覺幾乎一樣、profile diff workflow 接近、<em>差異 90% 在 ops 跟 ecosystem integration</em>。schema / paradigm 差距小、operational 差距大、就是 Type C operational hybrid 的 signature。</p>
<h2 id="為什麼是-type-coperational-為主">為什麼是 Type C（operational 為主）</h2>
<p>跑 <a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/#6-%e7%b6%ad-diff-dimension-audit" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6 維 diff dimension audit</a>：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>評</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Schema</td>
          <td>Low-Medium</td>
          <td>pprof 是 industry standard、profile types (CPU / heap / etc) 接近</td>
      </tr>
      <tr>
          <td>Operational</td>
          <td>High</td>
          <td>self-host backend storage / retention / scaling → SaaS 全託管</td>
      </tr>
      <tr>
          <td>Paradigm</td>
          <td>Low</td>
          <td>都是 pprof-based continuous profiling、diff workflow 接近</td>
      </tr>
      <tr>
          <td>Components</td>
          <td>Low-Medium</td>
          <td>都需要 agent + backend、元件數量接近</td>
      </tr>
      <tr>
          <td>App change</td>
          <td>Low</td>
          <td>agent / SDK config 改、code instrumentation 接近</td>
      </tr>
      <tr>
          <td>Topology</td>
          <td>Low</td>
          <td>都是 agent → backend 單向 ingest</td>
      </tr>
  </tbody>
</table>
<p>Operational = High（其他 Low） → <strong>Type C operational hybrid</strong>。Type C 結構是 <em>operational audit prefix + 4-phase drop-in cutover</em> — operational diff 集中在 ingest / cost / retention 三階段、其他階段是 schema-level drop-in。</p>
<h2 id="drivertco--datadog-ecosystem-內-deep-linking">Driver：TCO + Datadog ecosystem 內 deep linking</h2>
<p>從 Pyroscope 遷出 Datadog Profiler 的核心 driver 有兩條：</p>
<p><strong>TCO（total cost of ownership）</strong>：self-host Pyroscope 看起來免費（Apache 2.0）、但實際 ops 成本：</p>
<ul>
<li>Storage：profile sample 大、retention 與 storage cost 需要自己估（每 service 每天可能 1-10 GB）</li>
<li>Scaling：profile ingestion 突增（deploy event / canary rollout 期間）要 storage / ingester 撐住</li>
<li>On-call：Pyroscope server 自己會壞、要 on-call 帶</li>
<li>Ops engineer time：規模成長後可能需要 0.5-1 個 FTE 維護 Grafana stack 內的 Pyroscope</li>
</ul>
<p>對 <em>已經有 Datadog APM 帳單</em> 的 org、profiling 會跟 APM / profiled host 進同一個商務談判與 usage report，不需要額外 ops headcount。這條 TCO 拉力對 50-500 人 eng 規模最強 — 小於 50 人 self-host 也撐得住、大於 500 人 self-host 的 economy of scale 可能開始 favored Pyroscope。</p>
<p><strong>Ecosystem deep linking</strong>：Datadog Profiler 跟 trace / log / metrics <em>在同一個介面</em>、profile span 直接連到 trace span、deploy marker 直接顯示在 flame graph timeline、cross-signal query 不用 wire。Pyroscope 要透過 Grafana datasource correlation 達到類似效果、但需要 Tempo / Loki 已部署 + 手動配 correlation rule、整合精度跟自動程度都不如 Datadog 內建。</p>
<p>這條 driver 對 <em>已是 Datadog-heavy org</em> 強、對 <em>Grafana-heavy org</em> 弱（後者 Pyroscope 才是自然選擇、Datadog Profiler 反而 ecosystem misfit）。</p>
<h2 id="type-c-migration4-phase">Type C migration（4-phase）</h2>
<h3 id="phase-1operational-audit">Phase 1：Operational audit</h3>
<p>確認 Datadog Continuous Profiler 能 cover Pyroscope 當前用途、且 ops ownership 轉移可接受：</p>
<ul>
<li><strong>Language coverage</strong>：當前 Pyroscope 用哪些 SDK？Datadog Profiler 支援 Go / Java / Python / Node / Ruby / .NET / PHP / Rust / C / C++，但每個語言的 profiler type 與啟用方式不同；Erlang 等較小眾語言仍要逐項驗證</li>
<li><strong>Profile type coverage</strong>：Pyroscope 抓的 profile type（CPU / heap / allocation / goroutine / lock / wall time）在 Datadog Profiler 同語言是否都支援？Java 跟 Go 兩家都全、其他語言可能 partial</li>
<li><strong>Retention requirement</strong>：Pyroscope retention 可自管；Datadog Profiler retention 依產品資料保留政策與合約設定，要確認是否滿足既有 long-term baseline / audit 查詢需求</li>
<li><strong>資料主權</strong>：profile data 包含 application function name / line number、有時帶 customer data hint（function 名字暗示 customer-specific 邏輯）— 是否能 send to SaaS？</li>
<li><strong>Cost forecast</strong>：Datadog public pricing 以 profiled host / APM tier 計費，估算時要用實際 host 數、container density、APM plan 與 commit discount 跟 Pyroscope self-host TCO 比</li>
</ul>
<p>完成標準：寫出「Datadog 能 cover、不能 cover、不確定」三欄、不確定欄全部問過 Datadog SE / 用 trial 跑過 production-like load。</p>
<h3 id="phase-2agent-parallel-runprofile-雙寫">Phase 2：Agent parallel run（profile 雙寫）</h3>
<p>Datadog Agent 多半已部署（如果在用 Datadog APM）。Phase 2 在現有 Datadog Agent 開 profiling flag、<em>不關 Pyroscope agent</em>、跑 2-4 週 parallel：</p>
<ul>
<li>設定 <code>DD_PROFILING_ENABLED=true</code>（per service env var）</li>
<li>每個 service SDK init 加對應 profiling enable call（Go: <code>profiler.Start()</code>、Python: <code>import ddtrace.profiling.auto</code>、Java: agent flag 即可）</li>
<li>Pyroscope SDK / Alloy 繼續跑、profile 雙寫到兩家</li>
<li>對比同一個 service / 同一個時間段在 Pyroscope flame graph 跟 Datadog Profiler flame graph、確認 hot path 一致</li>
</ul>
<p>Parallel run 期間的 overhead：兩邊 agent 同時跑 profiling、CPU overhead 大致 2-4%（單一 profiler 通常 1-2%、雙寫 double）、production-acceptable but not free。Phase 2 不要超過 4 週、避免長期 double overhead。</p>
<p>完成標準：每個 production service 在 Datadog Profiler 都有 4 週連續 profile data、跟 Pyroscope flame graph 對比一致。</p>
<h3 id="phase-3tag-schema-reconcile--trace-correlation">Phase 3：Tag schema reconcile + trace correlation</h3>
<p>Pyroscope tag schema（自己設計）跟 Datadog standard tag（<code>service</code> / <code>env</code> / <code>version</code> / <code>host</code>）對齊：</p>
<ul>
<li>Pyroscope tag <code>app=checkout-api</code> → Datadog <code>service:checkout-api</code></li>
<li>Pyroscope tag <code>env=prod-us</code> → Datadog <code>env:prod</code> + <code>region:us-east-1</code></li>
<li>Pyroscope tag <code>git_sha=abc123</code> → Datadog <code>version:abc123</code>（透過 <code>DD_VERSION</code>）</li>
<li>Custom tag（team / business unit）→ Datadog custom tag（透過 SDK config 或 agent label）</li>
</ul>
<p>Trace correlation：Datadog Profiler 自動跟 APM trace 關聯（透過 <code>trace_id</code> injection into profile sample）— Phase 3 要驗證這個 correlation 可用（在 Datadog APM 點 trace span、應該能跳到對應時段 profile）。</p>
<p>Deploy marker：CI 在 deploy 時打 Datadog deployment marker（<code>datadog-ci deployment mark</code> 或 API call）、讓 Profiler diff view 知道 baseline / candidate 邊界。</p>
<p>完成標準：tag schema 1:1 對應、trace → profile deep link 可用、deploy marker 自動推送。</p>
<h3 id="phase-4pyroscope-agent-關掉--server-退役">Phase 4：Pyroscope agent 關掉 + server 退役</h3>
<p>逐步關 Pyroscope agent（per service rollout）：</p>
<ul>
<li>先關低重要性 service（dev / staging / non-critical prod）</li>
<li>觀察 1-2 週、確認沒事故再關下一批</li>
<li>最後關 critical service、留 Pyroscope server 跑 1-2 週空 ingest（rollback 緩衝）</li>
<li>取消 Pyroscope server（decommission storage、release K8s resource、關 on-call rotation）</li>
</ul>
<p>Pyroscope 歷史 profile data 保留策略：</p>
<ul>
<li>多數場景：直接 archive S3 / GCS、未來查得到但不維護 query UI</li>
<li>強合規場景：export Pyroscope flame graph data 為 pprof file 保存（pprof 是長期可讀格式）</li>
</ul>
<p>完成標準：所有 production service 只走 Datadog Profiler、Pyroscope server 取消、TCO 對比驗證符合預期。</p>
<h2 id="5-個-production-踩雷">5 個 production 踩雷</h2>
<h3 id="1-兩家-agent-同時跑造成-production-overhead">1. 兩家 agent 同時跑造成 production overhead</h3>
<p>Phase 2 parallel run 期間 CPU overhead 2-4%、預期內。但有些 service 設定錯誤（例如 sampling rate 預設都拉高）變成 6-10% overhead、p99 飄升、誤判為 Datadog Profiler 自己的問題。修法是 <em>parallel run 期間 Pyroscope sampling rate 降低 50%</em>（已經有歷史 baseline、不需要全採）、且 Phase 2 不要在 peak event 期間跑。</p>
<h3 id="2-tag-schema-不一致導致-historic-baseline-對不上">2. Tag schema 不一致導致 historic baseline 對不上</h3>
<p>Pyroscope tag <code>app=checkout-api</code> 跟 Datadog <code>service:checkout-api</code> 都指同一個 service、但 Datadog 內 <em>historic profile</em> 沒有 <code>app</code> tag、所以從 Pyroscope 視角看 baseline 跟 Datadog 視角看 baseline <em>是不同的時段切片</em>。Release regression 比較時用錯 baseline、會誤判 release 沒問題（實際 baseline 不對應）。修法是 Phase 3 明確記錄 <em>Datadog Profiler 的 baseline 起算時間是 Phase 2 開始日</em>、Pyroscope 歷史不直接搬入比較。</p>
<h3 id="3-trace_id-correlation-斷phase-3-最常見">3. Trace_id correlation 斷（Phase 3 最常見）</h3>
<p>Datadog Profiler 自動關聯 trace 的前提是 <em>同一個 Datadog Agent + APM SDK 注入 trace_id</em>。如果 service 用 OpenTelemetry SDK + Datadog Agent（OTel-first 配置）、trace_id 注入方式不同、profile 跟 trace 可能無法自動 correlate。修法是 <em>確認所有 service 用 Datadog SDK 或正確配 OTel-to-Datadog converter</em>、在 Datadog APM 介面 random 抽 10 個 trace 驗證 profile correlation 是否 wire 通。</p>
<h3 id="4-cost-突增phase-4-後常見">4. Cost 突增（Phase 4 後常見）</h3>
<p>關掉 Pyroscope agent 後、Datadog Profiler 變成 sole profile source、ingest volume 上升、Datadog bill 比預估高 30-50%。原因通常是：</p>
<ul>
<li>Profile sampling rate 不小心開太高（部分 service config 沒對齊）</li>
<li>Custom tag 太多（每個 unique tag combination 增加 indexing cost）</li>
<li>Profile event 量比預估高（service count × sampling rate × profile types）</li>
</ul>
<p>修法是 Phase 1 cost forecast 要保留 30% buffer、且 Phase 4 完成後立即跑 Datadog usage report 確認 actual 跟 forecast 對比。</p>
<h3 id="5-retention--baseline-政策變動造成歷史-query-斷層">5. Retention / baseline 政策變動造成歷史 query 斷層</h3>
<p>Pyroscope 自管 retention 可以設成配合內部 storage 與 compliance policy；Datadog Profiler 的 retention 依產品資料保留政策與合約設定。真正的風險不是固定「7 天 vs 90 天」，而是 <em>既有 baseline 查詢習慣是否還成立</em>：原 Pyroscope user 可能習慣查特定 release 前後的 flame graph、Datadog 端則要看 profile tag、deployment marker 與保留政策能否支援同樣查詢。修法是 Phase 1 明確列出「要查多久前、用什麼 tag 找、誰有權限看」三個問題，超出 profile retention 的長期 trend 改用 Datadog metrics-derived signal（cumulative CPU% / memory growth rate）或保留 Pyroscope archive。</p>
<h2 id="capability-對照">Capability 對照</h2>
<table>
  <thead>
      <tr>
          <th>能力</th>
          <th>Pyroscope（self-host）</th>
          <th>Datadog Continuous Profiler</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Language SDK 覆蓋</td>
          <td>Go / Java / Python / Node / Ruby / .NET / Rust / PHP</td>
          <td>Go / Java / Python / Node / Ruby / .NET / PHP / Rust / C / C++</td>
      </tr>
      <tr>
          <td>Profile type（CPU / heap / lock / etc）</td>
          <td>全（依語言 SDK 而定）</td>
          <td>全（依語言 SDK 而定）</td>
      </tr>
      <tr>
          <td>Flame graph diff workflow</td>
          <td>Grafana panel</td>
          <td>Datadog Profile Comparison</td>
      </tr>
      <tr>
          <td>Trace correlation</td>
          <td>手動配 Grafana correlation rule</td>
          <td>自動（trace_id injection）</td>
      </tr>
      <tr>
          <td>Deploy marker</td>
          <td>手動</td>
          <td>datadog-ci 自動</td>
      </tr>
      <tr>
          <td>Retention</td>
          <td>自管（無上限、cost 自負）</td>
          <td>依 Datadog retention policy / 合約設定</td>
      </tr>
      <tr>
          <td>資料主權</td>
          <td>完全自管</td>
          <td>SaaS（profile 出境）</td>
      </tr>
      <tr>
          <td>Ops ownership</td>
          <td>自管（storage / scaling / on-call）</td>
          <td>Vendor</td>
      </tr>
      <tr>
          <td>Cost model</td>
          <td>self-host TCO</td>
          <td>profiled host / APM tier / commit discount</td>
      </tr>
      <tr>
          <td>Cross-signal query</td>
          <td>Grafana cross-datasource</td>
          <td>Datadog native（trace / log / profile / metrics 同一 query bar）</td>
      </tr>
  </tbody>
</table>
<h2 id="何時不要切保留-pyroscope">何時不要切（保留 Pyroscope）</h2>
<ul>
<li><strong>資料主權 / compliance 不允許 profile data 出境</strong>：金融 / 醫療 / 政府 / 國防、保留 Pyroscope self-host</li>
<li><strong>內網 / air-gap 部署</strong>：物理上連不到 Datadog SaaS、保留 Pyroscope</li>
<li><strong>OSS-first / vendor neutrality policy</strong>：org 政策不允許 vendor lock-in profiling、保留 Pyroscope</li>
<li><strong>規模超大（&gt; 500 APM host）</strong>：Datadog Profiler add-on cost × host 數可能超過 Pyroscope self-host TCO、計算交叉點</li>
<li><strong>Long retention / 自訂 archive 強需求</strong>：若 profile data 必須照內部 retention policy 長期保存、保留 Pyroscope 或建立 export / archive 流程</li>
<li><strong>Datadog 不支援的語言或 profiler type</strong>：Erlang、特定 runtime 或特定 profile type 若 Datadog 無法覆蓋，保留 Pyroscope 為對應 service profiling</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>平行 batch：<a href="/blog/backend/09-performance-capacity/vendors/k6/migrate-from-jmeter/" data-link-title="JMeter → k6：k6 不是 JMeter 的「script 版本」、是 VU model 取代 thread model" data-link-desc="JMeter → k6 是 Type E paradigm shift、不是把 .jmx XML 翻成 JavaScript — VU (virtual user) model 跟 thread group model 是兩種對「使用者行為」不同的建模方式。本文走 6 維 audit（Schema High / Paradigm High / Operational Medium）、釐清反向定義、4-phase partial migration（多數 org 停 Phase 2-3 hybrid）、5 production 踩雷（thread group 翻譯失真 / arrival rate vs concurrent VU 混淆 / protocol gap / 結果 schema 改 / CI integration 重做）、protocol gap（JDBC / JMS / LDAP 在 k6 沒原生對應）、何時不要切">JMeter → k6</a>（Type E paradigm shift）</li>
<li>同 batch Type C：（待補、本篇是 batch 唯一 Type C）</li>
<li>上游：<a href="/blog/backend/09-performance-capacity/performance-observability/" data-link-title="9.8 效能可觀測性" data-link-desc="saturation metric、USE / RED method、cost dashboard">9.8 Performance Observability</a> / <a href="/blog/backend/04-observability/continuous-profiling/" data-link-title="4.9 Continuous Profiling" data-link-desc="把 CPU / memory / lock profile 從一次性除錯升級為持續訊號">4.9 Continuous Profiling</a></li>
<li>下游：<a href="/blog/backend/09-performance-capacity/improvement-loop/" data-link-title="9.9 Performance Improvement Loop" data-link-desc="壓測 → profile → fix → re-test → release gate 的閉環">9.9 Performance Improvement Loop</a>（profile diff 接入 release regression workflow）</li>
<li>vendor 對照：<a href="/blog/backend/09-performance-capacity/vendors/pyroscope/" data-link-title="Pyroscope" data-link-desc="用 Grafana 生態與開源 profiling backend 建立可自管 profile diff 與 flame graph 的工具">Pyroscope</a> / <a href="/blog/backend/09-performance-capacity/vendors/datadog-continuous-profiler/" data-link-title="Datadog Continuous Profiler" data-link-desc="用 SaaS APM 整合、deployment marker 與 profile diff 支援 release regression 定位的 profiling 工具">Datadog Continuous Profiler</a> / <a href="/blog/backend/09-performance-capacity/vendors/parca/" data-link-title="Parca" data-link-desc="用 eBPF 與開源 continuous profiling 平台建立 infrastructure-wide profile evidence 的工具">Parca</a></li>
<li>方法論：<a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">Migration Playbook Methodology</a>（Type C operational hybrid 結構說明）</li>
</ul>
]]></content:encoded></item></channel></rss>