【図解】DynamoDBのキャパシティ計算

## 早めの結論
### 計算方法
- `必要なブロック数 = データ / 項目のサイズ (小数点切り上げ)`
- `1 秒あたりの項目数 = 必要なブロック数 * 1 秒あたりのリクエスト数`
- `キャパシティユニット = 1 秒あたりの項目数 / 1 秒あたりの実行回数`

### RCU
- 読み込み方法は 3 種類
    - 結果整合性
    - 強力な整合性
    - トランザクション
- **結果整合性**は，**強力な整合性**の **1/2 倍**の RCU
- **トランザクション**は，**強力な整合性**の **2 倍**の RCU

### WCU
- 書き込み方法は 2 種類
    - 結果整合性
    - トランザクション
- **トランザクション**は，**結果整合性**の **2 倍**の WCU

## キャパシティユニットとは
DynamoDB のプロビジョニングモードでは，
予め 1 秒あたりどのくらいデータを読み書きするのか回数を指定します
その回数こそがキャパシティユニットです

> プロビジョニングされたキャパシティーのモードでは、
> アプリケーションに必要な
> 1 秒あたりのデータ読み込みと書き込みの回数を指定します。
> [プロビジョンドキャパシティの料金](https://aws.amazon.com/jp/dynamodb/pricing/provisioned/)

読み込みと書き込みそれぞれで計算します
また，読み込み書き込みそれぞれ以下のように表記します
- 読み込みのキャパシティユニット: **RCU**
- 書き込みのキャパシティユニット: **WCU**

## 登場人物のご紹介
計算に出てくるメンバーをご紹介！

|登場人物|説明|単位|
|:--|:--|:--|
|項目のサイズ|1ブロックの単位|KB|
|データ|読み書きするデータ|KB|
|必要なブロック数|データ / 項目のサイズ||
|1 秒あたりのリクエスト数|1 秒あたりに処理するリクエスト数|n/s|
|1 秒あたりの実行回数|1 秒あたりに処理を実行できる回数|n/s|
|キャパシティユニット|1 秒あたりのデータ処理回数|CU|

- `必要なブロック数 = データ / 項目のサイズ (小数点切り上げ)`
- `1 秒あたりの項目数 = 必要なブロック数 * 1 秒あたりのリクエスト数`
- `キャパシティユニット = 1 秒あたりの項目数 / 1 秒あたりの実行回数`

![必要なブロック数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/5f23dce6-0338-6d18-bf0a-30f55fecd2ae.png)
![1秒あたりの項目数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/183cb8d5-993b-0f6d-c61e-1a5c102d3d84.png)
![キャパシティユニット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/938f3d59-f78a-4e88-3f2f-56f4552cb812.png)




簡単な例で考えてみます
- 項目のサイズ: 4 [KB]
- データ: 8 [KB/S]
- 1 秒あたりのリクエスト数: 2 [n/s]
- 1 秒あたりの実行回数: 2 [n/s]


なので，
```math
必要なブロック数 = 8 * 4 = 2
```
```math
1 秒あたりの項目数 = 2 * 2 = 4
```
```math
キャパシティユニット = 4 / 2 = 2
```

## RCU: 読み込みキャパシティユニット
### 項目のサイズ
読み込みの場合は，`4 KB` です

### 読み込み方法
読み込み方法は 3 種類あります

![読み込み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/dd266560-1289-d56a-805c-2c0d83d351c2.png)
※ トランザクションについては実行回数の記載は無いですが計算の便宜上0.5にしました
https://aws.amazon.com/jp/dynamodb/pricing/provisioned/

読み込み実行回数についてのイメージをざっくりまとめると，
- 1 秒あたりの実行回数が多い ⇒ 処理は早いが結果は雑
- 1 秒あたりの実行回数が少ない ⇒ 処理は遅いが結果は正確

ということで RCU は以下の関係になります
- 結果整合性は，強力な整合性の **1/2 倍**の RCU
- トランザクションは，強力な整合性の **2 倍**の RCU

:::note info
直列化可能分離レベルについて少し解説です
処理Aと処理Bがあるとします
この時，以下のようにしても結果が同じになるのが直列化可能ということです
- 処理Aと処理Bを同時
- 処理A→処理B の順で実行
- 処理B→処理Aの順で実行
:::


### 読み込み計算例
では具体的に見ていきましょう
以下の設定で確認です

- 項目のサイズ: 4 (**読み込みなのでここは固定**)
- データ: 4 [KB/S]
- 1 秒あたりのリクエスト数: 1
- 1 秒あたりの実行回数: 1 (**強力な整合性**)

![読み込み例_必要なブロック数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/7b73dd31-cbd8-fe26-7d2f-363ee26094d3.png)
![読み込み例_1秒あたりの項目数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/11ade222-afdb-4064-5138-49e32200f860.png)
![読み込み例_キャパシティユニット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/102db5bb-4e3c-e1fb-1028-de69287cd6fb.png)


## 書き込み
### 項目のサイズ
読み込みの場合は，`1 KB` です

### 書き込み方法
書き込み方法は 2 種類あります

![書き込み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/9703da2c-94a8-7c2a-0775-98e113e8f46d.png)

WCU は以下の関係になります
- トランザクションは，結果整合性の **2 倍**の WCU

### 書き込み計算例
では具体的に見ていきましょう
以下の設定で確認です

- 項目のサイズ: 1 (**書き込みなのでここは固定**)
- データ: 3 [KB/S]
- 1 秒あたりのリクエスト数: 1
- 1 秒あたりの実行回数: 1 (**結果整合性**)

では計算していきます
- `必要なブロック数 = 3 / 1 = 3`
- `1 秒あたりの項目数 = 3 * 1 = 3`
- `キャパシティユニット = 3 / 1 = 3`

よって `WCU = 3` です
これが**トランザクション**なら **WCU が 2 倍**なので，`6WCU` です