[AWS DVA対策] DynamoDB 要点まとめ
概要
AWS DVA試験対策用にDynamoDBの要点をまとめる
用語・機能
グローバルセカンダリインデックス(GSI)
Indexとは別に検索用のIndexを作成できる
参考サイト
を読んだ方が理解が早い
セカンダリインデックス定義のベストプラクティス
- インデックス数は最小限に抑える
ほとんど使用されていないインデックスは、ストレージおよび I/O のコスト増大の一因になり、アプリケーションのパフォーマンスには効果がありません - 大量の書き込みアクティビティが発生するテーブルのインデックス作成は避ける
非常に高い書き込み負荷でテーブルのインデックスを維持するために必要なI / O操作のコストが大きくなる可能性があります。
DynamoDB 読み込みモード2種類
- | 結果整合性のある読み込み | 強力な整合性のある読み込み |
---|---|---|
英語表記 | Eventually Consistent Reads | Strongly Consistent Reads |
読み取り時の挙動 | 古いデータを返す可能性あり | 最新のデータを返す |
読み込みコスト(4KB以下) | 0.5RCU | 1RCU |
GSI使用時 | 使用可 | 使用不可 |
DynamoDB クエリとスキャン
テーブルからデータを読み取り方
デフォルトで全ての項目属性を返却する
クエリとスキャンデータのベストプラクティス
一般に、Scan オペレーションよりも、DynamoDB の他のオペレーションのほうが効率的です。
Scanの代替え案
テーブルの場合はGetItem
, BatchGetItem
APIの利用も有効
スキャン
常にテーブル全体、またはセカンダリインデックスを舐めてからフイルタを適用する
クエリ
主キーの値に基づいて項目を検索する
テーブルやインデックスが大きくなるに従ってスキャンは低速になる
DynamoDB クエリ操作
クエリ操作はプライマリキー値に基づいて項目を探します。
- 複合プライマリキー(パーティションキーとソートキー)のあるテーブル
- セカンダリインデックス
プロジェクション式
Query
, Scan
に対して、全ての属性ではなく一部属性のみ取得する方法
DAX 書き込みモード2種類
読み取り多いワークロードで使うイメージのあるDAXの書き込み事情について
書き込みスルーは書き込まれるたびに、項目キャッシュも即時更新されることがポイント
公式ドキュメント
- 書き込みスルー(Write Through)
- DAXからDynamoDBへ書き込みリクエストを転送し、先にDynamoDBを更新する
次にDAXに書き込み項目キャッシュに反映された後、ユーザに書き込み成功を返す
つまり、書き込みが即時DAXのキャッシュに反映される - DAX経由して書き込むため、余分なネットワークホップが発生し直接DynamoDB書き込みよりレイテンシ少し遅くなる
- DAXを経由せずにDynamoDBに直接書き込んだユーザがいる場合、DynamoDBからDAXへ反映されない仕様
同じ項目でもDAXのキャッシュの値をDynamoDBの値が一致しなくなる
DAXからその項目更新するか、項目キャッシュから削除されるまでこの状態が続く
- DAXからDynamoDBへ書き込みリクエストを転送し、先にDynamoDBを更新する
- 書き込み迂回(Write Around)
- 大量のデータを書き込むなど、DAXをバイパスして直接DynamoDBへ書き込む方が妥当な場合
- 書き込みスルー同様にDynamoDBへ直接書いた場合、DAXに反映されない仕様
DAX使用時の強力な整合性のある読み込み
キャッシュあり(DAX)で最新データを必ず要求(強力な整合性)してきた場合
クライアントからの強力な整合性ありの読み込みリクエストをDAXは何もせずDynamoDBへ渡し、 DynamoDBから返ってきたデータをDAXはクライアントに返す
DAXはキャッシュもしない
ただ、クライアントとDynamoDBを仲介するだけ
ドキュメント
エラーコード
HTTPステータスコード400
認証の失敗、必須パラメータの欠落、またはテーブルにプロビジョニングされているスループットの超過などのリクエストに関連した問題があることを示しています。
リクエストを再度送信する前に、アプリケーションで問題を修正する必要があります。
HTTPステータスコード5xx
AWS で解決する必要のある問題を示しています。
これは一時的なエラーかもしれず、その場合はリクエストを再試行することで成功する場合があります。
それ以外の場合、サービスに運用上の問題があるかどうかを確認するために、AWS サービスヘルスダッシュボードを参照してください。
格納できるアイテムサイズ
最大400KB
ドキュメント
ケース別
状況
リクエスト急増により、アプケーションのスロットルエラーが発生した
解決策
- アプリケーションからのリクエストでExponential Backoffを使用
- テーブルのスループット容量を上げる
要点
Exponential Backoff(指数関数的に増えるリトライ間隔) とは
1秒、2秒、4秒、8秒、16秒と指数関数的に増えていきます。
これによって無駄なリクエストを省きつつ、再試行する前に問題を修正して解決できるようになります。
特に外部APIが長期障害発生時に、単調に繰り返しリトライするとシステムへの不必要な負担をかけるので、
そういった問題時の負荷軽減にもなります。
イーサネットのCSMA/CD方式の衝突検出時にランダムな時間待ってから再送の
ランダム待機の部分が徐々に増えていくのが指数関数的の動作のようだ
CSMA/CDの再送方式はtruncated binary exponential backoff
とのこと
状況
ProvisionedThroughputExceededException
が発生した
解決策
- アプリケーションからのリクエストでExponential Backoffを使用
要点
ProvisionedThroughputExceededException とは?
1 つのテーブルまたは 1 つ以上のグローバルセカンダリインデックスのプロビジョンドスループットが許容されている最大値を超えました。
DynamoDBのSDKは、この例外エラーを受け取ったら自動的に再試行してくれる
状況
テーブルスキャンのパフォーマンスを向上させる方法
解決策
- 並列スキャンの使用
- クエリを使用
要点
- 並列スキャン
並列スキャンが適しているのは、次の条件に当てはまる場合です。
テーブルのサイズが 20 GB 以上である。
テーブルにプロビジョニングされている読み込みスループットが完全に使用されていない。
シーケンシャル Scan オペレーションでは遅すぎる。
使用上の注意
並列スキャンは有益ですが、プロビジョニングされたスループットが多量に消費される可能性があります。
安易に並列スキャンを使いたくなったけど、実装では考えないといけない
状況
グローバルセカンダリインデックス(GSI)を使用したテーブルを作成
RCU(Read Capacity Unit)を最小限に最新の値を取得する方法
解決策
- 結果整合性のある読み込みを使用したクエリ
要点
- GSIの時点で強力な整合性のある読み込みは使えない
- 最新の値と問われたら強力一択と考えがちなので注意
- クエリとスキャンならクエリの方が早い
状況
クエリの読み取りキャパシティの消費量を知りたい
解決策
- クエリで
ReturnConsumedCapacity
にTOTAL
か、INDEXES
のパラメータを指定する
デフォルトはNONE
が指定されており、読み取りキャパシティー消費量は返却されない
ドキュメント
要点
TOTAL — レスポンスには消費された読み込みキャパシティーユニットの合計値が含まれます。
INDEXES — レスポンスは、アクセスする各テーブルとインデックスの消費されるキャパシティーとともに、
消費される読み込みキャパシティーユニットの合計値を示します。
状況
大きなテーブルサイズのScan
時にスロットリングエラーが起きる。
回避方法
解決策
参考
Whizlabs
https://christina04.hatenablog.com/entry/exponential-backoff
https://dev.classmethod.jp/cloud/aws/fallback-queueing-pattern-on-dynamodb/