DynamoDB Global Tables:多區域複寫詳解
一個 global table 是單一張 DynamoDB 表,跨越多個 AWS 區域複寫, 而其中每一份複本都可寫入。DynamoDB 會自動讓它們保持同步——你在每個 區域都得到低延遲的本地讀取與寫入,外加跨區域的災難復原,而不用 自己跑一套複寫。
在稽核日誌這個情境裡,一位歐盟客戶要求他們的資料存放在
eu-west-1,而其餘部分則跑在 us-east-1。而且作為一份合規至關重要的
日誌,它需要在整個區域故障中存活。一個 global table 用一個功能就
回答了這兩件事。
DynamoDB Global Tables 是怎麼運作的?
DynamoDB Global Tables 是單一張表,跨越多個 AWS 區域複寫,而其中每一份複本都可讀可寫。DynamoDB 透過的非同步複寫自動讓它們同步,並以最後寫入者勝出來解決衝突。你在每個區域都得到低延遲的本地讀取與寫入,外加跨區域的災難復原,撐起 DynamoDB 的 99.999% 可用性 SLA。
- 多區域、主動-主動。 每一份複本都完全可讀可寫; 任何區域的寫入都會傳播到其他區域。
- 在預設模式下,複寫是非同步且的——跨區域 通常在一秒內,但不是即時。(一個強一致模式也 存在——見下文。)
- 衝突以最後寫入者勝出解決。 對同一個項目在兩個 區域的並行寫入,會協調成最近的那一個。
- 它撐起 99.999% 的可用性 SLA——一個多區域的 global table 是 DynamoDB 可用性最高的配置。
問題:一個區域不夠
一張單區域的表有兩個限制,是這份稽核日誌無法接受的。第一,資料
落地:一位歐盟客戶的事件必須存放在歐盟,但你的應用程式跑在
美國。第二,災難復原:如果 us-east-1 發生故障,一份單區域的
稽核日誌在那段期間就無法讀取也無法寫入——恰恰是你最
需要那份「發生了什麼」記錄的時候。
自己建構其中任一個——跨區域複寫、故障轉移、衝突處理—— 都是一個龐大、容易出錯的專案。Global tables 把它變成一個配置選項。
複寫機制
你把一個複本區域加到表上;DynamoDB 在那裡建立一份副本並讓 所有複本保持同步。
有兩條一致性規則定義了預設(MREC)的行為:
- 跨區域複寫是非同步的。 一次
us-east-1的寫入會在本地被 確認,然後傳播到eu-west-1——通常在一秒內, 但另一個區域緊接在寫入之後的一次讀取,可能還看不到它。(在 預設的 MREC 模式下,強一致仍能運作, 但只在_單一_區域_之內_。) - 衝突以最後寫入者勝出。 如果同一個項目在兩個區域幾乎 同時被寫入,DynamoDB 保留帶最新時間戳的那次寫入,並 丟棄另一次。
一個實作範例:一份也兼作 DR 的歐盟複本
你把 eu-west-1 加為稽核日誌表的一份複本。現在:
| write region | item | visible in | |
|---|---|---|---|
| us-east-1 | TENANT#acme | EVENT#…#a1 | both regions (~1s lag to EU) |
| eu-west-1 | TENANT#bmw | EVENT#…#e7 | both regions (~1s lag to US) |
那位歐盟客戶的應用程式對本地的 eu-west-1 複本寫入與讀取——
低延遲,且資料落地在區域內。同一套滿足落地要求的複寫,也
兼作災難復原:如果 us-east-1 掛掉,eu-west-1 複本仍持有
完整的日誌並服務流量;你就故障轉移到
它。
因為稽核日誌是僅附加且依租戶分割的,最後寫入者 勝出在這裡基本上不是問題——某個租戶的事件是從一個 區域寫入的,而事件 key 是唯一的,所以兩個區域很少在同一個項目上 競爭。那不是運氣;那正是為什麼一份僅附加的日誌是最乾淨 契合 global tables 的用例之一。相較之下,一個可變的計數器就會需要 在並行的跨區域寫入下多加小心。
在 DynoTable 中操作
加了一份複本之後,你會想確認資料真的落地到了新的
區域並和來源相符——確認那份歐盟複本真的持有 acme 的事件、
帶著正確的屬性、而且沒有落後。
DynoTable 用它自己的憑證連到任何區域,所以你可以把一個
視窗指向 us-east-1、另一個指向 eu-west-1,並排比較同一個租戶的
項目來驗證複寫。

你可以在 DynamoDB Expression Builder 裡 原型化你將對每份複本執行的各區域查詢。
陷阱與後續步驟
- 別跨區域讀取你自己剛寫入的。 複寫延遲意味著一個 區域的寫入可能要約一秒才會出現在另一個。別在美國寫入然後 立刻從歐盟讀取還期待它在那裡。在預設的 MREC 模式下,強 一致讀取只在單一區域之內運作;MRSC 才把強一致讀取 延伸到跨區域。
- 最後寫入者勝出會悄悄丟掉資料。 對於在兩個區域並行寫入的 可變項目,失敗的那個會被丟棄且不報錯。僅附加或 每個項目單一寫入者的設計(像這份稽核日誌)避開了這個問題;共享的 可變狀態需要一個具衝突意識的設計。
- 每一份複本都要成本。 每個區域都儲存一份完整副本並計費它自己的 容量與儲存——一份複本大致讓成本翻倍。為真正的 落地或 DR 需求加區域,而不是預設就加。
- 備份是每份複本各自的。 一張還原出來的 global table 會變成一張獨立的表 ——按區域規劃復原。見 備份與時間點復原。
Global tables 防的是失去一個區域。最後一個運維上的顧慮是 防止失去_資料_——一次糟糕的部署或誤刪——用 備份與時間點復原。
下載 DynoTable 來連到多個區域並驗證你的 global-table 複本持有相同的資料。


