<?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>Aws on Tarragon</title><link>https://tarrragon.github.io/blog/tags/aws/</link><description>Recent content in Aws on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 30 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/aws/index.xml" rel="self" type="application/rss+xml"/><item><title>有 SSH 但沒有 IaC 的雲端環境接管</title><link>https://tarrragon.github.io/blog/infra/takeover/cloud-no-iac/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/infra/takeover/cloud-no-iac/</guid><description>&lt;p>雲端資源存在且正在服務 production 流量，但沒有人能回答「我們有什麼、為什麼這樣設定、改了會影響什麼」。Console 裡有幾十個資源，有些名稱是 &lt;code>test-final-v2&lt;/code>，有些沒有名稱，security group 規則不知道哪條還在用，IAM user 清單裡有幾個已離職的人。這是接手全手動雲端環境的典型起點。&lt;/p>
&lt;p>接管的操作順序是：先拍下現況（盤點）、再理解結構（依賴）、再收斂風險（credential、備份）、再建立紀律（變更紀錄）、最後才考慮 IaC 導入。每一步都在不改動 production 的前提下進行。&lt;/p>
&lt;h2 id="資源盤點拍下雲端現況">資源盤點：拍下雲端現況&lt;/h2>
&lt;p>盤點的目標是把「雲端上有什麼」轉成一份可版本控制的清單。這份清單是後續所有操作的事實基礎 — 沒有清單就無法判斷哪些資源重要、哪些可以回收、哪些的設定有風險。&lt;/p>
&lt;p>盤點的工具依環境類型不同：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>VM 為主（EC2 / GCE）&lt;/strong> → 先跑 &lt;a href="#vm-%e5%b1%a4%e7%b4%9a%e7%9a%84%e5%bf%ab%e7%85%a7">VM 快照與系統清單&lt;/a>，再跑 &lt;a href="#%e7%94%a8-cli-%e6%8b%89%e6%b8%85%e5%96%ae">CLI 資源盤點&lt;/a>&lt;/li>
&lt;li>&lt;strong>Managed service 為主（RDS / Lambda / S3）&lt;/strong> → 直接跑 &lt;a href="#%e7%94%a8-cli-%e6%8b%89%e6%b8%85%e5%96%ae">CLI 資源盤點&lt;/a>&lt;/li>
&lt;li>&lt;strong>混合（VM + managed）&lt;/strong> → 兩個都跑：先 VM 快照（拍下機器狀態），再 CLI 盤點（拍下所有雲端資源）&lt;/li>
&lt;/ul>
&lt;h3 id="用-cli-拉清單">用 CLI 拉清單&lt;/h3>
&lt;p>盤點有三層工具可用，從粗到細：&lt;/p>
&lt;p>&lt;strong>全貌掃描&lt;/strong>：先用跨服務工具拿到「到底有多少資源」的量級感。AWS Resource Explorer 在 Console 開啟後可以用搜尋語法跨 region、跨 service 查資源（例如搜 &lt;code>resourcetype:ec2:instance&lt;/code> 列出所有 EC2）。Steampipe 是開源的 SQL 介面雲端查詢工具，用 &lt;code>select * from aws_ec2_instance&lt;/code> 這類語法查詢，對習慣 SQL 的人比 CLI flag 直覺。兩者都能在幾分鐘內拿到環境的全貌。&lt;/p>
&lt;p>&lt;strong>Tag 層掃描&lt;/strong>：AWS Resource Groups Tagging API 能跨服務撈出所有被標記的資源，但會漏掉沒有 tag 的 — 而接手環境裡沒 tag 的資源往往是風險最高的（沒人認領、不敢動）。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">aws resourcegroupstaggingapi get-resources &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --output json &amp;gt; inventory/tagged-resources.json&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Per-service 細節&lt;/strong>：全貌掃描只告訴你資源存在，細節（備份設定、SG 規則、IAM policy）要用 per-service describe 拉。以下是接手時最該優先盤點的四類：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># EC2：哪些機器在跑、什麼規格、在哪個 subnet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">aws ec2 describe-instances &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --query &lt;span class="s1">&amp;#39;Reservations[].Instances[].[InstanceId,InstanceType,State.Name,SubnetId,SecurityGroups[].GroupId,Tags]&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --output json &amp;gt; inventory/ec2.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c1"># RDS：資料庫的備份設定、刪除保護、Multi-AZ&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">aws rds describe-db-instances &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --query &lt;span class="s1">&amp;#39;DBInstances[].[DBInstanceIdentifier,Engine,DBInstanceClass,MultiAZ,BackupRetentionPeriod,DeletionProtection]&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --output json &amp;gt; inventory/rds.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="c1"># Security Group：哪些規則對外開放&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">aws ec2 describe-security-groups &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --query &lt;span class="s1">&amp;#39;SecurityGroups[].[GroupId,GroupName,IpPermissions]&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --output json &amp;gt; inventory/security-groups.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="c1"># S3：哪些 bucket、versioning 是否開啟&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="k">for&lt;/span> bucket in &lt;span class="k">$(&lt;/span>aws s3api list-buckets --query &lt;span class="s1">&amp;#39;Buckets[].Name&amp;#39;&lt;/span> --output text&lt;span class="k">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$bucket&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="k">$(&lt;/span>aws s3api get-bucket-versioning --bucket &lt;span class="nv">$bucket&lt;/span> --query &lt;span class="s1">&amp;#39;Status&amp;#39;&lt;/span> --output text&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="k">done&lt;/span> &amp;gt; inventory/s3-versioning.txt&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>把所有輸出存進一個 Git repo 的 &lt;code>inventory/&lt;/code> 目錄。這份快照的價值在於：一週後再跑一次比對差異，就能看出環境在背景長出了什麼新資源。&lt;/p>
&lt;h3 id="優先查三件事">優先查三件事&lt;/h3>
&lt;p>盤點不需要一次做完所有服務，但三件事要第一天就查：&lt;/p>
&lt;p>&lt;strong>對外暴露面&lt;/strong>：security group 裡有沒有 &lt;code>0.0.0.0/0&lt;/code> 入站規則指向非 HTTP/HTTPS 的 port（22、3306、5432、6379）。手動逐條查很慢 — 用安全掃描工具一次跑完更可靠。Prowler 是開源的 AWS 安全掃描工具，一次執行就能產出「哪些 SG 對外開放、哪些 S3 public、哪些 IAM 過寬」的分類報告：&lt;/p></description><content:encoded><![CDATA[<p>雲端資源存在且正在服務 production 流量，但沒有人能回答「我們有什麼、為什麼這樣設定、改了會影響什麼」。Console 裡有幾十個資源，有些名稱是 <code>test-final-v2</code>，有些沒有名稱，security group 規則不知道哪條還在用，IAM user 清單裡有幾個已離職的人。這是接手全手動雲端環境的典型起點。</p>
<p>接管的操作順序是：先拍下現況（盤點）、再理解結構（依賴）、再收斂風險（credential、備份）、再建立紀律（變更紀錄）、最後才考慮 IaC 導入。每一步都在不改動 production 的前提下進行。</p>
<h2 id="資源盤點拍下雲端現況">資源盤點：拍下雲端現況</h2>
<p>盤點的目標是把「雲端上有什麼」轉成一份可版本控制的清單。這份清單是後續所有操作的事實基礎 — 沒有清單就無法判斷哪些資源重要、哪些可以回收、哪些的設定有風險。</p>
<p>盤點的工具依環境類型不同：</p>
<ul>
<li><strong>VM 為主（EC2 / GCE）</strong> → 先跑 <a href="#vm-%e5%b1%a4%e7%b4%9a%e7%9a%84%e5%bf%ab%e7%85%a7">VM 快照與系統清單</a>，再跑 <a href="#%e7%94%a8-cli-%e6%8b%89%e6%b8%85%e5%96%ae">CLI 資源盤點</a></li>
<li><strong>Managed service 為主（RDS / Lambda / S3）</strong> → 直接跑 <a href="#%e7%94%a8-cli-%e6%8b%89%e6%b8%85%e5%96%ae">CLI 資源盤點</a></li>
<li><strong>混合（VM + managed）</strong> → 兩個都跑：先 VM 快照（拍下機器狀態），再 CLI 盤點（拍下所有雲端資源）</li>
</ul>
<h3 id="用-cli-拉清單">用 CLI 拉清單</h3>
<p>盤點有三層工具可用，從粗到細：</p>
<p><strong>全貌掃描</strong>：先用跨服務工具拿到「到底有多少資源」的量級感。AWS Resource Explorer 在 Console 開啟後可以用搜尋語法跨 region、跨 service 查資源（例如搜 <code>resourcetype:ec2:instance</code> 列出所有 EC2）。Steampipe 是開源的 SQL 介面雲端查詢工具，用 <code>select * from aws_ec2_instance</code> 這類語法查詢，對習慣 SQL 的人比 CLI flag 直覺。兩者都能在幾分鐘內拿到環境的全貌。</p>
<p><strong>Tag 層掃描</strong>：AWS Resource Groups Tagging API 能跨服務撈出所有被標記的資源，但會漏掉沒有 tag 的 — 而接手環境裡沒 tag 的資源往往是風險最高的（沒人認領、不敢動）。</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 resourcegroupstaggingapi get-resources <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --output json &gt; inventory/tagged-resources.json</span></span></code></pre></div><p><strong>Per-service 細節</strong>：全貌掃描只告訴你資源存在，細節（備份設定、SG 規則、IAM policy）要用 per-service describe 拉。以下是接手時最該優先盤點的四類：</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"># EC2：哪些機器在跑、什麼規格、在哪個 subnet</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">aws ec2 describe-instances <span class="se">\
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;Reservations[].Instances[].[InstanceId,InstanceType,State.Name,SubnetId,SecurityGroups[].GroupId,Tags]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="se"></span>  --output json &gt; inventory/ec2.json
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># RDS：資料庫的備份設定、刪除保護、Multi-AZ</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">aws rds describe-db-instances <span class="se">\
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;DBInstances[].[DBInstanceIdentifier,Engine,DBInstanceClass,MultiAZ,BackupRetentionPeriod,DeletionProtection]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="se"></span>  --output json &gt; inventory/rds.json
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># Security Group：哪些規則對外開放</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">aws ec2 describe-security-groups <span class="se">\
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;SecurityGroups[].[GroupId,GroupName,IpPermissions]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="se"></span>  --output json &gt; inventory/security-groups.json
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c1"># S3：哪些 bucket、versioning 是否開啟</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">for</span> bucket in <span class="k">$(</span>aws s3api list-buckets --query <span class="s1">&#39;Buckets[].Name&#39;</span> --output text<span class="k">)</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$bucket</span><span class="s2">: </span><span class="k">$(</span>aws s3api get-bucket-versioning --bucket <span class="nv">$bucket</span> --query <span class="s1">&#39;Status&#39;</span> --output text<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">done</span> &gt; inventory/s3-versioning.txt</span></span></code></pre></div><p>把所有輸出存進一個 Git repo 的 <code>inventory/</code> 目錄。這份快照的價值在於：一週後再跑一次比對差異，就能看出環境在背景長出了什麼新資源。</p>
<h3 id="優先查三件事">優先查三件事</h3>
<p>盤點不需要一次做完所有服務，但三件事要第一天就查：</p>
<p><strong>對外暴露面</strong>：security group 裡有沒有 <code>0.0.0.0/0</code> 入站規則指向非 HTTP/HTTPS 的 port（22、3306、5432、6379）。手動逐條查很慢 — 用安全掃描工具一次跑完更可靠。Prowler 是開源的 AWS 安全掃描工具，一次執行就能產出「哪些 SG 對外開放、哪些 S3 public、哪些 IAM 過寬」的分類報告：</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"># 安裝後執行，針對最相關的服務掃描</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">prowler aws --services ec2 iam s3 rds -M json-ocsf -o inventory/
</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"># 如果只想快速查 SG 暴露面，用 CLI：</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">aws ec2 describe-security-groups <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;SecurityGroups[].IpPermissions[?contains(IpRanges[].CidrIp, `0.0.0.0/0`)]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>  --output json <span class="p">|</span> jq <span class="s1">&#39;[.[][] | select(.FromPort != 80 and .FromPort != 443)]&#39;</span></span></span></code></pre></div><p>ScoutSuite 是類似工具、支援多雲（AWS / GCP / Azure）。AWS Trusted Advisor 的免費 tier 也有基本安全檢查（S3 public access、SG 開放埠），但覆蓋面比 Prowler 窄。接手時三者選一跑一次，比手動翻 Console 快且不會漏。</p>
<p><strong>備份狀態</strong>：RDS 的 <code>BackupRetentionPeriod</code> 是不是 0（代表沒有自動備份）。S3 的 versioning 是不是關的。如果是，這是接手後第一個要改的設定 — 改備份設定不影響服務運作，但沒有備份時任何資料操作失誤都不可逆。</p>
<p><strong>誰最近在動環境</strong>：CloudTrail 記錄了所有 API 呼叫。查最近 30 天的變更事件，能看出哪些資源被頻繁修改、被誰修改。這比逐一問前團隊成員可靠——CloudTrail 不會漏記。</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 cloudtrail lookup-events <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --lookup-attributes <span class="nv">AttributeKey</span><span class="o">=</span>ReadOnly,AttributeValue<span class="o">=</span><span class="nb">false</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --start-time <span class="k">$(</span>date -v-30d +%Y-%m-%dT%H:%M:%S<span class="k">)</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --max-items <span class="m">50</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;Events[].[EventTime,Username,EventName,Resources[0].ResourceName]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>  --output table</span></span></code></pre></div><h3 id="vm-層級的快照">VM 層級的快照</h3>
<p>如果接手的環境包含 EC2 或 GCE 等 VM，在做任何改動之前先對每台 VM 建一個 AMI（AWS）或 machine image（GCP）。這是最粗粒度但最完整的「拍照」——整台機器的 OS、安裝的軟體、設定檔、磁碟內容全部打包成一個可重建的映像。</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"># AWS: 對 EC2 建 AMI（--no-reboot 避免服務中斷）</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">aws ec2 create-image <span class="se">\
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="se"></span>  --instance-id i-0abc123 <span class="se">\
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="se"></span>  --name <span class="s2">&#34;takeover-baseline-</span><span class="k">$(</span>date +%Y%m%d<span class="k">)</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="se"></span>  --no-reboot
</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"><span class="c1"># 確認 AMI 建立完成</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">aws ec2 describe-images <span class="se">\
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="se"></span>  --owners self <span class="se">\
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="se"></span>  --filters <span class="s2">&#34;Name=name,Values=takeover-baseline-*&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;Images[].[ImageId,Name,State]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="se"></span>  --output table</span></span></code></pre></div><p><code>--no-reboot</code> 讓快照過程中服務不中斷，代價是檔案系統快照的一致性不如有 reboot 的版本（記憶體中的寫入可能還沒 flush 到磁碟），但對接手基線已經足夠。AMI 的費用是底層 EBS 快照的儲存費用（按 GB 計費、差異儲存），作為接手保險措施這筆成本值得。</p>
<p>除了 VM 快照，有 SSH 存取時也要拍 VM 內部的軟體環境——AMI 可以還原整台機器，但看不到「裡面裝了什麼、跑了什麼」的摘要：</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"># 作業系統與版本</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">cat /etc/os-release
</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"># 已安裝的套件清單</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">dpkg -l &gt; ~/takeover/packages-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span>.txt   <span class="c1"># Debian/Ubuntu</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">rpm -qa &gt; ~/takeover/packages-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span>.txt    <span class="c1"># RHEL/CentOS/Amazon Linux</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"><span class="c1"># 執行中的服務</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">systemctl list-units --type<span class="o">=</span>service --state<span class="o">=</span>running &gt; ~/takeover/services.txt
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># 所有使用者的 cron jobs</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">for</span> user in <span class="k">$(</span>cut -f1 -d: /etc/passwd<span class="k">)</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;=== </span><span class="nv">$user</span><span class="s2"> ===&#34;</span> &gt;&gt; ~/takeover/crontabs.txt
</span></span><span class="line"><span class="ln">14</span><span class="cl">  crontab -u <span class="s2">&#34;</span><span class="nv">$user</span><span class="s2">&#34;</span> -l 2&gt;/dev/null &gt;&gt; ~/takeover/crontabs.txt
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">done</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c1"># 網路監聽的 port（哪個 process 在聽哪個 port）</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">ss -tlnp &gt; ~/takeover/listening-ports.txt</span></span></code></pre></div><p>把這些輸出存進盤點 repo，跟 CLI 資源盤點（describe 指令的輸出）放在一起。<code>listening-ports.txt</code> 跟 security group 規則對照，可以看出「哪些 port 有服務在聽但 SG 沒開」（可能是內部服務）和「哪些 port SG 開了但沒有服務在聽」（可能是殘留規則）。</p>
<h2 id="依賴關係推導">依賴關係推導</h2>
<p>盤點回答「有什麼」，依賴推導回答「改一個會連帶影響什麼」。手動環境沒有 Terraform 的依賴圖可以看，需要從資源的引用關係反推。</p>
<h3 id="從-security-group-開始">從 security group 開始</h3>
<p>Security group 是依賴推導的最佳起點，因為它的引用關係最密集 — 幾乎每個資源都掛著至少一個 SG，而 SG 之間可以互相引用（app SG 的入站來源是 LB SG、DB SG 的入站來源是 app SG）。</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"># 列出每個 SG 被哪些 ENI（網卡）使用</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">aws ec2 describe-network-interfaces <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;NetworkInterfaces[].[NetworkInterfaceId,Description,Groups[].GroupId]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --output json &gt; inventory/sg-usage.json</span></span></code></pre></div><p>AWS Console 的 VPC 頁面有 Resource Map 功能，可以視覺化 subnet → instance → SG 的對應關係，接手時第一次瀏覽依賴用它比 CLI 直覺。要產出可存檔的依賴圖，draw.io（有 AWS icon set）或 Lucidchart 都能畫，重點是圖要存進 repo、不是畫完就丟。</p>
<p>如果後續打算導入 Terraform，Former2 可以掃描現有 AWS 資源、自動產出 Terraform / CloudFormation / CDK 程式碼。產出的程式碼不會完美（屬性常漏、命名要改），但作為反推依賴關係的起點比從零寫快。Inframap 則是從 Terraform state 產出依賴關係圖（在 import 階段才用得到）。</p>
<p>從 SG 的引用鏈可以畫出一張粗略的依賴圖：</p>
<table>
  <thead>
      <tr>
          <th>層次</th>
          <th>資源</th>
          <th>入站來自</th>
          <th>出站到</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>入口</td>
          <td>ALB</td>
          <td>0.0.0.0/0:443</td>
          <td>app SG</td>
      </tr>
      <tr>
          <td>應用</td>
          <td>EC2 / ECS</td>
          <td>ALB SG</td>
          <td>DB SG、外部 API</td>
      </tr>
      <tr>
          <td>資料</td>
          <td>RDS</td>
          <td>app SG:5432</td>
          <td>—</td>
      </tr>
  </tbody>
</table>
<p>這張圖不需要精確到每個 port — 它的用途是在改動任何資源前，快速判斷影響範圍。例如要改 app SG 的規則時，先查它被哪些 EC2 和 ECS 引用、它的入站來源 ALB SG 是否受影響。</p>
<h3 id="其他依賴面向">其他依賴面向</h3>
<p>除了 SG，以下幾個引用關係也要記錄：</p>
<ul>
<li><strong>EC2 → IAM role</strong>：instance profile 決定這台機器能存取什麼（S3 bucket、Secrets Manager、其他 AWS 服務）</li>
<li><strong>RDS → subnet group</strong>：決定資料庫在哪些 subnet 裡，改 VPC 或 subnet 時會受影響</li>
<li><strong>ALB → target group → EC2/ECS</strong>：流量路徑，改 target group 的 health check 或移除成員會影響服務可用性</li>
<li><strong>Lambda → VPC 設定</strong>：如果 Lambda 被放進 VPC，它的出站走 NAT，改 NAT 或 route table 會影響它</li>
<li><strong>Route 53 → ALB/EC2</strong>：DNS 指向哪個資源，改資源 IP 或 ALB 時要同步更新</li>
</ul>
<h2 id="credential-盤點與收斂">credential 盤點與收斂</h2>
<p>接手環境時，credential 是風險最高的一類 — 前團隊建立的 IAM user 和 access key 可能還在活躍狀態，而那些人已經不在團隊裡了。</p>
<p>接手後第一件事是用 aws-vault 管理自己的 credential。aws-vault 把 AWS access key 存在 OS keychain（macOS Keychain / Windows Credential Manager），而非明文放在 <code>~/.aws/credentials</code>。執行 AWS 指令時由 aws-vault 注入臨時 session，本地磁碟上不留長期 key 的明文。不要沿用前人留下的 AWS CLI profile — 那些 profile 的權限範圍和用途都不確定。</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"># 安裝後設定新的 profile</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">aws-vault add takeover-admin
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># 用臨時 session 執行指令</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">aws-vault <span class="nb">exec</span> takeover-admin -- aws sts get-caller-identity</span></span></code></pre></div><h3 id="產出-credential-報告">產出 credential 報告</h3>





<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 iam generate-credential-report
</span></span><span class="line"><span class="ln">2</span><span class="cl">aws iam get-credential-report <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;Content&#39;</span> --output text <span class="p">|</span> base64 -d &gt; inventory/credential-report.csv</span></span></code></pre></div><p>這份 CSV 列出所有 IAM user、每把 access key 的建立時間、上次使用時間、MFA 是否啟用。從中篩出三類需要處理的：</p>
<table>
  <thead>
      <tr>
          <th>類別</th>
          <th>判斷方式</th>
          <th>處理</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>已離職人員的 key</td>
          <td>user 名稱對照離職清單</td>
          <td>停用 key → 觀察 7 天無異常 → 刪除 user</td>
      </tr>
      <tr>
          <td>超過 90 天未使用的 key</td>
          <td><code>access_key_last_used</code> 超過 90 天</td>
          <td>停用 → 觀察是否有服務中斷 → 確認無影響後刪除</td>
      </tr>
      <tr>
          <td>有 admin 權限的 key</td>
          <td>policy 含 <code>AdministratorAccess</code> 或 <code>*:*</code></td>
          <td>降權到實際需要的最小權限</td>
      </tr>
  </tbody>
</table>
<p>停用（deactivate）而非直接刪除是關鍵 — 停用後如果某個自動化腳本依賴這把 key 會立刻報錯，這時候可以快速重新啟用；直接刪除就回不去了。觀察期設 7 天，涵蓋一個完整的業務週期（含週末的 cron job）。</p>
<h3 id="檢查-key-散落的位置">檢查 key 散落的位置</h3>
<p>Access key 可能被寫在不只一個地方：</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"># EC2 user data 裡是否有 hardcode 的 key</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">aws ec2 describe-instance-attribute <span class="se">\
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="se"></span>  --instance-id i-xxx --attribute userData <span class="se">\
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;UserData.Value&#39;</span> --output text <span class="p">|</span> base64 -d <span class="p">|</span> grep -i <span class="s2">&#34;aws_access_key\|aws_secret&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># Lambda 環境變數</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">aws lambda list-functions --query <span class="s1">&#39;Functions[].FunctionName&#39;</span> --output text <span class="p">|</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="se"></span>  xargs -I<span class="o">{}</span> aws lambda get-function-configuration --function-name <span class="o">{}</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;Environment.Variables&#39;</span> --output json <span class="p">|</span> grep -i <span class="s2">&#34;key\|secret\|password&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># SSM Parameter Store</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">aws ssm describe-parameters --query <span class="s1">&#39;Parameters[].Name&#39;</span> --output text</span></span></code></pre></div><p>找到 hardcode 的 key 後，替換路徑是改用 IAM role（EC2 用 instance profile、Lambda 用 execution role）。替換前先確認 role 的 policy 涵蓋這把 key 原本在做的操作。</p>
<h2 id="備份驗證">備份驗證</h2>
<p>盤點出的每個 stateful 資源（RDS、S3、EBS）都要確認備份狀態。接手環境時不能假設「前團隊應該有設定備份」— 要親自驗證。</p>
<h3 id="rds-備份">RDS 備份</h3>





<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"># 檢查每個 RDS instance 的備份設定</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">aws rds describe-db-instances <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;DBInstances[].[DBInstanceIdentifier,BackupRetentionPeriod,LatestRestorableTime,DeletionProtection]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --output table</span></span></code></pre></div><p><code>BackupRetentionPeriod</code> 為 0 代表沒有自動備份 — 立刻改成至少 7 天。<code>DeletionProtection</code> 為 false 代表一個誤操作就能刪掉資料庫 — 立刻開啟。這兩項設定的修改不需要重啟、不影響服務。</p>
<p>備份存在不等於備份可用。接手後的第一週內，從最近的 snapshot 還原一台測試 RDS、連進去確認資料完整。這個步驟的成本是一台 RDS 跑幾小時的費用，換到的是「備份確定能用」的確認 — 等到要用備份的時候才發現不能還原，代價是另一個量級。</p>
<h3 id="s3-versioning">S3 versioning</h3>
<p>沒有開 versioning 的 bucket，物件被覆寫或刪除後不可回復。對承載業務資料的 bucket（上傳的檔案、匯出的報表、設定檔），開啟 versioning：</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 s3api put-bucket-versioning <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --bucket my-business-data <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --versioning-configuration <span class="nv">Status</span><span class="o">=</span>Enabled</span></span></code></pre></div><p>開啟 versioning 不影響既有物件，但會讓後續的每次覆寫都保留舊版本。儲存成本會因為保留歷史版本而增加 — 配一條 lifecycle rule 設定 noncurrent version 的過期天數來控制。</p>
<h2 id="建立變更紀律">建立變更紀律</h2>
<p>盤點、依賴推導、credential 收斂做完後，環境的現況已經有一份可查的記錄。下一步是確保從現在開始的每一次變更都留下痕跡。</p>
<h3 id="變更日誌">變更日誌</h3>
<p>在 inventory repo 裡建一份 <code>CHANGELOG.md</code>，每次改動 production 就追加一筆：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">## 2026-06-26
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> **操作者**：alice
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> **資源**：rds/payments-prod
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> **變更**：BackupRetentionPeriod 0 → 14, DeletionProtection false → true
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> **原因**：接手盤點發現備份未開啟
</span></span><span class="line"><span class="ln">7</span><span class="cl">- <span class="gs">**回退方式**</span>：BackupRetentionPeriod 改回 0（不建議）</span></span></code></pre></div><h3 id="cloudtrail-確認">CloudTrail 確認</h3>
<p>確認 CloudTrail 正在記錄 management events。如果沒有 trail 存在，建一個指向 S3 bucket 的 trail — 這是事後追溯「誰動了什麼」的最後防線。</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 cloudtrail describe-trails --query <span class="s1">&#39;trailList[].{Name:Name,S3:S3BucketName,IsLogging:IsLogging}&#39;</span></span></span></code></pre></div><h3 id="開始標-tag">開始標 tag</h3>
<p>盤點過程中辨識出的每個資源，標上 <code>env</code>、<code>owner</code>、<code>service</code> 三個 tag。接手階段的 <code>owner</code> 通常標「待確認」或新接手的團隊名稱。tag 的價值在於讓後續的盤點和清理可以用查詢系統性地進行 — 沒有 tag 的資源無法被 filter 找到。</p>
<h2 id="往-iac-的銜接">往 IaC 的銜接</h2>
<p>盤點和紀律建立完成後，環境已經從「不知道有什麼」推進到「知道有什麼、知道誰在動、改了有紀錄」。這個狀態對應<a href="/blog/infra/00-infra-mindset/" data-link-title="模組零：infra 是什麼，為什麼 day 1 就要鋪地基" data-link-desc="基礎設施的責任邊界、成熟度階梯，以及地基為什麼總在環境爆炸時才被看見">成熟度階梯</a>的第零階到第一階之間。</p>
<h3 id="成本現況">成本現況</h3>
<p>接手環境通常伴隨「這個月帳單多少」的問題。AWS Cost Explorer（免費）能看過去幾個月的花費分布，按服務類型、帳號、tag 維度拆。接手時先拉一次 Cost Explorer 的月度趨勢，看有沒有異常成長或不預期的高額服務。後續導入 IaC 後，Infracost 可以在 <code>terraform plan</code> 階段預估變更的成本影響（例如「升 RDS 規格會多花多少」），讓成本決策在 apply 之前就被看見。</p>
<p>往 IaC 的銜接不需要一次做完。按穩定度和改動風險排序：</p>
<table>
  <thead>
      <tr>
          <th>優先級</th>
          <th>資源類型</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>先做</td>
          <td>VPC、subnet、route table</td>
          <td>形狀穩定、幾乎不會改、import 風險低</td>
      </tr>
      <tr>
          <td>次做</td>
          <td>security group</td>
          <td>規則明確、import 後 plan 容易驗證</td>
      </tr>
      <tr>
          <td>後做</td>
          <td>RDS、EC2、ALB</td>
          <td>stateful 或與部署耦合、import 風險較高</td>
      </tr>
      <tr>
          <td>最後</td>
          <td>Lambda、API Gateway</td>
          <td>通常跟應用程式碼耦合、import 後維護邊界需要釐清</td>
      </tr>
  </tbody>
</table>
<p>每批 import 的操作流程是：<code>terraform import</code> → <code>terraform plan</code> 確認零變更 → 寫 HCL 補齊差異 → 再跑 <code>plan</code> 直到零變更。具體的 import 步驟和工具選型在<a href="/blog/infra/01-minimal-iac/" data-link-title="模組一：最小可行 IaC — state 地基與 Console 唯讀鐵律" data-link-desc="Terraform / OpenTofu 選型、remote state 與 lock，以及「Console 只能看不能改」鐵律">模組一：最小可行 IaC</a>。</p>
<p>時程參考：10-20 個資源的環境，完成盤點 + credential 收斂 + 備份驗證約需 3-5 天；往 IaC 的 import 約需 1-2 週。兩者可以平行進行但建議先完成盤點 — 沒有完整的資源清單就開始 import，容易漏掉關鍵的依賴關係。</p>
<h2 id="跨分類引用">跨分類引用</h2>
<ul>
<li>→ <a href="/blog/infra/takeover/partial-iac-no-docs/" data-link-title="有半套 IaC 但文件缺失的環境接管" data-link-desc="IaC 覆蓋不完整、部分資源在 state 外、文件缺失的環境怎麼盤點差距、修復 state 健康、收斂 drift 並重建文件">有半套 IaC 但文件缺失的環境接管</a>：如果盤點過程中發現環境裡已有部分 Terraform code</li>
<li>→ <a href="/blog/infra/before-infra/" data-link-title="模組負一：還沒有 infra 的環境怎麼盡量做好" data-link-desc="手動點起家的環境怎麼守底線、降低未來納管成本、辨識何時該開始導入 IaC — 給還沒有能力上 IaC 的真實起點">模組負一：還沒有 infra 的環境</a>：盤點完成後的操作紀律對齊</li>
<li>→ <a href="/blog/infra/00-infra-mindset/" data-link-title="模組零：infra 是什麼，為什麼 day 1 就要鋪地基" data-link-desc="基礎設施的責任邊界、成熟度階梯，以及地基為什麼總在環境爆炸時才被看見">模組零：infra 是什麼</a>：成熟度階梯作為接手後現況評估的座標</li>
<li>→ <a href="/blog/infra/01-minimal-iac/" data-link-title="模組一：最小可行 IaC — state 地基與 Console 唯讀鐵律" data-link-desc="Terraform / OpenTofu 選型、remote state 與 lock，以及「Console 只能看不能改」鐵律">模組一：最小可行 IaC</a>：盤點完成後的第一步 IaC 導入</li>
<li>→ <a href="/blog/infra/02-identity-credentials/" data-link-title="模組二：身分與憑證地基 — IAM 與 OIDC" data-link-desc="IAM role / policy 設計、最小權限，以及用 OIDC 短期憑證取代長期 access key">模組二：身分與憑證</a>：credential 收斂的完整設計</li>
<li>→ <a href="/blog/infra/02-identity-credentials/team-access-management/" data-link-title="團隊權限分級與存取管理" data-link-desc="用 admin / operator / viewer 三級劃分團隊成員的雲端操作權限，設計臨時提權流程、定期 access review 節奏，以及 contractor 與外部 vendor 的存取邊界">團隊權限分級與存取管理</a>：接手後重新建立權限分級</li>
</ul>
]]></content:encoded></item><item><title>AWS Secrets Manager</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/</guid><description>&lt;p>AWS Secrets Manager 是 AWS 原生的 &lt;em>static secret 集中保管 service&lt;/em>、核心能力是把 secret 用 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &amp;#43; Grant 雙軌授權">KMS&lt;/a> 加密儲存、加上 &lt;em>built-in rotation Lambda&lt;/em>（針對 RDS / Redshift / DocumentDB）跟 &lt;em>Resource Policy + IAM Policy 雙層 grant&lt;/em>、把 secret lifecycle 鎖在 AWS account / IAM 邊界內。設計取捨跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault&lt;/a> 不同 — Secrets Manager 不做 dynamic credential、不做 transit encryption、不做內部 PKI、只把 &lt;em>static secret + AWS native DB rotation&lt;/em> 這條路徑做到極致。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>Secrets Manager 的定位是 &lt;em>AWS-only workload 的 static secret 控制面&lt;/em>、跟 &lt;a href="https://docs.aws.amazon.com/systems-manager/">SSM Parameter Store&lt;/a> SecureString 在 &lt;em>存 secret&lt;/em> 這層功能重疊、但設計目的不同。Parameter Store 是 &lt;em>parameter 管理&lt;/em>（free tier、advanced parameter 每 10000 個約 $0.05、KMS 加密但無 staging label 與 rotation Lambda）；Secrets Manager 是 &lt;em>secret 管理&lt;/em>（每個 secret per month $0.40 + API call、有 staging label / rotation Lambda / Resource Policy / Cross-Region Replica）。價差 8 倍以上、選擇基準在 &lt;em>是否需要 rotation 跟 cross-account sharing&lt;/em>。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault&lt;/a> 比、Secrets Manager 是 &lt;em>單一雲、簡單、低運維&lt;/em>、Vault 是 &lt;em>跨雲、dynamic credential、高表達力&lt;/em>。AWS-only 組織用 Vault 等於多扛一個 HA cluster 運維成本只為了拿 KV engine 跟 RDS rotation、ROI 不划算；反向跨雲組織用 Secrets Manager 等於每個雲都自己一套 secret store、治理鏈會斷。跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-secret-manager/" data-link-title="Google Secret Manager" data-link-desc="GCP 原生 secret store、CMEK &amp;#43; Workload Identity Federation 整合、rotation 走自寫 Cloud Function 而非 built-in Lambda">Google Secret Manager&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &amp;#43; Key &amp;#43; Certificate）、整合 Managed Identity &amp;#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault&lt;/a> 比、設計理念類似（雲廠 managed、KMS 加密、IAM 授權）但 rotation 機制各家不同 — Secrets Manager 用 built-in Lambda 四階段 flow、GSM 用 Pub/Sub event 觸發自寫 Cloud Function、Azure 用 Key Vault rotation policy + Event Grid。&lt;/p></description><content:encoded><![CDATA[<p>AWS Secrets Manager 是 AWS 原生的 <em>static secret 集中保管 service</em>、核心能力是把 secret 用 <a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">KMS</a> 加密儲存、加上 <em>built-in rotation Lambda</em>（針對 RDS / Redshift / DocumentDB）跟 <em>Resource Policy + IAM Policy 雙層 grant</em>、把 secret lifecycle 鎖在 AWS account / IAM 邊界內。設計取捨跟 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a> 不同 — Secrets Manager 不做 dynamic credential、不做 transit encryption、不做內部 PKI、只把 <em>static secret + AWS native DB rotation</em> 這條路徑做到極致。</p>
<h2 id="服務定位">服務定位</h2>
<p>Secrets Manager 的定位是 <em>AWS-only workload 的 static secret 控制面</em>、跟 <a href="https://docs.aws.amazon.com/systems-manager/">SSM Parameter Store</a> SecureString 在 <em>存 secret</em> 這層功能重疊、但設計目的不同。Parameter Store 是 <em>parameter 管理</em>（free tier、advanced parameter 每 10000 個約 $0.05、KMS 加密但無 staging label 與 rotation Lambda）；Secrets Manager 是 <em>secret 管理</em>（每個 secret per month $0.40 + API call、有 staging label / rotation Lambda / Resource Policy / Cross-Region Replica）。價差 8 倍以上、選擇基準在 <em>是否需要 rotation 跟 cross-account sharing</em>。</p>
<p>跟 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a> 比、Secrets Manager 是 <em>單一雲、簡單、低運維</em>、Vault 是 <em>跨雲、dynamic credential、高表達力</em>。AWS-only 組織用 Vault 等於多扛一個 HA cluster 運維成本只為了拿 KV engine 跟 RDS rotation、ROI 不划算；反向跨雲組織用 Secrets Manager 等於每個雲都自己一套 secret store、治理鏈會斷。跟 <a href="/blog/backend/07-security-data-protection/vendors/google-secret-manager/" data-link-title="Google Secret Manager" data-link-desc="GCP 原生 secret store、CMEK &#43; Workload Identity Federation 整合、rotation 走自寫 Cloud Function 而非 built-in Lambda">Google Secret Manager</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a> 比、設計理念類似（雲廠 managed、KMS 加密、IAM 授權）但 rotation 機制各家不同 — Secrets Manager 用 built-in Lambda 四階段 flow、GSM 用 Pub/Sub event 觸發自寫 Cloud Function、Azure 用 Key Vault rotation policy + Event Grid。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>哪些 secret 用 Secrets Manager、哪些可以下放到 Parameter Store、哪些該走 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a> 的 dynamic credential</li>
<li>Secrets Manager 的 <em>雙層 grant 模型</em>（Resource Policy + IAM Policy）跟 KMS encryption key custody 怎麼配</li>
<li>Built-in rotation 跟 Custom Rotation Lambda 的設計邊界、staging label 在 zero-downtime rotation 內的角色</li>
<li>何時 Secrets Manager 已經不夠用、要往 Vault / 跨雲 broker 走</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一個 Secrets Manager 部署是否健康、最少看四件事：</p>
<ul>
<li><strong>誰能 GetSecretValue</strong>：IAM Policy 那邊是不是用 <code>secretsmanager:GetSecretValue</code> 限定到 <em>特定 secret ARN</em>（不是 <code>*</code>）、Resource Policy 是不是只允許特定 principal（不是 <code>Principal: *</code>）、跨帳號 share 有沒有用 ABAC tag 限縮</li>
<li><strong>KMS key custody</strong>：secret 用 <em>AWS-managed key</em>（<code>aws/secretsmanager</code>）還是 <em>customer-managed key</em>（CMK）— production 應該全部 CMK、key policy 限定 only Secrets Manager service principal 可用、KMS key 持有者跟 secret 持有者要分離</li>
<li><strong>Rotation 設定</strong>：rotation 開了沒、rotation interval 多久、Lambda 過去執行 success rate、staging label 在 rotation 過程中是否依序 promote（AWSPENDING → AWSCURRENT → AWSPREVIOUS）</li>
<li><strong>CloudTrail data event</strong>：<code>GetSecretValue</code> 是 <em>Data event</em>、預設不記、要手動開 data event logging — 沒開等於事故時看不到 <em>誰拿了 secret</em>、只看得到 management API（CreateSecret / UpdateSecret）</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a> 跟 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Resource Policy + IAM Policy 雙層 grant</strong>：Secrets Manager 跟 S3 bucket policy 同模型 — IAM Policy 控制 <em>principal 端能做什麼</em>、Resource Policy 控制 <em>secret 端允許誰來</em>、兩者要 <em>都同意</em> 才放行。常見錯配：Resource Policy 寫 <code>Principal: &quot;*&quot;</code> 加 <code>aws:SourceAccount</code> condition 想做跨帳號 share、但 condition 漏寫或寫錯就變成公開可讀。跨帳號 share 一定要明確列 <code>Principal: arn:aws:iam::123456789012:role/AppRole</code>、不要靠 wildcard + condition 拼隔離。</p>
<p><strong>IAM Policy 細粒度授權</strong>：<code>secretsmanager:GetSecretValue</code> 該限定到 <em>specific secret ARN</em>（不是 <code>*</code>）、配合 ABAC tag condition（<code>secretsmanager:ResourceTag/team = payments</code>）限縮 blast radius。對應 <a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/circleci-2023-secrets-rotation/" data-link-title="7.R7.2.3 CircleCI 2023：CI secrets 輪替壓力" data-link-desc="工程端點入侵後，CI 平台 secrets 如何成為高風險擴散點">CircleCI 2023 Secrets Rotation</a> — CI 出事時要能依 tag 快速列出 <em>CI runner 可拿的所有 secret</em>、沒這套 tag 就只能盲目 rotate 全部。</p>
<p><strong>KMS encryption key 選 CMK 不是 default</strong>：每個 secret 用一把 KMS key 加密、預設用 AWS-managed key <code>aws/secretsmanager</code>、production 應該換 customer-managed key（CMK）。差別在 <em>key policy 是不是自己控</em> — AWS-managed key 的 policy 同 account 任何 service 可呼叫、CMK 的 key policy 可以鎖到 only Secrets Manager service principal 加 only specific role 可 Decrypt。對應 <a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Storm-0558</a> 的對照啟示：<em>key 的 blast radius 來自 key policy</em>、用 CMK 把 policy 寫窄是減 blast radius 的關鍵動作。</p>
<p><strong>Built-in Rotation Lambda 只限 AWS native DB</strong>：Secrets Manager 內建 rotation template 涵蓋 RDS（PostgreSQL / MySQL / MariaDB / Oracle / SQL Server）/ Aurora / Redshift / DocumentDB — 拿 AWS 提供的 Lambda template、設定 rotation interval（最短 1 天、最長 365 天）、Secrets Manager 自動排程觸發。其他 DB（self-hosted PostgreSQL、MongoDB Atlas、Snowflake）或 API key 要寫 <em>Custom Rotation Lambda</em>、走 4-step state machine：<code>createSecret</code>（產新 credential 存為 AWSPENDING）、<code>setSecret</code>（把新 credential 寫到 target system）、<code>testSecret</code>（用新 credential 驗證可連）、<code>finishSecret</code>（promote AWSPENDING → AWSCURRENT）。Lambda 任一步失敗 Secrets Manager 會 rollback、舊 credential 不受影響。</p>
<p><strong>Staging Label（AWSCURRENT / AWSPENDING / AWSPREVIOUS）</strong>：staging label 是 <em>指向 version 的 pointer</em>、app 一律用 <code>GetSecretValue</code> 不帶 VersionStage 拿 AWSCURRENT、rotation 過程中 Secrets Manager 先把新 credential 標 AWSPENDING、testSecret 過後 promote 到 AWSCURRENT、舊的降到 AWSPREVIOUS。設計初衷是 <em>zero-downtime rotation</em> — 但 <em>只有 app 端支援 AWSPREVIOUS fallback</em> 期間才有意義：rotation 完成瞬間有些 app instance 還拿著舊 credential，target system 應該同時接受 AWSCURRENT 跟 AWSPREVIOUS（DB rotation template 會在 setSecret 階段保留舊 user 一段時間）。對應 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a>：scope map 沒做、AWSPREVIOUS 窗口期太短、長尾 batch job 拿到舊 credential 就掛。</p>
<p><strong>Cross-Region Replica</strong>：multi-region app 把 secret replicate 到其他 region、replica 在 replica region 有獨立 ARN、KMS key 跟 rotation 都要在 replica region 各自配（不能跨 region 共用 KMS key）。replica 是 <em>讀副本</em>、寫只能在 primary region、rotation 觸發後新 version 自動 sync 到 replica（有秒級延遲）。failover 時 app 直接讀 replica region ARN、不需要 cross-region call。</p>
<p><strong>Cross-Account Sharing</strong>：跨帳號 share secret 走 Resource Policy + 對方帳號 IAM Policy 雙向授權 — Resource Policy 列對方 account 的具體 role ARN、對方 role 的 IAM Policy 加 <code>GetSecretValue</code> 對應 ARN。KMS key 也要跨帳號授權（KMS key policy 加對方 role 的 Decrypt 權限）— 漏了 KMS 授權會出現 <em>GetSecretValue 成功但 Decrypt 失敗</em> 的詭異錯誤。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS Secrets Manager</th>
          <th>SSM Parameter Store SecureString</th>
          <th><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a></th>
          <th><a href="/blog/backend/07-security-data-protection/vendors/google-secret-manager/" data-link-title="Google Secret Manager" data-link-desc="GCP 原生 secret store、CMEK &#43; Workload Identity Federation 整合、rotation 走自寫 Cloud Function 而非 built-in Lambda">Google Secret Manager</a></th>
          <th><a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>AWS managed</td>
          <td>AWS managed</td>
          <td>自管 cluster</td>
          <td>GCP managed</td>
          <td>Azure managed</td>
      </tr>
      <tr>
          <td>跨雲</td>
          <td>弱 — 綁 AWS</td>
          <td>弱 — 綁 AWS</td>
          <td>強</td>
          <td>弱 — 綁 GCP</td>
          <td>弱 — 綁 Azure</td>
      </tr>
      <tr>
          <td>每月每 secret 成本</td>
          <td>~$0.40 + API call</td>
          <td>free / advanced ~$0.05/10k</td>
          <td>self-hosted 成本</td>
          <td>~$0.06 + API call</td>
          <td>~$0.03 + operation</td>
      </tr>
      <tr>
          <td>Built-in rotation</td>
          <td>RDS / Redshift / DocumentDB 內建 Lambda</td>
          <td>無</td>
          <td>dynamic engine 自動發短期 credential</td>
          <td>無 built-in</td>
          <td>Key Vault rotation policy（key 為主）</td>
      </tr>
      <tr>
          <td>Staging label</td>
          <td>AWSCURRENT / AWSPENDING / AWSPREVIOUS</td>
          <td>無、用 version number</td>
          <td>KV v2 用 version</td>
          <td>version 機制</td>
          <td>version 機制</td>
      </tr>
      <tr>
          <td>Cross-account share</td>
          <td>Resource Policy + IAM</td>
          <td>不支援（同 account only）</td>
          <td>Vault namespace + policy</td>
          <td>IAM cross-project</td>
          <td>RBAC cross-tenant</td>
      </tr>
      <tr>
          <td>Dynamic credential</td>
          <td>無（rotation Lambda 是 static 換 static）</td>
          <td>無</td>
          <td>有（DB / cloud / SSH engine）</td>
          <td>弱（IAM impersonation）</td>
          <td>弱（Managed Identity）</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-only + static secret + RDS rotation 為主</td>
          <td>AWS-only + 大量低敏 config + 不需 rotation</td>
          <td>跨雲 + dynamic credential + 內部 PKI</td>
          <td>GCP-only + Workload Identity 已主導</td>
          <td>Azure-only + Managed Identity 已主導</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>低</td>
          <td>低</td>
          <td>中</td>
          <td>低</td>
          <td>低</td>
      </tr>
  </tbody>
</table>
<p>選 Secrets Manager 的核心訴求：<em>AWS-only</em> + <em>大部分 secret 是 static 或 AWS native DB credential</em> + <em>需要 cross-account share 或 rotation Lambda</em> + <em>不想 / 沒量能自管 Vault</em>。如果只是要存 config（feature flag、non-sensitive endpoint）、Parameter Store 8 倍便宜；如果跨雲 + 需要 dynamic credential / transit / PKI、Vault 才能滿足。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Custom Rotation Lambda 設計</strong>：4-step state machine 是 <em>idempotent contract</em> — Lambda 必須能被 Secrets Manager 重試任意步驟而不破壞狀態。常見實作陷阱：createSecret 不檢查 AWSPENDING 是否已存在、重試時又產生一把新的、AWSPENDING 對不上 setSecret 寫進去的；setSecret 沒處理「target system 已經有同名 user」的情況、第二次跑會卡住。Template 提供的 PostgreSQL rotation Lambda 用 <em>cloning approach</em> — 在 DB 內 clone 一份 user、改密碼、保留舊 user 跨 rotation 一個週期、下次 rotation 才 drop。</p>
<p><strong>Resource Policy + ABAC tag 跨帳號</strong>：跨帳號 share 時用 ABAC tag 條件比硬列 role ARN 有彈性 — Resource Policy 寫 <code>Condition: aws:PrincipalTag/team = payments</code>、對方 account 任何帶該 tag 的 role 都可讀。代價是 <em>tag 治理</em> 變成 critical control：對方 account 內誰能 attach tag = 誰能拿 secret、IAM Policy 要鎖 <code>iam:TagRole</code> 跟 <code>iam:UntagRole</code> 權限。</p>
<p><strong>Rotation 失敗的監控訊號</strong>：Lambda 執行失敗會在 CloudWatch 留 invocation error、Secrets Manager 把 rotation 標記為 failed、但 <em>secret 仍可用</em>（AWSCURRENT 保留舊 version）— 容易出現 <em>半年沒 rotate 成功但 app 看起來正常</em> 的盲區。要監控 <code>SecretsManager.RotationFailed</code> event（EventBridge rule）+ <code>LastRotatedDate</code> metric 超過 rotation interval 1.5 倍就 alert。</p>
<p><strong>跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 整合</strong>：誰可以 <code>GetSecretValue</code> 完全由 IAM 控制、最佳實踐是 <em>workload role</em> 拿 secret（EC2 instance role / ECS task role / Lambda execution role / EKS IRSA）、不要硬把 AWS credential 塞進 secret 再給 application read。Secret 內容應該是 <em>DB password / API token / third-party credential</em>、不應該是 <em>AWS credential</em>（AWS credential 用 IAM role 短期 STS 拿就好）。</p>
<p><strong>CloudTrail data event 的成本權衡</strong>：開 <code>GetSecretValue</code> data event 等於每次 secret 取用都進 CloudTrail、高 QPS application 一天可能跑數百萬筆、CloudTrail 成本（每 100k events 約 $0.10）跟 S3 儲存成本會明顯上升。降本作法：在 EventBridge 用 <em>filtering</em>（只送特定 sensitive secret 的 data event 到 SIEM）、CloudWatch Logs 端設 retention 短一點（7-30 天熱資料、長尾走 S3 + Athena）。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>GetSecretValue AccessDenied 但 IAM Policy 看起來對</strong>：檢查 Resource Policy 是否限定 source account / VPC、檢查 KMS key policy 是否允許該 role Decrypt — 兩層 grant + KMS 三點任一缺都會 AccessDenied</li>
<li><strong>跨帳號 secret 拿不到</strong>：Resource Policy 沒列對方 role、或 KMS key policy 沒給對方 Decrypt 權限 — 跨帳號要同步配三處（Resource Policy + 對方 IAM + KMS key policy）</li>
<li><strong>Rotation 一直失敗但沒人發現</strong>：沒設 EventBridge alert on <code>RotationFailed</code>、AWSCURRENT 保持舊 version、app 正常但 secret 過期 — 必設 LastRotatedDate metric alert</li>
<li><strong>App 拿到 stale secret rotation 後爆掉</strong>：app 端用了 SDK cache（如 AWS SDK 的 Secrets Manager Cache）、rotation 完成後 cache 沒 invalidate — cache TTL 要短於 staging label 重疊窗口、或實作 retry-on-auth-fail 觸發 cache refresh</li>
<li><strong>CloudTrail 看不到誰拿 secret</strong>：沒開 data event logging — 在 CloudTrail trail 設定加上 <code>AWS::SecretsManager::Secret</code> 為 data resource</li>
<li><strong>跨 region replica rotation 失效</strong>：rotation Lambda 只在 primary region 配、replica region 沒對應 Lambda — 每個 region 各自配 Lambda、或乾脆只在 primary rotate 讓 replica 自動 sync</li>
<li><strong>AWSPREVIOUS fallback 沒生效 batch job 掛</strong>：rotation Lambda finishSecret 太快 drop 舊 user、batch job 拿到舊 credential 連 DB 失敗 — DB rotation template 預設保留舊 user 一個 rotation 週期、custom Lambda 要自己實作雙軌窗口</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>大量低敏 config / feature flag</td>
          <td><a href="https://docs.aws.amazon.com/systems-manager/">SSM Parameter Store</a>（free tier、無 rotation 需求）</td>
      </tr>
      <tr>
          <td>跨雲統一 secret 控制面</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a></td>
      </tr>
      <tr>
          <td>Dynamic DB credential（non-AWS DB）</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault database engine</a></td>
      </tr>
      <tr>
          <td>Workload 拿 AWS credential</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> role（EC2 instance role / ECS task role / IRSA）— 不要把 AWS credential 塞 secret</td>
      </tr>
      <tr>
          <td>Encryption-as-a-service / envelope encryption</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a> Encrypt / Decrypt API、或 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault transit engine</a></td>
      </tr>
      <tr>
          <td>內部 PKI / mTLS workload cert</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a> + <a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS Private CA</a></td>
      </tr>
      <tr>
          <td>Secret rotation 跨服務 scope 治理</td>
          <td><a href="/blog/backend/07-security-data-protection/credential-rotation-scoped-evidence/" data-link-title="7.27 Credential Rotation with Scoped Evidence 實作示範" data-link-desc="以 webhook/API credential 輪替示範 scope map、證據欄位與回退窗口如何一起設計。">7.5 Credential Rotation Scoped Evidence</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>Secrets Manager 完整 API reference 跟 SDK 用法</li>
<li>每種 RDS engine 的 rotation Lambda template 內部 SQL 細節</li>
<li>AWS pricing 詳細計算（每 region 略有差異）</li>
<li>Terraform / CDK 跟 Secrets Manager 的 IaC 整合</li>
<li>AWS account organization / SCP 怎麼限制 secret 建立</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>Secrets Manager 在 07 案例庫沒有直接 vendor-level 事件、以下案例採對照引用：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 Secrets Manager 的關係（對照）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>Secrets Manager rotation 必須有 scope map — 跨服務共用同一把 secret 時、AWSPREVIOUS 窗口期 + 雙軌驗證要對齊長尾 batch job、不能單靠 Lambda 自動 promote</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/circleci-2023-secrets-rotation/" data-link-title="7.R7.2.3 CircleCI 2023：CI secrets 輪替壓力" data-link-desc="工程端點入侵後，CI 平台 secrets 如何成為高風險擴散點">CircleCI 2023 Secrets Rotation (red-team)</a></td>
          <td>CI 出事時 Secrets Manager 內 <em>所有 CI runner role 可拿的 secret</em> 都要 rotate — 必須事先以 ABAC tag 標 blast radius、不然只能盲掃整個 account</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain (red-team)</a></td>
          <td>對照啟示 — Secrets Manager 的 KMS encryption key 必須走 CMK 而非 AWS-managed key、key policy 限定 only Secrets Manager service principal 且 only specific role 可 Decrypt、把 blast radius 鎖在 key policy 內</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a>、<a href="/blog/backend/07-security-data-protection/vendors/google-secret-manager/" data-link-title="Google Secret Manager" data-link-desc="GCP 原生 secret store、CMEK &#43; Workload Identity Federation 整合、rotation 走自寫 Cloud Function 而非 built-in Lambda">Google Secret Manager</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a>（Secrets Manager 加密 key custodian、CMK 與 key policy 治理）</li>
<li>下游：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a>（誰可以 GetSecretValue、跨帳號 share 的 principal 來源）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（secret 外洩事件如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/secretsmanager/">AWS Secrets Manager Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>AWS WAF</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-waf/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-waf/</guid><description>&lt;p>AWS WAF 是 &lt;em>AWS-internal&lt;/em> 的 Web Application Firewall、掛在 ALB、CloudFront、API Gateway、App Runner、AppSync 與 Cognito User Pool 的前面，攔截 HTTP/HTTPS 攻擊。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &amp;#43; DDoS &amp;#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &amp;#43; ATO &amp;#43; Bot 一體">Fastly Next-Gen WAF&lt;/a> 的核心差異是 &lt;em>部署位置在 AWS 內部&lt;/em>：流量先經 AWS 邊界進來、再進 Web ACL 過濾、最後抵達 origin；不是在 Cloudflare anycast edge 提早攔。對 AWS-heavy 客戶、AWS WAF 的價值是 &lt;em>跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> / VPC / &lt;a href="https://docs.aws.amazon.com/waf/latest/developerguide/shield-chapter.html">AWS Shield&lt;/a> 同一個控制面&lt;/em>；對 multi-cloud / on-prem origin、AWS WAF 觸不到、要回到 edge WAF。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>AWS WAF 的核心定位是 &lt;em>跟 AWS 服務深度耦合的 L7 防護層&lt;/em>。Web ACL 直接掛 AWS resource、規則用 IAM policy 管理、log 進 Kinesis Firehose / CloudWatch Logs / S3、跟 AWS Shield Standard（內含、L3/L4 DDoS）自動整合。這跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &amp;#43; DDoS &amp;#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF&lt;/a> 在 &lt;em>origin 之前的 edge&lt;/em> 攔截不同 — AWS WAF 流量 &lt;em>已經進到 AWS 邊界&lt;/em>、不是擋在外部。對 origin 跑在 ALB / CloudFront / API Gateway 後的客戶、AWS WAF 是天然選項；origin 在其他雲或地端、AWS WAF 觸不到。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &amp;#43; ATO &amp;#43; Bot 一體">Fastly Next-Gen WAF&lt;/a> 相比、AWS WAF 走 &lt;em>signature + managed rule group&lt;/em> 偵測模型、不像 Fastly NG-WAF 走語意 / behavioral；AWS WAF 的 Managed Rule Group 來自 AWS Managed 與 AWS Marketplace 第三方（Fortinet、F5、Imperva 等）、客戶端 &lt;em>看不到 rule logic&lt;/em>、debug 時要靠 sampled request 反推。&lt;/p></description><content:encoded><![CDATA[<p>AWS WAF 是 <em>AWS-internal</em> 的 Web Application Firewall、掛在 ALB、CloudFront、API Gateway、App Runner、AppSync 與 Cognito User Pool 的前面，攔截 HTTP/HTTPS 攻擊。它跟 <a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a> / <a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly Next-Gen WAF</a> 的核心差異是 <em>部署位置在 AWS 內部</em>：流量先經 AWS 邊界進來、再進 Web ACL 過濾、最後抵達 origin；不是在 Cloudflare anycast edge 提早攔。對 AWS-heavy 客戶、AWS WAF 的價值是 <em>跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> / VPC / <a href="https://docs.aws.amazon.com/waf/latest/developerguide/shield-chapter.html">AWS Shield</a> 同一個控制面</em>；對 multi-cloud / on-prem origin、AWS WAF 觸不到、要回到 edge WAF。</p>
<h2 id="服務定位">服務定位</h2>
<p>AWS WAF 的核心定位是 <em>跟 AWS 服務深度耦合的 L7 防護層</em>。Web ACL 直接掛 AWS resource、規則用 IAM policy 管理、log 進 Kinesis Firehose / CloudWatch Logs / S3、跟 AWS Shield Standard（內含、L3/L4 DDoS）自動整合。這跟 <a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a> 在 <em>origin 之前的 edge</em> 攔截不同 — AWS WAF 流量 <em>已經進到 AWS 邊界</em>、不是擋在外部。對 origin 跑在 ALB / CloudFront / API Gateway 後的客戶、AWS WAF 是天然選項；origin 在其他雲或地端、AWS WAF 觸不到。</p>
<p>跟 <a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly Next-Gen WAF</a> 相比、AWS WAF 走 <em>signature + managed rule group</em> 偵測模型、不像 Fastly NG-WAF 走語意 / behavioral；AWS WAF 的 Managed Rule Group 來自 AWS Managed 與 AWS Marketplace 第三方（Fortinet、F5、Imperva 等）、客戶端 <em>看不到 rule logic</em>、debug 時要靠 sampled request 反推。</p>
<p>計費模型也是關鍵差異：AWS WAF 按 <em>per-Web-ACL + per-rule + per-request</em> 計費（單 ACL $5/月、單 rule $1/月、$0.60 per 1M request），Managed Rule Group 算多 rule、開太多套 ruleset 與流量大時帳單會明顯漲。Cloudflare 是 plan-tier 計費（Pro / Business / Enterprise）、不會因為多開 rule 線性漲價。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>AWS WAF 在 AWS-internal 防護 stack 中承擔哪一段、哪些要靠 <a href="https://docs.aws.amazon.com/waf/latest/developerguide/shield-chapter.html">AWS Shield</a> / VPC / CloudFront 補位</li>
<li>Web ACL scope（Regional vs CloudFront）的選擇與跨 region 部署成本</li>
<li>Managed Rule Group / Custom Rule / Rate-based Rule 的取捨、Bot Control add-on 是否值得開</li>
<li>何時用 AWS WAF、何時走 <a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a> / <a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly NG-WAF</a> 的判準</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 AWS WAF 配置是否健康、最少看四件事：</p>
<ul>
<li><strong>Web ACL scope 對不對</strong>：CloudFront distribution 必須掛 <em>CloudFront scope</em>（強制在 us-east-1 建立 ACL）、ALB / API Gateway 必須掛 <em>Regional scope</em>（每個 region 各一份）；scope 配錯掛不上去、跨 region 部署是否用 IaC（Terraform / CloudFormation）同步複製 ACL</li>
<li><strong>Managed Rule Group 與 sensitivity</strong>：是否啟用 <em>AWSManagedRulesCommonRuleSet</em>（CRS）、<em>AmazonIpReputationList</em>（已知惡意 IP）、<em>AnonymousIpList</em>（VPN / proxy / Tor）、<em>KnownBadInputsRuleSet</em>（已知 exploit pattern）、Marketplace rule 是否在 Count mode 觀察 1-2 週 FP 再切 Block</li>
<li><strong>Logging 有沒有開</strong>：Web ACL log 預設關閉、必須手動配 Kinesis Firehose / CloudWatch Logs / S3 destination；event 是否進 SIEM（見 <a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a>）、是否能對 sampled request 反推 rule 行為</li>
<li><strong>IAM 邊界</strong>：誰能 update Web ACL（<code>wafv2:UpdateWebACL</code>、<code>wafv2:UpdateRuleGroup</code>）、是否限定 admin role 才能改、CI 是否只有 <code>wafv2:Get*</code> / <code>List*</code> 用來 verify、敏感變更是否走 Change Management / <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a></li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">Entry Point Protection</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Web ACL 與 scope</strong>：Web ACL 是 AWS WAF 的 <em>規則容器</em>、必須 attach 到 AWS resource。Scope 兩種：<em>Regional</em>（給 ALB / API Gateway / App Runner / AppSync / Cognito User Pool、每 region 獨立）與 <em>CloudFront</em>（給 CloudFront distribution、必須在 us-east-1 建立、全球生效）。同一個 ACL 不能跨 scope 共用；跨 region 部署同一套規則必須複製 ACL、用 Terraform / CloudFormation 管理避免 drift。</p>
<p><strong>Rule action 五種</strong>：每個 rule 觸發時可以做 <em>Block</em>（直接 403）、<em>Allow</em>（跳過後續 rule、放行）、<em>Count</em>（不擋、只記錄、用於 dry-run 觀察 FP）、<em>CAPTCHA</em>（出題給人類解、bot 過不去）、<em>Challenge</em>（silent JS challenge、無感驗證）。新 rule 上線標準動作是先 <em>Count</em> 1-2 週看 sample、確認 FP 在容忍範圍才切 <em>Block</em>。CAPTCHA / Challenge 是 <a href="https://docs.aws.amazon.com/waf/latest/developerguide/waf-bot-control.html">Bot Control add-on</a> 配套、要額外計費。</p>
<p><strong>Managed Rule Group（managed by AWS / Marketplace）</strong>：AWS Managed（免費含在 WAF）涵蓋 <em>Common Rule Set</em>（OWASP top10 對應）、<em>Known Bad Inputs</em>、<em>SQL Database</em>、<em>Linux</em>、<em>Unix</em>、<em>Windows</em>、<em>Anonymous IP List</em>、<em>Amazon IP Reputation List</em>、<em>Account Takeover Prevention (ATP)</em>、<em>Account Creation Fraud Prevention (ACFP)</em>。AWS Marketplace（付費）來自 Fortinet / F5 / Imperva / Cyber Security Cloud 等。Marketplace 規則 <em>不公開 rule logic</em>、攔錯時只能用 sampled request 反推、debug 比 AWS Managed 困難。</p>
<p><strong>Custom Rule（statement + 條件）</strong>：Custom Rule 用 <em>statement</em>（match condition + transformation）組合：IP Set match、Geo match、Regex Pattern Set、Size constraint、SQL injection match、XSS match、String match（含 header / body / URI / query 各部位）。複雜條件用 AND / OR / NOT 組合、上限是每 Web ACL 5,000 Web ACL Capacity Units（WCU）— 規則越複雜 WCU 越高、Marketplace 大型 rule group 可能直接吃掉一半 budget。</p>
<p><strong>IP Set / Regex Pattern Set</strong>：IP Set 存 IPv4 / IPv6 CIDR 清單、Regex Pattern Set 存正則表達式集合。兩者都是 <em>獨立資源</em>、可在多個 Web ACL 引用、單獨更新（不必動 Web ACL 結構）。實務上 threat intel feed 應該 push 到 IP Set、用 Lambda 自動 sync、不用手動加。</p>
<p><strong>Rate-based Rule</strong>：限制 <em>單一 aggregate key</em> 在滾動 5 分鐘窗口內的請求數、超過 threshold 觸發 action。aggregate key 可選 <em>IP</em>、<em>Forwarded-IP</em>（看 X-Forwarded-For）、<em>HTTP method</em>、<em>URI path</em>、<em>Header</em>、<em>Cookie</em> 或組合。關鍵陷阱：<strong>CloudFront 後 origin ALB 必須用 Forwarded-IP</strong>、否則 Rate-based Rule 看到的全是 CloudFront 邊緣節點 IP、所有真實使用者被合併計算、要嘛全擋要嘛全放。</p>
<p><strong>Logging 必須手動開</strong>：Web ACL log 預設關閉、destination 三選一：<em>Kinesis Data Firehose</em>（推到 S3 / Splunk / Datadog）、<em>CloudWatch Logs</em>（簡單但貴）、<em>S3</em>（直寫、需自己處理 partition）。production 通常走 Kinesis Firehose → S3 + Athena query、配合 SIEM 拉 alert。沒開 log 等於 <em>攻擊發生時沒證據</em>、事後無法回查。</p>
<p><strong>跟 AWS Shield 整合</strong>：所有 AWS WAF 客戶自動含 <em>Shield Standard</em>（L3/L4 DDoS、免費、SYN flood / UDP reflection 等基礎防護）。<em>Shield Advanced</em> 是付費 add-on（$3,000/month per organization + per-resource fee + data transfer out fee）、提供 <em>24/7 DRT（DDoS Response Team）</em>、cost protection（DDoS 期間 AWS service scaling fee 補貼）、進階分析。一般客戶 Shield Standard 已足夠；金融 / 政府 / 高知名度品牌需要 Shield Advanced 的 DRT 與 cost protection。</p>
<p><strong>Lambda@Edge / CloudFront Functions 補位</strong>：當 WAF rule statement 表達不出複雜業務邏輯（geofencing + business hour + user tier 組合、JWT claim 解析後判斷 routing）、用 <em>Lambda@Edge</em>（Node.js / Python、跑在 CloudFront 邊緣節點、4 個 phase：viewer-request / origin-request / origin-response / viewer-response）或 <em>CloudFront Functions</em>（純 JS、輕量、低延遲、只在 viewer-request / viewer-response）補位。Lambda@Edge 適合複雜邏輯、CloudFront Functions 適合 header rewrite / 簡單 routing；兩者都不能取代 WAF managed rule、但補位 WAF 表達力上限。</p>
<p><strong>跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 整合</strong>：誰能改 Web ACL 是 <em>IAM policy</em> 決定（<code>wafv2:CreateWebACL</code>、<code>wafv2:UpdateWebACL</code>、<code>wafv2:AssociateWebACL</code>、<code>wafv2:UpdateRuleGroup</code> 等 action）。production 標準配置：admin role 才能 update、CI / 開發者只有 <code>wafv2:Get*</code> / <code>List*</code> 用來 verify、敏感變更走 Change Management + CloudTrail <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">audit log</a>。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS WAF</th>
          <th>Cloudflare WAF</th>
          <th>Fastly Next-Gen WAF</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署位置</td>
          <td>AWS 內部（ALB / CloudFront / API Gateway 前）</td>
          <td>Cloudflare global edge（300+ POP）</td>
          <td>Fastly global edge / 各 origin agent</td>
      </tr>
      <tr>
          <td>Origin 適配</td>
          <td>強耦合 — origin 必須在 AWS</td>
          <td>強中立 — 任意雲 / on-prem</td>
          <td>強中立 — Fastly CDN / 任何 origin</td>
      </tr>
      <tr>
          <td>計費模型</td>
          <td>per-ACL + per-rule + per-request</td>
          <td>plan tier（Free / Pro / Business / Enterprise）</td>
          <td>request-based + plan</td>
      </tr>
      <tr>
          <td>Managed Rule</td>
          <td>AWS Managed（免費）+ Marketplace（付費、logic 不透明）</td>
          <td>Cloudflare Managed + OWASP CRS + Exposed Credentials</td>
          <td>Signal-based（語意、低 FP、不靠 regex signature）</td>
      </tr>
      <tr>
          <td>Rate Limiting</td>
          <td>Rate-based Rule（含在 WAF、5 分鐘 window）</td>
          <td>Rate Limiting 獨立 product</td>
          <td>inline rate limit + Signal</td>
      </tr>
      <tr>
          <td>Bot 對應</td>
          <td>AWS WAF Bot Control（add-on、付費）</td>
          <td>Bot Management（Pro+ add-on）</td>
          <td>NG-WAF behavioral bot detection</td>
      </tr>
      <tr>
          <td>DDoS 內建</td>
          <td>Shield Standard 自動含（L3/L4）、Advanced 加價</td>
          <td>同套餐內建</td>
          <td>內建 + Fastly DDoS</td>
      </tr>
      <tr>
          <td>控制面整合</td>
          <td>跟 IAM / CloudTrail / Shield / VPC 同 plane</td>
          <td>Cloudflare 控制面、跟其他 Cloudflare 產品同套</td>
          <td>Fastly 控制面、agent 跑在 origin</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>中陡 — Web ACL + WCU + scope + IAM policy 多軌</td>
          <td>中 — UI / Rules language / Terraform 完整</td>
          <td>中 — agent 安裝 + Signal 語意設定</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-heavy、ALB / CloudFront 是主要入口</td>
          <td>Multi-cloud / on-prem origin、要整套 edge security</td>
          <td>高 FP 容忍度低、業務有 schema、想避 regex signature</td>
      </tr>
  </tbody>
</table>
<p>選 AWS WAF 的核心訴求：<em>AWS-internal app</em> + origin 跑在 ALB / CloudFront / API Gateway / App Runner 後 + 想跟 IAM / CloudTrail / Shield 同套 control plane 治理。Origin 不在 AWS、或要 <em>把攻擊擋在抵達雲之前</em>、應該走 <a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a> 或 <a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly NG-WAF</a>。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>AWS WAF Bot Control（add-on）</strong>：付費 add-on、用 AWS 自家 bot fingerprinting 區分 <em>verified bot</em>（搜尋引擎）/ <em>signal: automated browser</em>（headless Chrome 等）/ <em>signal: known bot</em>（已標記 IoT / scraper），給每個請求 <em>bot category label</em>。Custom Rule 在 label 上做條件、決定 Block / Challenge / CAPTCHA。比 user-agent 過濾準很多、但要額外計費（per-request）。Bot Control 有兩個 inspection level：<em>common</em>（便宜、基礎指紋）與 <em>targeted</em>（貴、含 JavaScript challenge、CAPTCHA、token-based）。</p>
<p><strong>Fraud Control（ATP / ACFP）</strong>：<em>Account Takeover Prevention</em>（ATP）跟 <em>Account Creation Fraud Prevention</em>（ACFP）是 Managed Rule Group 的特殊類別、需付費啟用。ATP 看登入端點的 credential stuffing、ACFP 看註冊端點的 bot signup。兩者都用 AWS 自家 threat intel（被竊憑證 list、行為模型）打 label、客戶側用 Custom Rule 處理。對有 login / signup 端點的 SaaS / 電商有價值、純內部後台不必開。</p>
<p><strong>CAPTCHA / Challenge</strong>：AWS WAF 內建 CAPTCHA puzzle 與 silent JS Challenge、可在 rule action 直接呼叫。Challenge 在客戶端執行 proof-of-work、合法瀏覽器無感、headless 工具卡住；CAPTCHA 是視覺題、人類解、bot 不會。Production 標準做法：Bot Control 給 label → Custom Rule 看 label → likely bot 走 Challenge、known bad 走 Block、人類流量直接 Allow。</p>
<p><strong>ACM Private CA + WAF 對 mTLS</strong>：AWS WAF 本身不做 mTLS 驗證、mTLS 是 ALB / API Gateway / CloudFront 自己的功能（搭配 <a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS ACM</a> Private CA 簽發 client cert）。WAF 在 mTLS 完成後才看 L7 流量、可以用 <em>HTTP header match</em>（mTLS 後 ALB 注入 client cert 資訊到 header）做進一步 rule。Internal API 用 mTLS + WAF 是常見組合。</p>
<p><strong>Lambda@Edge 補 inline business logic</strong>：複雜判斷（user tier × geo × business hour × A/B test）WAF rule statement 表達不出來、用 Lambda@Edge 在 <em>viewer-request</em> phase 解析 JWT、查 internal risk API、回 response header 給 WAF 後續判斷。代價：Lambda@Edge 部署只能在 us-east-1、code 更新傳播到全球 edge 要幾分鐘、debug 是分散式 CloudWatch Logs。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Web ACL 掛不上 CloudFront</strong>：scope 配成 Regional、CloudFront 拒絕 attach — Web ACL 必須在 us-east-1 + CloudFront scope 才能掛 CloudFront；ALB / API Gateway 反過來只能掛 Regional scope</li>
<li><strong>Rate-based Rule 全擋 / 全放</strong>：CloudFront 後 origin 看到全部都是 CloudFront IP、aggregate key 沒換 Forwarded-IP — 改用 <em>Forwarded-IP</em>（X-Forwarded-For）作 aggregate key，並設 Fallback behavior</li>
<li><strong>Managed Rule Group 誤殺合法請求</strong>：CRS High sensitivity 開後 file upload / rich text editor 端點被 Block — 找 sampled request 看 rule_id、用 <em>Scope-down statement</em> 限定該 rule 在某 path 不執行、或開該 rule 為 Count、不要關整個 group</li>
<li><strong>Marketplace Rule 攔不明流量</strong>：Marketplace rule logic 不公開、sampled request 看到 rule label 但不知為何 — 切該 rule 到 Count mode 觀察、若無 attack 跡象換 AWS Managed 同類 rule</li>
<li><strong>WCU 超限</strong>：Web ACL 上限 5,000 WCU、加 Marketplace + 多個 AWS Managed 就會爆 — 看 <em>Capacity Used</em>、移除重疊 rule、把 Custom Rule 表達式簡化（少用 <em>transformation chain</em>）</li>
<li><strong>Logging 沒設 / 設錯</strong>：事件發生後沒有完整 log 可查、只有 sampled request（保留 3 小時、機率抽樣） — 必開 <em>Logging configuration</em> 到 Kinesis Firehose / S3 / CloudWatch Logs、確認 IAM role 有 firehose:PutRecord 權限</li>
<li><strong>IAM 權限過寬</strong>：CI account 拿到 <code>wafv2:*</code> 整 zone 都能改 — 收斂到 <code>wafv2:Get*</code> / <code>List*</code> 唯讀、敏感寫入限 admin role + MFA + Change Management</li>
<li><strong>跨 region 部署 drift</strong>：手動在 console 改 us-east-1 ACL、其他 region 沒同步 — 用 Terraform / CloudFormation IaC 管理、PR review、CI plan 檢查 drift</li>
<li><strong>Shield Standard 不夠擋大型 L7 DDoS</strong>：Standard 只防 L3/L4、L7 attack 靠 WAF Rate-based Rule + Bot Control — 若反覆遭遇大型 L7 DDoS、評估 Shield Advanced 的 DRT + cost protection 是否值得</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Multi-cloud / on-prem origin</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a></td>
      </tr>
      <tr>
          <td>低 FP 容忍 / 業務有 schema</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly Next-Gen WAF</a></td>
      </tr>
      <tr>
          <td>L3/L4 DDoS 進階防護</td>
          <td>AWS Shield Advanced / Cloudflare Magic Transit</td>
      </tr>
      <tr>
          <td>純內部 mTLS / east-west</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/spire/" data-link-title="SPIRE" data-link-desc="SPIFFE Runtime Environment、attested workload identity、short-lived SVID &#43; Trust Bundle、跨組織 federation">SPIRE</a> + service mesh</td>
      </tr>
      <tr>
          <td>Cert lifecycle</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS ACM</a> / <a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a></td>
      </tr>
      <tr>
          <td>Secrets / API key</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a> / <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a></td>
      </tr>
      <tr>
          <td>複雜業務邏輯 inline 處理</td>
          <td>Lambda@Edge / CloudFront Functions</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>AWS WAF Classic（v1）的遷移細節 — 本頁全以 WAFv2 為準</li>
<li>完整 WCU 計算規則與每個 statement 的 WCU cost reference</li>
<li>Marketplace 第三方 rule group 各家功能矩陣</li>
<li>AWS WAF 在 GovCloud / China region 的差異</li>
<li>Bot Control / ATP / ACFP 完整 label schema reference</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>AWS WAF 在 07 案例庫無直接 vendor-level case、但多個 case 對應 WAF 作為 <em>修補窗口期臨時控制</em> 與 <em>entry point 治理</em> 的角色：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 AWS WAF 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/supply-chain/log4shell-cve-2021-44228-component-chain/" data-link-title="7.R7.2.7 Log4Shell 2021：共用元件風險與修補鏈" data-link-desc="共用元件漏洞如何同步影響多服務，並迫使團隊建立依賴治理 workflow">Log4Shell CVE-2021-44228</a></td>
          <td>對照啟示 — AWS Managed Rule Group 當時推出 Log4Shell 規則作為 emergency mitigation；但 exploitation 通過 WAF 後在後端執行，不能單靠 WAF 防 supply chain</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/edge-exposure/citrix-bleed-2023-session-hijack/" data-link-title="7.R7.3.3 Citrix Bleed 2023：會話被劫持與重放風險" data-link-desc="邊界設備會話資料外洩後，如何演變成帳號與服務風險">Citrix Bleed 2023 Session Hijack</a></td>
          <td>對照啟示 — WAF 攔不住 edge appliance zero-day、需要「修補 + session 失效 + 異常清查」三同步</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/edge-exposure/fortinet-cve-2023-27997-sslvpn-overflow/" data-link-title="7.R7.3.21 Fortinet 2023：CVE-2023-27997 SSL-VPN 溢位" data-link-desc="SSL-VPN 漏洞在邊界設備上會放大大規模掃描與利用速度">Fortinet SSL-VPN CVE 2023-27997</a></td>
          <td>對照啟示 — vendor patch 前的臨時 AWS WAF Custom Rule + Shield Advanced + Origin lockdown 是修補窗口期動作</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理與伺服器防護</a></td>
          <td>AWS WAF 是 entry point protection 的工具、章節原則對應 WAF rule lifecycle 治理（Count → Block、IaC、IAM 收斂）</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理與伺服器防護</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/cloudflare-waf/" data-link-title="Cloudflare WAF" data-link-desc="Edge WAF &#43; DDoS &#43; Bot management 整合套件、global anycast 網路、控制面信任邊界跟客戶側補強的對照">Cloudflare WAF</a>、<a href="/blog/backend/07-security-data-protection/vendors/fastly-ngwaf/" data-link-title="Fastly Next-Gen WAF" data-link-desc="Behavioral / 語意分析 WAF（前 Signal Sciences）、低 false positive、Edge / Agent / Cloud 三種部署模型、API &#43; ATO &#43; Bot 一體">Fastly Next-Gen WAF</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 資料保護與遮罩治理</a>（WAF block 不夠時、資料層也要遮罩）</li>
<li>跨類：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a>（誰能改 Web ACL）、<a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS ACM</a>（mTLS client cert）、<a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a>（rule update 用的 API key）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（WAF block 事件如何 routing 進 IR）</li>
<li>官方：<a href="https://docs.aws.amazon.com/waf/latest/developerguide/">AWS WAF Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>AWS 2021 US-EAST-1 Control Plane Degradation</title><link>https://tarrragon.github.io/blog/backend/08-incident-response/cases/aws-s3/2021-us-east-1-control-plane-degradation/</link><pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/08-incident-response/cases/aws-s3/2021-us-east-1-control-plane-degradation/</guid><description>&lt;p>2021 年 AWS us-east-1 事件的核心教訓是：控制面退化不一定來自服務程式錯誤，內部網路壓力也能讓 API 與依賴鏈條同時失真。這類事故要先確認控制面健康，再決定是否進行服務層回退。&lt;/p>
&lt;h2 id="事故摘要">事故摘要&lt;/h2>
&lt;p>AWS 在 2021-12-07 發生 us-east-1 多服務退化事件。官方資訊指出，內部網路裝置的異常行為導致這個區域的 API 請求與內部服務通訊壅塞，進而造成多個服務管理與控制面能力受影響。部分資料面能力可用，但控制面操作、狀態回報與恢復節奏出現延遲。&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>多服務 API 錯誤率同時上升&lt;/td>
 &lt;td>共享控制面或內部網路層可能失真&lt;/td>
 &lt;td>優先調查共用控制平面，不先分散逐服務排障&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>控制操作延遲遠高於資料讀寫&lt;/td>
 &lt;td>控制面與資料面可用性不同步&lt;/td>
 &lt;td>對外通訊要分清 control/data plane 差異&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>區域集中異常（us-east-1）&lt;/td>
 &lt;td>區域依賴與路由聚集形成單點風險&lt;/td>
 &lt;td>啟動跨區降載或備援策略&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>狀態更新節奏出現抖動&lt;/td>
 &lt;td>事故資訊供應鏈本身受影響&lt;/td>
 &lt;td>建立固定 cadence 與替代更新通道&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="事故路徑">事故路徑&lt;/h2>
&lt;ol>
&lt;li>區域內部網路層出現異常與壅塞。&lt;/li>
&lt;li>控制面 API 與內部依賴通訊受阻。&lt;/li>
&lt;li>多服務管理能力與狀態回報受到影響。&lt;/li>
&lt;li>部分服務資料面仍可運作，但操作與恢復節奏失真。&lt;/li>
&lt;li>團隊逐步收斂網路壓力並恢復控制面可用性。&lt;/li>
&lt;/ol>
&lt;p>這條路徑顯示：真正的擴散點在 shared internal network + control plane，不是某個單一服務程式。&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>Control/Data plane 分離判讀&lt;/td>
 &lt;td>對外敘述常把兩者混在一起&lt;/td>
 &lt;td>在通訊與 runbook 明確區分控制面與資料面狀態&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>區域依賴治理&lt;/td>
 &lt;td>單區域控制面異常可牽動多服務&lt;/td>
 &lt;td>把跨區備援與降載條件納入 release 與 incident gate&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Shared network health 訊號治理&lt;/td>
 &lt;td>內部網路異常訊號未被快速上提&lt;/td>
 &lt;td>補 shared infrastructure 指標到 [4.20 evidence package]&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Incident communication cadence&lt;/td>
 &lt;td>事故中更新節奏易受狀態不完整影響&lt;/td>
 &lt;td>固定 cadence，並保留「已知 / 未知 / 下一更新時間」欄位&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>觀測證據包： &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">4.20 Observability Evidence Package&lt;/a>&lt;/li>
&lt;li>可觀測性 operating model： &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/observability-operating-model/" data-link-title="4.18 Observability Operating Model" data-link-desc="定義 platform / service team / on-call 對訊號、dashboard、alert 與成本的 ownership">4.18 Observability Operating Model&lt;/a>&lt;/li>
&lt;li>可靠性準備度： &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/reliability-readiness-review/" data-link-title="6.19 Reliability Readiness Review" data-link-desc="把上線前、重大變更前與高風險操作前的可靠性準備度變成可檢查門檻">6.19 Reliability Readiness Review&lt;/a>&lt;/li>
&lt;li>止血與回復： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/containment-recovery-strategy/" data-link-title="8.3 止血、降級與回復策略" data-link-desc="把短期止血與正式回復拆成可執行步驟">8.3 Containment / Recovery Strategy&lt;/a>&lt;/li>
&lt;li>事故通訊： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">8.4 Incident Communication&lt;/a>&lt;/li>
&lt;li>影響評估： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/customer-impact-assessment/" data-link-title="8.20 Customer Impact Assessment" data-link-desc="把受影響用戶、功能、區域、金額、SLO 與補償判斷串成影響評估模型">8.20 Customer Impact Assessment&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://aws.amazon.com/message/12721/">Summary of the AWS service event in the Northern Virginia (US-EAST-1) Region&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>2021 年 AWS us-east-1 事件的核心教訓是：控制面退化不一定來自服務程式錯誤，內部網路壓力也能讓 API 與依賴鏈條同時失真。這類事故要先確認控制面健康，再決定是否進行服務層回退。</p>
<h2 id="事故摘要">事故摘要</h2>
<p>AWS 在 2021-12-07 發生 us-east-1 多服務退化事件。官方資訊指出，內部網路裝置的異常行為導致這個區域的 API 請求與內部服務通訊壅塞，進而造成多個服務管理與控制面能力受影響。部分資料面能力可用，但控制面操作、狀態回報與恢復節奏出現延遲。</p>
<p>這類事故的難點在於，使用者看到的是「很多服務一起怪」，而工程上真正要先判斷的是：共同依賴是否先失真。</p>
<h2 id="判讀訊號">判讀訊號</h2>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>事故中代表什麼</th>
          <th>第一波決策價值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多服務 API 錯誤率同時上升</td>
          <td>共享控制面或內部網路層可能失真</td>
          <td>優先調查共用控制平面，不先分散逐服務排障</td>
      </tr>
      <tr>
          <td>控制操作延遲遠高於資料讀寫</td>
          <td>控制面與資料面可用性不同步</td>
          <td>對外通訊要分清 control/data plane 差異</td>
      </tr>
      <tr>
          <td>區域集中異常（us-east-1）</td>
          <td>區域依賴與路由聚集形成單點風險</td>
          <td>啟動跨區降載或備援策略</td>
      </tr>
      <tr>
          <td>狀態更新節奏出現抖動</td>
          <td>事故資訊供應鏈本身受影響</td>
          <td>建立固定 cadence 與替代更新通道</td>
      </tr>
  </tbody>
</table>
<h2 id="事故路徑">事故路徑</h2>
<ol>
<li>區域內部網路層出現異常與壅塞。</li>
<li>控制面 API 與內部依賴通訊受阻。</li>
<li>多服務管理能力與狀態回報受到影響。</li>
<li>部分服務資料面仍可運作，但操作與恢復節奏失真。</li>
<li>團隊逐步收斂網路壓力並恢復控制面可用性。</li>
</ol>
<p>這條路徑顯示：真正的擴散點在 shared internal network + control plane，不是某個單一服務程式。</p>
<h2 id="可回寫控制面">可回寫控制面</h2>
<table>
  <thead>
      <tr>
          <th>控制面</th>
          <th>這次事故暴露的缺口</th>
          <th>回寫方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Control/Data plane 分離判讀</td>
          <td>對外敘述常把兩者混在一起</td>
          <td>在通訊與 runbook 明確區分控制面與資料面狀態</td>
      </tr>
      <tr>
          <td>區域依賴治理</td>
          <td>單區域控制面異常可牽動多服務</td>
          <td>把跨區備援與降載條件納入 release 與 incident gate</td>
      </tr>
      <tr>
          <td>Shared network health 訊號治理</td>
          <td>內部網路異常訊號未被快速上提</td>
          <td>補 shared infrastructure 指標到 [4.20 evidence package]</td>
      </tr>
      <tr>
          <td>Incident communication cadence</td>
          <td>事故中更新節奏易受狀態不完整影響</td>
          <td>固定 cadence，並保留「已知 / 未知 / 下一更新時間」欄位</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<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 與資料品質限制包成可交接證據">4.20 Observability Evidence Package</a></li>
<li>可觀測性 operating model： <a href="/blog/backend/04-observability/observability-operating-model/" data-link-title="4.18 Observability Operating Model" data-link-desc="定義 platform / service team / on-call 對訊號、dashboard、alert 與成本的 ownership">4.18 Observability Operating Model</a></li>
<li>可靠性準備度： <a href="/blog/backend/06-reliability/reliability-readiness-review/" data-link-title="6.19 Reliability Readiness Review" data-link-desc="把上線前、重大變更前與高風險操作前的可靠性準備度變成可檢查門檻">6.19 Reliability Readiness Review</a></li>
<li>止血與回復： <a href="/blog/backend/08-incident-response/containment-recovery-strategy/" data-link-title="8.3 止血、降級與回復策略" data-link-desc="把短期止血與正式回復拆成可執行步驟">8.3 Containment / Recovery Strategy</a></li>
<li>事故通訊： <a href="/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">8.4 Incident Communication</a></li>
<li>影響評估： <a href="/blog/backend/08-incident-response/customer-impact-assessment/" data-link-title="8.20 Customer Impact Assessment" data-link-desc="把受影響用戶、功能、區域、金額、SLO 與補償判斷串成影響評估模型">8.20 Customer Impact Assessment</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://aws.amazon.com/message/12721/">Summary of the AWS service event in the Northern Virginia (US-EAST-1) Region</a></li>
</ul>
]]></content:encoded></item><item><title>AWS：Control Plane 事故的責任邊界與通訊節奏樣式（2023）</title><link>https://tarrragon.github.io/blog/backend/08-incident-response/cases/aws-s3/2023-control-plane-accountability-and-communication-pattern/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/08-incident-response/cases/aws-s3/2023-control-plane-accountability-and-communication-pattern/</guid><description>&lt;p>這篇的核心責任是補齊「控制面事故如何說清楚責任邊界」。和 2017、2021 兩篇相比，這裡重點在事故治理樣式、單一技術細節是次要的：怎麼分辨控制面與資料面、怎麼維持對外更新節奏、怎麼保留決策脈絡。&lt;/p>
&lt;h2 id="問題場景">問題場景&lt;/h2>
&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>多服務管理 API 同步抖動&lt;/td>
 &lt;td>shared control plane 可能異常&lt;/td>
 &lt;td>先建立單一 incident thread&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料讀寫可用但控制操作失真&lt;/td>
 &lt;td>control/data plane 分離已發生&lt;/td>
 &lt;td>對外更新分兩條狀態敘述&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>更新頻率不穩、描述反覆修正&lt;/td>
 &lt;td>evidence pipeline 不穩定&lt;/td>
 &lt;td>固定更新 cadence 與欄位結構&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>回退有效但後續仍有殘留警訊&lt;/td>
 &lt;td>依賴鏈條尚未收斂&lt;/td>
 &lt;td>增加 dependency-level 驗證步驟&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="事故治理路徑樣式">事故治理路徑（樣式）&lt;/h2>
&lt;ol>
&lt;li>啟動單一事件線，避免按產品拆散。&lt;/li>
&lt;li>明確標註控制面與資料面狀態，分開追蹤。&lt;/li>
&lt;li>固定對外 cadence（例如每 30 分鐘）更新「已知 / 未知 / 下一步」。&lt;/li>
&lt;li>在 decision log 記錄假設、證據、回退條件與 owner。&lt;/li>
&lt;li>收斂後把通訊節奏與責任邊界回寫 runbook 與 evidence package。&lt;/li>
&lt;/ol>
&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>Incident decision log&lt;/td>
 &lt;td>事中假設與回退條件缺少結構化&lt;/td>
 &lt;td>強制套用 [8.19] 欄位（假設/證據/條件/責任）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Customer impact assessment&lt;/td>
 &lt;td>對外影響描述粒度不一致&lt;/td>
 &lt;td>在 [8.20] 補 control/data plane 影響分欄&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Communication cadence&lt;/td>
 &lt;td>更新節奏受資訊不完整影響&lt;/td>
 &lt;td>在 [8.4] 固定 cadence 與狀態模板&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Evidence package&lt;/td>
 &lt;td>事後很難回推當時判斷基礎&lt;/td>
 &lt;td>在 [4.20] 補控制面健康、依賴鏈與更新記錄欄位&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>事故決策紀錄： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log&lt;/a>&lt;/li>
&lt;li>客戶影響評估： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/customer-impact-assessment/" data-link-title="8.20 Customer Impact Assessment" data-link-desc="把受影響用戶、功能、區域、金額、SLO 與補償判斷串成影響評估模型">8.20 Customer Impact Assessment&lt;/a>&lt;/li>
&lt;li>事故通訊： &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">8.4 Incident Communication&lt;/a>&lt;/li>
&lt;li>觀測證據包： &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">4.20 Observability Evidence Package&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="引用源">引用源&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://health.aws.amazon.com/health/status">AWS Service Health Dashboard&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://aws.amazon.com/message/">AWS post-event summaries&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>這篇的核心責任是補齊「控制面事故如何說清楚責任邊界」。和 2017、2021 兩篇相比，這裡重點在事故治理樣式、單一技術細節是次要的：怎麼分辨控制面與資料面、怎麼維持對外更新節奏、怎麼保留決策脈絡。</p>
<h2 id="問題場景">問題場景</h2>
<p>當控制面退化時，最容易出現三種混亂：第一，內部把多個症狀拆成獨立事件；第二，對外更新把控制面和資料面混在一起；第三，決策紀錄只留結論，沒有留下假設與回退條件。這三種混亂會直接拉長復原時間。</p>
<h2 id="判讀訊號">判讀訊號</h2>
<table>
  <thead>
      <tr>
          <th>訊號</th>
          <th>代表意義</th>
          <th>第一波決策價值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多服務管理 API 同步抖動</td>
          <td>shared control plane 可能異常</td>
          <td>先建立單一 incident thread</td>
      </tr>
      <tr>
          <td>資料讀寫可用但控制操作失真</td>
          <td>control/data plane 分離已發生</td>
          <td>對外更新分兩條狀態敘述</td>
      </tr>
      <tr>
          <td>更新頻率不穩、描述反覆修正</td>
          <td>evidence pipeline 不穩定</td>
          <td>固定更新 cadence 與欄位結構</td>
      </tr>
      <tr>
          <td>回退有效但後續仍有殘留警訊</td>
          <td>依賴鏈條尚未收斂</td>
          <td>增加 dependency-level 驗證步驟</td>
      </tr>
  </tbody>
</table>
<h2 id="事故治理路徑樣式">事故治理路徑（樣式）</h2>
<ol>
<li>啟動單一事件線，避免按產品拆散。</li>
<li>明確標註控制面與資料面狀態，分開追蹤。</li>
<li>固定對外 cadence（例如每 30 分鐘）更新「已知 / 未知 / 下一步」。</li>
<li>在 decision log 記錄假設、證據、回退條件與 owner。</li>
<li>收斂後把通訊節奏與責任邊界回寫 runbook 與 evidence package。</li>
</ol>
<h2 id="可回寫控制面">可回寫控制面</h2>
<table>
  <thead>
      <tr>
          <th>控制面</th>
          <th>暴露缺口</th>
          <th>回寫方向</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Incident decision log</td>
          <td>事中假設與回退條件缺少結構化</td>
          <td>強制套用 [8.19] 欄位（假設/證據/條件/責任）</td>
      </tr>
      <tr>
          <td>Customer impact assessment</td>
          <td>對外影響描述粒度不一致</td>
          <td>在 [8.20] 補 control/data plane 影響分欄</td>
      </tr>
      <tr>
          <td>Communication cadence</td>
          <td>更新節奏受資訊不完整影響</td>
          <td>在 [8.4] 固定 cadence 與狀態模板</td>
      </tr>
      <tr>
          <td>Evidence package</td>
          <td>事後很難回推當時判斷基礎</td>
          <td>在 [4.20] 補控制面健康、依賴鏈與更新記錄欄位</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>事故決策紀錄： <a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log</a></li>
<li>客戶影響評估： <a href="/blog/backend/08-incident-response/customer-impact-assessment/" data-link-title="8.20 Customer Impact Assessment" data-link-desc="把受影響用戶、功能、區域、金額、SLO 與補償判斷串成影響評估模型">8.20 Customer Impact Assessment</a></li>
<li>事故通訊： <a href="/blog/backend/08-incident-response/incident-communication/" data-link-title="8.4 事故通訊與狀態更新" data-link-desc="建立內外部通報節奏與狀態更新格式">8.4 Incident Communication</a></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 與資料品質限制包成可交接證據">4.20 Observability Evidence Package</a></li>
</ul>
<h2 id="引用源">引用源</h2>
<ul>
<li><a href="https://health.aws.amazon.com/health/status">AWS Service Health Dashboard</a></li>
<li><a href="https://aws.amazon.com/message/">AWS post-event summaries</a></li>
</ul>
]]></content:encoded></item><item><title>拿到雲端帳號的第一天</title><link>https://tarrragon.github.io/blog/infra/00-infra-mindset/first-day-with-cloud-account/</link><pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/infra/00-infra-mindset/first-day-with-cloud-account/</guid><description>&lt;p>這篇寫給一種特定的讀者：你的專業可能是後端、前端、資料工程或其他領域，但因為組織需要，你被指派處理雲端基礎設施。公司（或主管）給了你一個 AWS / GCP / Azure 帳號，你登入之後看到一個很大的 Console，不確定該做什麼、也不確定動了什麼會出事。&lt;/p>
&lt;p>這是 infra 工作最常見的真實入口。比起從零自學建一套環境，「接到指派、拿到帳號、搞清楚狀況」才是多數工程師第一次碰 infra 的方式。&lt;/p>
&lt;p>這篇用 AWS 為主要範例。GCP 和 Azure 的判讀邏輯相同（安全底線 → 現況盤點 → 路線分流），但具體服務名稱、IAM 模型和 Console 操作位置不同。&lt;/p>
&lt;h2 id="第一小時安全底線">第一小時：安全底線&lt;/h2>
&lt;p>登入帳號後，在做任何其他事之前先完成這些。這些步驟的共同目的是確保帳號的存取控制處於安全狀態——雲端帳號被入侵的代價遠高於本機電腦被入侵，因為雲端資源可以在幾分鐘內被大量建立（產生帳單）或被刪除（資料遺失）。&lt;/p>
&lt;h3 id="確認-root-帳號的-mfa">確認 root 帳號的 MFA&lt;/h3>
&lt;p>Root 帳號是雲端環境的最高權限，能做任何事，包括關閉整個帳號。如果 root 帳號沒有 MFA（Multi-Factor Authentication，多因子驗證），任何拿到 root 密碼的人都能完全控制整個環境。&lt;/p>
&lt;p>確認路徑（AWS）：Console 右上角帳號名稱 → Security credentials → Multi-factor authentication (MFA)。如果顯示「No MFA device」，立刻設定一個——手機 app（Google Authenticator / Authy）或硬體 key（YubiKey）都可以。&lt;/p>
&lt;p>如果你拿到的帳號是公司用 AWS Organizations 開出來的子帳號，子帳號 root 的密碼和 MFA 是獨立的——管理帳號無法代設。子帳號 root 通常需要先用帳號 email 做密碼重置才能首次登入。確認 root MFA 後，日常操作用 IAM Identity Center 登入。&lt;/p>
&lt;h3 id="確認你的登入身分">確認你的登入身分&lt;/h3>
&lt;p>你登入用的是哪種身分？這決定了你的權限範圍和操作方式。&lt;/p>
&lt;p>&lt;strong>IAM user&lt;/strong>：Console 右上角會顯示 &lt;code>username @ account-id&lt;/code>。這是最傳統的登入方式——帳號管理員幫你建了一個使用者，給了你一組帳密。&lt;/p>
&lt;p>&lt;strong>IAM Identity Center（SSO）&lt;/strong>：你透過一個特別的登入頁面（通常是 &lt;code>https://d-xxxxxxxxxx.awsapps.com/start&lt;/code>）登入，然後選擇帳號和角色。這是較新的做法，多帳號組織常用。&lt;/p>
&lt;p>&lt;strong>Root 帳號&lt;/strong>：Console 右上角顯示帳號 email 而非 username。如果你拿到的是 root 帳號的帳密，日常操作應該換成 IAM user 或 SSO 登入——root 帳號只在需要 root-only 操作（如設定 MFA、關閉帳號）時使用。建立 IAM user 的方式見模組一的&lt;a href="https://tarrragon.github.io/blog/infra/01-minimal-iac/iac-tool-state-backend/" data-link-title="IaC 工具選型與 state 地基" data-link-desc="Terraform / OpenTofu / CDK / Pulumi 的選型判準，state 作為 IaC 工具對現實的唯一記憶，以及 remote state backend 的自管與託管路線">動手前的前提&lt;/a>段。&lt;/p>
&lt;h3 id="檢查既存的-access-key">檢查既存的 access key&lt;/h3>
&lt;p>帳號如果被前人用過，可能有暴露風險的 access key——之前的管理員建了 IAM user、生了 key，但那組 key 可能已經寫在某個 Git repo 或環境變數裡而沒有停用。&lt;/p>
&lt;p>確認路徑：Console → IAM → Users → 逐一點每個 user → Security credentials 分頁 → Access keys。檢查每組 key 的狀態（Active / Inactive）和建立時間。超過 90 天未 rotate 的 Active key 是風險——帳號接手後優先 rotate 或停用這些 key。如果帳號裡沒有任何 IAM user，這步跳過。&lt;/p>
&lt;h3 id="確認-cloudtrail-是否開啟">確認 CloudTrail 是否開啟&lt;/h3>
&lt;p>CloudTrail 記錄帳號內所有 API 操作（誰在什麼時間做了什麼）。AWS 預設會開啟 90 天的事件歷史，但長期保存需要建一個 Trail 把 log 寫到 S3。&lt;/p>
&lt;p>確認路徑：Console 搜尋 CloudTrail → Dashboard。如果有 Trail 已建立，表示操作紀錄有長期保存。如果只有預設的 Event history，90 天前的紀錄會消失——這是一個需要但不緊急的改善點，&lt;a href="https://tarrragon.github.io/blog/infra/06-observability-logging/" data-link-title="模組六：可觀測性與 log 一併寫進 code" data-link-desc="log group、metric、alarm 跟基礎設施同生命週期管理，出事時追得到查得到">模組六：可觀測性&lt;/a>會展開。&lt;/p></description><content:encoded><![CDATA[<p>這篇寫給一種特定的讀者：你的專業可能是後端、前端、資料工程或其他領域，但因為組織需要，你被指派處理雲端基礎設施。公司（或主管）給了你一個 AWS / GCP / Azure 帳號，你登入之後看到一個很大的 Console，不確定該做什麼、也不確定動了什麼會出事。</p>
<p>這是 infra 工作最常見的真實入口。比起從零自學建一套環境，「接到指派、拿到帳號、搞清楚狀況」才是多數工程師第一次碰 infra 的方式。</p>
<p>這篇用 AWS 為主要範例。GCP 和 Azure 的判讀邏輯相同（安全底線 → 現況盤點 → 路線分流），但具體服務名稱、IAM 模型和 Console 操作位置不同。</p>
<h2 id="第一小時安全底線">第一小時：安全底線</h2>
<p>登入帳號後，在做任何其他事之前先完成這些。這些步驟的共同目的是確保帳號的存取控制處於安全狀態——雲端帳號被入侵的代價遠高於本機電腦被入侵，因為雲端資源可以在幾分鐘內被大量建立（產生帳單）或被刪除（資料遺失）。</p>
<h3 id="確認-root-帳號的-mfa">確認 root 帳號的 MFA</h3>
<p>Root 帳號是雲端環境的最高權限，能做任何事，包括關閉整個帳號。如果 root 帳號沒有 MFA（Multi-Factor Authentication，多因子驗證），任何拿到 root 密碼的人都能完全控制整個環境。</p>
<p>確認路徑（AWS）：Console 右上角帳號名稱 → Security credentials → Multi-factor authentication (MFA)。如果顯示「No MFA device」，立刻設定一個——手機 app（Google Authenticator / Authy）或硬體 key（YubiKey）都可以。</p>
<p>如果你拿到的帳號是公司用 AWS Organizations 開出來的子帳號，子帳號 root 的密碼和 MFA 是獨立的——管理帳號無法代設。子帳號 root 通常需要先用帳號 email 做密碼重置才能首次登入。確認 root MFA 後，日常操作用 IAM Identity Center 登入。</p>
<h3 id="確認你的登入身分">確認你的登入身分</h3>
<p>你登入用的是哪種身分？這決定了你的權限範圍和操作方式。</p>
<p><strong>IAM user</strong>：Console 右上角會顯示 <code>username @ account-id</code>。這是最傳統的登入方式——帳號管理員幫你建了一個使用者，給了你一組帳密。</p>
<p><strong>IAM Identity Center（SSO）</strong>：你透過一個特別的登入頁面（通常是 <code>https://d-xxxxxxxxxx.awsapps.com/start</code>）登入，然後選擇帳號和角色。這是較新的做法，多帳號組織常用。</p>
<p><strong>Root 帳號</strong>：Console 右上角顯示帳號 email 而非 username。如果你拿到的是 root 帳號的帳密，日常操作應該換成 IAM user 或 SSO 登入——root 帳號只在需要 root-only 操作（如設定 MFA、關閉帳號）時使用。建立 IAM user 的方式見模組一的<a href="/blog/infra/01-minimal-iac/iac-tool-state-backend/" data-link-title="IaC 工具選型與 state 地基" data-link-desc="Terraform / OpenTofu / CDK / Pulumi 的選型判準，state 作為 IaC 工具對現實的唯一記憶，以及 remote state backend 的自管與託管路線">動手前的前提</a>段。</p>
<h3 id="檢查既存的-access-key">檢查既存的 access key</h3>
<p>帳號如果被前人用過，可能有暴露風險的 access key——之前的管理員建了 IAM user、生了 key，但那組 key 可能已經寫在某個 Git repo 或環境變數裡而沒有停用。</p>
<p>確認路徑：Console → IAM → Users → 逐一點每個 user → Security credentials 分頁 → Access keys。檢查每組 key 的狀態（Active / Inactive）和建立時間。超過 90 天未 rotate 的 Active key 是風險——帳號接手後優先 rotate 或停用這些 key。如果帳號裡沒有任何 IAM user，這步跳過。</p>
<h3 id="確認-cloudtrail-是否開啟">確認 CloudTrail 是否開啟</h3>
<p>CloudTrail 記錄帳號內所有 API 操作（誰在什麼時間做了什麼）。AWS 預設會開啟 90 天的事件歷史，但長期保存需要建一個 Trail 把 log 寫到 S3。</p>
<p>確認路徑：Console 搜尋 CloudTrail → Dashboard。如果有 Trail 已建立，表示操作紀錄有長期保存。如果只有預設的 Event history，90 天前的紀錄會消失——這是一個需要但不緊急的改善點，<a href="/blog/infra/06-observability-logging/" data-link-title="模組六：可觀測性與 log 一併寫進 code" data-link-desc="log group、metric、alarm 跟基礎設施同生命週期管理，出事時追得到查得到">模組六：可觀測性</a>會展開。</p>
<p>現階段只需要確認 CloudTrail 存在，不需要馬上改它。</p>
<h3 id="設定帳單警報">設定帳單警報</h3>
<p>雲端帳單是開放式的——資源跑著就持續產生費用，被入侵後被開出大量資源更可能在幾小時內累積數千美元帳單。設一個帳單警報，超過閾值時收到通知。</p>
<p>設定路徑（AWS）：Console 搜尋 Billing → Budgets → Create budget → Cost budget。設一個月預算（如 $50 或 $100，依你的環境規模），超過 80% 和 100% 時發 email 通知。</p>
<h2 id="帳號現況判讀空帳號還是有東西">帳號現況判讀：空帳號還是有東西？</h2>
<p>安全底線做完後，下一步是搞清楚帳號的現況。這決定了你接下來走哪條路線。</p>
<h3 id="怎麼判斷">怎麼判斷</h3>
<p>EC2 Dashboard 只顯示當前 region 的資源。Console 右上角有 region 選擇器——先切幾個主要 region（us-east-1、ap-northeast-1、ap-southeast-1）看一下，確認資源是否分散在不同 region。</p>
<p>打開 EC2 Dashboard（Console 搜尋 EC2）。如果 Running instances 是 0、沒有 volumes、沒有 security groups（除了 default）——大概率是空帳號。也檢查 Lambda（Console 搜尋 Lambda → Functions）——如果有 function 在跑但 EC2 是空的，可能是 serverless 架構，帳號不是空的。</p>
<p>再看 S3（Console 搜尋 S3）。S3 是全域服務，不分 region。如果沒有 bucket，或只有 CloudTrail 的 log bucket——大概率是空帳號。</p>
<p>如果有正在跑的 EC2 instance、有 Lambda function、有 RDS 資料庫、有 S3 bucket 存著資料——這是一個有東西的帳號，可能是前人建的、可能是其他團隊在用的。</p>
<h3 id="空帳號--從零建置">空帳號 → 從零建置</h3>
<p>帳號是空的，你要從零開始建基礎設施。這是最乾淨的起點。</p>
<p>路線：先讀<a href="/blog/infra/00-infra-mindset/" data-link-title="模組零：infra 是什麼，為什麼 day 1 就要鋪地基" data-link-desc="基礎設施的責任邊界、成熟度階梯，以及地基為什麼總在環境爆炸時才被看見">模組零</a>建立心智模型（什麼是 infra、成熟度階梯），然後照模組一到五的順序走。模組一的<a href="/blog/infra/01-minimal-iac/iac-tool-state-backend/" data-link-title="IaC 工具選型與 state 地基" data-link-desc="Terraform / OpenTofu / CDK / Pulumi 的選型判準，state 作為 IaC 工具對現實的唯一記憶，以及 remote state backend 的自管與託管路線">動手前的前提</a>段會帶你設好本機工具和認證。</p>
<h3 id="有東西的帳號--接手維運">有東西的帳號 → 接手維運</h3>
<p>帳號裡已經有資源在跑。你需要先搞清楚「有什麼」「誰建的」「哪些還在用」，再決定怎麼處理。</p>
<p>路線：讀<a href="/blog/infra/takeover/" data-link-title="接手維運：別人建的環境怎麼接管" data-link-desc="接手前人的專案時，怎麼在不搞壞東西的前提下盤點現況、建立維運能力、逐步正規化 — 從無 SSH 的 FTP 環境到有半套 IaC 的雲端環境都適用">接手維運</a>模組。它按環境類型（全手動的遺留環境、部分有 IaC、多帳號結構）分篇，教你怎麼盤點、怎麼在不搞壞的前提下逐步接管。</p>
<h3 id="不確定--先盤點再說">不確定 → 先盤點再說</h3>
<p>如果帳號裡有東西但你不確定是不是還在用、能不能動，先盤點。以下指令需要 AWS CLI 並完成認證——安裝和 <code>aws configure</code> 設定見模組一的<a href="/blog/infra/01-minimal-iac/iac-tool-state-backend/" data-link-title="IaC 工具選型與 state 地基" data-link-desc="Terraform / OpenTofu / CDK / Pulumi 的選型判準，state 作為 IaC 工具對現實的唯一記憶，以及 remote state backend 的自管與託管路線">前提段</a>（macOS 快速安裝：<code>brew install awscli &amp;&amp; aws configure</code>）：</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"># 列出所有 region 的 EC2 instance</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">for</span> region in <span class="k">$(</span>aws ec2 describe-regions --query <span class="s1">&#39;Regions[].RegionName&#39;</span> --output text<span class="k">)</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;=== </span><span class="nv">$region</span><span class="s2"> ===&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  aws ec2 describe-instances --region <span class="s2">&#34;</span><span class="nv">$region</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="se"></span>    --query <span class="s1">&#39;Reservations[].Instances[].[InstanceId,State.Name,Tags[?Key==`Name`].Value|[0]]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="se"></span>    --output table
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">done</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 列出所有 S3 bucket</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">aws s3 ls
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 列出所有 RDS instance</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">aws rds describe-db-instances <span class="se">\
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="se"></span>  --query <span class="s1">&#39;DBInstances[].[DBInstanceIdentifier,Engine,DBInstanceStatus]&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="se"></span>  --output table</span></span></code></pre></div><p>這些指令只做讀取，不會改變任何東西。如果輸出很多資源，去讀<a href="/blog/infra/takeover/" data-link-title="接手維運：別人建的環境怎麼接管" data-link-desc="接手前人的專案時，怎麼在不搞壞東西的前提下盤點現況、建立維運能力、逐步正規化 — 從無 SSH 的 FTP 環境到有半套 IaC 的雲端環境都適用">接手維運</a>再決定下一步。如果幾乎是空的，走「從零建置」路線。</p>
<h2 id="雲端-console-的基本導覽">雲端 Console 的基本導覽</h2>
<p>AWS Console 列出幾百個服務，日常 infra 工作常用的集中在以下幾個：</p>
<table>
  <thead>
      <tr>
          <th>服務</th>
          <th>做什麼</th>
          <th>什麼時候用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>EC2</td>
          <td>虛擬機器（運算）</td>
          <td>看有什麼機器在跑、管 security group</td>
      </tr>
      <tr>
          <td>S3</td>
          <td>物件儲存</td>
          <td>放檔案、放 Terraform state、放 log</td>
      </tr>
      <tr>
          <td>IAM</td>
          <td>身分與權限</td>
          <td>管使用者、角色、權限</td>
      </tr>
      <tr>
          <td>VPC</td>
          <td>虛擬網路</td>
          <td>管網路拓撲、子網路、路由</td>
      </tr>
      <tr>
          <td>RDS</td>
          <td>託管資料庫</td>
          <td>看有沒有資料庫在跑</td>
      </tr>
      <tr>
          <td>CloudWatch</td>
          <td>監控與 log</td>
          <td>看 metric、設 alarm、查 log</td>
      </tr>
      <tr>
          <td>CloudTrail</td>
          <td>操作審計</td>
          <td>查誰做了什麼</td>
      </tr>
      <tr>
          <td>Billing</td>
          <td>帳單</td>
          <td>看花了多少錢</td>
      </tr>
  </tbody>
</table>
<p>Console 左上角的搜尋列可以直接搜服務名稱，不用從選單找。</p>
<p>每個服務在 Console 上的操作都有一個對應的 AWS CLI 指令和 API 呼叫。這個對應關係是 IaC 的基礎——<a href="/blog/infra/01-minimal-iac/" data-link-title="模組一：最小可行 IaC — state 地基與 Console 唯讀鐵律" data-link-desc="Terraform / OpenTofu 選型、remote state 與 lock，以及「Console 只能看不能改」鐵律">模組一</a>會教怎麼把 Console 上的操作轉成程式碼。</p>
<h2 id="你接下來該讀什麼">你接下來該讀什麼</h2>
<p>根據你的情境選一條路線：</p>
<table>
  <thead>
      <tr>
          <th>你的情境</th>
          <th>路線</th>
          <th>從哪裡開始</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>完全沒碰過雲端、想先理解概念</td>
          <td>入門認識</td>
          <td><a href="/blog/infra/00-infra-mindset/personal-project-to-infra/" data-link-title="雲端部署裡已經存在的 infra 元件" data-link-desc="VPC、security group、IAM、儲存 — 這些元件在任何雲端部署裡都已經在運作，差別在於有沒有被有意識地管理">個人專案到團隊服務</a></td>
      </tr>
      <tr>
          <td>空帳號、要從零建 infra</td>
          <td>從零建置</td>
          <td><a href="/blog/infra/01-minimal-iac/" data-link-title="模組一：最小可行 IaC — state 地基與 Console 唯讀鐵律" data-link-desc="Terraform / OpenTofu 選型、remote state 與 lock，以及「Console 只能看不能改」鐵律">模組一：最小可行 IaC</a></td>
      </tr>
      <tr>
          <td>帳號有東西、要接手維運</td>
          <td>接手前人專案</td>
          <td><a href="/blog/infra/takeover/" data-link-title="接手維運：別人建的環境怎麼接管" data-link-desc="接手前人的專案時，怎麼在不搞壞東西的前提下盤點現況、建立維運能力、逐步正規化 — 從無 SSH 的 FTP 環境到有半套 IaC 的雲端環境都適用">接手維運</a></td>
      </tr>
      <tr>
          <td>手動環境、暫時無法導入 IaC</td>
          <td>還沒有 IaC</td>
          <td><a href="/blog/infra/before-infra/" data-link-title="模組負一：還沒有 infra 的環境怎麼盡量做好" data-link-desc="手動點起家的環境怎麼守底線、降低未來納管成本、辨識何時該開始導入 IaC — 給還沒有能力上 IaC 的真實起點">模組負一：還沒有 infra 的環境</a></td>
      </tr>
      <tr>
          <td>要跟主管解釋為什麼要做 infra</td>
          <td>說服決策者</td>
          <td><a href="/blog/infra/09-driving-adoption/infra-explained-for-non-engineers/" data-link-title="給非工程背景決策者的 infra 說明" data-link-desc="從管理視角解釋基礎設施在解決什麼營運問題、不做的代價、出事怎麼處理，讓參與資源決策的人能判斷投入的優先級">給非工程人員的 infra 說明</a></td>
      </tr>
      <tr>
          <td>拿到一台主機、要從 OS 層連入初始化</td>
          <td>機器初始化</td>
          <td><a href="/blog/linux/install/" data-link-title="Linux 安裝與機器初始化" data-link-desc="在 VM 或新機器從零裝好 Linux、判讀安裝程式選項、驗證最小系統、或要從外部連入跑 bootstrap 時回來讀">Linux 安裝與機器初始化</a></td>
      </tr>
  </tbody>
</table>
<p>如果你不確定自己屬於哪種情境，先做完本篇的「帳號現況判讀」再決定。</p>
]]></content:encoded></item><item><title>AWS IAM Identity Center</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/</guid><description>&lt;p>AWS IAM Identity Center 是 AWS 原生的 workforce SSO 控制面、前身為 AWS SSO（2022 改名）。它承擔三個責任：人類身份進 AWS 多帳號的 &lt;em>統一入口&lt;/em>（Access Portal）、把使用者映射到各帳號 IAM role 的 &lt;em>Permission Set&lt;/em> 模板、以及對少量已整合 SAML app 的 SSO gateway。它不是 AWS IAM 的替代品、是疊在 AWS IAM 之上的 &lt;em>人類入口層&lt;/em>。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>IAM Identity Center 是 &lt;em>人類身份進 AWS 的 portal&lt;/em>、不是 cloud resource permission engine。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> 的分工是兩層：Identity Center 管「人是誰、能登入哪些 account」、AWS IAM 管「進到 account 後對 resource 能做什麼」。實際機制是 Identity Center 透過 Permission Set 在每個目標 account 建一個 &lt;code>AWSReservedSSO_*&lt;/code> 命名的 IAM role、使用者 assume 該 role 拿短期 STS token。&lt;/p>
&lt;p>跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> 相比、Identity Center 的核心優勢是 &lt;em>跟 AWS Organizations + Control Tower 原生整合&lt;/em>、Permission Set 可以一次發佈到數百個 account、不必每個 account 各接 SAML。代價是 SaaS app integration 量級遠少於 Okta（Okta 7000+ 預建、Identity Center 僅中等規模）、跨雲 federation（GCP / Azure）也不在原生範圍。&lt;/p>
&lt;p>許多大型組織採三層架構：Okta 是 HRIS 下游的 identity source of truth、SCIM push 進 Identity Center、Identity Center 再 map 到 AWS IAM Permission Set。Okta 管「人是誰」、Identity Center 管「AWS portal 入口」、AWS IAM 管「resource 能做什麼」。中小組織可以省略 Okta、直接用 Identity Center 內建 user store、但就失去跨 SaaS 統一 SSO。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>Identity Center 在 &lt;em>人類身份 / AWS portal / resource permission&lt;/em> 三層裡的位置、何時該交回 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> 或上游 IdP&lt;/li>
&lt;li>Identity Source 選擇（內建 / Active Directory / 外部 SAML）對 lifecycle 與 lock-in 的長期影響&lt;/li>
&lt;li>Permission Set / Account Assignment / Access Portal 三個核心概念的稽核重點&lt;/li>
&lt;li>何時 Identity Center 夠用、何時要疊 Okta 在前、何時 Identity Center 反而是錯選擇&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 Identity Center 配置是否健康、最少看四件事：&lt;/p></description><content:encoded><![CDATA[<p>AWS IAM Identity Center 是 AWS 原生的 workforce SSO 控制面、前身為 AWS SSO（2022 改名）。它承擔三個責任：人類身份進 AWS 多帳號的 <em>統一入口</em>（Access Portal）、把使用者映射到各帳號 IAM role 的 <em>Permission Set</em> 模板、以及對少量已整合 SAML app 的 SSO gateway。它不是 AWS IAM 的替代品、是疊在 AWS IAM 之上的 <em>人類入口層</em>。</p>
<h2 id="服務定位">服務定位</h2>
<p>IAM Identity Center 是 <em>人類身份進 AWS 的 portal</em>、不是 cloud resource permission engine。它跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 的分工是兩層：Identity Center 管「人是誰、能登入哪些 account」、AWS IAM 管「進到 account 後對 resource 能做什麼」。實際機制是 Identity Center 透過 Permission Set 在每個目標 account 建一個 <code>AWSReservedSSO_*</code> 命名的 IAM role、使用者 assume 該 role 拿短期 STS token。</p>
<p>跟 <a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> 相比、Identity Center 的核心優勢是 <em>跟 AWS Organizations + Control Tower 原生整合</em>、Permission Set 可以一次發佈到數百個 account、不必每個 account 各接 SAML。代價是 SaaS app integration 量級遠少於 Okta（Okta 7000+ 預建、Identity Center 僅中等規模）、跨雲 federation（GCP / Azure）也不在原生範圍。</p>
<p>許多大型組織採三層架構：Okta 是 HRIS 下游的 identity source of truth、SCIM push 進 Identity Center、Identity Center 再 map 到 AWS IAM Permission Set。Okta 管「人是誰」、Identity Center 管「AWS portal 入口」、AWS IAM 管「resource 能做什麼」。中小組織可以省略 Okta、直接用 Identity Center 內建 user store、但就失去跨 SaaS 統一 SSO。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>Identity Center 在 <em>人類身份 / AWS portal / resource permission</em> 三層裡的位置、何時該交回 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 或上游 IdP</li>
<li>Identity Source 選擇（內建 / Active Directory / 外部 SAML）對 lifecycle 與 lock-in 的長期影響</li>
<li>Permission Set / Account Assignment / Access Portal 三個核心概念的稽核重點</li>
<li>何時 Identity Center 夠用、何時要疊 Okta 在前、何時 Identity Center 反而是錯選擇</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 Identity Center 配置是否健康、最少看四件事：</p>
<ul>
<li><strong>誰能 assume 哪個 role</strong>：Permission Set 跟 Account Assignment 是否走最小權限、<code>AdministratorAccess</code> 範圍 Permission Set 是否限定 break-glass、是否強制 <a href="/blog/backend/knowledge-cards/authentication/" data-link-title="Authentication" data-link-desc="說明系統如何確認呼叫者身份">phishing-resistant 認證</a> 才能 assume 高權限</li>
<li><strong>Permission Set 邊界</strong>：每個 Permission Set 的 session duration（預設 1 hour、可調 12 hour）、inline policy vs Customer Managed Policy reference、是否用 ABAC tag 收斂跨 account 散佈</li>
<li><strong>External IdP federation 狀態</strong>：Identity Source 是內建 / AD / 外部 SAML、若走外部 IdP SCIM push 是否監控 sync 失敗、signing certificate 是否在 rotation 排程內</li>
<li><strong>CloudTrail 是否完整</strong>：Identity Center 事件分布在 management account 跟 member account、是否有 organization trail 收齊、admin 變更 / Permission Set 變更 / failed assume 是否 alert</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 與 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Identity Source 是根信任</strong>：Identity Center 支援三種 user/group 來源 — 內建 store、AWS Managed AD / on-prem AD via AD Connector、外部 SAML IdP（Okta / Entra ID 等、SCIM 推進來）。選了之後 user lifecycle 從哪來就鎖死、換 Identity Source 是大工程（要重建所有 Permission Set assignment、舊 user GUID 不通用）。早期決定錯比 Permission Set 設錯難救。</p>
<p><strong>Permission Set 是 cross-account role template</strong>：定義一次、apply 到多 account、實際在每個 account 部署成一個 AWS-Reserved 命名的 IAM role。Permission Set 本身不是 role、是 <em>role 的部署模板</em> — 改 Permission Set 會 push 到所有 account 上對應的 role。Customer Managed Policy reference 比 inline policy 好維護、但要先確保每個 target account 都有同名 policy、否則 assignment 會失敗。</p>
<p><strong>Account Assignment</strong>：把 user/group 綁到 Permission Set + 特定 account 的三元組。這層用 group 而不是個別 user、跟著 Identity Source 的 group 變動自動同步。臨時權限（離職員工延長、incident 應變）走 access request workflow 或 IAM Access Analyzer + Just-in-Time、不要永久 assignment。</p>
<p><strong>Access Portal URL 是 phishing 目標</strong>：custom URL（<code>https://&lt;alias&gt;.awsapps.com/start</code>）設定後變成員工每天用的入口、phishing 攻擊會 mimic。要強制 phishing-resistant MFA（WebAuthn / passkey）、純 push MFA 抗不過 fatigue。CLI 走 <code>aws sso login</code> 自帶 browser-based flow、不要叫員工複製貼 access key。</p>
<p><strong>Application assignment</strong>：Identity Center 也能管 SAML app 的 SSO assignment、但 integration 數量遠少於 Okta。大量 SaaS app 的場景應該疊 Okta 在前、Identity Center 只管 AWS portal。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>IAM Identity Center</th>
          <th>Okta + AWS IAM</th>
          <th>直接用 AWS IAM Users（不推薦）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>控制面責任</td>
          <td>AWS 託管、限 AWS 帳號 + 中等 SAML app</td>
          <td>Okta 管人類身份、AWS IAM 管 resource、兩層分工</td>
          <td>每個 account 各自管 user、無跨帳號統一</td>
      </tr>
      <tr>
          <td>多帳號統一入口</td>
          <td>原生、Permission Set 一次發到全 Org</td>
          <td>透過 SAML federation 到 IAM role</td>
          <td>不存在 — 每個 account 各自 IAM Users</td>
      </tr>
      <tr>
          <td>SaaS app 範圍</td>
          <td>中等規模 integration</td>
          <td>7000+ 預建 integration</td>
          <td>無</td>
      </tr>
      <tr>
          <td>Lifecycle</td>
          <td>內建 / AD / 外部 SCIM 進來</td>
          <td>Okta 走 HRIS SCIM 同步、Identity Center 接 Okta SCIM</td>
          <td>手動管理、容易 stale</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>中 — AWS 內部換</td>
          <td>高 — Okta + Identity Center 都要拆</td>
          <td>高 — 大量 IAM Users 散佈在 N 個 account</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-heavy、員工數中等、SaaS app 少</td>
          <td>多雲 + 大量 SaaS + AWS 帳號數十個以上</td>
          <td>不存在合理場景（small lab 例外）</td>
      </tr>
  </tbody>
</table>
<p>選 Identity Center 的核心訴求：<em>AWS 是主要工作環境、員工 SaaS app 用量低、要統一多帳號入口而不要再付 Okta 訂閱</em>。員工大量用 SaaS 的場景應該疊 Okta 在前。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>External IdP federation（Okta / Entra ID SCIM 進來）</strong>：Identity Center 接外部 IdP 是 <em>push model</em> — IdP 主動 SCIM push、Identity Center 不 pull。push provisioning 失敗會 silent（IdP 端有 log、Identity Center 端只看到 user 沒出現）、要在 IdP 端設 sync failure alert。SAML signing certificate rotation 兩邊都要排程、過期會整個 federation 斷。</p>
<p><strong>Multi-account Permission Set 設計</strong>：避免每個 environment / team 各自一份 Permission Set — 用 ABAC（tag-based access control）把「<code>Environment=Prod</code> + <code>Team=Payments</code>」的條件寫進一個 Permission Set 的 policy、tag 跟著 user attribute 跑。Permission Set 數量爆炸是 Identity Center 老化最常見訊號。</p>
<p><strong>Customer Managed Policy reference</strong>：Permission Set 可以 reference target account 裡的 customer managed policy（同名同 path）、policy 本身在每個 account 獨立維護。比 inline policy 適合大規模、但要靠 CI / Terraform 確保 policy 在所有 target account 同步存在、否則 assignment 失敗。</p>
<p><strong>Session duration 是攻擊面</strong>：預設 1 hour、可調到 12 hour。長 session 對 dev 體驗友善、但不利於 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">credential rotation</a> — 高權限 Permission Set（<code>AdministratorAccess</code>、production write）應該短 session（1-2 hour）、低風險 read-only 可放 8-12 hour。</p>
<p><strong>IAM Identity Center API 不該當 workforce IdP 用</strong>：API 是給 admin 管 assignment 用、不是給 app 拿 user token。要 workforce app SSO 走 SAML / OIDC federation、不要叫 app 打 Identity Center API 查 user。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Permission Set 數量爆炸</strong>：每個 team / environment 各一份、上百個 Permission Set 沒人敢動 — 改用 ABAC + user attribute 把條件寫進 policy、收斂到十位數</li>
<li><strong>Identity Source 選錯難換</strong>：早期選內建 store、後來公司導入 Okta 要換成外部 SAML — 整個 user GUID 重新映射、Permission Set assignment 重綁、評估比建新 tenant 還久</li>
<li><strong>External SCIM sync 失敗 silent</strong>：Okta 端 push 失敗、Identity Center 沒人 — 要在上游 IdP 設 SCIM provisioning failure alert、不要等使用者反映「我登不進去」</li>
<li><strong>Access Portal URL 被 phishing</strong>：custom URL 員工記憶、phishing 站 mimic、無 phishing-resistant MFA 擋不住 — 強制 WebAuthn / passkey、員工教育只認 bookmark / SSO launcher</li>
<li><strong>CloudTrail 不完整</strong>：只開 management account trail、member account 的 role assumption 看不到 — 開 organization trail 收齊、特別 alert Permission Set 變更與失敗 assume</li>
<li><strong>Break-glass 缺席</strong>：Identity Center 控制面故障時 console 進不去 — 保留每個 account 的 root credential（離線存）跟少數 break-glass IAM User（hardware MFA、與 Identity Center 獨立 audit）、季度驗證</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>大量 SaaS app 統一 SSO</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta vendor</a>（疊在 Identity Center 前）</td>
      </tr>
      <tr>
          <td>Customer / B2C identity</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0 vendor</a></td>
      </tr>
      <tr>
          <td>自管 / 不接受 cloud-managed IdP</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak vendor</a></td>
      </tr>
      <tr>
          <td>AWS resource permission（policy / role / STS）</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM vendor</a></td>
      </tr>
      <tr>
          <td>跨雲 federation（GCP / Azure workforce）</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></td>
      </tr>
      <tr>
          <td>Secret / API key 治理</td>
          <td><a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>AWS IAM 的 policy / role / STS 機制細節（屬 AWS IAM vendor 頁）</li>
<li>Permission Set 的 JSON policy 撰寫教學</li>
<li>AWS Organizations / Control Tower 的完整架構</li>
<li>各 SaaS app SAML 接線教學</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 IAM Identity Center 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a></td>
          <td>Identity Center 控制面故障會擋住 AWS console portal、降級路徑必須事先設計（emergency root credential、break-glass IAM User）</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>Permission Set session duration 跟 external IdP signing key rotation 是不同域、要分開排程、不能混為一談</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/okta-support-system-incident-2023/" data-link-title="7.C5 Okta：2023 Support System 事件" data-link-desc="支援系統憑證風險如何擴散到客戶租戶的案例。">Okta Support System Incident 2023</a></td>
          <td>Okta 作為 Identity Center 的 external IdP 時、上游事件會傳導下來、Identity Center 端要看 SCIM sync 異常與 federation token reuse</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/cloudflare-2023-okta-token-follow-through/" data-link-title="7.R7.1.6 Cloudflare 2023：供應商事件後的身分收斂" data-link-desc="同一條供應商事件鏈，如何在客戶端變成 session 與 token 的收斂壓力">Cloudflare 2023 Okta Token Follow-Through</a></td>
          <td>上游 IdP 出事後、Identity Center 端的 active session 是否要強制 reauth、不能等供應商公告</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a>、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta vendor</a>（外部 IdP 疊在前）、<a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0 vendor</a>、<a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak vendor</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM vendor</a>（Permission Set 落地的 resource permission 層）、<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a>（多雲對照）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（Identity Center 事件如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/singlesignon/">AWS IAM Identity Center Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>AWS KMS</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-kms/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-kms/</guid><description>&lt;p>AWS KMS 是 AWS 原生的 key management service、解決 &lt;em>對稱 / 非對稱金鑰生命週期管理&lt;/em> 與 &lt;em>envelope encryption pattern&lt;/em>：service 內部保管 master key（KMS Key）、應用層用 &lt;code>GenerateDataKey&lt;/code> 取得短暫的 data key 對實際資料加密、master key 完全不離 KMS 服務邊界。整合面跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &amp;#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager&lt;/a> / S3 / EBS / RDS 都串好、是 AWS 上幾乎所有靜態資料加密的後端。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>AWS KMS 的核心定位是 &lt;em>AWS-only 的 multi-tenant managed key management&lt;/em>，FIPS 140-2 Level 3 認證、跨服務 envelope encryption 的共同地基。跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &amp;#43; 資料主權場景的 key custody">CloudHSM&lt;/a> 比、KMS 是 &lt;em>managed + shared HSM 池&lt;/em>、CloudHSM 是 &lt;em>single-tenant dedicated HSM&lt;/em>；需要更高隔離 / 自管 cluster / FIPS Level 3 single-tenant 時走 CloudHSM、或用 KMS Custom Key Store 把 KMS 後端指向自己的 CloudHSM。跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-kms/" data-link-title="Google Cloud KMS" data-link-desc="GCP 原生 key management service、KeyRing / CryptoKey Version 設計、CMEK 整合 &amp;#43; Cloud HSM &amp;#43; External Key Manager">Google Cloud KMS&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &amp;#43; Key &amp;#43; Certificate）、整合 Managed Identity &amp;#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault&lt;/a> 比、設計概念相近、但 KMS 把 secret store 切出去（&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &amp;#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">Secrets Manager&lt;/a>）、Key Vault 則把兩者合一。&lt;/p></description><content:encoded><![CDATA[<p>AWS KMS 是 AWS 原生的 key management service、解決 <em>對稱 / 非對稱金鑰生命週期管理</em> 與 <em>envelope encryption pattern</em>：service 內部保管 master key（KMS Key）、應用層用 <code>GenerateDataKey</code> 取得短暫的 data key 對實際資料加密、master key 完全不離 KMS 服務邊界。整合面跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a> / S3 / EBS / RDS 都串好、是 AWS 上幾乎所有靜態資料加密的後端。</p>
<h2 id="服務定位">服務定位</h2>
<p>AWS KMS 的核心定位是 <em>AWS-only 的 multi-tenant managed key management</em>，FIPS 140-2 Level 3 認證、跨服務 envelope encryption 的共同地基。跟 <a href="/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &#43; 資料主權場景的 key custody">CloudHSM</a> 比、KMS 是 <em>managed + shared HSM 池</em>、CloudHSM 是 <em>single-tenant dedicated HSM</em>；需要更高隔離 / 自管 cluster / FIPS Level 3 single-tenant 時走 CloudHSM、或用 KMS Custom Key Store 把 KMS 後端指向自己的 CloudHSM。跟 <a href="/blog/backend/07-security-data-protection/vendors/google-cloud-kms/" data-link-title="Google Cloud KMS" data-link-desc="GCP 原生 key management service、KeyRing / CryptoKey Version 設計、CMEK 整合 &#43; Cloud HSM &#43; External Key Manager">Google Cloud KMS</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a> 比、設計概念相近、但 KMS 把 secret store 切出去（<a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">Secrets Manager</a>）、Key Vault 則把兩者合一。</p>
<p>跟 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault transit engine</a> 比、行為相似（key 不離 service、app 拿 ciphertext）、但治理面完全不同：KMS 綁 AWS 控制面、IAM + Key Policy 雙層授權、CloudTrail 是稽核入口；Vault transit 是跨雲統一介面、token + policy 為主、需要自管 cluster。AWS-heavy 組織首選 KMS、跨雲組織才會把 KMS 當下游、上游用 Vault transit 抽象。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>哪些資料 / 場景該用 Customer Managed KMS Key、哪些 AWS Managed Key 已經夠用、什麼時候直接走 CloudHSM</li>
<li>Key Policy + IAM + Grant 三層授權的分工、production 必開的 CloudTrail Data event 與 monitor 範圍</li>
<li>Multi-Region Key、Custom Key Store、External Key Store、BYOK 等進階形態的取捨</li>
<li>KMS 出事（IAM 過寬、Key Policy 把自己鎖死、Schedule Deletion 誤觸發）時的判讀路徑跟回退選項</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一個 AWS KMS deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Key Policy 設計</strong>：是否含 <code>root</code> principal（不然 key 變孤兒）、是否走 least privilege（不是 <code>kms:*</code> 給整個 account）、admin / user / monitor 三類 principal 是否分開、policy 變更是否走 PR review</li>
<li><strong>Grant 治理</strong>：哪些 service-to-service 短期授權走 Grant（rotation Lambda / RDS / EBS）、Grant TTL 是否設、廢棄 grant 是否定期 <code>RetireGrant</code></li>
<li><strong>Multi-Region 與 rotation 策略</strong>：是否啟用 annual automatic rotation（適用 symmetric encryption key）、Multi-Region Key 的 replica 是否跟 DR plan 對齊、asymmetric / signing key 的 manual rotation 流程是否有 runbook</li>
<li><strong>CloudTrail Data Event 必開</strong>：management event 預設記、但 <code>Encrypt</code> / <code>Decrypt</code> / <code>GenerateDataKey</code> 是 data event、預設不記 — 沒這層 forensic 沒著力點、Storm-0558 對照下完全無法回答「誰用哪把 key 簽了什麼 token」</li>
</ul>
<p>四件事任一缺失、就回到 <a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a> 跟 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 的補丁清單。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Key Type 選擇</strong>：symmetric encryption key（AES-256-GCM、最常用、S3 / EBS / RDS / Secrets Manager 都走這個）；asymmetric key pair（RSA / ECC、用於 sign / verify 或 encrypt / decrypt、JWT 簽署、CodeSign、文件簽章）；HMAC key（generate / verify MAC、API request signing）。對應 <a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Storm-0558 signing key chain</a> — 自己 host signing key 出事的核心教訓是 <em>key 不該離 HSM service</em>、所以 JWT signing 用 asymmetric KMS key 是 baseline 設計、private key 永遠不離 KMS。</p>
<p><strong>Key Origin（key material 來源）</strong>：<code>AWS_KMS</code>（KMS 內部生成、預設）；<code>EXTERNAL</code>（BYOK、組織自己生成 key material、import 進 KMS、可以隨時 reimport 或刪除）；<code>AWS_CLOUDHSM</code>（Custom Key Store、key material 存在自己的 CloudHSM cluster）；<code>EXTERNAL_KEY_STORE</code>（XKS、AWS 外的 HSM、控制面在 AWS、key material 在 on-prem）。多數場景用 <code>AWS_KMS</code> 就夠、合規 / 主權需求才走 EXTERNAL / Custom Key Store。</p>
<p><strong>Key Policy 跟 IAM 的雙層</strong>：KMS 跟其他 AWS service 最大差異是 <em>Key Policy 是主要授權機制</em>、IAM policy 單獨不夠。Key Policy 必含 <code>arn:aws:iam::ACCOUNT_ID:root</code> 給 root principal（不是 root user、是讓 IAM 能參與授權的開關）— 沒這條 key 變孤兒、即使 IAM 開了 admin 也救不回來。production 通常分三類 statement：admin（Create / Delete / Schedule、走 break-glass）、user（Encrypt / Decrypt / GenerateDataKey、給 app）、monitor（Describe / List、給 SRE）。</p>
<p><strong>Grant 是程式化短期授權</strong>：service-to-service 整合（<a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">Secrets Manager</a> rotation Lambda、RDS 自動加密、EBS volume attach）通常走 Grant 而不是改 Key Policy — 每個 grant 有自己的 grant token、可以帶 TTL、可以 <code>RetireGrant</code> / <code>RevokeGrant</code> 收回、不跟 key policy 永久綁定。沒治理時 grant 累積上千個 / 沒人 retire 是常見問題、跟 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a> 同類 — 沒 scope map 等於沒治理。</p>
<p><strong>Alias 與 Key ID 的解耦</strong>：alias（<code>alias/my-app-prod-key</code>）是 <em>指向 key 的可變指標</em>、key ID / ARN 是 <em>不可變識別</em>。production code 應該用 alias、要換 key 時只需要重綁 alias、不用改 deployment。Cross-account 跨帳號使用必須用 ARN（alias 不跨帳號）。</p>
<p><strong>Key Rotation 的真實語義</strong>：annual automatic rotation（symmetric encryption key 才支援）換的是 <em>KMS 內部的 backing key material</em>、key ARN / Alias / Key ID 都不變、app 完全不需要動。<strong>舊資料仍用舊 backing key 解密、KMS 自動處理</strong>、不是「資料全部重新加密」— 這是常見誤解。asymmetric / HMAC key 不支援 automatic rotation、必須 manual 建新 key + alias 切換 + app 端雙讀容忍窗口（跟 JWT signing key rotation 同套路）。</p>
<p><strong>Multi-Region Key</strong>：跨 region replicate 的 KMS key 共用 <em>key material</em> 跟 <em>Key ID</em>（後綴帶 <code>mrk-</code>）、不是建立新 key — 跨 region 加密的 ciphertext 在另一 region 可以直接 decrypt、不用 cross-region API call。適合 multi-region active-active app + DR scenario。代價是 <em>replica region 跟 primary region 的權限要分別治理</em>、Key Policy 不會自動同步。</p>
<p><strong>Encryption Context 是 <em>authenticated data</em></strong>：encrypt 時帶的 key-value pair（例：<code>{&quot;app&quot;: &quot;billing&quot;, &quot;tenant&quot;: &quot;acme&quot;}</code>）、decrypt 必須提供同一組 context — 否則失敗。用來防 <em>ciphertext 被 replay 到別的 context</em>（攻擊者拿到 billing 的 ciphertext 想當 payroll 的 ciphertext 用）、所有 context 都會進 CloudTrail、是 forensic 上的關鍵欄位。production 一律帶 context、單純加密不帶 context 等於少一層防護。</p>
<p><strong>Customer Managed vs AWS Managed vs AWS Owned</strong>：三層分權 — Customer Managed（CMK、自己控 Key Policy + 自選 rotation）、AWS Managed（<code>aws/secretsmanager</code>、<code>aws/s3</code>、AWS 管 Key Policy、看得到但改不了）、AWS Owned（完全看不見、AWS 自己用、無 CloudTrail）。production 高敏感資料應該用 Customer Managed、才能控 policy + 開 data event + 自選 rotation 週期。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS KMS</th>
          <th>Google Cloud KMS</th>
          <th>Azure Key Vault</th>
          <th>AWS CloudHSM</th>
          <th>Vault transit engine</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>AWS managed multi-tenant、FIPS 140-2 Level 3</td>
          <td>GCP managed multi-tenant、FIPS 140-2 L3</td>
          <td>Azure managed、Standard / Premium tier</td>
          <td>AWS managed single-tenant HSM cluster</td>
          <td>自管 Vault cluster</td>
      </tr>
      <tr>
          <td>跨雲</td>
          <td>弱 — AWS-only</td>
          <td>弱 — GCP-only</td>
          <td>弱 — Azure-only</td>
          <td>弱 — AWS-only</td>
          <td>強 — 跨雲統一介面</td>
      </tr>
      <tr>
          <td>授權模型</td>
          <td>Key Policy（強制） + IAM + Grant 三層</td>
          <td>IAM 為主、Resource policy 輔</td>
          <td>Access policy + RBAC 雙模式</td>
          <td>CloudHSM user / role + Cluster IAM</td>
          <td>path-based policy + token</td>
      </tr>
      <tr>
          <td>Multi-Region</td>
          <td>Multi-Region Key（共用 key material）</td>
          <td>自動跨 region replication 較易</td>
          <td>Geo-replication 透過 Premium tier</td>
          <td>自管 cross-region replication</td>
          <td>Replication（Enterprise）</td>
      </tr>
      <tr>
          <td>Envelope encryption</td>
          <td>一級 pattern（<code>GenerateDataKey</code>）</td>
          <td>一級 pattern</td>
          <td>一級 pattern</td>
          <td>自己實作</td>
          <td>內建（transit engine）</td>
      </tr>
      <tr>
          <td>Asymmetric signing</td>
          <td>支援（RSA / ECC、JWT / CodeSign 直用）</td>
          <td>支援</td>
          <td>支援</td>
          <td>支援 + 完整 PKCS#11</td>
          <td>支援（部分）</td>
      </tr>
      <tr>
          <td>整合面</td>
          <td>全 AWS service 原生（S3 / EBS / RDS / Lambda）</td>
          <td>全 GCP service 原生</td>
          <td>全 Azure service 原生</td>
          <td>PKCS#11 / JCE / OpenSSL</td>
          <td>應用層 SDK</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-heavy + envelope encryption + JWT signing</td>
          <td>GCP-heavy</td>
          <td>Azure-heavy + 跟 AD 整合</td>
          <td>合規 / FIPS L3 single-tenant / 自管 HSM</td>
          <td>跨雲 + key 不離 service</td>
      </tr>
      <tr>
          <td>不適合場景</td>
          <td>跨雲統一 custody、需 FIPS L4、需自管 HSM cluster</td>
          <td>同左</td>
          <td>同左</td>
          <td>純 envelope encryption 用 KMS 即可</td>
          <td>AWS-only 簡單需求（KMS 更便宜）</td>
      </tr>
  </tbody>
</table>
<p>KMS 是 AWS 上的 <em>預設選擇</em>、CloudHSM 是合規 / 自管要求才上的 <em>昇級</em>、Vault transit 是跨雲統一介面、Google / Azure 對標品在各自雲一樣是預設選擇。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>KMS Custom Key Store + CloudHSM 整合</strong>：Custom Key Store 把 KMS 的 <em>控制面</em>（API、Key Policy、CloudTrail、IAM 整合）保留、但 <em>key material 存在自己的 CloudHSM cluster</em>。組織需要 FIPS 140-2 Level 3 single-tenant 但又不想放棄 KMS 的 service 整合（S3 SSE-KMS / EBS encryption）時用。代價是 CloudHSM cluster 的運維成本（cluster HA、user 管理、backup）。</p>
<p><strong>External Key Store (XKS)</strong>：更激進的形態 — key material 完全在 AWS 之外（on-prem HSM 或第三方 HSM）、AWS 透過 XKS proxy 呼叫外部 HSM 做 cryptographic operation。用於 <em>資料主權</em> 場景（金融 / 政府 / 跨境合規要求 key 不出組織邊界）、代價是 latency 跟 availability 完全綁外部 HSM、AWS service 整合面要算清楚。</p>
<p><strong>Multi-Region Replica Key 跟 DR</strong>：primary region 出事時 replica region 仍能 decrypt 既有 ciphertext、不需要 cross-region API call。但 <em>primary 跟 replica 是各自獨立的 Key Policy</em>、變更不會自動同步 — 跟 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 治理一樣、replica region 也要納入 CloudTrail Data Event 覆蓋範圍。</p>
<p><strong>BYOK（Bring Your Own Key）</strong>：<code>Origin = EXTERNAL</code> 的 KMS Key、key material 由組織自己生成、用 wrapping key 加密後 import 進 KMS。優點是組織保有 <em>master copy</em>（KMS 出事時仍能 re-import 到別處）、缺點是 <em>automatic rotation 不支援</em>（必須手動 import 新 key material）、且必須自己處理 wrapping key 的生命週期。</p>
<p><strong>跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">Secrets Manager</a> 的整合</strong>：Secrets Manager 的 secret 本身用 KMS key 加密（預設 AWS Managed <code>aws/secretsmanager</code>、production 應該指到 Customer Managed CMK）。rotation Lambda 透過 Grant 取得 Decrypt + Encrypt 能力、跟 Secrets Manager 一起構成 <em>static secret rotation 的證據鏈</em> — 跟 <a href="/blog/backend/07-security-data-protection/credential-rotation-scoped-evidence/" data-link-title="7.27 Credential Rotation with Scoped Evidence 實作示範" data-link-desc="以 webhook/API credential 輪替示範 scope map、證據欄位與回退窗口如何一起設計。">credential rotation scoped evidence</a> 對齊。</p>
<p><strong>Asymmetric signing 的 use cases</strong>：JWT signing（KMS <code>Sign</code> API 直接簽 JWT header.payload、private key 不離 KMS、跟 Storm-0558 的設計對照鮮明）；CodeSign / S3 object signing（artifact integrity）；mTLS client cert 的 private key（搭配 <a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a> AWS issuer）。代價是 <em>latency</em>（每次 sign 一次 KMS API call、~10ms 級別、不適合超高 QPS）跟 <em>cost</em>（asymmetric operation 比 symmetric 貴 ~5x）。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Key Policy 沒有 <code>root</code> principal</strong>：Schedule 時忘了寫、key 立刻變孤兒、誰都不能用 — 只能透過 AWS Support 救（流程慢）；建立流程強制 template 含 root principal</li>
<li><strong>IAM admin 改不動 KMS key</strong>：Key Policy 沒授權 IAM 介入、即使 admin policy 有 <code>kms:*</code> 也擋掉 — 加 <code>Enable IAM User Permissions</code> statement 給 root principal、IAM 才能參與授權</li>
<li><strong>Schedule Key Deletion 誤觸發</strong>：min 7 天、max 30 天的等待期、期內可 cancel — production key 必含 alert（CloudWatch Alarm on <code>ScheduleKeyDeletion</code> event）+ 強制 4-eyes approval</li>
<li><strong>CloudTrail Data Event 沒開</strong>：事故後想查「誰 decrypt 了什麼」、發現只有 management event — production 必開 KMS data event、預估 cost（每 100k events ~$0.10）、敏感 key 一律開</li>
<li><strong>Encryption Context 不一致</strong>：encrypt 時帶 context、decrypt 時忘了帶（或帶錯）、<code>InvalidCiphertextException</code> — code review 強制 context schema、用 typed wrapper 避免人手帶錯</li>
<li><strong>Grant 累積 + 沒 retire</strong>：每個 KMS key 有 50,000 grant 上限、rotation Lambda 跑久了 grant 累積 — 定期 <code>ListGrants</code> + <code>RetireGrant</code> 廢棄的、IaC 治理 grant lifecycle</li>
<li><strong>Cross-region decrypt 失敗</strong>：以為 ciphertext 跨 region 通用、結果原本不是 Multi-Region Key — production 跨 region 場景一律建 Multi-Region Key、不要事後補</li>
<li><strong>CMK rotation 後舊 ciphertext 還能 decrypt</strong>：annual rotation 不會 re-encrypt 舊資料、KMS 自動用對應 backing key — 這是設計、不是 bug；真要全量 re-encrypt 要走 application-level migration</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>FIPS 140-2 Level 3 single-tenant HSM</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &#43; 資料主權場景的 key custody">CloudHSM</a>、或 KMS Custom Key Store 橋接</td>
      </tr>
      <tr>
          <td>GCP-heavy 環境</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/google-cloud-kms/" data-link-title="Google Cloud KMS" data-link-desc="GCP 原生 key management service、KeyRing / CryptoKey Version 設計、CMEK 整合 &#43; Cloud HSM &#43; External Key Manager">Google Cloud KMS</a></td>
      </tr>
      <tr>
          <td>Azure-heavy + 跟 AD / Managed Identity 整合</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a></td>
      </tr>
      <tr>
          <td>跨雲統一 key custody</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault transit engine</a></td>
      </tr>
      <tr>
          <td>Static secret + rotation orchestration</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a>（後端是 KMS）</td>
      </tr>
      <tr>
          <td>K8s workload mTLS cert</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a>（可用 KMS asymmetric key）</td>
      </tr>
      <tr>
          <td>Public TLS cert</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS ACM</a> / <a href="/blog/backend/07-security-data-protection/vendors/letsencrypt/" data-link-title="Let&#39;s Encrypt" data-link-desc="免費 &#43; 自動化的公共 ACME CA、90 天 TTL 強制自動化、跨雲跨平台 public TLS cert 的事實基礎">Let&rsquo;s Encrypt</a></td>
      </tr>
      <tr>
          <td>數據主權 / on-prem HSM required</td>
          <td>KMS External Key Store (XKS) 或直接 <a href="/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &#43; 資料主權場景的 key custody">CloudHSM</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>KMS 完整 API reference 跟 SDK 範例</li>
<li>各 AWS service（S3 SSE-KMS、EBS encryption、RDS encryption、DynamoDB encryption）的詳盡設定步驟</li>
<li>跟 AWS Organizations / SCPs 的 cross-account KMS sharing 完整治理流程</li>
<li>CloudHSM cluster 的完整運維（高可用、user 管理、backup）— 看 <a href="/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &#43; 資料主權場景的 key custody">CloudHSM</a></li>
<li>各種 cryptographic algorithm 的數學原理跟選型細節</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>KMS 在 07 案例庫沒有直接 vendor-level 事件、以下案例採對照引用：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 KMS 的關係（對照）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/microsoft-storm-0558-signing-key-2023/" data-link-title="7.C4 Microsoft：Storm-0558 簽章金鑰事件" data-link-desc="簽章金鑰事件如何回寫 identity 信任邊界與觀測證據鏈。">Microsoft Storm-0558 Signing Key 2023</a></td>
          <td>KMS 設計核心對照 — signing key 必須 HSM-bound + 不可導出、KMS 預設 key 完全不離 service；自己 host private key 是 Storm-0558 級事件的根因</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain (red-team)</a></td>
          <td>三件事必到位：asymmetric KMS Key 做 JWT signing（private key 永遠不離 KMS）、強制 rotation 流程、CloudTrail Data Event 紀錄「誰用 key 簽什麼 token」</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>KMS Alias / Grant 的 rotation 跟 revocation 要分域 — 一次 Schedule Key Deletion 沒 scope map 等於潛在全停、Grant lifecycle 要納入治理</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>、<a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">7.5 傳輸信任與憑證生命週期</a>（KMS 為 TLS / signing key 的 root custodian）、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-kms/" data-link-title="Google Cloud KMS" data-link-desc="GCP 原生 key management service、KeyRing / CryptoKey Version 設計、CMEK 整合 &#43; Cloud HSM &#43; External Key Manager">Google Cloud KMS</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a>、<a href="/blog/backend/07-security-data-protection/vendors/cloudhsm/" data-link-title="AWS CloudHSM" data-link-desc="Single-tenant dedicated HSM（FIPS 140-2 Level 3）、AWS 不持 Crypto User credential、合規 &#43; 資料主權場景的 key custody">CloudHSM</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a>（後端用 KMS）、<a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a>（可用 KMS asymmetric key 當 issuer）</li>
<li>對照：<a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a>（transit engine / 跨雲統一介面）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（KMS 事件如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/kms/">AWS KMS Documentation</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>AWS IAM</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam/</guid><description>&lt;p>AWS IAM 是 AWS 的 cloud resource permission engine — 它回答的問題是「這個身份能對哪一個 AWS resource 做哪一個 API call」。它不是 workforce IdP、也不負責「這個人類是誰」的判定。所有 AWS API 流量（無論來自 console 操作、CI pipeline、Lambda、EC2、跨帳號 partner）最終都要經過 IAM 的 policy 評估、IAM 是 AWS 安全模型的根。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>AWS IAM 是 &lt;em>cloud resource permission engine&lt;/em>、人類 workforce 的 SSO 與 lifecycle 應該走 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center&lt;/a> 或外部 IdP（&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak&lt;/a>）。Identity Center 把人類映射到 &lt;em>Permission Set&lt;/em>、Permission Set 在每個目標帳號裡實際上是 AWS-Reserved IAM Role — 也就是說：人類登入走 Identity Center、實際的 API 授權判斷一定回到 IAM。兩層責任分清楚、policy 才不會錯放在「誰是誰」的地方。&lt;/p>
&lt;p>AWS IAM 跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &amp;#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&amp;#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC&lt;/a> 在 policy model 上設計差異很大。AWS 的表達力最強 — identity-based policy、resource-based policy、Service Control Policy（SCP）、Permission Boundary、Session Policy 是五個獨立的層、最終結果由 &lt;em>Explicit Deny &amp;gt; Org SCP &amp;gt; Resource-based &amp;gt; Identity-based &amp;gt; Permission Boundary &amp;gt; Session Policy&lt;/em> 的評估順序決定。表達力換來的代價是 &lt;em>最容易設定錯&lt;/em>：S3 bucket policy 設錯 = public、KMS key policy 漏一個 condition = 跨帳號可以解密、Trust Policy 沒設 ExternalID = confused deputy 攻擊面。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>哪些 IAM first-class concept（User / Group / Role / Policy / STS）對應到自己的場景、哪些要避免（例如：給人類發 IAM User access key）&lt;/li>
&lt;li>跨帳號信任、CI / 第三方 SaaS 連進 AWS、service-to-service 認證該走 Role assumption / OIDC trust 還是 Roles Anywhere&lt;/li>
&lt;li>SCP、Permission Boundary、resource-based policy 三層上限的疊加方式、何時用哪一層&lt;/li>
&lt;li>CloudTrail + Access Analyzer 的稽核 baseline、出事時的最短取證路徑&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷一個 AWS 帳號的 IAM 配置是否健康、最少看四件事：&lt;/p></description><content:encoded><![CDATA[<p>AWS IAM 是 AWS 的 cloud resource permission engine — 它回答的問題是「這個身份能對哪一個 AWS resource 做哪一個 API call」。它不是 workforce IdP、也不負責「這個人類是誰」的判定。所有 AWS API 流量（無論來自 console 操作、CI pipeline、Lambda、EC2、跨帳號 partner）最終都要經過 IAM 的 policy 評估、IAM 是 AWS 安全模型的根。</p>
<h2 id="服務定位">服務定位</h2>
<p>AWS IAM 是 <em>cloud resource permission engine</em>、人類 workforce 的 SSO 與 lifecycle 應該走 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a> 或外部 IdP（<a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / <a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak</a>）。Identity Center 把人類映射到 <em>Permission Set</em>、Permission Set 在每個目標帳號裡實際上是 AWS-Reserved IAM Role — 也就是說：人類登入走 Identity Center、實際的 API 授權判斷一定回到 IAM。兩層責任分清楚、policy 才不會錯放在「誰是誰」的地方。</p>
<p>AWS IAM 跟 <a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a> / <a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a> 在 policy model 上設計差異很大。AWS 的表達力最強 — identity-based policy、resource-based policy、Service Control Policy（SCP）、Permission Boundary、Session Policy 是五個獨立的層、最終結果由 <em>Explicit Deny &gt; Org SCP &gt; Resource-based &gt; Identity-based &gt; Permission Boundary &gt; Session Policy</em> 的評估順序決定。表達力換來的代價是 <em>最容易設定錯</em>：S3 bucket policy 設錯 = public、KMS key policy 漏一個 condition = 跨帳號可以解密、Trust Policy 沒設 ExternalID = confused deputy 攻擊面。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>哪些 IAM first-class concept（User / Group / Role / Policy / STS）對應到自己的場景、哪些要避免（例如：給人類發 IAM User access key）</li>
<li>跨帳號信任、CI / 第三方 SaaS 連進 AWS、service-to-service 認證該走 Role assumption / OIDC trust 還是 Roles Anywhere</li>
<li>SCP、Permission Boundary、resource-based policy 三層上限的疊加方式、何時用哪一層</li>
<li>CloudTrail + Access Analyzer 的稽核 baseline、出事時的最短取證路徑</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷一個 AWS 帳號的 IAM 配置是否健康、最少看四件事：</p>
<ul>
<li><strong>誰能 assume 哪個 Role</strong>：所有 Role 的 Trust Policy（誰能呼叫 <code>sts:AssumeRole</code>）、有沒有跨帳號 trust、跨帳號 trust 是否帶 ExternalID、有沒有 <code>*</code> 在 Principal 裡</li>
<li><strong>Resource-based policy 暴露面</strong>：S3 bucket policy、KMS key policy、Lambda function policy、SNS / SQS policy 是否有 <code>Principal: *</code> 或來自非預期帳號；用 <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html">IAM Access Analyzer</a> 找 <em>unintended external access</em></li>
<li><strong>Permission Boundary 與 SCP 是否生效</strong>：開發者建的 Role 是否 attach Permission Boundary（防止 admin 自己給自己升權）、Organization 是否 attach SCP 做整個 OU 的上限</li>
<li><strong>CloudTrail 是否完整、是否進 SIEM</strong>：management event 跟 data event 都開、跨 region、跨帳號、保留期符合稽核要求、特定事件（<code>AssumeRole</code> 失敗、root login、<code>CreateAccessKey</code>）接 <a href="/blog/backend/knowledge-cards/alert-runbook/" data-link-title="Alert Runbook" data-link-desc="說明告警如何連到可執行的排障與恢復流程">alert runbook</a></li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/knowledge-cards/authorization/" data-link-title="Authorization" data-link-desc="說明授權如何判斷誰能對哪些資源執行哪些操作">Authorization</a> 與 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 邊界的待補項目。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Role 設計（cross-account / service / OIDC trust）</strong>：所有 <em>持續性</em> 的身份都應該是 Role、不是 IAM User。Service Role（給 EC2 / Lambda / ECS task）是 AWS 內部 service-to-service；Cross-account Role 給 partner 帳號或自家其他帳號用 <code>sts:AssumeRole</code> 進來；OIDC trust 是現代 CI 必備路徑（GitHub Actions / GitLab / 自管 K8s 用短期 OIDC token 換 AWS STS 短期憑證、不在 secret store 存 long-lived access key）。</p>
<p><strong>Policy 種類分工</strong>：identity-based policy attach 在 User / Group / Role 上、回答「這個身份能做什麼」。Resource-based policy attach 在 resource 上（S3 bucket、KMS key、SNS topic、Lambda function）、回答「誰能對這個 resource 做什麼」— 同帳號內 identity-based 跟 resource-based 任一個 allow 就通過、跨帳號 <em>兩邊都要 allow</em>。SCP 是 Organization 層級的上限、不是 grant — SCP allow 不會給任何權限、SCP deny 會擋掉整個 OU 的所有 identity。Permission Boundary 是 <em>user 角度的上限</em>、給 admin 用來限制「我把 admin 權限委派給 developer 後、developer 自己建的 role 不能超過這條線」。</p>
<p><strong>STS 與臨時憑證</strong>：所有 cross-account、service-to-service、人類 console federation 都應該走 STS — <code>sts:AssumeRole</code>（跨帳號 / 跨 role）、<code>sts:AssumeRoleWithSAML</code>（SAML IdP）、<code>sts:AssumeRoleWithWebIdentity</code>（OIDC）、<code>sts:GetFederationToken</code>（外部 broker）。Session 預設 1 小時、最長可設 12 小時（依 Role 設定）。Debug 起手式：<code>aws sts get-caller-identity</code> 確認當前 caller 是誰、是 User、Role 還是 federated session。</p>
<p><strong>Access Key 治理</strong>：IAM User 的 long-lived access key 是 <em>最後手段</em>、用於 break-glass 或無法跑 IMDS / Roles Anywhere 的 legacy。所有 access key 走 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a>、定期 rotation、IAM Access Analyzer 的 unused access finding 找閒置 key。</p>
<p><strong>CloudTrail / Access Analyzer baseline</strong>：CloudTrail organization trail 開到所有帳號、management event 必開、data event（S3 object level、Lambda invoke）依資料敏感度開。Access Analyzer 至少跑 <em>external access</em>（找 resource-based policy 把資源暴露給外部帳號）跟 <em>unused access</em>（找閒置 Role、user、permission）。</p>
<p><strong>Trust Policy / ExternalID</strong>：第三方 SaaS（監控、CSPM、備份服務）要進你的 AWS 帳號時、其 Trust Policy 必須要求 ExternalID — 否則攻擊者只要知道 Role ARN 就能假冒第三方 SaaS 的呼叫端、走 confused deputy 攻擊面（<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html">AWS confused deputy 官方說明</a>）。自家跨帳號 trust 不一定要 ExternalID、第三方一定要。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS IAM</th>
          <th>Google Cloud IAM</th>
          <th>Azure RBAC</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>基本單位</td>
          <td>Policy（attach 到 identity 或 resource）</td>
          <td>Role Binding（principal + role + resource）</td>
          <td>Role Assignment（scope + principal + role）</td>
      </tr>
      <tr>
          <td>隔離邊界</td>
          <td>Account（root）+ Organization SCP</td>
          <td>Project / Folder / Org（階層 inherit）</td>
          <td>Subscription / Management Group（階層 inherit）</td>
      </tr>
      <tr>
          <td>Policy 表達力</td>
          <td>高 — identity / resource / SCP / boundary / session 五層</td>
          <td>中 — Conditional IAM + Organization Policy</td>
          <td>中 — RBAC + Azure Policy 兩層</td>
      </tr>
      <tr>
          <td>Resource-based</td>
          <td>多 service 支援（S3 / KMS / SNS / SQS / Lambda&hellip;）</td>
          <td>較少（GCS / Pub/Sub / KMS 等）</td>
          <td>較少、多走 RBAC 統一</td>
      </tr>
      <tr>
          <td>設定錯誤代價</td>
          <td>高 — bucket / key policy 設錯就 public</td>
          <td>中 — 較統一但精細度也較低</td>
          <td>中 — 階層 inherit 容易誤放</td>
      </tr>
  </tbody>
</table>
<p>AWS IAM 是 <em>表達力最強、最容易設定錯</em> 的雲端 IAM。Google Cloud IAM 設計較統一、policy model 易讀但精細度有限。Azure RBAC 走 inheritance + scope、靠 Management Group 結構治理。三家都不能直接互換、跨雲環境需要在每家自己的 IAM 模型裡建等價的 least-privilege baseline。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Service Control Policy（SCP）</strong>：Organization 層級的上限、用來宣告「整個 OU 永遠不能做什麼」 — 例如禁止 root user 操作、禁止關閉 CloudTrail、禁止在非允許 region 建 resource。SCP 是 <em>deny-list 防護網</em>、不是日常授權；日常授權交給 identity-based policy。SCP 過嚴會擋住合法操作、過鬆等於沒設、設計時要對齊 organization 的安全政策骨幹。</p>
<p><strong>Permission Boundary</strong>：用在 <em>委派 admin</em> 場景 — 公司想讓 platform team 自己建 IAM Role 給應用、但又不想讓他們建出 admin role。Admin 給 platform team 一個 Permission Boundary policy、platform team 建的所有 Role 都會被這個 boundary 限制 <em>上限</em>、就算 attach 了 <code>AdministratorAccess</code> 也只能在 boundary 範圍內生效。</p>
<p><strong>ABAC（attribute-based / tag-based access control）</strong>：大規模 multi-account 環境、每個 service 一個 Role 會 Role 爆炸。ABAC 用 <em>tag</em>（principal tag、resource tag、request tag）做 policy condition — 例如「Role 上有 <code>team=payments</code> tag 的人能操作 <code>team=payments</code> tag 的 resource」。設計成立的前提是 tag 來源可信、不能讓使用者自己改 principal tag。</p>
<p><strong>IAM Roles Anywhere</strong>：給 AWS 之外的 workload（地端 K8s、其他雲、邊緣設備）用 X.509 憑證換 STS 短期憑證。前提是有一個可信的 PKI（自管 CA 或公開 CA）跟 trust anchor。比起把 IAM User access key 放在地端 secret store、Roles Anywhere 是更安全的設計。</p>
<p><strong>OIDC trust（GitHub Actions / GitLab CI / 第三方 CI）</strong>：CI / CD 連 AWS 的標準做法。在 AWS 建一個 OIDC identity provider 指向 CI 的 OIDC issuer、Role 的 Trust Policy condition 限制 <code>repo:org/repo:ref:refs/heads/main</code>、CI workflow 直接 <code>aws sts assume-role-with-web-identity</code>。完全不需要在 CI secret store 存 long-lived AWS access key、token TTL 隨 job 結束自動失效。</p>
<p><strong>Resource-based policy 跨帳號設計</strong>：S3 bucket policy、KMS key policy、SNS / SQS / Lambda policy 都支援跨帳號授權。設計時兩件事必查：Principal 是否包含預期的帳號 / Role ARN、condition 是否限制來源（<code>aws:SourceAccount</code>、<code>aws:SourceArn</code>、<code>aws:PrincipalOrgID</code>）。漏了 condition、就可能讓任何拿到「假裝是某個 service」身份的人都能呼叫 — Capital One 2019 事件本質就是 SSRF 取得 EC2 IMDS 的 Role credential、再用該 Role 的權限去 S3 列舉跟讀取資料、揭示 <em>resource-based policy + identity-based policy 沒有最小化、就會在事故時最大化</em>。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong><code>AccessDenied</code> 但 policy 看起來 allow</strong>：先用 <a href="https://policysim.aws.amazon.com/">IAM Policy Simulator</a> 或 <code>aws iam simulate-principal-policy</code> 重算、確認是 SCP 擋、Permission Boundary 擋、resource-based policy 沒 allow、還是 condition key 不匹配。Explicit Deny 永遠贏。</li>
<li><strong>跨帳號 <code>sts:AssumeRole</code> 失敗</strong>：兩邊都要設 — caller 帳號的 identity-based policy 要 allow <code>sts:AssumeRole</code> 到目標 Role ARN、目標 Role 的 Trust Policy 要 allow caller 的 Principal。漏其一就失敗。</li>
<li><strong>S3 bucket 不小心 public</strong>：用 Access Analyzer 的 external access finding 找、用 <em>Block Public Access</em> 帳號級別開關擋掉（即使 bucket policy 寫了 public、Block Public Access 也會擋）。常見根因：bucket policy 寫 <code>Principal: *</code> 沒加 condition、或 ACL 殘留歷史設定。</li>
<li><strong>Role / access key 殘留</strong>：用 Access Analyzer 的 unused access finding、或 IAM credential report 找超過 90 天沒用的 user / role、配 <a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a> 的分域分批 rotation 流程清理</li>
<li><strong>第三方 SaaS Role 缺 ExternalID</strong>：稽核第三方 vendor 的 onboarding 文件、若沒要求 ExternalID 是 vendor 自己安全模型有破口、自己這邊也要拒絕這種 onboarding</li>
<li><strong>CloudTrail 落地不全</strong>：Organization trail 沒覆蓋新建帳號、data event 沒開、log 沒進 SIEM、保留期不足 — 這四件事都會讓事故發生時拿不到證據</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>人類員工 SSO 進 AWS</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a></td>
      </tr>
      <tr>
          <td>多雲 / SaaS app 統一 SSO</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/okta/" data-link-title="Okta" data-link-desc="SaaS Identity Provider 主流選項、SSO / MFA / lifecycle 整合、第三方信任邊界的代價">Okta</a> / <a href="/blog/backend/07-security-data-protection/vendors/keycloak/" data-link-title="Keycloak" data-link-desc="Open source self-hosted Identity Provider、Red Hat 主導、Realm-based multi-tenancy、適合資料主權與自訂 flow 需求">Keycloak</a></td>
      </tr>
      <tr>
          <td>Customer / B2C identity</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/auth0/" data-link-title="Auth0" data-link-desc="B2C / B2B Customer Identity Provider、Universal Login、Action / Rule hook、屬 Okta 旗下 Customer Identity Cloud">Auth0</a></td>
      </tr>
      <tr>
          <td>Google Cloud resource 權限</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a></td>
      </tr>
      <tr>
          <td>Azure resource 權限</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></td>
      </tr>
      <tr>
          <td>Secret / API key 治理</td>
          <td><a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
      <tr>
          <td>Key lifecycle / envelope encryption</td>
          <td>AWS KMS vendor 頁（S2 批次撰寫中）+ <a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a></td>
      </tr>
      <tr>
          <td>事件偵測（CloudTrail 以外）</td>
          <td>04 SIEM / detection 工具與 07 SIEM 章節</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>IAM policy JSON 語法完整 reference 與所有 condition key 清單</li>
<li>每個 AWS service 的細部 IAM 動作對照</li>
<li>AWS Organization、Control Tower、Landing Zone 完整建置流程</li>
<li>KMS / Secrets Manager / Certificate Manager 的內部細節（見對應 vendor 頁）</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 AWS IAM 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/microsoft-storm-0558-signing-key-2023/" data-link-title="7.C4 Microsoft：Storm-0558 簽章金鑰事件" data-link-desc="簽章金鑰事件如何回寫 identity 信任邊界與觀測證據鏈。">Microsoft Storm-0558 Signing Key 2023</a></td>
          <td>雖是 Microsoft Entra / Exchange Online 事件、對 AWS <em>cross-account role assumption signing chain</em> 提供對照：ExternalID 設計、HSM-bound key、跨帳號 token 驗證一致性</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>IAM User access key、STS session、Role trust 的 rotation 必須分域分批、不能單一指令打全部</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain (red-team)</a></td>
          <td>對 IAM Roles Anywhere / OIDC trust 的 signing material 治理啟示：trust anchor、key custody、跨環境驗證</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/identity-access-boundary/" data-link-title="7.2 身分與授權邊界" data-link-desc="以問題驅動方式整理身分、授權、會話與供應商身分鏈">7.2 身分與授權邊界</a>、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam-identity-center/" data-link-title="AWS IAM Identity Center" data-link-desc="AWS 原生 workforce SSO、前 AWS SSO、Permission Set 跨帳號 access、可串外部 IdP federation">AWS IAM Identity Center</a>、<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-iam/" data-link-title="Google Cloud IAM" data-link-desc="GCP cloud resource permission engine、Role Binding / Service Account / Workload Identity Federation、resource hierarchy 為核心的權限治理">Google Cloud IAM</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-rbac/" data-link-title="Azure RBAC &#43; Entra ID" data-link-desc="Azure 雙層身份/權限體系、Entra ID（IdP）&#43; Azure RBAC（resource permission）、Conditional Access、PIM、Managed Identity">Azure RBAC</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>（AWS KMS vendor 頁 S2 批次撰寫中）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（CloudTrail / Access Analyzer 訊號如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/">AWS IAM User Guide</a>、<a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/">AWS IAM Identity Center User Guide</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.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>AWS CloudHSM</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cloudhsm/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cloudhsm/</guid><description>&lt;p>AWS CloudHSM 是 &lt;em>single-tenant dedicated HSM&lt;/em> 服務（FIPS 140-2 Level 3）、客戶獨享一個 HSM cluster、AWS 提供 &lt;em>硬體 + network + provisioning&lt;/em>、客戶自己管 &lt;em>crypto user / partition / key custody / backup&lt;/em>。它跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &amp;#43; Grant 雙軌授權">AWS KMS&lt;/a> 是 &lt;em>不同信任模型&lt;/em> — KMS 是 multi-tenant managed、AWS 持有 key custody 與 API plane；CloudHSM 上 &lt;em>AWS 看不到 key、也不能 reset Crypto User password&lt;/em>、客戶丟了 credential 等於 key 永久遺失。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>CloudHSM 的核心定位是 &lt;em>把 cryptographic root of trust 放回客戶手上&lt;/em> — 適合金融、政府、醫療這類有資料主權、FIPS 140-2 Level 3、PCI HSM、HIPAA 合規壓力的場景。跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &amp;#43; Grant 雙軌授權">AWS KMS&lt;/a> 比、KMS 也滿足 FIPS 140-2 Level 3、但 &lt;em>HSM cluster 是 AWS 多租戶共用&lt;/em>、key material 由 AWS-controlled HSM 持有、控制面 API 也是 AWS。CloudHSM 把 HSM cluster 物理隔離給單一客戶、PKCS#11 / JCE / OpenSSL Dynamic Engine 直接打 HSM、AWS 在資料平面 &lt;em>沒有讀 key 的能力&lt;/em>。&lt;/p>
&lt;p>跟 &lt;em>自管 on-prem HSM&lt;/em>（SafeNet / Thales 自架）比、CloudHSM 把硬體採購、機房、network、firmware patch 交還 AWS、客戶只管 key custody 跟 Crypto User policy；代價是不能完全脫離 AWS region。跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault auto-unseal&lt;/a> 整合場景中、CloudHSM 是 &lt;em>Vault master key 的 root custodian&lt;/em> — Vault unseal key 用 CloudHSM 加密、CloudHSM 出事整個 Vault cluster 沒法 unseal、所以可用性設計（cross-AZ cluster、cross-region backup）很關鍵。多數一般 web app / SaaS 用 KMS 即可、不需要 CloudHSM 的物理隔離。&lt;/p></description><content:encoded><![CDATA[<p>AWS CloudHSM 是 <em>single-tenant dedicated HSM</em> 服務（FIPS 140-2 Level 3）、客戶獨享一個 HSM cluster、AWS 提供 <em>硬體 + network + provisioning</em>、客戶自己管 <em>crypto user / partition / key custody / backup</em>。它跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a> 是 <em>不同信任模型</em> — KMS 是 multi-tenant managed、AWS 持有 key custody 與 API plane；CloudHSM 上 <em>AWS 看不到 key、也不能 reset Crypto User password</em>、客戶丟了 credential 等於 key 永久遺失。</p>
<h2 id="服務定位">服務定位</h2>
<p>CloudHSM 的核心定位是 <em>把 cryptographic root of trust 放回客戶手上</em> — 適合金融、政府、醫療這類有資料主權、FIPS 140-2 Level 3、PCI HSM、HIPAA 合規壓力的場景。跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a> 比、KMS 也滿足 FIPS 140-2 Level 3、但 <em>HSM cluster 是 AWS 多租戶共用</em>、key material 由 AWS-controlled HSM 持有、控制面 API 也是 AWS。CloudHSM 把 HSM cluster 物理隔離給單一客戶、PKCS#11 / JCE / OpenSSL Dynamic Engine 直接打 HSM、AWS 在資料平面 <em>沒有讀 key 的能力</em>。</p>
<p>跟 <em>自管 on-prem HSM</em>（SafeNet / Thales 自架）比、CloudHSM 把硬體採購、機房、network、firmware patch 交還 AWS、客戶只管 key custody 跟 Crypto User policy；代價是不能完全脫離 AWS region。跟 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault auto-unseal</a> 整合場景中、CloudHSM 是 <em>Vault master key 的 root custodian</em> — Vault unseal key 用 CloudHSM 加密、CloudHSM 出事整個 Vault cluster 沒法 unseal、所以可用性設計（cross-AZ cluster、cross-region backup）很關鍵。多數一般 web app / SaaS 用 KMS 即可、不需要 CloudHSM 的物理隔離。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>何時需要 CloudHSM 的 dedicated 模型、何時 <a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a> 已足夠</li>
<li>CloudHSM cluster 的最低安全 / 可用性需求（cross-AZ、Crypto Officer 分離、Quorum、backup）</li>
<li>Crypto User credential 出事的降級路徑（AWS 不能幫忙、靠 backup + Quorum）</li>
<li>跟 <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">KMS Custom Key Store</a> / <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault auto-unseal</a> 整合的取捨</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 CloudHSM deployment 是否健康、最少看四件事：</p>
<ul>
<li><strong>Cluster 拓樸</strong>：production cluster 是否至少 2 個 HSM instance 跨 AZ、cluster 內自動 replicate、單一 AZ 故障時 key 是否仍可用</li>
<li><strong>Crypto User 管理</strong>：Crypto Officer（CO）跟 Crypto User（CU）是否分離、CO password 是否走 break-glass 保管、CU credential 是否走 short-lived 取得 + audit</li>
<li><strong>Quorum-based policy</strong>：高敏 operation（建 CU、改 policy、key export wrapped）是否設 M-of-N approval、避免單一 admin compromise 後 silent abuse</li>
<li><strong>Backup 治理</strong>：automatic 24h backup 跟 manual backup 是否都開、cross-region backup 是否走 explicit copy、restore 流程是否定期演練</li>
</ul>
<p>四件事任一缺失、就是 CloudHSM deployment 待補項目 — 跟 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">secret management</a> 的 evidence 邊界同類。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Cluster + HSM Instance 拓樸</strong>：CloudHSM 的部署單位是 <em>cluster</em>、cluster 內可以有 1-N 個 <em>HSM instance</em>。production 場景至少 2 個 HSM instance 跨 AZ、cluster 自動把 key material replicate 在所有 instance 上、單一 AZ 失效不影響 cryptographic operation。跨 region 不自動 replicate — 跨 region DR 要靠 backup copy。</p>
<p><strong>Crypto Officer (CO) vs Crypto User (CU)</strong>：CO 是 cluster 管理員、能建 / 刪 CU、設 policy、做 backup；CU 是真的做 cryptographic operation 的 identity（encrypt / decrypt / sign / verify）。production 必須分離 — CO credential 走 break-glass 保管、CU credential 給 application 使用、application compromise 只影響 CU 邊界、不能改 CO policy。</p>
<p><strong>Quorum-based policy（M-of-N approval）</strong>：CloudHSM 支援把高敏操作（建 CU、改 policy、key export wrapped）綁定 <em>M-of-N CO approval</em>。例如 3-of-5 quorum、單一 CO 即使 credential 外洩也不能單獨建後門 CU、必須拿到另外 2 個 CO 的 signed token。對應 <a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Storm-0558 signing key chain</a> 啟示：高價值 key custodian 的 admin operation 不該是 <em>單人單 token</em>、必須有第二人簽核才能改變信任根。</p>
<p><strong>Backup 治理</strong>：CloudHSM 每 24 小時自動 backup 整個 cluster state（含 key material）、backup 是 AWS-managed encrypted blob、AWS 自己也不能解密、restore 必須在 CloudHSM cluster context 內進行。可手動 backup、可 copy 到其他 region 做 DR。Backup retention 預設 90 天、可延長。Backup 不是 <em>export</em> — 不能把 key material 從 HSM 拿出來看 plaintext。</p>
<p><strong>Key Replication 跨 region</strong>：CloudHSM cluster 綁定單一 AWS region、跨 region 走 <em>backup → copy → restore</em> 流程、不是 active replication。設計 DR 時要算 RTO：restore 一個 cluster 從 backup 大約小時級、不適合 hot failover、應該 <em>primary region 跑、DR region 備好空 cluster + backup copy</em>。</p>
<p><strong>PKCS#11 / JCE / OpenSSL Dynamic Engine 整合</strong>：application 不用 AWS SDK 講 CloudHSM、而是透過 <em>標準 cryptographic API library</em>（PKCS#11 for C/C++、JCE Provider for Java、OpenSSL Dynamic Engine 走 TLS termination）。好處是 <em>application code 用業界標準介面</em>、未來換 HSM 廠也只需要換 library。代價是 client SDK 要裝在 application host、CU credential 要 deploy 到 host、host security baseline 變成 cryptographic boundary 的一部分。</p>
<p><strong>跟 KMS Custom Key Store 整合</strong>：<a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">KMS Custom Key Store</a> 把 KMS Key 的 <em>backing material 放在 CloudHSM</em>、API 仍透過 KMS（<code>kms:Encrypt</code> / <code>kms:Decrypt</code>）、application code 不需要改。這是 <em>KMS 易用 + HSM dedicated 雙重</em>：保留 KMS 的 IAM policy / key rotation / audit log（CloudTrail）、又得到 single-tenant HSM 的合規屬性。代價是 CloudHSM 失效時、Custom Key Store backing 的 KMS Key 全部不可用、需要監控 cluster health。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>AWS CloudHSM</th>
          <th>AWS KMS</th>
          <th>Azure Managed HSM</th>
          <th>Google Cloud HSM</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>Single-tenant dedicated cluster</td>
          <td>Multi-tenant managed</td>
          <td>Single-tenant pool</td>
          <td>HSM-backed Cloud KMS（Protection Level=HSM）</td>
      </tr>
      <tr>
          <td>FIPS 140-2</td>
          <td>Level 3（dedicated）</td>
          <td>Level 3（shared cluster）</td>
          <td>Level 3</td>
          <td>Level 3</td>
      </tr>
      <tr>
          <td>AWS / 雲廠持 key？</td>
          <td>不持（CU credential 客戶獨有）</td>
          <td>持（managed key custody）</td>
          <td>不持（HSM admin 客戶獨有）</td>
          <td>不持 plaintext key material</td>
      </tr>
      <tr>
          <td>整合介面</td>
          <td>PKCS#11 / JCE / OpenSSL</td>
          <td>AWS SDK / CLI / KMS API</td>
          <td>Key Vault SDK / REST</td>
          <td>Cloud KMS API</td>
      </tr>
      <tr>
          <td>Quorum 多人簽核</td>
          <td>內建（M-of-N）</td>
          <td>透過 IAM policy + organization SCP</td>
          <td>RBAC + Privileged Identity Management</td>
          <td>IAM Condition + organization policy</td>
      </tr>
      <tr>
          <td>運維成本</td>
          <td>高 — 自管 CU credential / patch / topology</td>
          <td>低</td>
          <td>中</td>
          <td>低</td>
      </tr>
      <tr>
          <td>合規憑證</td>
          <td>FIPS 140-2 L3 + PCI HSM + Common Criteria</td>
          <td>FIPS 140-2 L3 + PCI DSS</td>
          <td>FIPS 140-2 L3 + Common Criteria</td>
          <td>FIPS 140-2 L3</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>金融 / 政府 / 醫療、需要物理隔離 + AWS 不持 key</td>
          <td>一般 AWS-heavy workload、需要 IAM 整合</td>
          <td>Azure-heavy + 合規壓力</td>
          <td>GCP-heavy + 合規壓力</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>中 — backup 跨廠不可移植、key 不能 export</td>
          <td>中</td>
          <td>中</td>
          <td>中</td>
      </tr>
  </tbody>
</table>
<p>選 CloudHSM 的核心訴求：<em>合規明文要求 dedicated HSM</em>（PCI HSM、某些國家資料主權法規）、或 <em>trust model 上不接受 AWS 持 key</em>。多數 AWS-heavy workload 用 KMS 即可、加 CloudHSM 反而引入 <em>Crypto User credential 的單點失誤</em>（丟了 = key 永久遺失）。需要 KMS API 但又要 dedicated HSM、走 <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">Custom Key Store</a> 是折衷路徑。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>Quorum Auth 設計</strong>：production 把 Quorum threshold 設為 <em>3-of-5</em> 或 <em>2-of-3</em>、五位 CO 由不同部門 / 不同地理位置持有、避免單一辦公室 / 單一網路同時被攻陷。Quorum token 有 TTL、單次 operation 用完就失效、防止 replay。建議 quarterly 演練：模擬一個 CO 不在、用剩餘 quorum 完成 emergency operation、驗證流程在事故時跑得通。</p>
<p><strong>KMS Custom Key Store 整合決策</strong>：用 Custom Key Store 的關鍵問題是 <em>availability blast radius</em> — KMS Key 出事影響範圍是 <em>使用該 Key 的 AWS service</em>（S3、EBS、RDS encryption）、Custom Key Store backing 失效會讓這些 service 同步斷。設計時做 <em>分層 key strategy</em>：mass volume 的 S3 / EBS 用 AWS-managed KMS Key、高合規敏感的 database / secret 才用 Custom Key Store backing 的 KMS Key、降低單一 cluster 失效的影響面。</p>
<p><strong>Cross-Region Backup</strong>：DR 要把 backup copy 到第二個 region、走 <code>CopyBackupToRegion</code> API、restore 時建空 cluster + 套 backup。整個 RTO 通常數小時、不適合熱備、設計上是 <em>容忍小時級 outage 換到 BCDR 環境</em>、不是 <em>秒級 failover</em>。對應 <a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a> 對照啟示：身份 / 加密控制面的單點 outage 影響整個 platform、availability 的 topology 設計跟 confidentiality 同等重要。</p>
<p><strong>跟 Vault auto-unseal 整合</strong>：<a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">Vault</a> auto-unseal 可用 CloudHSM 作 master key custodian、走 PKCS#11 plugin、Vault unseal 時呼叫 CloudHSM <code>Unwrap</code> master key。比起 <a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS auto-unseal</a> 多一層 dedicated HSM 保證、適合監管特別嚴的場景。代價是 CloudHSM cluster 失效 → Vault 不能 unseal → 下游所有 secret 拿不到、要設計 break-glass 流程。</p>
<p><strong>合規憑證</strong>：CloudHSM 同時持有 FIPS 140-2 Level 3、PCI HSM、Common Criteria EAL4+ 多個認證、可作金融 PIN block 處理、payment 業者的 HSM 上鏈、政府機敏資料加密的 <em>直接合規承諾</em>、不需要客戶端再做 HSM 認證 audit。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Crypto User credential 丟失</strong>：CU password 全公司只有一份、保管人離職 → AWS <em>不能 reset</em>、key material 永久不可用 — CU credential 要走 password manager + 多人持有、CO 有能力 revoke 舊 CU 建新 CU</li>
<li><strong>Cluster 只有單一 HSM instance</strong>：成本省了、單一 instance 故障 cluster 整個失效 — production 強制至少 2 個 instance、跨 AZ</li>
<li><strong>Backup 沒測過 restore</strong>：每天 automatic backup 跑、從未 restore 演練、DR 真要用時發現流程不通 — quarterly 演練 restore 到測試 cluster、驗證 key material 可用</li>
<li><strong>Custom Key Store 沒監控 CloudHSM health</strong>：CloudHSM cluster degraded 時、KMS Custom Key Store 跟著失效、application 看到 KMS 5xx — CloudWatch metric 監 <code>HsmsActive</code> / <code>HsmTemperature</code>、cluster health degrade 立即 alert</li>
<li><strong>PKCS#11 library 版本漂移</strong>：application host 的 client SDK 版本跟 cluster firmware 不相容、cryptographic operation 失敗 — version compatibility matrix 進 deployment pipeline、firmware upgrade 前先測 staging</li>
<li><strong>Quorum CO 全部同地點</strong>：5 個 CO 全在同一個辦公室、辦公室斷網 = quorum 不能組 — CO 跨 region / 跨組織分散</li>
<li><strong>Audit log 沒接 SIEM</strong>：CloudHSM activity 透過 CloudTrail + cluster audit log、沒接 SIEM 就無 forensic — CloudTrail 跟 cluster audit 都 push 到 SIEM（見 <a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a>）</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一般 AWS workload 加密、無 dedicated 合規</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a></td>
      </tr>
      <tr>
          <td>Azure-heavy + dedicated HSM 合規需求</td>
          <td>Azure Managed HSM（見上方對照表）</td>
      </tr>
      <tr>
          <td>GCP-heavy + dedicated HSM 合規需求</td>
          <td>Google Cloud HSM（Cloud KMS Protection Level=HSM）</td>
      </tr>
      <tr>
          <td>Secret storage + dynamic credential</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a> / <a href="/blog/backend/07-security-data-protection/vendors/aws-secrets-manager/" data-link-title="AWS Secrets Manager" data-link-desc="AWS 原生 secret store &#43; 內建 RDS / Redshift rotation Lambda、Resource Policy 跨帳號共享、KMS 加密">AWS Secrets Manager</a></td>
      </tr>
      <tr>
          <td>Certificate / PKI（不是 key custody）</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/aws-acm/" data-link-title="AWS ACM" data-link-desc="AWS-managed certificate provisioning、DNS validation &#43; auto-renewal、整合 ELB / CloudFront / API Gateway、Private CA 後端">AWS ACM</a> / <a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a></td>
      </tr>
      <tr>
          <td>跨雲 unified key custody</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a> transit engine（雲廠中立）</td>
      </tr>
      <tr>
          <td>Key rotation 證據鏈</td>
          <td><a href="/blog/backend/07-security-data-protection/credential-rotation-scoped-evidence/" data-link-title="7.27 Credential Rotation with Scoped Evidence 實作示範" data-link-desc="以 webhook/API credential 輪替示範 scope map、證據欄位與回退窗口如何一起設計。">7.5 Credential Rotation Scoped Evidence</a></td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>CloudHSM 完整 PKCS#11 / JCE API reference</li>
<li>CloudHSM Classic（舊版、已 EOL）的差異</li>
<li>每種合規法規（PCI HSM、HIPAA、FedRAMP）的逐條對應</li>
<li>CloudHSM CLI 跟 <code>cloudhsm_mgmt_util</code> 詳細指令</li>
<li>應用層使用 HSM-bound key 做 TLS termination 的 nginx / Apache 配置細節</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>CloudHSM 在 07 案例庫沒有直接 vendor-level 事件、以下案例採對照引用：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 CloudHSM 的關係（對照）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/identity-access/microsoft-storm-0558-2023-signing-key-chain/" data-link-title="7.R7.1.5 Microsoft Storm-0558 2023：簽章金鑰鏈與郵件存取" data-link-desc="從簽章金鑰保護失效到雲端郵件存取，拆解身分信任鏈的關鍵控制點">Microsoft Storm-0558 Signing Key Chain</a></td>
          <td>核心對照 — CloudHSM 設計 <em>AWS 不持 key + key 不能 export</em> 是 Storm-0558 反設計、攻擊者進 cluster 也搬不走 key material、Quorum policy 阻單一 admin compromise</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/failure-credential-rotation-without-scope/" data-link-title="7.C9 反例：憑證輪替未分 Scope" data-link-desc="憑證輪替若未分域分批，容易造成跨系統連鎖中斷。">Failure: Credential Rotation Without Scope</a></td>
          <td>CloudHSM key rotation 需要應用層配合 key alias 切換、不像 KMS 自動 rotation；scope map 跟雙軌驗證窗口更明顯、PKCS#11 client 散落 host 群時 rotation 要分批</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/cases/azure-ad-identity-control-plane-2021/" data-link-title="7.C3 Azure AD：2021 Identity Control-plane 事件" data-link-desc="身分控制面事件如何影響多服務信任鏈與回復優先序。">Azure AD Identity Control Plane 2021</a></td>
          <td>對照啟示 — HSM cluster 是 single point of compromise、cross-AZ topology + cross-region backup 是 <em>availability</em> 的設計依據、不是 confidentiality</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/secrets-and-machine-credential-governance/" data-link-title="7.6 秘密管理與機器憑證治理" data-link-desc="以問題驅動方式整理 secret、token、key 與機器身份治理">7.6 秘密管理與機器憑證治理</a>、<a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">7.5 傳輸信任與憑證生命週期</a>（HSM 為 CA / signing key 的 FIPS-grade root custodian）、<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a>、<a href="/blog/backend/07-security-data-protection/vendors/google-cloud-kms/" data-link-title="Google Cloud KMS" data-link-desc="GCP 原生 key management service、KeyRing / CryptoKey Version 設計、CMEK 整合 &#43; Cloud HSM &#43; External Key Manager">Google Cloud KMS</a>、<a href="/blog/backend/07-security-data-protection/vendors/azure-key-vault/" data-link-title="Azure Key Vault" data-link-desc="Azure 三合一 service（Secret &#43; Key &#43; Certificate）、整合 Managed Identity &#43; Entra ID RBAC、Premium tier 走 HSM">Azure Key Vault</a></li>
<li>整合：<a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a>（CloudHSM 作為 Vault auto-unseal master key custodian）</li>
<li>整合：<a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">KMS Custom Key Store</a>（KMS API + CloudHSM backing 雙重）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（HSM 失效如何 routing 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/cloudhsm/">AWS CloudHSM Documentation</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>AWS ACM</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-acm/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/aws-acm/</guid><description>&lt;p>AWS Certificate Manager (ACM) 是 AWS-managed 的 &lt;em>certificate provisioning 服務&lt;/em>、解決兩件事：&lt;em>public TLS cert 全自動化&lt;/em>（Amazon Trust Services 簽發、DNS validation 通過後 60 天前自動 renew）跟 &lt;em>AWS-managed service 的 cert 整合&lt;/em>（&lt;a href="https://docs.aws.amazon.com/acm/latest/userguide/acm-services.html">ELB / CloudFront / API Gateway / App Runner&lt;/a> 直接 attach、不需要客戶持有私鑰）。內部 mTLS / 自管 endpoint 的 private cert 走另一個產品 ACM Private CA（PCA）— ACM 是 &lt;em>frontend&lt;/em>、PCA 是 &lt;em>自管 CA hierarchy backend&lt;/em>。&lt;/p>
&lt;h2 id="服務定位">服務定位&lt;/h2>
&lt;p>ACM 的核心定位是 &lt;em>AWS 平台內 cert 的全託管 lifecycle&lt;/em>。客戶不持私鑰、不跑 ACME client、不手動 renew — 但代價是 ACM public cert &lt;em>只能 attach 到 AWS-managed service&lt;/em>（ELB / CloudFront / API Gateway / App Runner / Nitro Enclaves）、不能 export 給自管 Nginx / EC2 應用。Private cert 必須有 ACM Private CA (PCA) 後端、ACM 自己不是 CA。&lt;/p>
&lt;p>跟其他 cert 工具的場景重疊度低、定位是分工互補：&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&amp;#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &amp;#43; Challenge solver">cert-manager&lt;/a> 走 cluster 內 K8s workload cert（Ingress / service mesh）、&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/letsencrypt/" data-link-title="Let&amp;#39;s Encrypt" data-link-desc="免費 &amp;#43; 自動化的公共 ACME CA、90 天 TTL 強制自動化、跨雲跨平台 public TLS cert 的事實基礎">Let&amp;rsquo;s Encrypt&lt;/a> 走跨平台公共 ACME cert（可 export 任何地方使用）、ACM Private CA 走自管 CA hierarchy（root + intermediate、客戶控制 policy）。常見組合：AWS-native endpoint 用 ACM、K8s workload + 自管伺服器走 cert-manager + Let&amp;rsquo;s Encrypt、內部 mTLS root 走 PCA。詳細差異見「核心取捨表」。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本頁、讀者能判斷：&lt;/p>
&lt;ol>
&lt;li>ACM public cert vs private cert vs imported cert 各自的使用邊界（能 attach 哪些 service、能不能 export）&lt;/li>
&lt;li>DNS validation vs Email validation 的差異、跟 auto-renewal 條件的關聯&lt;/li>
&lt;li>跨 region 跟 CloudFront 的 us-east-1 限制如何處理&lt;/li>
&lt;li>何時 ACM 不夠用、要改走 cert-manager / Let&amp;rsquo;s Encrypt / ACM Private CA&lt;/li>
&lt;/ol>
&lt;h2 id="最短判讀路徑">最短判讀路徑&lt;/h2>
&lt;p>判斷 ACM cert 部署是否健康、最少看四件事：&lt;/p></description><content:encoded><![CDATA[<p>AWS Certificate Manager (ACM) 是 AWS-managed 的 <em>certificate provisioning 服務</em>、解決兩件事：<em>public TLS cert 全自動化</em>（Amazon Trust Services 簽發、DNS validation 通過後 60 天前自動 renew）跟 <em>AWS-managed service 的 cert 整合</em>（<a href="https://docs.aws.amazon.com/acm/latest/userguide/acm-services.html">ELB / CloudFront / API Gateway / App Runner</a> 直接 attach、不需要客戶持有私鑰）。內部 mTLS / 自管 endpoint 的 private cert 走另一個產品 ACM Private CA（PCA）— ACM 是 <em>frontend</em>、PCA 是 <em>自管 CA hierarchy backend</em>。</p>
<h2 id="服務定位">服務定位</h2>
<p>ACM 的核心定位是 <em>AWS 平台內 cert 的全託管 lifecycle</em>。客戶不持私鑰、不跑 ACME client、不手動 renew — 但代價是 ACM public cert <em>只能 attach 到 AWS-managed service</em>（ELB / CloudFront / API Gateway / App Runner / Nitro Enclaves）、不能 export 給自管 Nginx / EC2 應用。Private cert 必須有 ACM Private CA (PCA) 後端、ACM 自己不是 CA。</p>
<p>跟其他 cert 工具的場景重疊度低、定位是分工互補：<a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a> 走 cluster 內 K8s workload cert（Ingress / service mesh）、<a href="/blog/backend/07-security-data-protection/vendors/letsencrypt/" data-link-title="Let&#39;s Encrypt" data-link-desc="免費 &#43; 自動化的公共 ACME CA、90 天 TTL 強制自動化、跨雲跨平台 public TLS cert 的事實基礎">Let&rsquo;s Encrypt</a> 走跨平台公共 ACME cert（可 export 任何地方使用）、ACM Private CA 走自管 CA hierarchy（root + intermediate、客戶控制 policy）。常見組合：AWS-native endpoint 用 ACM、K8s workload + 自管伺服器走 cert-manager + Let&rsquo;s Encrypt、內部 mTLS root 走 PCA。詳細差異見「核心取捨表」。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本頁、讀者能判斷：</p>
<ol>
<li>ACM public cert vs private cert vs imported cert 各自的使用邊界（能 attach 哪些 service、能不能 export）</li>
<li>DNS validation vs Email validation 的差異、跟 auto-renewal 條件的關聯</li>
<li>跨 region 跟 CloudFront 的 us-east-1 限制如何處理</li>
<li>何時 ACM 不夠用、要改走 cert-manager / Let&rsquo;s Encrypt / ACM Private CA</li>
</ol>
<h2 id="最短判讀路徑">最短判讀路徑</h2>
<p>判斷 ACM cert 部署是否健康、最少看四件事：</p>
<ul>
<li><strong>Cert 跟 service 整合</strong>：cert ARN 是否真的 attach 到 ELB / CloudFront / API Gateway listener、<code>DescribeCertificate</code> 的 <code>InUseBy</code> 有沒有資源、有 cert 但沒 attach 等於 issue 失敗</li>
<li><strong>DNS validation 設定</strong>：cert 是 DNS 還是 Email validation、DNS 的 CNAME record 是否還留在 DNS（auto-renewal 需要這條 record 持續存在）、Route53 vs 外部 DNS 的責任分界</li>
<li><strong>Renewal status</strong>：<code>DescribeCertificate</code> 的 <code>RenewalSummary.RenewalStatus</code> 是 <code>SUCCESS</code> / <code>PENDING_AUTO_RENEWAL</code> / <code>FAILED</code>、失敗時 <code>RenewalStatusReason</code> 是什麼（多半是 DNS record 被刪、CNAME 不再回應）</li>
<li><strong>CloudTrail 證據</strong>：<code>RequestCertificate</code> / <code>ImportCertificate</code> / <code>DeleteCertificate</code> 的 caller identity、是否有非預期的 cert 建立或刪除（防誤刪 / 惡意刪）</li>
</ul>
<p>四件事任一缺失、就是 <a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">Transport Trust and Certificate Lifecycle</a> 的覆蓋缺口。</p>
<h2 id="日常操作與決策形狀">日常操作與決策形狀</h2>
<p><strong>Request public cert</strong>：對 internet-facing endpoint（網站、API）issue public cert、走 <code>RequestCertificate</code> API、選 DNS validation。ACM 給一組 CNAME record、放進 DNS（Route53 可一鍵 create）、ACM 自動驗證 + issue。Cert 生效後 attach 到 ELB / CloudFront / API Gateway listener。Issuer 是 Amazon Trust Services、所有主流瀏覽器 / OS trust store 都認。</p>
<p><strong>Request private cert（需 PCA 後端）</strong>：內部 service mTLS root、走 <code>RequestCertificate</code> 但指定 PCA ARN。ACM 透過 PCA 簽 cert、cert chain 是組織內部 CA hierarchy。Trust store 必須在各 workload 手動建立（不像 public cert 自動 trust）。</p>
<p><strong>DNS validation vs Email validation</strong>：DNS validation 是預設 + 推薦 — CNAME record 放進 DNS 後、ACM 持續驗證 domain ownership、auto-renewal 全自動。Email validation 是 legacy、ACM 寄信到 domain 的 WHOIS / 預設 admin email、人工點連結驗證；auto-renewal 不會自動完成、cert 到期前必須手動 re-validate。Production 一律用 DNS validation。</p>
<p><strong>Auto-renewal 條件</strong>：ACM 在 cert lifetime 60 天前嘗試 renew、條件嚴格：(1) cert 是 ACM-issued（不是 imported）(2) DNS validation 走 CNAME record 仍存在且可回應 (3) cert 至少 attach 到一個 AWS service。三個條件任一不滿足、renewal 不自動觸發、cert 會 expire。Imported cert <em>完全不自動 renew</em>、必須在 expiry 前手動 re-import。</p>
<p><strong>跟 ELB / CloudFront / API Gateway 整合</strong>：ELB / API Gateway 用所在 region 的 ACM cert、CloudFront 例外 — <em>只認 us-east-1 region 的 ACM cert</em>（CloudFront edge 是 global、cert metadata 統一從 us-east-1 拉）。Multi-region app 要在每個 region 各 request 一份 cert、CloudFront 那份固定放 us-east-1。</p>
<p><strong>Imported certificate</strong>：自管 cert（外部 CA 簽的、舊系統遷移過來的）可以 import 進 ACM、拿到 ARN 後一樣 attach 到 AWS service。代價是 <em>ACM 不會 renew</em>、expiry 前必須手動 re-import 新版。常見事故源：imported cert 過期、AWS service 突然 serve expired cert、Browser 顯示警告。建議 imported cert 都設 CloudWatch alarm 監 <code>DaysToExpiry</code>。</p>
<p><strong>跟 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 整合</strong>：誰能 issue / delete cert 走 IAM policy 控制 — <code>acm:RequestCertificate</code> / <code>acm:DeleteCertificate</code> / <code>acm:ImportCertificate</code>。Tag-based access control 可以限定「只有帶 <code>team=platform</code> tag 的 cert 才能被 platform team IAM role 改」、防誤刪 production cert。Cert 是 region-scoped resource、IAM policy 可指定 <code>Resource</code> ARN 限定 region / cert ID。</p>
<h2 id="核心取捨表">核心取捨表</h2>
<table>
  <thead>
      <tr>
          <th>取捨維度</th>
          <th>ACM (public)</th>
          <th>ACM Private CA (PCA)</th>
          <th>cert-manager + Let&rsquo;s Encrypt</th>
          <th>手動 OpenSSL CA</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>部署模型</td>
          <td>AWS managed</td>
          <td>AWS managed CA hierarchy</td>
          <td>K8s cluster 內 self-hosted controller</td>
          <td>手動腳本</td>
      </tr>
      <tr>
          <td>私鑰持有</td>
          <td>AWS 持有、客戶不能 export</td>
          <td>AWS 持有 CA key、subordinate 可 export</td>
          <td>cluster 內 Secret、可 export</td>
          <td>自己持有</td>
      </tr>
      <tr>
          <td>Issuer</td>
          <td>Amazon Trust Services（public trust store）</td>
          <td>客戶自管 CA（內部 trust）</td>
          <td>Let&rsquo;s Encrypt / 任何 ACME CA</td>
          <td>自簽</td>
      </tr>
      <tr>
          <td>適用 endpoint</td>
          <td>AWS-managed service（ELB / CloudFront / API GW）</td>
          <td>內部 mTLS、AWS service 也可用</td>
          <td>K8s workload、Ingress、任何持有 PEM 的服務</td>
          <td>實驗 / 內部小規模</td>
      </tr>
      <tr>
          <td>Auto-renewal</td>
          <td>DNS validation 全自動</td>
          <td>透過 ACM 自動</td>
          <td>cert-manager 自動</td>
          <td>自己寫 cron</td>
      </tr>
      <tr>
          <td>跨雲 / 跨平台</td>
          <td>弱 — AWS 內</td>
          <td>弱 — AWS 內</td>
          <td>強 — K8s 在哪都可</td>
          <td>強</td>
      </tr>
      <tr>
          <td>計費</td>
          <td>public cert 免費</td>
          <td>per CA + per cert（PCA 較貴）</td>
          <td>免費（Let&rsquo;s Encrypt）</td>
          <td>免費</td>
      </tr>
      <tr>
          <td>適合場景</td>
          <td>AWS-heavy + edge endpoint</td>
          <td>內部 mTLS root + AWS 整合</td>
          <td>K8s workload + 跨雲</td>
          <td>實驗、極小規模</td>
      </tr>
      <tr>
          <td>退場成本</td>
          <td>中 — cert 重 issue 但 service 配置要改</td>
          <td>高 — CA hierarchy 遷移痛苦</td>
          <td>低 — PEM 在手、換 issuer 容易</td>
          <td>低</td>
      </tr>
  </tbody>
</table>
<p>選 ACM 的核心訴求：cert 主要 attach 到 AWS-managed service、希望 cert 完全 hands-off、不需要 export 私鑰、能接受 AWS lock-in。需要 export PEM 或跨雲 / 自管 endpoint、改走 cert-manager + Let&rsquo;s Encrypt。需要內部 mTLS root + CA hierarchy 控制、走 ACM Private CA。</p>
<h2 id="進階主題">進階主題</h2>
<p><strong>ACM Private CA hierarchy</strong>：PCA 支援 root CA + 多層 intermediate CA、生產建議 root CA 離線（CA 簽完 intermediate 後 disable）、日常簽發走 subordinate CA。Subordinate CA compromise 時 revoke 該層、root 不受影響。Cert policy（path length、key usage、name constraint）在 CA 建立時設定、之後無法改、設計時要算對。</p>
<p><strong>Cross-region cert（CloudFront 的 us-east-1 限制）</strong>：CloudFront 是 global service、但 attach 的 ACM cert <em>必須在 us-east-1</em>。Multi-region 部署：每個 region 各 issue 一份 cert 給該 region 的 ELB / API Gateway、CloudFront 的那份單獨在 us-east-1 issue。Terraform / CloudFormation 要顯式宣告 provider region。</p>
<p><strong>Imported cert 跟 auto-renewal 邊界</strong>：imported cert（外部 CA 簽的）ACM 知道存在、可以 attach、但 <em>不 renew</em>。常見事故：團隊 import cert 後忘了；幾個月後 cert 到期；CloudFront / ELB serve expired cert；客戶看到 browser 警告。對策：所有 imported cert 設 CloudWatch alarm <code>DaysToExpiry &lt; 30</code>、<code>AlmostExpired</code> event 推 EventBridge → PagerDuty。長期策略是把 imported cert 都遷移成 ACM-issued cert（如果 domain ownership 可驗證）。</p>
<p><strong>Tag-based access control</strong>：cert 加 tag（<code>team=platform</code>、<code>env=prod</code>）後、IAM policy 用 <code>Condition</code> 限定：只有同 tag 的 role 才能 update / delete。防誤刪 production cert（dev IAM role 跑 cleanup script 不會誤刪 prod）。配合 <a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a> 的 ABAC 模型運作。</p>
<p><strong>Wildcard cert 跟 SAN cert</strong>：ACM 支援 wildcard（<code>*.example.com</code> 涵蓋一層 subdomain）跟 SAN（一張 cert 多個 domain，最多 100 個）。Wildcard 簡化部署但 blast radius 大 — 一張 cert compromise 等於整個 subdomain tree 出事；SAN cert 細粒度但管理成本高。Production 建議按服務邊界拆 — 每個 service 一張 cert、不共用 wildcard，除非確實有大量短 lifecycle subdomain。</p>
<h2 id="排錯與失敗快速判讀">排錯與失敗快速判讀</h2>
<ul>
<li><strong>Cert PENDING_VALIDATION 一直卡住</strong>：DNS validation CNAME record 沒放對、或 DNS provider 緩存太久 — 用 <code>dig</code> 直接查 CNAME 是否生效、Route53 + ACM 整合通常幾分鐘、外部 DNS 可能 30 分鐘以上</li>
<li><strong>Cert renewal FAILED</strong>：<code>RenewalStatusReason</code> 多半是 <code>DOMAIN_VALIDATION_DENIED</code>（CNAME record 被刪了）或 cert 沒 attach 到任何 service — 補回 CNAME record、或把 cert attach 到至少一個 resource</li>
<li><strong>CloudFront 找不到 cert</strong>：cert 在 us-east-1 以外的 region issue — 在 us-east-1 重 issue、或用 Terraform 顯式跨 provider 設定</li>
<li><strong>Imported cert expired</strong>：忘了 manual renewal、AWS service serve expired cert — CloudWatch alarm + EventBridge 推 alert、長期遷成 ACM-issued</li>
<li><strong>ACM cert 無法用在 EC2 自管 Nginx</strong>：public cert 私鑰不能 export 是設計限制 — 改用 ACM Private CA 或 Let&rsquo;s Encrypt + cert-manager</li>
<li><strong>誤刪 production cert</strong>：沒設 tag-based protection、admin script bug — 開 deletion protection（暫時無內建、用 IAM Condition 限定 delete operation + 24h cooldown via Lambda）+ CloudTrail alert 上 <code>acm:DeleteCertificate</code></li>
<li><strong>Cross-account cert 共用</strong>：ACM cert 不支援 RAM 共用 — 跨 account 要在每個 account 各 issue（或用 PCA + RAM 共用 PCA、各 account 從 PCA issue）</li>
</ul>
<h2 id="何時改走其他服務">何時改走其他服務</h2>
<table>
  <thead>
      <tr>
          <th>需求形狀</th>
          <th>改走</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>K8s workload mTLS / Ingress TLS</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a> + Let&rsquo;s Encrypt / 內部 issuer</td>
      </tr>
      <tr>
          <td>自管 Nginx / EC2 / 跨雲 endpoint</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/letsencrypt/" data-link-title="Let&#39;s Encrypt" data-link-desc="免費 &#43; 自動化的公共 ACME CA、90 天 TTL 強制自動化、跨雲跨平台 public TLS cert 的事實基礎">Let&rsquo;s Encrypt</a> + 自管 ACME client</td>
      </tr>
      <tr>
          <td>內部 mTLS root + CA hierarchy 控制</td>
          <td>ACM Private CA（PCA）或 <a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/" data-link-title="HashiCorp Vault" data-link-desc="Self-hosted secret management 與 dynamic credential / encryption-as-a-service / PKI engine、跨雲跨環境的 secret 控制面">HashiCorp Vault</a> PKI engine</td>
      </tr>
      <tr>
          <td>Workload identity（SPIFFE）跨平台</td>
          <td><a href="/blog/backend/07-security-data-protection/vendors/spire/" data-link-title="SPIRE" data-link-desc="SPIFFE Runtime Environment、attested workload identity、short-lived SVID &#43; Trust Bundle、跨組織 federation">SPIRE</a></td>
      </tr>
      <tr>
          <td>Cert renewal 證據鏈（rotation evidence）</td>
          <td><a href="/blog/backend/07-security-data-protection/credential-rotation-scoped-evidence/" data-link-title="7.27 Credential Rotation with Scoped Evidence 實作示範" data-link-desc="以 webhook/API credential 輪替示範 scope map、證據欄位與回退窗口如何一起設計。">7.5 Credential Rotation Scoped Evidence</a></td>
      </tr>
      <tr>
          <td>Cert + session invalidation 邊界</td>
          <td><a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理</a>、cert renew 跟 session token 是兩條獨立 lifecycle</td>
      </tr>
  </tbody>
</table>
<h2 id="不在本頁內的主題">不在本頁內的主題</h2>
<ul>
<li>ACM Private CA 完整 hierarchy 設計（root CA 離線儲存、HSM-backed CA key、CRL / OCSP responder 部署）</li>
<li>ACM API 完整 CLI reference 跟 Terraform resource 詳盡欄位</li>
<li>TLS protocol 本身（TLS 1.2 vs 1.3、cipher suite、handshake 流程）</li>
<li>Certificate Transparency log 跟 SCT embedding 內部機制</li>
<li>各 browser / OS trust store 的更新週期</li>
</ul>
<h2 id="案例回寫">案例回寫</h2>
<p>ACM 在 07 案例庫沒有直接 vendor-level 事件、以下採對照引用：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 ACM 的關係（對照）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">Transport Trust and Certificate Lifecycle (section)</a></td>
          <td>ACM 是 AWS 平台 cert lifecycle 自動化的具體落地 — DNS validation + auto-renewal 是 <em>自動化覆蓋率</em> 的指標、imported cert 是覆蓋缺口、要單獨設 alarm 兜底</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/red-team/cases/edge-exposure/citrix-bleed-2023-session-hijack/" data-link-title="7.R7.3.3 Citrix Bleed 2023：會話被劫持與重放風險" data-link-desc="邊界設備會話資料外洩後，如何演變成帳號與服務風險">Citrix Bleed 2023 Session Hijack</a></td>
          <td>對照啟示 — cert 自動 renew 不等於 session 自動 invalidate、舊 session token 在新 cert 下仍可重放、session lifecycle 是另一層責任、不在 ACM 範圍</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/07-security-data-protection/credential-rotation-scoped-evidence/" data-link-title="7.27 Credential Rotation with Scoped Evidence 實作示範" data-link-desc="以 webhook/API credential 輪替示範 scope map、證據欄位與回退窗口如何一起設計。">Credential Rotation Scoped Evidence (section)</a></td>
          <td>ACM renewal 自動、但 <em>Certificate Transparency log 比對</em> + <em>fleet-wide trust bundle update</em> 是另一條 evidence chain、要跟 SBOM / CMDB 對齊</td>
      </tr>
  </tbody>
</table>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>上游：<a href="/blog/backend/07-security-data-protection/transport-trust-and-certificate-lifecycle/" data-link-title="7.5 傳輸信任與憑證生命週期" data-link-desc="以問題驅動方式整理傳輸信任鏈、會話完整性與憑證節奏">7.4 傳輸信任與憑證生命週期</a>、<a href="/blog/backend/07-security-data-protection/entrypoint-and-server-protection/" data-link-title="7.3 入口治理與伺服器防護" data-link-desc="以問題驅動方式整理對外入口、管理平面與伺服器邊界">7.3 入口治理與伺服器防護</a></li>
<li>平行：<a href="/blog/backend/07-security-data-protection/vendors/cert-manager/" data-link-title="cert-manager" data-link-desc="K8s 原生 certificate lifecycle automation、支援 Let&#39;s Encrypt / Vault PKI / Venafi 等多 issuer、auto-renewal &#43; Challenge solver">cert-manager</a>、<a href="/blog/backend/07-security-data-protection/vendors/letsencrypt/" data-link-title="Let&#39;s Encrypt" data-link-desc="免費 &#43; 自動化的公共 ACME CA、90 天 TTL 強制自動化、跨雲跨平台 public TLS cert 的事實基礎">Let&rsquo;s Encrypt</a>、<a href="/blog/backend/07-security-data-protection/vendors/spire/" data-link-title="SPIRE" data-link-desc="SPIFFE Runtime Environment、attested workload identity、short-lived SVID &#43; Trust Bundle、跨組織 federation">SPIRE</a></li>
<li>下游：<a href="/blog/backend/07-security-data-protection/vendors/aws-iam/" data-link-title="AWS IAM" data-link-desc="AWS cloud resource permission engine、Role / Policy / STS、跨帳號信任邊界與 OIDC federation 的核心">AWS IAM</a>（誰能 issue / delete cert）、<a href="/blog/backend/07-security-data-protection/vendors/aws-kms/" data-link-title="AWS KMS" data-link-desc="AWS 原生 key management service、envelope encryption / digital signing / Multi-Region Key、Key Policy &#43; Grant 雙軌授權">AWS KMS</a>（PCA CA key 後端）</li>
<li>跨模組：<a href="/blog/backend/08-incident-response/vendors/" data-link-title="事故處理 Vendor 清單" data-link-desc="規劃 on-call、incident response、status page 與 postmortem 工具的服務頁撰寫順序與判準">8 事故處理 vendor 清單</a>（cert expiry / mis-issuance 進 IR 流程）</li>
<li>官方：<a href="https://docs.aws.amazon.com/acm/">AWS Certificate Manager Documentation</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>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>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>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>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.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></channel></rss>