こんにちは、えいりんぐーです。
今回はAmazon DynamoDBについてまとめます。
Amazon DynamoDBとは
DynamoDB は、あらゆる規模に適した高速で柔軟な非リレーショナルデータベースサービスです。DynamoDB を使用すると、分散データベースの運用と AWS にスケーリングするための管理負荷を軽減できます。ハードウェアのプロビジョニング、設定と構成、スループット容量のプランニング、レプリケーション、ソフトウェアのパッチ適用、クラスターのスケーリングなどについて心配する必要はありません。
参考資料
基本的に以下の資料を参考にしています。
- Black Belt資料
- 公式ドキュメント
- ブログ
- その他
特徴
- フルマネージドNoSQLデータベースサービス
- スケーラブル・低レイテンシー
- 管理運用なしで高可用性
- SPOFがない
- 3カ所のAZに保存
- プロビジョンドスループット
- ReadとWriteに必要な分だけのスループットキャパシティを割り当てる
- 無制限のストレージ
- 従量課金制のストレージ
- 整合性モデル
- Write
- 少なくとも2つのAZで書き込み完了が確認取れた時点で肯定応答
- Read
- デフォルトは結果整合性
- GetItem, Query, ScanではConsistent Readオプションを使うことで強整合性を指定できる
- キャパシティユニットを2倍消費する
- Write
キャパシティユニット
大雑把に処理能力のこと
- 書き込み
- 1WCU
- 最大1KBの書き込みを1秒に1回できる
- 1WCU
- 読み込み
- 1RCU
- 最大4KBの書き込みを1秒に1回できる
- 1RCU
ユースケース
- KVS
- 広告やゲームのユーザー行動履歴DB
- モバイルアプリのバックエンド
- バッチ処理のロック管理
- ストレージのインデックス
使い方
- HTTPベースのAPIでオペレーションをする
- GetItem, PutItem, Queryなど
- SDKやCLIもある
- テーブル設計
- アトリビュート
- 各レコードの個々の要素
- String, Number List, Mapなど
- パーティションキー
- キーバリューとしてアクセスする。
- データ分散にも利用される
- ハッシュインデックスを構築するためのキー
- テーブルは性能の確保のためパーティションされる
- ソートキー
- オプション
- 同一パーティションキーで異なるアイテムを取る際にも使う
- プライマリキー
- パーティションキーとソートキーの組み合わせで作る
- セカンダリーインデックス
- Local Secondary Index
- ソートキー以外に絞り込み検索を行うキー
- パーティションキーが同一で、他のアイテムからの検索をする
- 既存のテーブルに追加・削除できない
- 結果整合性と強整合性
- Global Secondary Index
- パーティションキーをまたいで検索をするためのインデックス
- 既存のテーブルに追加・削除できる
- 結果整合性のみ
- スループットやストレージを追加で必要とするので注意
- Local Secondary Index
- アトリビュート
- スケーリング
- テーブルレベルでスループットをプロビジョンする
- RCUやWCUを指定する
- テーブルはパーティションに分割される
- パーティションキーでデータ分散する
- スループットはパーティションに均等に付与される
- e.g. RCU=10,000、パーティション10個
- 各パーティションのRCU=1,000
- e.g. RCU=10,000、パーティション10個
- パーティションは最大RCU=3,000、最大WCU=1,000、最大ストレージ=10Gまで
- キャパシティを減らすと各パーティションのキャパシティが減るので注意
- バーストキャパシティ
- 各パーティションで容量を超えなかった分のキャパシティを過去300秒ぶんリザーブ
- プロビジョン分を超えた際にトラフィック処理に活用
- テーブルレベルでスループットをプロビジョンする
- 高度なテーブル操作
- Conditional Write
- ある値がXX以上/以下だったら、といった条件付き書き込みができる
- Filter式
- QueryまたはScanでフィルター式を指定して、返される結果を絞り込みできる
- UpdateItemによるAttribute操作
- Put, Add, Deleteという3つの操作ができる
- Atomic Counter
- テーブルに操作が行われるとカウンターが増えるといった動作を実現する
- Conditional Write
- バックアップ
- DynamoDB Streamsを使ったクロスリージョンレプリケーション
- Data Pipelineを使って別のDynamoDBに対してコピー
- EMRのhiveを使ってS3や別のDynamoDBに対してコピー
DynamoDB Accelerator (DAX)
DynamoDB 用完全マネージド型インメモリキャッシュ。リージョン内でマルチAZ構成かつキャッシュ情報のレプリケーション、障害時のフェイルオーバーなどをフルマネージドで実現。キャッシュはライトスルーで保持。最大10ノードまでスケールアウト。
DynamoDB Streams
DynamoDBに行われた追加・更新・削除の変更履歴を取り出して保存する。過去24時間以内に行われた変更のストリームにアクセスできる。24時間後にはストリームデータが削除される。操作の順に従ってデータはシリアライズされる。ハッシュキーが同じ場合は正しい順が保証されるが、ハッシュキーが異なる場合は保証されない。
データのストリーム処理とは少し異なる。
SDKやKCLから読み取り可能。書き込みスループットの2倍の速度で更新の読み取りが可能。Lambdaの起動トリガーとすることで、柔軟なイベント実行ができる。Lambdaだけでなく、SNS、Kinesis Data Streamsへもファンアウトできる。
ユースケースとしてはクロスリージョンレプリケーション、非同期集計、通知など。
アクセスコントロール
基本的にIAMを用いる。ルートユーザー・IAMユーザー・IAMロールからアクセスできる。IAMロールは次のようなケースで効果的。
- フェデレーテッドユーザーアクセス
- サードパーティのIdPと連携したい時
- AWSサービスアクセス
- AWSのサービスからDynamoDBにアクセスしたい時
- EC2上で実行されているアプリケーション
- EC2にIAMロールを付与してアプリケーションからDynamoDBへのアクセスを許可する
また、条件キーを指定して、条件に応じてDynamoDBへのアクセスを許可するような挙動を実現できる。
ベストプラクティス
- DynamoDB に合わせた NoSQL 設計
- DynamoDB の場合は、答えが必要な質問が分かるまで、スキーマの設計を開始しないでください。ビジネス上の問題とアプリケーションのユースケースを理解することが不可欠です。
- DynamoDB アプリケーションではできるだけ少ないテーブルを維持する必要があります。設計が優れたアプリケーションでは、必要なテーブルは 1 つのみです。
- DynamoDB アプリケーションを設計する最初のステップは、システムが満たす必要がある特定のクエリパターンを見極めることです。
- パーティションキーを効率的に設計し、使用するためのベストプラクティス
- 一般的に言えば、テーブルとそのセカンダリインデックスの論理的なすべてのパーティションキー全体でアクティビティが均一になるようにアプリケーションを設計する必要があります。
- ソートキーを使用してデータを整理するためのベストプラクティス
- 関連情報を 1 つの場所にまとめて、効率的にクエリを実行することができます。ソートキーを慎重に設計することで、starts-with、between、>、< などの演算子による範囲のクエリを使用して、一般的に必要な関連項目のグループを検索することができます。
- 複合ソートキーを作成すれば、データの階層的 (1 対多) な関係を定義して、任意の階層レベルでクエリを実行することができます。
- DynamoDB でセカンダリインデックスを使用するためのベストプラクティス
- インデックス数は最小限に抑えます。
- セカンダリインデックスはストレージとプロビジョニング済みのスループットを消費するため、インデックスのサイズは可能な限り小さくすべきです。
- 特定のパーティションキー値に対するテーブルおよびインデックス項目の合計が 10 GB を超えると予想される場合は、そのインデックスの作成を回避できないかどうかを検討してください。
- スパースなインデックスは、テーブルの小さなサブセクションに対して行うクエリに役立ちます。
- 大きな項目と属性を格納するベストプラクティス
- 大きな属性値を圧縮すると、DynamoDB の項目制限に収まり、ストレージコストが削減されます。GZIP や LZO などの圧縮アルゴリズムはバイナリ出力を生成し、これを Binary 属性タイプに格納することができます。
- Amazon S3 のオブジェクトとして保存してから、DynamoDB 項目にオブジェクト識別子を格納することができます。
- DynamoDB で時系列データを処理するベストプラクティス
- DynamoDB の一般的な設計原則では、使用するテーブルの数を最小限に抑えることをお勧めします。ほとんどのアプリケーションで、必要なテーブルは 1 つだけです。ただし、時系列データでは、期間あたりアプリケーションごとにテーブルを 1 個使用すると、多くの場合最適に処理できます。
- DynamoDB でリレーショナルデータをモデル化するためのベストプラクティス
- DynamoDB では、複合ソートキー、過負荷になっているグローバルセカンダリインデックス、パーティションテーブル/インデックス、その他のデザインパターンを使用することを意味します。これらの要素を使用してデータを構造化することで、アプリケーションは、テーブルまたはインデックスの単一のクエリを使用して、特定のアクセスパターンに必要なものを取得できます。
- クエリとスキャンデータのベストプラクティス
- 一般に、Scan オペレーションよりも、DynamoDB の他のオペレーションのほうが効率的です。
- ページサイズを小さくする
- スキャンオペレーションを分離する
その他
Time To Live (TTL)
テーブル項目の有効期限を設定し、データベースから自動的に削除するタイミングを定義できる。スループットを使用しない。追加料金なし。
AutoScaling
フルマネージドでWCU、RCU、GSIに対する設定を管理する。上限・加減・目標使用率の設定に合わせて、自動的な容量の拡大・縮小。瞬間的なスパイクに対応するにはDAXの使用を推奨。
クロスリージョンレプリケーション
前述のDynamoDB Streamsを利用して、別リージョンにテーブルをコピーする。ユースケースとしては、ディザスタリカバリー、レイテンシーの低いリード、負荷分散のためのリードレプリカ、リージョンマイグレーションなどがある。ライブラリーを用いてCloudFormation化することもできる。
DynamoDB on-demand
pay-per-requestモデルでの利用。事前のキャパシティユニットの設計が不要。
Dynamo DB Transactions
複数アイテム・複数テーブルに対する書き込み・読み込み操作についてAICDトランザクションが可能。分離レベルはserializableでロックは取らない。トランザクションの進行中にトランザクション外でアイテムが変更された場合、トランザクションをキャンセルしてアイテムの詳細がスローされる。
インデックスの活用
アトリビュートを結合してコンポジットキーとしたり、スパースなインデックスを作成したりしてクエリすることで、フィルターと比べてクエリが効率的になる。
Time-based workflows
例えば時系列データが必要なアプリケーションで、ホットデータとコールドデータを分ける。DynamoDB StreamsとGSIを活用して、非同期でホットデータをコールドデータへと移動する。
暗号化
AWS KMSを使ってデータの暗号化ができる。CMKはAWS所有のものと、AWS管理のものとが利用できる。