<?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>Kv on Tarragon</title><link>https://tarrragon.github.io/blog/tags/kv/</link><description>Recent content in Kv on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 13 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/kv/index.xml" rel="self" type="application/rss+xml"/><item><title>DynamoDB</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/dynamodb/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/dynamodb/</guid><description>&lt;p>DynamoDB 是 AWS managed key-value store、用 partition-based scaling 提供 &lt;em>可預測 P99 latency&lt;/em> 跟 &lt;em>elastic capacity&lt;/em>。Amazon 自家 Ads（9000 萬 RPS）、Disney+、Zoom（COVID 30x surge）、Capcom（billions of requests / single-digit ms）都用 DynamoDB 撐核心 workload — 它是目前公開 case 最多、最被驗證的 managed KV 服務。&lt;/p>
&lt;h2 id="教學路線access-pattern-與-partition-capacity">教學路線：Access pattern 與 partition capacity&lt;/h2>
&lt;p>DynamoDB 服務頁的教學目標是把 access pattern 轉成 partition key、sort key、GSI、capacity mode 與 global tables 的設計判斷。讀者讀完後要能從查詢路徑反推資料模型，並估算 hot partition、成本與 consistency trade-off。&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>Access pattern&lt;/td>
 &lt;td>查詢形狀如何先於資料表設計&lt;/td>
 &lt;td>定位、適用場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Partition key&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">hot partition&lt;/a>、single-digit latency、GSI 如何成為設計核心&lt;/td>
 &lt;td>容量規劃要點、常見陷阱&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Capacity mode&lt;/td>
 &lt;td>on-demand、provisioned、auto scaling 如何對應高峰與成本&lt;/td>
 &lt;td>容量特性、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Global tables&lt;/td>
 &lt;td>multi-region availability 與 consistency 會付出哪些代價&lt;/td>
 &lt;td>適用場景、跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時回 SQL、MongoDB、Cosmos DB 或 cache / queue&lt;/td>
 &lt;td>不適用場景、下一步路由&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位partition-based-kv-scale">定位：partition-based KV scale&lt;/h2>
&lt;p>DynamoDB 的核心設計是「partition 透明、capacity 抽象化」。不像 MongoDB 要主動 shard、不像 Cassandra 要管 ring topology、不像 PostgreSQL 要選 instance type — DynamoDB 把所有底層 scaling 隱藏在 RCU / WCU 抽象層後。&lt;/p>
&lt;p>&lt;strong>容量單位&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>1 RCU（Read Capacity Unit）= 1 strongly consistent read of 4KB / sec、2 eventually consistent reads&lt;/li>
&lt;li>1 WCU（Write Capacity Unit）= 1 write of 1KB / sec&lt;/li>
&lt;li>每個 partition 上限：3000 RCU / 1000 WCU&lt;/li>
&lt;li>總容量 = partition 數量 × 每 partition 上限（partition 數量透明、vendor 自動管理）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>延遲特性&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>single-digit millisecond p99 latency（read / write）&lt;/li>
&lt;li>同 region 跨 AZ replication 內建、預設 eventually consistent reads&lt;/li>
&lt;li>strongly consistent reads 依 region 內 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum&lt;/a> 成立，跨 region 讀寫要看 Global Tables 語意&lt;/li>
&lt;/ul>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/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 選擇">1.10 KV / Document DB 容量規劃&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> 的 partition 設計章節。&lt;/p></description><content:encoded><![CDATA[<p>DynamoDB 是 AWS managed key-value store、用 partition-based scaling 提供 <em>可預測 P99 latency</em> 跟 <em>elastic capacity</em>。Amazon 自家 Ads（9000 萬 RPS）、Disney+、Zoom（COVID 30x surge）、Capcom（billions of requests / single-digit ms）都用 DynamoDB 撐核心 workload — 它是目前公開 case 最多、最被驗證的 managed KV 服務。</p>
<h2 id="教學路線access-pattern-與-partition-capacity">教學路線：Access pattern 與 partition capacity</h2>
<p>DynamoDB 服務頁的教學目標是把 access pattern 轉成 partition key、sort key、GSI、capacity mode 與 global tables 的設計判斷。讀者讀完後要能從查詢路徑反推資料模型，並估算 hot partition、成本與 consistency trade-off。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Access pattern</td>
          <td>查詢形狀如何先於資料表設計</td>
          <td>定位、適用場景</td>
      </tr>
      <tr>
          <td>Partition key</td>
          <td><a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">hot partition</a>、single-digit latency、GSI 如何成為設計核心</td>
          <td>容量規劃要點、常見陷阱</td>
      </tr>
      <tr>
          <td>Capacity mode</td>
          <td>on-demand、provisioned、auto scaling 如何對應高峰與成本</td>
          <td>容量特性、案例對照</td>
      </tr>
      <tr>
          <td>Global tables</td>
          <td>multi-region availability 與 consistency 會付出哪些代價</td>
          <td>適用場景、跟其他 vendor 的取捨</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時回 SQL、MongoDB、Cosmos DB 或 cache / queue</td>
          <td>不適用場景、下一步路由</td>
      </tr>
  </tbody>
</table>
<h2 id="定位partition-based-kv-scale">定位：partition-based KV scale</h2>
<p>DynamoDB 的核心設計是「partition 透明、capacity 抽象化」。不像 MongoDB 要主動 shard、不像 Cassandra 要管 ring topology、不像 PostgreSQL 要選 instance type — DynamoDB 把所有底層 scaling 隱藏在 RCU / WCU 抽象層後。</p>
<p><strong>容量單位</strong>：</p>
<ul>
<li>1 RCU（Read Capacity Unit）= 1 strongly consistent read of 4KB / sec、2 eventually consistent reads</li>
<li>1 WCU（Write Capacity Unit）= 1 write of 1KB / sec</li>
<li>每個 partition 上限：3000 RCU / 1000 WCU</li>
<li>總容量 = partition 數量 × 每 partition 上限（partition 數量透明、vendor 自動管理）</li>
</ul>
<p><strong>延遲特性</strong>：</p>
<ul>
<li>single-digit millisecond p99 latency（read / write）</li>
<li>同 region 跨 AZ replication 內建、預設 eventually consistent reads</li>
<li>strongly consistent reads 依 region 內 <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a> 成立，跨 region 讀寫要看 Global Tables 語意</li>
</ul>
<p>詳見 <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 選擇">1.10 KV / Document DB 容量規劃</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> 的 partition 設計章節。</p>
<h2 id="適用場景">適用場景</h2>
<p>按公開 case 提煉的典型適用場景：</p>
<p><strong>1. KV / single-table design 為主的查詢</strong>：</p>
<ul>
<li>用 partition key + sort key 設計、單筆 / 範圍查詢</li>
<li>查詢路徑固定，JOIN / ad-hoc query 需求低</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 萬 reads/sec + 500 萬 writes/sec、99.999% 可用</li>
</ul>
<p><strong>2. 可預測 sub-10ms p99 latency 需求</strong>：</p>
<ul>
<li>遊戲後端（玩家狀態、戰績）</li>
<li>內容平台 metadata（watchlist、播放進度）</li>
<li>對應案例：<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>（billions of requests / single-digit ms）、<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>（每日數十億 actions）</li>
</ul>
<p><strong>3. 流量 spiky 或 surge 場景</strong>：</p>
<ul>
<li>on-demand capacity 自動吸收 burst</li>
<li>不需 connection pool（HTTP API、無 stateful connection）</li>
<li>對應案例：<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 1000 萬 → 3 億 DAU）、<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、售票搶購）、<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 limit → 改 DynamoDB）</li>
</ul>
<p><strong>4. 大規模通知 / 訊息系統</strong>：</p>
<ul>
<li>TTL 自動清理過期 records</li>
<li>partition key 用 user_id / message_id 天然均勻</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>（行動支付每日 3 億訊息）</li>
</ul>
<p><strong>5. 5 個 9 可用性 B2B SaaS</strong>：</p>
<ul>
<li>multi-region Global Tables active-active</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</a>（99.999% 跨 15 region）</li>
</ul>
<p><strong>6. 高吞吐 budget 敏感</strong>：</p>
<ul>
<li>on-demand 適合突發、provisioned 適合 sustained</li>
<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>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. 複雜 ad-hoc query / JOIN</strong>：</p>
<ul>
<li>DynamoDB query 以 partition key + sort key 為主，JOIN-heavy workload 交給 SQL 系統</li>
<li>PartiQL 提供 SQL-like 語法但底層還是 KV、複雜 query 會 scan 全表</li>
<li>替代：用 Aurora / PostgreSQL / Spanner</li>
</ul>
<p><strong>2. 強一致 multi-row transaction</strong>：</p>
<ul>
<li>DynamoDB Transaction 支援 25 個 item 的 ACID</li>
<li>超過 25 個 item 或跨 region 的 transaction 要改用 workflow / SQL / distributed SQL 設計</li>
<li>替代：Spanner / Aurora DSQL / CockroachDB</li>
</ul>
<p><strong>3. 跨雲需求</strong>：</p>
<ul>
<li>DynamoDB only on AWS、vendor lock-in</li>
<li>替代：Cosmos DB（Azure global NoSQL）、自管 ScyllaDB</li>
</ul>
<p><strong>4. 大物件 / 文件儲存</strong>：</p>
<ul>
<li>單一 item 最大 400KB</li>
<li>大物件用 S3、metadata 用 DynamoDB</li>
</ul>
<p><strong>5. 預算極度敏感 + 流量穩定</strong>：</p>
<ul>
<li>流量高度 predictable 的 sustained workload，自管 PostgreSQL / MySQL 可能更便宜</li>
<li>DynamoDB 的 managed 跟 elastic 是有溢價的</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs MongoDB（自管或 Atlas）</strong>：</p>
<ul>
<li>DynamoDB：managed、partition 透明、application 主要管理 partition key，有 5 個 9 SLA</li>
<li>MongoDB：彈性高、可自管、aggregation pipeline 強、跨雲可用</li>
<li>選 DynamoDB：AWS-only、想轉移 operation、partition 設計簡單可預測</li>
<li>選 MongoDB：跨雲、複雜 query、ad-hoc analysis</li>
</ul>
<p><strong>vs Aurora（同 AWS）</strong>：</p>
<ul>
<li>DynamoDB：KV、partition 擴展、無 connection pool 限制</li>
<li>Aurora：SQL（PostgreSQL / MySQL）、有 transaction、ad-hoc query</li>
<li>詳見 <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 選擇">1.10 KV / Document DB 容量規劃</a> 跟 <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 case</a> — connection limit 是 RDB vs DynamoDB 的關鍵差異</li>
</ul>
<p><strong>vs Redis（含 ElastiCache）作為 KV 替代</strong>：</p>
<ul>
<li>DynamoDB：持久化、單 item 持久查得到、有 TTL 但物件不會自動失蹤</li>
<li>Redis：純記憶體、預設不持久（MemoryDB 例外）、快但易失</li>
<li>選 DynamoDB：data 是 <a href="/blog/backend/knowledge-cards/source-of-truth/" data-link-title="Source of Truth" data-link-desc="說明正式資料來源如何決定資料判斷、修復與一致性責任">source of truth</a>，需要持久保存</li>
<li>選 Redis：data 是 cache、丟了能 recompute</li>
</ul>
<p><strong>vs Cosmos DB（cross-cloud）</strong>：</p>
<ul>
<li>DynamoDB：AWS-only、KV 為主、無 multi-model</li>
<li>Cosmos DB：Azure-only、multi-model（SQL / Mongo / Cassandra / Gremlin / Table）、5 個 <a href="/blog/backend/knowledge-cards/consistency-level/" data-link-title="Consistency Level" data-link-desc="資料系統對讀寫一致性語意的可選擇層級">consistency level</a>s</li>
<li>選 DynamoDB：AWS 生態、KV 純粹</li>
<li>選 Cosmos DB：Azure 生態、需要 multi-model、需要 multi-region active-active write</li>
</ul>
<p><strong>vs Cassandra / ScyllaDB（self-managed）</strong>：</p>
<ul>
<li>DynamoDB：managed、5 個 9 SLA、無 ops 負擔</li>
<li>Cassandra / ScyllaDB：可自管、更深 tuning、跨雲可用</li>
<li>選 DynamoDB：團隊想把 DBA / SRE 操作責任交給 AWS</li>
<li>選 Cassandra / ScyllaDB：有 DBA、想 lock-in 風險低、需要極限 throughput tuning</li>
</ul>
<p><strong>vs PostgreSQL（SQL baseline）</strong>：</p>
<ul>
<li>詳見 <a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL 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 選擇">1.10 KV / Document DB 容量規劃</a> 的 connection model 對比</li>
<li>摘要：DynamoDB 是 <em>access pattern 固定 + 需要避免 connection-bound</em> 的選項；ad-hoc query / 複雜 transaction 留 PostgreSQL</li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p>從 09 案例庫提煉的 DynamoDB 容量規劃實踐：</p>
<p><strong>1. partition key 設計是命脈</strong>：</p>
<ul>
<li>partition key 不均 → hot partition → 名義容量達不到</li>
<li>composite key（event_id + user_id_hash）強制分散</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 靠 partition 均勻、<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> 用 composite key 分散售票流量</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>
<p><strong>2. on-demand vs provisioned 選型</strong>：</p>
<ul>
<li>流量 peak/avg &gt; 5x → on-demand</li>
<li>sustained predictable → provisioned + auto-scaling</li>
<li>知名大事件（Black Friday）→ provisioned baseline + scheduled scale-up</li>
<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> — on-demand 解放 over-provisioning</li>
</ul>
<p><strong>3. Global Tables（multi-region active-active）</strong>：</p>
<ul>
<li>每個 region 都能寫、conflict resolution 用 LWW</li>
<li>容量在每個 region 獨立配置，全球總和要按 region 分別估算</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</a> — 15 region 達 5 個 9 可用</li>
</ul>
<p><strong>4. DAX（DynamoDB Accelerator）</strong>：</p>
<ul>
<li>DynamoDB 前置 in-memory cache</li>
<li>從 single-digit ms 降到 microsecond</li>
<li>適合超高 read 重複的 workload（同樣 key 大量讀）</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> 用 DAX 加速</li>
</ul>
<p><strong>5. Streams + Lambda</strong>：</p>
<ul>
<li>DynamoDB 寫入 → Stream event → Lambda 處理</li>
<li>適合 CDC、event-driven 工作流</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> 用 Stream 把 DynamoDB 當 durable queue 給 legacy server 消費</li>
</ul>
<h2 id="anti-recommendation-與升級路由">Anti-recommendation 與升級路由</h2>
<p>DynamoDB 的 managed elasticity 會讓團隊忽略 access pattern 的前置成本。這一段先說何時維持單純 table / index，再說何時升級到 Global Tables、DAX、Streams、或改回 SQL / document DB。</p>
<table>
  <thead>
      <tr>
          <th>機制 / 路線</th>
          <th>維持簡單設計的條件</th>
          <th>升級訊號</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>單 table / 少量 GSI</td>
          <td>access pattern 穩定、partition key 均勻、query 成本可預測</td>
          <td>新查詢路徑大量增加、GSI 成本壓過主表、hot partition 出現</td>
          <td><a href="/blog/backend/knowledge-cards/hot-partition/" data-link-title="Hot Partition" data-link-desc="說明分散式 KV / OLTP 中、單一 partition 流量遠超其他的容量問題">Hot Partition</a>、<a href="/blog/backend/knowledge-cards/workload-model/" data-link-title="Workload Model" data-link-desc="描述 production traffic 形狀的可重播模型 — 容量規劃跟壓測的共同輸入">Workload Model</a></td>
      </tr>
      <tr>
          <td>On-demand capacity</td>
          <td>peak/avg 差距大、流量有事件性 surge</td>
          <td>sustained traffic 穩定、成本曲線可預測</td>
          <td><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></td>
      </tr>
      <tr>
          <td>Provisioned + autoscaling</td>
          <td>baseline 穩定、團隊能預測高峰</td>
          <td>黑五、售票、直播等已知大事件需要預先升配</td>
          <td><a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling</a></td>
      </tr>
      <tr>
          <td>DAX</td>
          <td>read 重複率低、single-digit ms 已足夠</td>
          <td>同 key 超高讀取、需要 microsecond read</td>
          <td><a href="/blog/backend/knowledge-cards/cache-aside/" data-link-title="Cache Aside" data-link-desc="說明 application 如何在讀取時自行管理快取與正式資料來源">Cache Aside</a>、<a href="/blog/backend/knowledge-cards/stale-data/" data-link-title="Stale Data" data-link-desc="說明過期資料在快取、replica 與衍生資料中的產品影響">Stale Data</a></td>
      </tr>
      <tr>
          <td>Global Tables</td>
          <td>single-region availability 已足夠</td>
          <td>RTO/RPO、region residency 或 active-active write 是產品需求</td>
          <td><a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a>、<a href="/blog/backend/knowledge-cards/consistency-level/" data-link-title="Consistency Level" data-link-desc="資料系統對讀寫一致性語意的可選擇層級">Consistency Level</a></td>
      </tr>
      <tr>
          <td>SQL / document DB</td>
          <td>access pattern 可提前列舉</td>
          <td>ad-hoc query、JOIN、multi-row transaction 或 document traversal 成主題</td>
          <td><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>、<a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor</a></td>
      </tr>
  </tbody>
</table>
<p>DynamoDB 的簡單路徑是先把每個 query path 寫成契約。table、partition key、sort key、GSI 與 TTL 都應從 access pattern 反推；如果需求仍在探索期，PostgreSQL 或 MongoDB 可能提供更低的變更成本。</p>
<p>Global Tables 的升級路徑要先處理 conflict 與讀寫語意。它提供 multi-region availability，但 LWW conflict resolution、region-local capacity 與跨 region reconciliation 仍要由 application contract 承擔。</p>
<h2 id="deep-article已完成">Deep article（已完成）</h2>
<p>本 vendor 現有 deep article 覆蓋 DynamoDB 從 access pattern 反推到寫一致性、讀加速、事件驅動與資料生命週期的核心 production 議題：</p>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>對應 production 議題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>適用度 4 軸前置判讀 + access pattern 反推 PK/SK + durable queue</td>
          <td><a href="single-table-design-pattern/">single-table-design-pattern</a></td>
          <td>適用度判讀 + control plane vs data plane + 9.C15 Tixcraft Stream durable queue</td>
      </tr>
      <tr>
          <td>1000 WCU partition 上限 + composite key / calculated shard 修法</td>
          <td><a href="partition-key-antipatterns/">partition-key-antipatterns</a></td>
          <td>9.C15 Tixcraft 6750x 擴展、mode × partition 在 provisioned / on-demand 表現</td>
      </tr>
      <tr>
          <td>GSI / LSI projection 三型、sparse、DAX 補位</td>
          <td><a href="gsi-lsi-design/">gsi-lsi-design</a></td>
          <td>GSI 自己會 hot partition、Capcom derive vs Lemino case fact 分層</td>
      </tr>
      <tr>
          <td>6 軸 capacity mode 決策 + auto-scaling 邊界 + cost crossover</td>
          <td><a href="on-demand-vs-provisioned/">on-demand-vs-provisioned</a></td>
          <td>Zomato 50% 成本下降、Zoom 30x permanent surge、Amazon Ads sustained workload</td>
      </tr>
      <tr>
          <td>Multi-region active-active + LWW conflict + cross-device sync</td>
          <td><a href="global-tables-conflict/">global-tables-conflict</a></td>
          <td>Genesys 99.999% / 15 region、Disney+ 跨裝置同步</td>
      </tr>
      <tr>
          <td>Strongly / eventually consistent read 取捨</td>
          <td><a href="consistency-model-optimization/">consistency-model-optimization</a></td>
          <td>read consistency 成本選擇</td>
      </tr>
      <tr>
          <td>跨 item 原子性 + conditional write + optimistic lock + idempotency</td>
          <td><a href="transactions-conditional-writes/">transactions-conditional-writes</a></td>
          <td>雙寫不一致、超賣 race、transaction 2x 成本邊界</td>
      </tr>
      <tr>
          <td>DAX cluster + item/query cache + write-through + invalidation 邊界</td>
          <td><a href="dax-caching-strategy/">dax-caching-strategy</a></td>
          <td>讀峰值 p99 尖刺、query cache 只靠 TTL 失效、strong read 繞過 cache</td>
      </tr>
      <tr>
          <td>Streams CDC + shard 順序 + Lambda 消費 + 失敗處理</td>
          <td><a href="streams-lambda-event-driven/">streams-lambda-event-driven</a></td>
          <td>下游即時反應、at-least-once 冪等、毒丸 record 隔離</td>
      </tr>
      <tr>
          <td>TTL 自動過期 + 48h 刪除延遲 + 過期仍可讀 + storage 成本</td>
          <td><a href="ttl-data-lifecycle/">ttl-data-lifecycle</a></td>
          <td>9.C26 PayPay 每日上億訊息 storage 清理、過期未刪 item 讀取陷阱</td>
      </tr>
  </tbody>
</table>
<p>Migration playbook：<a href="migrate-rds-mongodb-to-dynamodb/">從 RDS / MongoDB 遷移到 DynamoDB</a>（Type E paradigm shift、access-pattern-first 重建模 + 混合架構 + Zomato cost crossover）。</p>
<p>跨 vendor entry：先看 <a href="../db3-vendor-selection/">DB3 vendor selection</a>（MongoDB / DynamoDB / Cosmos DB 三方選型 + workload shape 前置判讀），再進本 vendor 的 deep article。</p>
<h2 id="後續擴充仍待補">後續擴充（仍待補）</h2>
<ul>
<li>DynamoDB Streams 進階 lab：Kinesis Data Streams for DynamoDB 多消費者 fan-out 與長 retention 重播（Lambda vs Kinesis 比較層已在 <a href="streams-lambda-event-driven/">streams-lambda-event-driven</a> 覆蓋、此處指可操作的深度 hands-on lab）</li>
<li>Export to S3 / point-in-time export 做離線分析</li>
<li>DynamoDB → SQL / search / analytics split（遷出方向 playbook）</li>
<li>Backup / PITR restore drill（hands-on lab）</li>
</ul>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <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</a></td>
          <td>9000 萬 RPS + 500 萬 WPS</td>
          <td>partition 均勻設計典範</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>IOPS 20 → 135K（6750x 擴展）</td>
          <td>flash-sale 緩衝模式</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（1000 萬 → 3 億）</td>
          <td>SaaS surge baseline 重新校準</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>billions of requests / single-digit ms</td>
          <td>遊戲後端 KV、跨遊戲共用平台</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>4x 吞吐、90% latency 降、50% 成本降</td>
          <td>TiDB → DynamoDB cross-DB 遷移</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 / 8000+ orgs</td>
          <td>B2B SaaS 5 個 9 可用性</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>
          <td>行動支付通知系統、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>每日數十億 actions</td>
          <td>串流 metadata 層 + cross-device 同步</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>tens of thousands req/sec、5M MAU / 3 月</td>
          <td>RDB connection limit → DynamoDB</td>
      </tr>
  </tbody>
</table>
<p>DynamoDB case 的讀法是先分類 access pattern，再看容量模式。Amazon Ads / Capcom / Disney+ 說明高吞吐 KV，Zoom / Tixcraft / Lemino 說明 surge 與 connection-free scaling，Zomato 則說明 on-demand cost model 如何改變 over-provision 壓力。</p>
<h2 id="反向-sibling-路由">反向 sibling 路由</h2>
<p>DynamoDB 的反向 sibling 路由用來把 RDBMS 退場條件寫清楚。若讀者從 PostgreSQL / MySQL 的 connection bottleneck 過來，先讀 <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 case</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 選擇">1.10 KV / Document DB 容量規劃</a>；若需求仍需要 ad hoc SQL、join 與 transaction report，回 <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> 或 <a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor</a>；若需求是 global document model 與 Azure 生態，再對照 <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</a>。</p>
<p>這條路由的判準是 access pattern 是否穩定到可以先設計 key。DynamoDB 擅長固定 lookup、寫入尖峰、connection-free scaling 與 TTL 類生命週期；資料探索、報表 join 與多條件查詢仍應留在 SQL / search / analytics service。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<p>從公開 incident 跟 case 提煉：</p>
<ul>
<li><strong>partition key 集中</strong>：event_id 一個演唱會、bot user 大量同 user_id 寫入 → 用 composite key 或 write sharding</li>
<li><strong>單一 partition 達 3000 RCU / 1000 WCU 上限</strong>：throttling event 出現、即使整體 capacity 還沒滿</li>
<li><strong>Scan 全表</strong>：scan 會吃光 capacity，正式讀取路徑應回到 query / index design</li>
<li><strong>DAX 跟 DynamoDB 直連混用</strong>：寫入直連 DynamoDB、讀經過 DAX → cache 一致性問題</li>
<li><strong>Global Tables conflict</strong>：跨 region 同 key 同時被寫、LWW 可能丟失寫入、要設計 idempotency</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<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 page</a>（SQL 對比）</li>
<li>上游：<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 選擇">1.10 KV / Document DB 容量規劃</a></li>
<li>下游：<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>（從 RDBMS 遷 DynamoDB 案例）</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>、<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>Last reviewed：2026-05-22（capacity mode / Global Tables / best practices 屬時間敏感 claim）</li>
<li>官方：<a href="https://aws.amazon.com/dynamodb/customers/">Amazon DynamoDB Customers</a>、<a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html">DynamoDB 設計 best practices</a></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></channel></rss>