<?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>RPO on Tarragon</title><link>https://tarrragon.github.io/blog/tags/rpo/</link><description>Recent content in RPO on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 27 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/rpo/index.xml" rel="self" type="application/rss+xml"/><item><title>CockroachDB Survival Goals：zone 級 vs region 級配置與業務 SLO 倒推流程</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/cockroachdb/survival-goals/</link><pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/cockroachdb/survival-goals/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor overview&lt;/a> 的 implementation-layer deep article。Overview 已界定 CockroachDB 的 multi-region 能力、本文聚焦 &lt;em>survival goal 配置怎麼從業務 SLO 倒推、怎麼避開「cross-region = 更快」的動機誤判&lt;/em>。Raft replica 分佈機制屬前置、見 &lt;a href="../hlc-raft-consensus/">HLC + Raft consensus&lt;/a>。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="multi-region-上線前的兩個錯誤期待">Multi-region 上線前的兩個錯誤期待&lt;/h2>
&lt;p>multi-region CockroachDB cluster 上線時、團隊最常踩的兩個錯誤期待：&lt;/p>
&lt;ul>
&lt;li>&lt;em>「default 配置應該就好、上線後再說」&lt;/em>：default 是 &lt;code>SURVIVE ZONE FAILURE&lt;/code>、一旦遇到 region failure 整 cluster 變 read-only、客訴湧入才發現要重新配&lt;/li>
&lt;li>&lt;em>「跨 region 應該會讓全球用戶都更快」&lt;/em>：跨 region quorum 物理上必然 &lt;em>增&lt;/em> 寫入 latency、把 multi-region 動機誤判成 latency 優化會在 production 撞牆&lt;/li>
&lt;/ul>
&lt;p>讀者進來最常問：&lt;/p>
&lt;ul>
&lt;li>&lt;code>SURVIVE ZONE FAILURE&lt;/code> 跟 &lt;code>SURVIVE REGION FAILURE&lt;/code> 差在哪？&lt;/li>
&lt;li>為什麼 region survival 寫入 latency 是 zone survival 的 3 倍？&lt;/li>
&lt;li>Default 配置是什麼、上線前該不該改？&lt;/li>
&lt;/ul>
&lt;p>要回答這三題、必須先把 survival goal 跟業務 SLO 的對應關係講清楚。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/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 合規 &amp;#43; 跨州單一邏輯 DB" data-link-desc="Hard Rock Digital 用 CockroachDB 跨 AWS Outposts &amp;#43; US-East-1、Wire Act 強制資料留州、單一邏輯 DB 解多州 sportsbook、100 node 32 vCPU 撐 Super Bowl">9.C41 Hard Rock Digital&lt;/a> 提供最 concrete 的 SLO 倒推路徑：sportsbook 中 &lt;em>bet placement 不能 lose&lt;/em> — 玩家下注後系統 crash 沒紀錄、對博彩牌照是合規事故。CockroachDB Raft 3-replica + 跨 AZ + survival goal 配置是把這個業務不可丟事件翻譯成 DB 層保證。&lt;/p>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/" data-link-title="9.C40 Netflix：380&amp;#43; CockroachDB cluster 的 multi-active 拓樸艦隊" data-link-desc="Netflix 把 Cassandra 不夠用的 transactional workload 移到 CockroachDB、380&amp;#43; cluster / 60&amp;#43; 跨 region、含 Open Connect、studio cloud drive、gaming control plane">9.C40 Netflix&lt;/a> 則提供反直覺判讀：60+ multi-region cluster 主要動機是 &lt;em>region failure 0 downtime&lt;/em>、不是降 latency。Gaming cluster 48-node 跨 4 region 就是為了「region failover 不停服」、不是讓玩家延遲變低。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor overview</a> 的 implementation-layer deep article。Overview 已界定 CockroachDB 的 multi-region 能力、本文聚焦 <em>survival goal 配置怎麼從業務 SLO 倒推、怎麼避開「cross-region = 更快」的動機誤判</em>。Raft replica 分佈機制屬前置、見 <a href="../hlc-raft-consensus/">HLC + Raft consensus</a>。</p></blockquote>
<hr>
<h2 id="multi-region-上線前的兩個錯誤期待">Multi-region 上線前的兩個錯誤期待</h2>
<p>multi-region CockroachDB cluster 上線時、團隊最常踩的兩個錯誤期待：</p>
<ul>
<li><em>「default 配置應該就好、上線後再說」</em>：default 是 <code>SURVIVE ZONE FAILURE</code>、一旦遇到 region failure 整 cluster 變 read-only、客訴湧入才發現要重新配</li>
<li><em>「跨 region 應該會讓全球用戶都更快」</em>：跨 region quorum 物理上必然 <em>增</em> 寫入 latency、把 multi-region 動機誤判成 latency 優化會在 production 撞牆</li>
</ul>
<p>讀者進來最常問：</p>
<ul>
<li><code>SURVIVE ZONE FAILURE</code> 跟 <code>SURVIVE REGION FAILURE</code> 差在哪？</li>
<li>為什麼 region survival 寫入 latency 是 zone survival 的 3 倍？</li>
<li>Default 配置是什麼、上線前該不該改？</li>
</ul>
<p>要回答這三題、必須先把 survival goal 跟業務 SLO 的對應關係講清楚。</p>
<p><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> 提供最 concrete 的 SLO 倒推路徑：sportsbook 中 <em>bet placement 不能 lose</em> — 玩家下注後系統 crash 沒紀錄、對博彩牌照是合規事故。CockroachDB Raft 3-replica + 跨 AZ + survival goal 配置是把這個業務不可丟事件翻譯成 DB 層保證。</p>
<p><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> 則提供反直覺判讀：60+ multi-region cluster 主要動機是 <em>region failure 0 downtime</em>、不是降 latency。Gaming cluster 48-node 跨 4 region 就是為了「region failover 不停服」、不是讓玩家延遲變低。</p>
<p>對照 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 走另一條路：銀行受監管市場資料 <em>不能跨境</em>、不可用 region survival、必須拆每市場獨立 Aurora cluster + zone survival。這個 anti-recommendation 提醒「survival goal 不是越強越好、合規邊界優先於技術 HA 配置」。</p>
<h2 id="核心機制兩種-survival-goal--replica-placement">核心機制：兩種 survival goal + replica placement</h2>
<h3 id="兩種宣告式配置">兩種宣告式配置</h3>
<p>CockroachDB 把 HA 配置抽象成兩個 database-level（或 table-level）宣告：</p>
<ul>
<li><strong><code>SURVIVE ZONE FAILURE</code></strong>（default）：失去 1 個 AZ 仍能寫入。replica 跨 AZ 分佈、但可能集中在同一個 region 內。對應 RTO ~ 數秒（Raft + <a href="/blog/backend/knowledge-cards/leaseholder/" data-link-title="Leaseholder" data-link-desc="分散式 SQL 每個 range 在任一時間點的 read / write entry point、通常等於 Raft leader、承擔該 range 的 coordination">Leaseholder</a> 自動 failover）、RPO = 0（已 commit 資料不丟）</li>
<li><strong><code>SURVIVE REGION FAILURE</code></strong>：失去 1 個整個 region 仍能寫入。voting replica 強制跨 region、需要至少 3 個 region。對應 RTO ~ 數秒、RPO = 0、但寫入 latency 因跨 region quorum 結構性增加</li>
</ul>
<p>survival goal 是 <em>宣告式</em> 配置 — application 端不用手動指定 <a href="/blog/backend/knowledge-cards/range-sharding/" data-link-title="Range Sharding" data-link-desc="分散式 SQL 把 key space 切成可自動 split / merge 的 range、每個 range 自己的 consensus group、application 透明">Range Sharding</a> 的 replica placement、Raft 根據 survival goal + locality 自動分佈、用 <a href="/blog/backend/knowledge-cards/hybrid-logical-clock/" data-link-title="Hybrid Logical Clock" data-link-desc="用 physical wall clock &#43; monotonic logical counter 給每個事件 timestamp、靠軟體 max-offset 保證跨節點時鐘差不超過上限、超過 panic 保護一致性">Hybrid Logical Clock</a> 串接 commit ordering。對比通用 HA 設計（如 PostgreSQL streaming + Patroni manual failover）、CockroachDB 把這層邏輯壓進系統內。</p>
<h3 id="voting-vs-non-voting-replica">Voting vs non-voting replica</h3>
<p>region survival 模式下、CockroachDB 區分兩種 replica：</p>
<ul>
<li><strong>Voting replica</strong>：參與 Raft majority 決策、commit 必須等 voting majority ack。region survival 下 voting replica 強制跨 region — 這就是 <a href="/blog/backend/knowledge-cards/cross-region-quorum/" data-link-title="Cross-Region Quorum" data-link-desc="multi-region distributed SQL 強制 voting replica 跨 region、commit 等多 region quorum ack、跨洲 RTT 物理硬限">Cross-Region Quorum</a> 拓樸、commit latency 受跨洲 RTT 物理硬限主導</li>
<li><strong>Non-voting replica</strong>：只用來 serve <a href="/blog/backend/knowledge-cards/follower-read/" data-link-title="Follower Read" data-link-desc="分散式 SQL 從 non-voting replica 讀 closed timestamp 之前的資料、不參與 Raft commit、低 latency 但 read-after-write 場景仍可能 stale">Follower Read</a>、不參與 Raft commit。可以放在「不想列入 quorum 但希望本地 read 快」的 region</li>
</ul>
<p>實務影響：region survival 下、跨 3 region 配置最少 3 voting replica（每 region 1 個）、寫入要等其中 2 個 region 的 ack。若想讓第 4 個 region 也能本地 read、可以加 non-voting replica、不影響 commit latency 但增加 storage cost。</p>
<h3 id="配置語法">配置語法</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">-- Database-level
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">mydb</span><span class="w"> </span><span class="n">SURVIVE</span><span class="w"> </span><span class="n">REGION</span><span class="w"> </span><span class="n">FAILURE</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="c1">-- Table-level（覆蓋 database 設定）
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">orders</span><span class="w"> </span><span class="n">SURVIVE</span><span class="w"> </span><span class="k">ZONE</span><span class="w"> </span><span class="n">FAILURE</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w"></span><span class="c1">-- 驗證
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="c1"></span><span class="k">SHOW</span><span class="w"> </span><span class="n">SURVIVAL</span><span class="w"> </span><span class="n">GOAL</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">mydb</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="w"></span><span class="k">SHOW</span><span class="w"> </span><span class="k">ZONE</span><span class="w"> </span><span class="n">CONFIGURATION</span><span class="w"> </span><span class="k">FOR</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">mydb</span><span class="p">;</span></span></span></code></pre></div><p>對應 <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum 卡</a>、<a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">rto 卡</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">rpo 卡</a>、<a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius 卡</a> 的具體機制實現。</p>
<h3 id="為什麼選-region-survival-是業務動機判讀不是技術-factf48">為什麼選 region survival 是業務動機判讀、不是技術 fact（F4.8）</h3>
<p>Netflix 60+ multi-region cluster 揭露的反直覺結論：<em>主要動機是 region failure 0 downtime、不是降 latency</em>。跨 region quorum 物理上必然增 latency — 跨洲 round trip 物理 ~70-80ms、Raft majority 需要 2 個 region ack、寫入 p99 因此被光速下界限制。</p>
<p>Gaming cluster 48-node 跨 4 region 就是為了「region failover 不停服」、不是讓玩家延遲變低。<strong>Scope warning</strong>：case 沒揭露 Gaming cluster 具體 p99 數字、只揭露「48-node、跨 4 region、region failure 不停服」這個拓樸 fact 跟業務動機釐清。</p>
<p>引用時若提到「region survival 怎麼提升用戶體驗」、要 <em>釐清成 survival、不是 latency 優化</em>。讓讀者誤把跨 region 當成 latency 解法、是這條決策最常見的源頭錯誤。</p>
<h2 id="操作流程從業務-slo-倒推-survival-goal">操作流程：從業務 SLO 倒推 survival goal</h2>
<h3 id="配置前置">配置前置</h3>
<p>region survival 的最小可運行配置：</p>
<ul>
<li>cluster 至少 3 個 region</li>
<li>每 region 至少 3 個節點（保證單一 region 內也能扛 AZ failure）</li>
<li>locality tag 配齊（region + zone）</li>
</ul>





<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 us-east1 的節點</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">cockroach start --locality<span class="o">=</span><span class="nv">region</span><span class="o">=</span>us-east1,zone<span class="o">=</span>us-east1-a ...
</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"># Region us-west2 的節點</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">cockroach start --locality<span class="o">=</span><span class="nv">region</span><span class="o">=</span>us-west2,zone<span class="o">=</span>us-west2-a ...
</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"># Region eu-west1 的節點</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">cockroach start --locality<span class="o">=</span><span class="nv">region</span><span class="o">=</span>eu-west1,zone<span class="o">=</span>eu-west1-a ...</span></span></code></pre></div><h3 id="從業務-slo-倒推9c41-hard-rock-揭露f411">從業務 SLO 倒推（9.C41 Hard Rock 揭露、F4.11）</h3>
<p>Hard Rock Digital sportsbook 揭露的 5 步倒推流程：</p>
<ol>
<li><strong>列業務「不能丟」事件清單</strong>：bet placement、payment、order commit、settlement 等業務事件</li>
<li><strong>對每個事件決定 RPO</strong>：bet placement → RPO = 0（不可丟）、log audit → RPO = 1 分鐘（可接受 short-window 丟失）</li>
<li><strong>對 RPO = 0 事件決定故障域容忍</strong>：Hard Rock 案例 <em>Outpost 或 AZ 失敗不丟</em> 是業務要求、跨 region failure 不是 sportsbook 的硬需求（因為各州各自合規邊界）</li>
<li><strong>故障域容忍翻譯成 survival goal</strong>：
<ul>
<li>Outpost / AZ 失敗 → <code>SURVIVE ZONE FAILURE</code> 即可</li>
<li>region 失敗也不丟 → <code>SURVIVE REGION FAILURE</code></li>
</ul>
</li>
<li><strong>反過來驗 replica 分佈</strong>：survival goal 配置產出的 replica 分佈是否覆蓋業務故障域。Hard Rock CockroachDB Raft 3-replica + 跨 AZ → Outpost 失敗時其他 replica 在、自動 failover、滿足 bet placement RPO = 0</li>
</ol>
<h3 id="跟業務動機釐清的互補">跟業務動機釐清的互補</h3>
<p>Netflix 從技術配置 <em>反推</em>「為什麼選 region survival」（survival 動機、不是 latency）、Hard Rock 從業務不能丟事件 <em>正推</em> 該選哪個 survival goal。兩個方向是同一條路徑：</p>
<ul>
<li>正推（Hard Rock）：業務不能丟 → RPO → 故障域 → survival goal</li>
<li>反推（Netflix）：survival goal 配置 → 揭露的不是「會變快」而是「region failover 不停服」</li>
</ul>
<p>兩個方向互相驗證、避免把跨 region 配置誤解成 latency 工具。</p>
<h3 id="升級流程跟-rollback-邊界">升級流程跟 rollback 邊界</h3>
<p>zone survival → region survival 是 <em>非破壞性</em> 配置變更、Raft 自動 rebalance replica。但要注意：</p>
<ul>
<li>rebalance 期間 cross-region traffic 暴增、p99 短期波動</li>
<li>replication factor 增加 → storage 用量 × 新 RF</li>
<li>升級後 application 寫入 latency 結構性上升、要先在 staging 量過</li>
</ul>
<p>監控 rebalance：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">-- 看 range 數量變化跟 rebalance queue
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="k">SELECT</span><span class="w"> </span><span class="n">range_count</span><span class="p">,</span><span class="w"> </span><span class="n">used</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">crdb_internal</span><span class="p">.</span><span class="n">kv_store_status</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="c1">-- CockroachDB Console「Rebalance queue size」應該歸零</span></span></span></code></pre></div><p>Rollback：survival goal 可即時降級（region → zone）、replica 自動 rebalance、無不可逆動作。但 application 端如果已經依賴 region failover 0 downtime、降級回 zone survival 後 region failure 會讓 cluster 變 read-only — 配置 rollback 容易、業務 SLO rollback 不容易。</p>
<h2 id="失敗模式5-種典型錯配">失敗模式：5 種典型錯配</h2>
<h3 id="default-zone-survival-期待-region-survival">Default zone survival 期待 region survival</h3>
<p>最常見：上線後一個 region 掛、cluster 變 read-only、客訴。要在 production 前 <em>明確選</em> survival goal、不依賴 default。</p>
<h3 id="region-survival-但只配-2-region">Region survival 但只配 2 region</h3>
<p>Raft majority 需要 3 個獨立 fault domain。2 region 配置實際是 zone survival — 任一 region 失敗剩 1 region 拿不到 majority。要 region survival <em>至少</em> 3 region。</p>
<h3 id="cross-region-cost-暴漲">Cross-region cost 暴漲</h3>
<p>region survival 強制 voting replica 跨 region、每次 write 跨 region traffic × 3。AWS / GCP 的 cross-region data transfer 是高 markup、月費可能 2-3 倍。</p>
<p>production 前必須估：</p>
<ul>
<li>寫 QPS × row size × 3 = cross-region traffic GB/day</li>
<li>對應 cloud provider 定價（AWS 跨 region $0.02/GB、GCP 類似量級）</li>
<li>月度 traffic cost 加總、跟 single-region 配置比</li>
</ul>
<h3 id="locality-跟-survival-goal-衝突">Locality 跟 survival goal 衝突</h3>
<p>業務想把 user data partition by region 留 local（locality 配置）、但 survival goal 要求跨 region replica、結果 replica 仍跑遠端。這是 locality + survival 的互動議題、見 <a href="../locality-aware-schema/">locality-aware schema</a> 詳細展開。</p>
<h3 id="合規邊界-violation">合規邊界 violation</h3>
<p>受監管市場（金融 / 醫療 / 博彩）資料 <em>不能跨境</em>、但 region survival 強制 voting replica 跨 region — 這直接違反合規。對照 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> 走的是「每市場獨立 Aurora cluster + zone survival」、不是 region survival。</p>
<p>合規邊界判讀：</p>
<ul>
<li>跨境合規 <em>禁止</em> 跨 region replica → 不可用 region survival、走 cluster-per-市場</li>
<li>跨州合規 <em>允許</em> 跨州但要求資料留國內 → 可用 region survival、選同國內的 region</li>
<li>業務邏輯要求跨 boundary（如 Hard Rock 跨州統一帳戶）→ 不可拆獨立 cluster、必須 locality + placement</li>
</ul>
<h2 id="容量與觀測">容量與觀測</h2>
<h3 id="必看-metric">必看 metric</h3>
<ul>
<li><code>Raft replicas per node</code>：replica 分佈均勻度</li>
<li><code>Range count by survival mode</code>：region survival 配置的 range 數量</li>
<li><code>Cross-region write latency p99</code>：跨 region quorum 實測 latency</li>
<li><code>Rebalance queue size</code>：rebalance 是否完成</li>
<li><code>Network traffic by direction</code>：cross-region 流量、cost signal</li>
</ul>
<h3 id="容量公式">容量公式</h3>
<ul>
<li>region survival 最小：region count × 3 nodes</li>
<li>replica factor 預設 3、storage 用量 × replication factor</li>
<li>cross-region traffic = write QPS × row size × (region count - 1)</li>
</ul>
<h3 id="write-latency-預算屬通用工程估算case-未揭露具體-latency-數字">Write latency 預算（屬通用工程估算、case 未揭露具體 latency 數字）</h3>
<p><strong>Scope warning</strong>：以下數字屬通用工程估算（跨 region 物理光速下界推導）、<strong>Netflix / Hard Rock case 都沒揭露 zone / region survival 的 p99 latency 數字</strong>。引用時必須明示來源層次：</p>
<ul>
<li>zone survival single-region 寫入 p99 5-10ms（跨 AZ Raft round trip）</li>
<li>region survival 同洲跨 region p99 30-60ms（跨 region round trip × Raft majority）</li>
<li>region survival 跨洲 p99 100-150ms（跨洲光速下界 ~70-80ms × 2）</li>
</ul>
<p>數字屬「合理的工程估算量級」、不是 case 揭露的 p99。讀者用這些做容量規劃時應該自己 benchmark、不要直接套。</p>
<h3 id="賽季型容量擺盪9c41-hard-rock">賽季型容量擺盪（9.C41 Hard Rock）</h3>
<p>sportsbook 業務年度循環：NFL / NBA 季初季末流量結構性差異 — Hard Rock 100 nodes ↔ 33 nodes 擺盪是 <em>計畫內</em>、不是異常事件。CockroachDB 加減節點靠 range rebalance、不停服。</p>
<p>容量規劃要點：</p>
<ul>
<li>NFL / NBA / 國際賽事曆塞進預測模型、不要當 surprise</li>
<li>scale up 提前 1-2 週執行、留 rebalance 時間</li>
<li>scale down 在淡季低流量時段執行、避免 rebalance 期間 p99 spike</li>
</ul>
<h3 id="回路徑">回路徑</h3>
<ul>
<li><a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.6 容量規劃模型</a> survival goal 對 replica count / cost 影響</li>
<li><a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置能撐多少、要加多少機器』變成可量化、可驗證、可改進的工程流程">9.11 高峰事件準備</a> event-driven scaling</li>
<li><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">latency budget 卡</a> cross-region 預算</li>
</ul>
<h2 id="邊界與整合">邊界與整合</h2>
<h3 id="sibling-deep-articles">Sibling deep articles</h3>
<ul>
<li><a href="../hlc-raft-consensus/">HLC + Raft consensus</a>：Raft 機制是 survival goal 的基礎</li>
<li><a href="../locality-aware-schema/">locality-aware schema</a>：locality + survival 一起決定 placement</li>
<li><a href="../transaction-retry-pattern/">transaction retry pattern</a>：cross-region latency 加長 retry window</li>
</ul>
<h3 id="跟-aurora-對照">跟 Aurora 對照</h3>
<ul>
<li>Aurora cross-AZ failover：zone-level survival 等價、但只在 single-region 內</li>
<li>Aurora Global Database：跨 region async replication、不是 sync — region failure 仍會丟 last seconds</li>
<li>CockroachDB region survival：sync majority、region failure RPO = 0</li>
</ul>
<p>Aurora 沒有 row-level locality 配置、跨 region 強一致要走 Aurora DSQL（AWS 2024 GA）。</p>
<h3 id="aurora-dsql--spanner-對比">Aurora DSQL / Spanner 對比</h3>
<p>完整三家 distributed SQL 在 multi-region survival 的取捨、見 <a href="../aurora-dsql-spanner-decision-tree/">aurora-dsql-spanner-decision-tree</a>。</p>
<h3 id="1x-章節互引">1.x 章節互引</h3>
<ul>
<li><a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 上游</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 強一致取捨">1.3 Transaction Boundary</a> distributed transaction</li>
</ul>
<h3 id="何時不用-region-survival">何時不用 region survival</h3>
<ul>
<li>single-region 已滿足業務 SLO → zone survival 即可</li>
<li>預算敏感、cross-region traffic cost 不划算</li>
<li>合規禁止跨境 → 必須拆每市場獨立 cluster + zone survival</li>
</ul>
<h2 id="相關連結">相關連結</h2>
<ul>
<li><a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor overview</a></li>
<li><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>（bet placement RPO=0 倒推）</li>
<li><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>（Gaming 48-node 跨 4 region survival）</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>（anti-recommendation、為何 <em>不用</em> region survival）</li>
<li><a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum 卡</a> / <a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">rto 卡</a> / <a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">rpo 卡</a> / <a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius 卡</a></li>
<li>官方：<a href="https://www.cockroachlabs.com/docs/stable/multiregion-survival-goals.html">CockroachDB Multi-Region Survival Goals</a> / <a href="https://www.cockroachlabs.com/docs/stable/multiregion-overview.html">Multi-Region Capabilities Overview</a></li>
</ul>
]]></content:encoded></item><item><title>RPO</title><link>https://tarrragon.github.io/blog/backend/knowledge-cards/rpo/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/knowledge-cards/rpo/</guid><description>&lt;p>RPO 的核心概念是「事故後可接受的最大資料損失窗口」。它回答回復後最多能遺失多久的資料變更。 可先對照 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">Database&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>RPO 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">database&lt;/a>、備份策略、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/replication-lag/" data-link-title="Replication Lag" data-link-desc="說明資料副本落後正式來源多久，以及它如何影響讀取正確性">replication lag&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/data-reconciliation/" data-link-title="Data Reconciliation" data-link-desc="說明多個資料來源不一致時如何比對、修復與留下證據">data reconciliation&lt;/a> 緊密相關。RPO 越嚴格，資料保護與同步成本通常越高。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>系統需要 RPO 的訊號是資料遺失會造成財務或合規風險。訂單與付款資料若目標 RPO 接近零，需要更嚴格的持久化與回復設計。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>RPO 要定義資料類型分級、保護機制、驗證流程與例外處理。設定後應透過備份回復演練檢查實際可達成範圍。&lt;/p></description><content:encoded><![CDATA[<p>RPO 的核心概念是「事故後可接受的最大資料損失窗口」。它回答回復後最多能遺失多久的資料變更。 可先對照 <a href="/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">Database</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>RPO 與 <a href="/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">database</a>、備份策略、<a href="/blog/backend/knowledge-cards/replication-lag/" data-link-title="Replication Lag" data-link-desc="說明資料副本落後正式來源多久，以及它如何影響讀取正確性">replication lag</a> 與 <a href="/blog/backend/knowledge-cards/data-reconciliation/" data-link-title="Data Reconciliation" data-link-desc="說明多個資料來源不一致時如何比對、修復與留下證據">data reconciliation</a> 緊密相關。RPO 越嚴格，資料保護與同步成本通常越高。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>系統需要 RPO 的訊號是資料遺失會造成財務或合規風險。訂單與付款資料若目標 RPO 接近零，需要更嚴格的持久化與回復設計。</p>
<h2 id="設計責任">設計責任</h2>
<p>RPO 要定義資料類型分級、保護機制、驗證流程與例外處理。設定後應透過備份回復演練檢查實際可達成範圍。</p>
]]></content:encoded></item></channel></rss>