DynamoDBの概要1

DynamoDBの概要1:

投稿はブログにまとめてます。System Engineer Blog


はじめに

DynamoDBはキーバリュー形式のNoSQLデータベースであることはわかっている。そして、テーブル単位でありスキーマという概念こともわかった。この記事では、DynamoDBの概要についてまとめる。


全体像

DynamoDBの全体像を図にまとめる。


image.png


なるほど、AZ間で3重冗長化しているため、信頼性は確かに高い。そして、AZの中では複数のパーティションに分散されることで物理的な性能を確保している。パーティションの数がいくらかになるかは、計算式により算出できる別途後述する。


2種類のテーブル

まず押さえておきたいのはDynamoDBのテーブルはプライマリキーの構成によって、2種類にわかれるということだ。


image.png


1つは、パーティションキーのみのパターン。(これを便宜的に単独PKテーブルとする)

プライマリキーは重複が許されないため、この場合パーティションキーは一意となる。パーティションへの分散はパーティションキーをHash関数にかませた結果により決定される。

もう1つは、パーティションキー&ソートキーのパターン。(これを便宜的に複合PKテーブルとする)

この場合は、2つのキーを組み合わせた結果が一意であればいい。パーティションの中では、ソートキーにより物理的にデータがソートされている。


キーを使った検索

単独PKテーブルと複合PKテーブルで仕様が異なる。


image.png


単独PKテーブルの場合は、プライマリキー(≒パーティションキー)指定による1件検索か、全件SCAN検索しかできない。

一方、複合PKテーブルにはパーティション内にインデックスが作成されるため、「パーティションキーを指定した上でのソートキーによる範囲を指定したクエリ検索」が可能になる。

このインデックスを便宜的にローカル・プライマリ・インデックス(LPI)と呼ぶ。ローカルとは、各パーティション内に作成されていることを意味する。この構成上、「パーティションキーを指定しないソートキーのみの検索」はできない。


インデックスを使った検索

DynamoDBでキー以外での検索を行うためには、インデックスを最初に定義しておく必要がある。

なお、インデックスにはLSI(ローカル・セカンダリ・インデックス)とGSI(グローバル・セカンダリ。インデックス)の2種類が作成できる。


LSI

LSIはLPIを踏襲した仕組みだ。ソートキー以外にインデックスを作成できる。結果として、パーティションキーを指定した上でのインデックスを作成した属性のクエリ検索が可能になる。


image.png


なお、LSIは最大10GBまでの制約がある。


GSI

GSIはインデックス用に新たにパーティションキーとソートキーを指定して検索できるようになる。つまり、物理パーティションに囚われない検索が可能になる。


image.png


図でいうと「statusがOKでnameがTで始まるユーザを検索する」といった検索が可能になる。

なお、注意しないといけないのは、インデックス用のパーティションキーとソートキーは一意にならない可能性がある。したがって、完全な一意制は担保されず、2件以上が検索の結果として帰ってくる可能性があることは頭に入れておく必要がある。

また、GSIに指定した属性はnull(=存在しない)可能性もある。つまりSCANの結果返される値については「属性が存在するitemの全件数」となる。

ここで1点疑問が生じる。DynamoDBはパーティションの概念により性能を担保しているのに、GSIはパーティションを無視しているが大丈夫なのか?なんとGSIは実体テーブルとは別に新たにパーティションを再分配しなおした射影テーブルが生成されるとのこと。これはテーブルの容量や後述する整合性、キャパシティに関連してくる。(なお、LSIも射影自体は生成される。ただし、実体テーブルと同じパーティション配置になる。)


整合性

Dynamo DBでは結果整合性という特性がある。つまり、データを更新(あるいは削除)した直後には一定の確率で古いデータが取得できてしまうことがある。


image.png


ただし、「強い整合性の読み込み」というオプションを利用できる。このオプションを利用すると、2つのAZを選択し、その値を比較。値が一致した場合は値を返し、もし値が不一致だった場合は残りの1つも読み出して、多数決で多い方の値を返す。つまり古いデータを読み込む可能性がない。


強い整合性の読み込みの制約

読み込みには「プライマリキーを利用した読み込み」と「インデックスを利用した読み込み」がるが、GSIを利用している場合は実体とは別の射影テーブルから読み込まれる。実体への更新が射影に反映は非同期とならざるを得ないため、GSIによる読み込みには強い整合性の読み込みが利用できない。


image.png


LSIの場合には実体テーブルと射影テーブルが同じ物理配置となるため、同期が可能であり、強い整合性の読み込みが可能となる。


image.png



読み込み・書き込みキャパシティ

DynamoDBでは読み込みと書き込みのキャパシティをそれぞれユニットと呼ばれる単位で設定できる。

設定した値をプロビジョンドスループットと呼ぶ。

1ユニットの性能は以下である。

* 書き込み(WCU):1秒間に最大1KBのデータを1回書き込むことが可能

* 読み込み(RCU):1秒間に最大4KBのデータを2回読み込むことが可能

なお、強い整合性の読み込みを利用すると、 2回が1回に半減する。


プロビジョンドスループットの分配

プロビジョンドスループットはテーブルに対して設定する。一方テーブルは物理的にはパーティションに分割されている。この場合、プロビジョンドスループットはパーティションに均等に分配される。

つまり、ホットパーティション(一部のパーティションに読み書きが集中すること)するようなテーブル設計をしてしまった場合、プロビジョンドスループットは実質1/nしか利用されないこととなる。


リクエストスロットリング

クライアントからユニットを超えるリクエストを送った場合、DynamoDBはエラーを返す。

なので、エラーが返された場合の処理をクライアントには実装する必要がある。


プロビジョンドスループットの変更

プロビジョンドスループットはオンラインで変更することが可能。


インデックスのスループット

LSIの場合、テーブルのプロビジョンドスループットが使われる。GSIの場合は、テーブルとは別にGSI用のプロビジョンドスループットが別に定義される。


パーティション数の決定

パーティション数の決定はストレージ利用容量による基準とプロビジョンドスループットによる基準があり、算出式でそれぞれ算出された値のうち大きいほうが採用される。

  1. スループット

    1パーティションの最大ユニット数は、読み込み:3000RCU、書き込み:1000WCRであるので...

    パーティション数 = (読み込み)プロビジョンドスループット/3000RCU + (書き込み)プロビジョンドスループット/1000RCU
  2. ストレージ利用容量

    1パーティションの最大容量は10GBであるので...

    パーティション数 = 利用容量/10GB
つまり、プロビジョンドスループットが小さくても容量を多く使っていればパーティションは多くなし、容量を使ってなくてもプロビジョンドスループットが大きければパーティションは多くなる。


パーティション数の増減

容量が増えたり、プロビジョンドスループットを大きくするとパーティションは増える。

一方、容量が減ったり、プロビジョンドスループットを小さくしてもパーティションが減ることはない。代わりに1つ当たりのパーティションのキャパシティが減る。

1つあたりのパーティションのキャパシティが低くなるため、ホットパーティションの影響を一層受けることになる。


パーティションのバースト

パーティションのキャパシティは300秒前分で使われなかったキャパシティをストックする。

つまり、一時的にプロビジョンドスループットが上がっても、ストック分を利用することでリクエストスロットリングを回避できる。ただし、ストック分を使い切ってしまった場合はリクエストスロットリングが発生する。


料金

  • プロビジョンドスループットによる時間料金
  • 利用容量


その他

  • 1アイテムの容量は400KB以内。
  • DynamoDBにJSONデータ(多次元でもOK)を1アイテムとして格納することが可能。ただし、DynamoDB内では形を変えているので、取り出す際にはSDK等で変換し元の形に戻す必要がある。


参考資料

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)