Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って初めたブログ

DynamoDBについて調べてみたことを書いてみた その1

以前「NoSQLについて誤解していたことと学びについて」という記事を書いて、NoSQLへの知識が少し深まったので、引き続き書いてみたいなと思います。

kodak.hatenablog.com

今回はNoSQLの中でも代表的なDynamoDBについて、深掘りたいと思います。

DynamoDBとは?

Amazon DynamoDB(以降、DynamoDB)といいます。AWSで提供しているNoSQLの1つです。DynamoDBの特徴は以下の通り。

  • NoSQL
  • 分散型データベース
  • スケールアウトが容易
  • 結果整合性という考え方を持つ
  • KVS(Key-Value Store)
  • HashとRangeという考え方

なぜDynamoDBって人気なの?

数あるCloudサービスの中で、良く使われているのはAWSだと思います。
そのAWSを使ってサーバーレスにサービスを提供したい!と考えた時、まず考えるのがAWSのLambdaを用いたイベント駆動のサービスだと思います。
しかし、Lambdaはイベントに応じて処理を動かすというだけで、データを格納するストレージ機能はもっていません。データを保存しておくにはデータベースが必要です。データベースといえば、OracleMySQL、PostgresなどのRDBが有名ですが、それらはLambdaと相性が非常に悪いのです。

詳細はこちらの記事を見ていただければと思います。すごく勉強になりました!

www.keisuke69.net

私の理解ですが、OracleMySQL、PostgresなどがLambdaと相性が悪いのは、それらDBがスケールアップしかできなくて、(Lambdaのような)大量の同時接続が発生するケースは、接続制限を設けたり、(DBに繋ぐための)コネクションを再利用しているから。
図にすると、こんな感じ・・・

f:id:special-moucom:20190311011520p:plain

DynamoDBならスケールアウトできるし、そもそも「結果整合性」という考え方なので、データの即時反映は目指しておらず「いつか反映されれば良い」のでコネクションについて深く考えなくて良い。

f:id:special-moucom:20190311011542p:plain

というわけで、AWSを使ってサーバーレスにサービスを提供したい!ならDBの選択はDynamoDB一択なので、人気があるということです。じゃあ、Lambdaと相性の良いRDBはないのか?という話になると思いますが、Amazon Auroraと呼ばれるDBがあり、こちらも人気です。
私は使ったことがないので何とも言えないのですが、大抵の場合はDynamoDBでよかったりするのと、DynamoDBよりもコスト(お金)が掛かるといったところで、どうしてもRDBでないといけない以外は使われないイメージです。

KVSとは?

Key-Value Storeのことです。 KeyとValueを組み合わせた構造でデータを格納する仕組みで、JSONのような構造を思い浮かべるとイメージしやすいかと思います。

HashとRangeという考え方

DBには、データを識別するための一意となるKey(プライマリーキー)が必要です。DynamoDBはそれをHash、HashとRangeの組み合わせの2つから作ります。

Hash

Hashという1カラムを選択することで、そのカラムをプライマリーキーとして扱います。
なので、そのカラムは一意でなくてはならい・・・のですが、名前はプライマリーキーとは書いていないので、別に一意にしなきゃいけないルールはありません。Hashは、いわゆるHash値(データを特定の計算方法によって出力する値)のことです。そうなんです。DynamoDBはHash値ごとにデータを分散して格納しているんです。
図で書くとこんな感じで、hashの「bb」が同じところに保存されます。

f:id:special-moucom:20190311012132p:plain

データが分散すればするほど、DBはデータを探す手間が省けるので効率が良くなります。逆にを同値が多いカラムをHashにしてしまうと、DBはデータを探す手間がかかり効率が悪くなります。つまり「DBが遅い」「DBが落ちる」等の事象が発生します。

DynamoDBの設計は難しいと言われるのは、こういった裏の仕組みを知らないといけないからでしょうね(- - ;;)。

HashとRangeの組み合わせ

Range、こちらはHashの抽出範囲を決めるため(検索用)のカラムです。
Hashは一意であることが多いので、このカラムを使って値の抽出範囲を広げることができます。さきほどのHashとRangeを組み合わせて、そのカラムをプライマリーキーとして扱えます。Hashをどうしても一意にできない場合やGSIを使用したい場合に使います。
ここで注意したいのは、Hashの役割は変わらないということです。「Hashをどうしても一意にできない場合」と書きましたが、だからといってhashの値がすべて同値だと、やはり効率が悪くなります。

f:id:special-moucom:20190311012142p:plain

まとめ

というわけで、DynamoDBについて調べたことを書いてみました。LSIやGSIのことも書けてないので、それはまた別の機会に書きたいと思います。いやぁ、やっぱりこうやって自分が調べた事を記事にすると、自身も考えも纏まって非常に良いですね。
記事にするのに時間がかかりますが・・・(T T)

さて、DynamoDBについては、以下記事のシリーズが丁寧にまとまっていたので、DynamoDBについて知りたい方はこちらの記事を読むことをオススメします。すごく参考になると思います。

dev.classmethod.jp