Amazon DVA-C02: Amazon DynamoDB 與 NoSQL 設計 — 學習指南

屬於 AWS Developer Associate DVA-C02 — 學習指南. 使用經過驗證的解答練習: Amazon 考試中心, 或參加限時模擬考試: ExamRoll.io.

資料模型與存取模式

設計 DynamoDB 時,要從存取模式開始著手:每個查詢都應該對應到主索引鍵、全域次要索引 (GSI) 或本機次要索引 (LSI);資料表的設計是由應用程式讀寫項目 (item) 的方式所驅動,而不是依循關聯式結構的設計方式。選擇高基數 (high-cardinality) 的分割區索引鍵以避免熱分割區 (hot partition),並在您需要範圍查詢時,使用複合主索引鍵 (分割區索引鍵 + 排序索引鍵);Query 操作要求對分割區索引鍵進行等式比對,並可選擇性地對排序索引鍵使用 KeyConditionExpression。在使用 SDK 時,建議優先採用 DynamoDB Document 的抽象層:例如使用 AWS SDK for JavaScript v3 的 DynamoDBDocumentClient (它會為您處理 marshall/unmarshall),或是在 Java 中使用 DynamoDB Enhanced Client 來將物件對應到屬性。只有在讀取模式共用索引鍵,且您可以透過一個類型屬性來編碼項目類型時,才實作單一資料表模式 (single-table pattern);透過僅將屬性寫入到需要它們的項目中,來使用稀疏 GSI (sparse GSI) 以提供次要的存取路徑。一個常見的陷阱是過度使用 Scan:掃描大型資料表不僅成本高昂,而且是分頁的 (paginated),會用到 LastEvaluatedKey;建議優先使用帶有 ProjectionExpression 的 Query 來減少 RCU 的使用量。對於條件式寫入,請使用帶有 ConditionExpression 的 UpdateItem,或使用 TransactWriteItems 來達成多個項目的原子性;處理 ConditionalCheckFailedException 並採用帶有抖動 (jitter) 的退避 (back off) 機制。

索引、查詢與交易模式

本機次要索引 (LSI) 只能在建立資料表時一併建立,它與基礎資料表共用相同的分割區索引鍵,並且在查詢時會消耗基礎資料表的讀取容量,而全域次要索引 (GSI) 則可以在資料表建立後再新增,它擁有獨立的容量或隨需計費模式,並允許使用不同的分割區索引鍵。Query 呼叫會使用 KeyConditionExpression 和 ExpressionAttributeNames/Values;投影表達式 (projection expression) 可以減少資料傳輸量。GSI 預設是最終一致性 (eventually consistent),且會產生額外的寫入成本,因為每次對基礎資料表的寫入,只要其中包含被索引的屬性,就會觸發對應的 GSI 寫入——因此需要相應地規劃 WCU,並監控索引的 ConsumedWriteCapacityUnits。若需要強一致性 (strong consistency),請對基礎資料表使用 GetItem 或帶有 ConsistentRead=true 的 Query (GSI 不支援強一致性讀取)。交易 (TransactWriteItems 和 TransactGetItems) 能保證最多 25 個項目或 4 MB 資料量的原子性;使用 ReturnValuesOnConditionCheckFailure 來檢視失敗的原因。BatchWriteItem 和 BatchGetItem 分別限制為 25 和 100 個項目,且它們並非交易性的;程式碼應該要處理 UnprocessedItems,並透過指數退避 (exponential backoff) 來重試。一個常見的疏忽是,在將關聯式資料庫的 join 操作遷移到使用索引時,忘記了 GSI 的成本和最終一致性的影響。

容量模式、效能調校與問題排解

根據可預測性來決定要使用預配置 (provisioned) 還是隨需 (on-demand) 容量模式:對於穩定的工作負載,搭配 Auto Scaling (針對 DynamoDB 的 Application Auto Scaling) 的預配置模式能讓您控制 RCU/WCU 和成本,而隨需模式則簡化了對突發流量的處理,無需進行容量規劃,但每個請求的定價較高。啟用 Auto Scaling 時,可設定目標使用率和多個擴展政策;監控 CloudWatch 指標,如 ConsumedReadCapacityUnits、ConsumedWriteCapacityUnits、ThrottledRequests、SuccessfulRequestLatency、SystemErrors 和 ConditionalCheckFailedRequests,以偵測熱點和限流 (throttling) 問題。使用適應性容量 (adaptive capacity) 來緩解單一索引鍵造成的限流,但不要過度依賴它——設計上仍應追求均勻的索引鍵分佈。對於讀取密集型的工作負載,可以考慮使用 DAX 來達到微秒級的讀取延遲,或使用 Amazon ElastiCache 進行快取;對於寫入密集型的場景,則可使用寫入分片 (write sharding) (例如加上前綴或分桶) 來將寫入分散到不同的分割區。排解問題時,可檢查 ProvisionedThroughputExceededException,並在 SDK 用戶端中實作帶有抖動的指數退避機制,啟用 CloudWatch Contributor Insights 來找出熱點索引鍵,並對大型的一次性分析工作,使用帶有分段工作者 (segmented worker) 的 Parallel Scan。請記住項目大小有 400 KB 的限制,且較大的項目會增加 RCU/WCU 的消耗;必要時,應將大型的二進位物件 (blob) 拆分存放到 S3,並將其中繼資料 (metadata) 存放在 DynamoDB 中。

串流、整合、備份與維運最佳實務

DynamoDB Streams 會針對每個分割區索引鍵 (partition key),依序擷取項目層級的變更 (INSERT、MODIFY、REMOVE),並透過事件來源映射 (event source mapping) 直接與 Lambda 整合 (設定 startingPositionTRIM_HORIZONLATEST,設定 batchSizemaximumBatchingWindowInSeconds,並調整 bisectBatchOnErrormaximumRetryAttempts)。為了實現穩健的處理,請將 Lambda 與無效信件佇列 (Dead-Letter Queue) (SQS 或 SNS) 搭配使用,或將串流紀錄路由至 Kinesis 或 Kinesis Data Firehose 進行分析。啟用存留時間 (Time To Live, TTL) 以自動讓項目過期;請注意,TTL 的刪除是最終會被處理的,不應依賴它來達成即時一致性。使用時間點復原 (Point-in-Time Recovery, PITR) 和隨需備份 (on-demand backups) 進行災難復原;若需多區域可用性,請使用 Global Tables 將變更複製到不同區域。對服務套用最低權限的 IAM 角色,並僅授予 Lambda 必要的 dynamodb:Querydynamodb:PutItemdynamodb:UpdateItemdynamodb:GetItemdynamodb:DescribeStreamdynamodb:ListStreams 動作。常見的維運陷阱包括消費者端缺少重試/退避 (retry/backoff) 邏輯、GSI 容量規劃不當,以及未能監控 Streams 的 IteratorAge 來偵測延遲;請使用 CloudWatch Logs 和 X-Ray 來檢測並追蹤端到端的延遲。

實務問題:使用案例情境

情境:AcmeMedia 在 us-east-1 的單一 DynamoDB 資料表中執行一個中繼資料目錄,其中包含數千萬個項目。一個新上線的影像處理管線需要依 photographerIduploadTimestamp 範圍進行低延遲查詢,且下游的 Lambda 消費者必須可靠地處理變更。

挑戰:在不重新設計資料表的情況下,為 photographerId + 時間戳範圍新增一個高效率的查詢路徑,確保下游的 Lambda 以至少一次 (at-least-once) 的語意處理串流紀錄,並避免因多產的攝影師而造成熱分割區 (hot partitions)。

建議方法:

  1. 建立一個名為 photographer-gsi 的 GSI,其分割區索引鍵為 photographerId,排序索引鍵為 uploadTimestamp;使用 UpdateTable API 或主控台新增此 GSI,並透過 UpdateTable 指定 ProvisionedThroughputOn-Demand 計費模式,同時設定 IndexStatus 監控。
  2. 寫入項目時,包含 photographerIduploadTimestamp 屬性,這樣索引投影 (index projection) 便是稀疏的 (sparse);選擇 ProjectionType=INCLUDE 並包含查詢所需的非索引鍵屬性,以降低儲存和寫入成本。
  3. 在資料表上設定 DynamoDB Streams 為 ENABLED,並建立一個 Lambda 事件來源映射,設定 startingPosition=TRIM_HORIZON、調整過的 batchSize (例如:100)、bisectBatchOnError=truemaximumRetryAttempts=2,並在 Lambda 函數設定中將一個 SQS 佇列設為無效信件目的地 (Dead-Letter Destination)。
  4. 實作帶有抖動 (jitter) 的 SDK 用戶端重試 (使用 AWS SDK 內建的重試策略),如果單一 photographerId 仍然導致調節 (throttling),則應用寫入分片 (write sharding) (在寫入時為 photographerId 加上 N 個儲存桶的前綴,並在讀取時由用戶端移除此前綴)。

基本原理:新增 GSI 提供了所需的存取模式,而無需變更基礎主索引鍵;僅投影必要的屬性可降低 GSI 的寫入成本。Streams + Lambda 搭配 DLQ 和重試控制提供了可靠的至少一次處理,而分片 (sharding) 則可防止高基數流量造成的熱分割區。


Amazon API Gateway 與應用程式整合 · 所有領域 · CloudFormation 與基礎設施即程式碼 (SAM

練習這些題目 → · 在 ExamRoll.io 上限時練習 →

Pass the whole exam — not just this question

You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.

通過考試 →

瀏覽 Amazon →

Related guides

一站式存取

一份訂閱。所有考試。

每個方案都可無限存取答案搜尋、練習測驗、AI 解釋和完整的資源庫 — 支援 20 多種語言。

每月
24.87
Just €0.83/day
包含所有內容:
  • 無限答案搜尋
  • 無限練習測驗
  • AI 驅動的解釋
  • 完整資源庫
  • 20 多種語言
  • 每週內容更新
  • 獎勵與推薦
  • 優先支援
開始免費試用

無需信用卡*

最佳價值
12 個月
179.87
Just €0.49/daySave 40%
包含所有內容:
  • 無限答案搜尋
  • 無限練習測驗
  • AI 驅動的解釋
  • 完整資源庫
  • 20 多種語言
  • 每週內容更新
  • 獎勵與推薦
  • 優先支援
開始免費試用

無需信用卡*

✓ 包含免費方案 · ✓ 隨時取消 · ✓ 所有方案解鎖完整產品