AWS Dynamodb 調べてみた

キーワードをメモしてみました。

## Dynamodbとは
###NoSQLである
・Not Only SQL（RDBじゃないよとは違うよという意味）
・「大量データを高速に、かつ容易に扱えるようにした」データベース
・キーバリュー型・ドキュメント型・カラム型を扱える
・テーブルの結合ができない
・スキーマレス
　主キー（パーティションキー＋ソートキー）以外は定義しなくてもいい。
　定義しなくてもカラムを登録することができる。
　ログにDynamoDBに使用すると、このログはこのカラムにデータセットするけど、
　別のログはそのカラムは使わないなどの柔軟に対応できる。

###高いスケーラビリティ
データ量が増えても対応できるという事
①ストレージサイズ無制限
②テーブルを１つ作成しても、内部的には複数のパーティションテーブルに分かれている。
　さらに、データ量が増えると、自動でパーティションテーブルを増やしてくれるため、
　検索性能が劣化しずらい。
###イベントドリブンプログラミング
イベントを起点に、プログラムを動かせるという事。
例えば、DynamoDBにデータが登録されたらlambdaを動かすようなことができる。
###マネージドサービス（管理不要）
OS、DBバッチ適用などなど。
###３リージョンレプリケーション
単一障害点がない。

##結果整合性という特性がある。
結果的にデータが整合性が取れた状態になると。
###write
・2つのAZの書き込みが完了したときにレスポンスを返す。もう１つは数秒後に反映
　⇒結果整合性
・Conditional write 、条件に合致したら書き込む

###read
・1つのAZのデータを取得する。
　writeが2か所なので、古いデータが取れることがある。
・強力な整合性のある読み込み
　必ず最新のデータが取得できる。3つのAZのデータを取得し２か所以上一致するデータを返す。
　※速度落ちる。キャパシティユニット２倍消費

※DynamoDB Transactions
　BachGetItemなどで、複数itemの操作をした時の動きを決めることができる。
　一つでもエラーであれば、ロールバックするのかどうか。

## テーブル構造
・パーティションキー
　主キーの一部であると同時に、データをどのパーティションテーブルに登録するか決める値になる。
　そのため、Dynamodbを検索する場合は基本的にパーティションキーを検索条件に指定
　⇒これをすることで、特定のパーティションテーブルだけ検索することで、
　　データ量増加時の検索速度劣化を防いでいる。
・ソートキー（オプション）
　主キーの一部であると同時に、並べ替えに使用される。（ほかのカラムで並び替えできない）
　⇒厳密にいうとデータ登録時にソートキー順に並べて登録している。
・アトリビュート
　その他カラム
※パーティションキー、またはパーティションキー＋ソートキーで一意となる。

・ローカルセカンダリインデックス（上限5）
　パーティションキーは変更できないが、
　ソートキーの代わり、第二のソートキーとして検索に使用できる。
　※テーブルをもう1つ作るようなイメージ（非同期なのでレイテンシーに影響なし）

・グローバルセカンダリインデックス（上限20）
　これは上記と異なり、パーティションキーの代わり
　※テーブルをもう1つ作るようなイメージ（非同期なのでレイテンシーに影響なし）

##主要機能
###TTL（time to live）※自動削除機能
データ登録時にアイテムに有効期限日時（未来日付）を登録すると、その日時から0～48時間以内に削除される。

###ポイントインタイムリカバリ
自動バックアップ機能
⇒復元は別テーブルとしてなされる。

###DAX
キャッシュシステム
ライトスルーといって、データ登録時にキャッシュにデータを持たせることもできる。

###AWSコンソール（Dynamo）
データの検索ができる

##テーブル設計について（ベストプラクティス）
①想定している検索方法・データの並び替えをまとめる
②”①”に沿って、パーティションキー、ソートキー、グローバルセカンダリインデックスを決めていく。

##検索方法
###クエリ検索
パーティション気を指定して検索。つまり、パーティションテーブルを絞り込んで検索するという事。
###スキャン検索
パーティションキーを指定せずに検索。つまり、全パーティションテーブルを検索するよという事。

##バーストキャパシティ
パーティションごとのキャパシティのうち、利用されなかった分を過去300秒分までリザーブ。
バースト時に使用される。

##DynamoDB Auto Scaling　VS　on-demand
###①Auto Scaling
最小と最大のキャパシティを設定して、
ターゲット使用率XX%によって、キャパシティを自動でコントロールする。
※EC2のAuto Scalingと同じ、即時に反映されるわけではない。
　スパイクに対応するには、DAX。
###②on-demand
リクエストの分だけお金がかかる。（単価が高いと思われる）
※キャパシティをがんばって設定する必要がない。
　トラフィックが読めないときや、スパイクがある場合。
　⇒EC2のオートスケールみたいなもので、急激な負荷には耐えられない。
　　サーバ立ち上げに数分かかるから。
★オンデマンドで運用して、アクセス負荷を把握してから、
　場合によってプロビジョニングモードに変更する。

##パーティション内のスループット
　設定したキャパシティはパーティション数で割ったキャパシティを各キャパシティで利用できる。
　⇒Adaptive capacity（自動らしい）
　　あるパーティションに負荷が集中した場合に、
　　余力のあるパーティションのキャパシティを集中したパーティションにもっていく

##非正規化
各テーブルで重複データをもっていい。
テーブルの結合等ができないため。

##Dynamodb API
>https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html
⇒アプリケーションから直接低レベルAPIにリクエストを行うのではなく、
　プログラミング言語にAWS Software Development Kit（SDK）の
　いずれかを使用することが推奨されている。

##アクセス方法
①SDK
>https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Programming.SDKOverview.html

②低レベルAPIを直接呼ぶ
>https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html

##グローバルセカンダリインデックス　オーバーローディング（GSIの多重定義）
テーブル当たり、セカンダリインデックスは20個まで
⇒カラムの縦もち。GSIを作りすぎると、
　データ量も増えてコストに影響すると思っていた。それの対策となる。
　ただ、カラム数が少ないとパーティションがカラム数しか分割されない気がするので、
　readの参照データサイズが増える気もする。（個人的意見）
>https://dev.classmethod.jp/cloud/aws/basic-of-gsi-overloading/

##料金体系
・プロビジョンドスループットで決まる時間料金
　※オンデマンドはいったん省略しています。
　－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
　書き込みキャパシティーユニット (WCU) 0.000742USD/WCU
　　※1 秒あたりの (1 KB までの) 書き込み 1 回ごとに WCU 1 個分
　読み込みキャパシティーユニット (RCU) 0.0001484USD/RCU
　　※1 秒あたり 1 回ごとに RCU 0.5 個分
　－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
　
　※ちなみに、キャパシティユニットを超過した場合は例外エラーが返却される。

・ストレージ利用量
　月額 0.285USD/GB
　　
※無料枠
　25 GB のストレージ
　25 個のプロビジョニングされた書き込みキャパシティーユニット (WCU)
　25 個のプロビジョニングされた読み込みキャパシティーユニット (RCU)
　1 か月あたり最大 2 億リクエストの処理が十分に可能。

※キャパシティの決め方（設定する場合）
　①キャパシティを想定より多めに設定し、運用
　②CloudWatchを確認
　③"②"をの結果で、キャパシティを決める。

##データモデリング参考
>https://aws.amazon.com/jp/blogs/news/webinar-bb-dynamodb-advanced-design-pattern-2018/
>https://www.slideshare.net/AmazonWebServicesJapan/db-20190905

##動画
https://www.youtube.com/watch?v=16RYHfe89WY