最近、NoSQLやキーバリュー型データベースについて勉強する機会があったので、普段使っているRDBと何が違うのか整理してみました。
特に「なぜKey-Value型は大量アクセスに強いのか?」というところが気になったので、そこも含めてまとめようと思います。
1. キーバリュー型DBとは?
名前の通り、Key(キー)とValue(値)の組み合わせでデータを管理するデータベースです。
例えば、ユーザー情報を保存するとします。
Key Value
-------------------------------
user001 {name: "田中", age: 30}
user002 {name: "佐藤", age: 25}
「user001」というキーを指定すると、それに対応するユーザー情報を取得できます。
一方、RDBでは次のようなテーブルとして管理します。
ユーザーテーブル
ID 名前 年齢
---------------------
001 田中 30
002 佐藤 25
RDBではSQLを使って、
SELECT *
FROM USER
WHERE AGE >= 30;
のように、さまざまな条件で検索できます。
Key-Value型では、
「このキーのデータが欲しい」
というアクセスが基本になります。
代表的なサービスとして、AWSの Amazon DynamoDB などがあります。
DynamoDBの場合は、SDKを用いて、API経由で取得するのが基本になります。
2. RDBとの違い・メリットとデメリット
ざっくり比較すると、こんな感じです。
| RDB | Key-Value型 | |
|---|---|---|
| データ構造 | テーブル・行・列 | KeyとValue |
| スキーマ | 基本的に固定 | 柔軟 |
| 検索 | SQLで柔軟に検索 | Keyを指定した検索が得意 |
| JOIN | 利用できる | 基本的に行わない |
| データ設計 | データの関係を重視 | アクセス方法を重視 |
| 得意な処理 | 複雑な検索・集計 | 高速な読み書き・大量アクセス |
| スケール | 垂直スケールが中心 | 水平スケールしやすい |
メリット・デメリットとして見ると、さらに分かりやすいです。
| DB | メリット | デメリット |
|---|---|---|
| RDB | ・複雑な検索ができる ・JOINでデータの関係を扱える ・トランザクションや整合性を扱いやすい |
・大規模化すると構成が複雑になりやすい ・水平スケールには工夫が必要 ・スキーマ変更などが必要になる場合がある |
| Key-Value型 | ・Keyによる検索が高速 ・大量アクセスに対応しやすい ・水平スケールしやすい |
・複雑な検索は苦手 ・アクセスパターンを考えたデータ設計が必要 ・RDBのようなJOINを前提にできない |
つまり、
RDBが苦手だからKey-Value型を使うというより、そのシステムが何を求めるかによって使い分ける
と考えると分かりやすいです。
自分としては、複雑なSQLを用いるシステムは「RDB」、とにかくシンプルなDB構成かつレスポンスの早さといった性能面を重視したシステムは「キーバリュー型DB」というくらいでとらえています。
実際は、複数の判断要素の元に選定がされると思いますが、ここでは簡単に表現しています。
3. 垂直スケールと水平スケール
サーバーの性能を上げる方法には、大きく
- 垂直スケール(スケールアップ)
- 水平スケール(スケールアウト)
があります。
垂直スケール
1台のサーバー自体を強くする方法です。
CPU 4コア
メモリ 16GB
↓
CPU 16コア
メモリ 64GB
というように、サーバーのスペックを上げます。
RDBでは、このような垂直スケールがよく利用されます。
水平スケール
こちらは、サーバーの台数を増やして処理を分散する方法です。
サーバー1
サーバー2
サーバー3
サーバー4
のように、複数のサーバーで処理を分担します。
アクセスが増えてきたらサーバーを追加することで、全体として処理能力を増やしていけます。
Key-Value型のNoSQLでは、この水平スケールを利用した構成を取りやすいことが特徴の一つです。
4. DynamoDBではどうやってデータを分散するのか?
例えばDynamoDBに、
user001
user002
user003
user004
...
という大量のデータが入っているとします。
これを1台のサーバーだけで管理してしまうと、アクセスが集中したときに負荷が高くなってしまいます。
そこで、データを複数のパーティションに分散して管理します。
イメージとしては、
DynamoDB
|
+----------+----------+
| | |
パーティション1 パーティション2 パーティション3
| | |
user001 user002 user003
user004 user005 user006
のようなイメージです。
DynamoDBでは、パーティションキーをもとに内部的なハッシュ処理(キー値をハッシュ化させ、任意の数値で割った余りでパーティションを決める)が行われ、その結果などを利用してデータを適切なパーティションへ分散します。
※具体的なハッシュ処理は、AWS側で非公表になっています。
そのため、
user001 → パーティションA
user002 → パーティションC
user003 → パーティションB
のようにデータが分散されます。
重要なのは、
キーをもとにデータを分散させ、複数のパーティションで処理を分担する
という考え方です。
そして、データ量やアクセス量が増えれば、必要に応じてパーティションが増えていくことで、システム全体として処理能力を拡張できます。
これが、DynamoDBが大量のアクセスを処理するための基本的な考え方です。
ちなみに、物理サーバーとしては、負荷が上がってきた時点で裏で自動で分散させるような仕組みも持っているそうです。ここが従量課金にも繋がってくるのですかね。
まとめ
今回調べてみて、RDBとKey-Value型の一番大きな違いは、
「データの管理方法の違いと、スケールの仕方の違い」
であると認識しました。
RDBは、
データ同士の関係を持たせて、SQLで柔軟に検索する
ことが得意です。
一方、Key-Value型は、
キーを使って必要なデータを取得し、大量のアクセスを複数のパーティションに分散して処理する
ことが得意です。
また、サーバーの性能を上げる方法として、
-
垂直スケール:1台のサーバーを強くする
-
水平スケール:サーバーを増やして処理を分散する
という違いがあります。
DynamoDBのようなKey-Value型のDBでは、データをパーティションに分散することで水平スケールしやすく、大量のアクセスを処理できるようになっています。