ちょっと話題の記事

AWS再入門 Amazon DynamoDB 編

2015.12.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

コンニチハ、千葉です。

当エントリはDevelopers.IOで弊社AWSチームによる『AWS サービス別 再入門アドベントカレンダー 2015』の15日目のエントリです。昨日14日目のエントリは川原の『AWS CodeDeploy』でした。

このアドベントカレンダーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

本日15日目のテーマは『Amazon DynamoDB』です。

Amazon DynamoDBとは?

一言で言うと、マネージドなNoSQLデータベースです。

マネージドなため、利用者はOSやミドルのことを意識しなくてよいサービスとなります。可用性や堅牢性が考慮したインフラの構築、パッチの適用等は全てAmazonがやってくれます。

そのため利用者はデータベースレイヤから考えればよくなります。例えば、テーブル設計等です。

そしてもう一つの特徴として、RDBMSではなくNoSQLデータベースとなります。高速かつ予測可能なパフォーマンスとシームレスな拡張性が提供されます。

なぜNoSQLなの?

RDBMSは、厳密なトランザクション処理(ACID)を行うためサーバーのスケールアウトが難しい構成となっています。 スケールアウトする場合は、サーバー間でトランザクションの整合性を取る必要がありメモリレベルでの同期などを行ったりします。 しかし、このスケールアウト方式にも限界があり、ノードを追加すればするほど全サーバ間で整合性をあわせなければならず、整合性をあわせる処理がボトルネックになってきます。

NoSQLではACID特性の一部を保証しない、シンプルなクエリのみという制限をすることで、柔軟なスケールアウトや可用性の向上、高スループットが可能となっています。

すべての処理をRDBMSでする必要はなく、トランザクション処理が不要なデータに関してはNoSQLを利用することでメリットも多くなります。 ※ DB側にトランザクション機能がないのであって、トランザクション処理を行いたい場合はアプリ側で実装することで実現も可能です

DynamoDBの利用ケース

低レイテンシ、大量アクセスが必要というデータはDynamoDBの利用検討対象かなと思います。

DynamoDBの特徴

ここでは、DynamoDBの特徴について記載します。

書き込み/読み込み時の挙動

  • 書き込み時
  • DynamoDBは3つのAZへ書き込みを行いますが、2つのAZへの書き込み完了確認がとれたら書き込み完了とみなします。

  • 読み込み時(デフォルト)

  • 結果整合性の読み込みモデルとなっております。書き込みを行った直後に、読み込みを行った場合古いデータを返す可能性がります。
  • 結果整合性とは、結果的に整合性がとれてればよいという考え方でS3でも採用されています。即座にデータが反映されるのではなく、ある程度時間がたったら整合性がとれているというモデルになります。

  • 読み込み時(Consistent Readオプションを指定)

  • 強力な整合性のある読み込みが可能となります(GetItem、Query、Scan)
  • Readするときに、Read前のWriteが全て反映されたレスポンスを保証
  • ただし、Capacity Unitを2倍消費

高可用性・高スケーラビリティ

  • データは3箇所のAZに保存されるため、可用性・堅牢性ともに高くなります
  • ストレージに容量制限がない、使った容量に対して課金が発生します。EBSみたいに確保した容量での課金ではないためコストパフォーマンスも高いです。
  • データ容量、指定したスループットに応じたディスクやノードの増設はAmazon側で自動でやってくれます。

シンプルなリクエスト

RDBMSみたいに複雑なクエリを実施することができません。 DynamoDBはSQL文でのデータ操作ではなく、シンプルなAPIによる操作となります。

スループットを指定できる

DynamoDBでは、キャパシティユニット(1秒間の処理能力)にてスループットを指定します。

1キャパシティユニットでできること(書き込み、読み込みそれぞれ指定が可能です)

  • 1 秒あたりの項目読み込み数 × 4 KB の項目サイズ(結果整合性のある読み込みを使用する場合は、1 秒あたりの読み込み数が倍になります)
  • 1 秒あたりの項目書き込み数 × 1 KB の項目サイズ

例えば、2KBの書き込みを1秒間に行いたい場合は、書き込みに2キャパシティユニットが必要となります。

テーブル

RDBMSと比較すると以下のようになります

  • Table = テーブル
  • items = 行
  • attributes = カラム

また、RDBMSと比べてスキーマレスという特徴があります。(同じテーブルでも、カラムを揃える必要はありません)

キーやインデックスについては、こちらを参考に。

実践

とにかくやってみます!手を動かすことで、イメージを掴みます。 今回は、テーブル作成からデータの挿入・検索・アップデート等をやってみたいと思います。

まずは、サンプル・データとして以下を使用します。かなりシンプルです。

aws-re-entering-dynamodb-3

テーブルの作成

マネージメントコンソールから作成します。

aws-re-entering-dynamodb-1

aws-re-entering-dynamodb-2

データの挿入

AWS CLIを利用してデータを挿入します。データはJSON形式で指定します。

※ AWS CLIインストール、アクセスキーの設定は省略しています

aws dynamodb put-item --table-name hello-dynamodb --item '{ "id": {"N": "1"}, "first_name": {"S": "Jun"}, "last_name": { "S": "Chiba"}, "Score": {"N": "50"}}'
aws dynamodb put-item --table-name hello-dynamodb --item '{ "id": {"N": "2"}, "first_name": {"S": "James"}, "last_name": { "S": "Smith"}, "Score": {"N": "50"}}'
aws dynamodb put-item --table-name hello-dynamodb --item '{ "id": {"N": "3"}, "first_name": {"S": "Robert"}, "last_name": { "S": "Johnson"}, "Score": {"N": "50"}}'
aws dynamodb put-item --table-name hello-dynamodb --item '{ "id": {"N": "4"}, "first_name": {"S": "David"}, "last_name": { "S": "Wilson"}, "Score": {"N": "50"}}'
aws dynamodb put-item --table-name hello-dynamodb --item '{ "id": {"N": "5"}, "first_name": {"S": "Richard"}, "last_name": { "S": "Moore"}, "Score": {"N": "50"}}'

データの抽出

先ほど投入したデータを抽出します。key指定での抽出、全件抽出の2パターン試します。

aws dynamodb get-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }'
{
"Item": {
"first_name": {
"S": "Jun"
},
"last_name": {
"S": "Chiba"
},
"Score": {
"N": "50"
},
"id": {
"N": "1"
}
}
}

aws dynamodb scan --table-name hello-dynamodb
{
"Count": 5,
"Items": [
{
"first_name": {
"S": "Robert"
},
"last_name": {
"S": "Johnson"
},
"Score": {
"N": "50"
},
"id": {
"N": "3"
}

・・・省略

データのアップデート

投入したデータに他指定アップデート操作をします。

attributeの更新をします。first_nameをJunJunに更新します。

aws dynamodb update-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }' --attribute-updates '{ "first_name": { "Action": "PUT", "Value": {"S": "JunJun" } } }'

attributeの数値に+10してみます。Scoreに10を足します。

aws dynamodb update-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }' --attribute-updates '{ "Score": { "Action": "ADD", "Value": {"N": "10" } } }'

attributeを削除します。last_nameを削除してみます。

aws dynamodb update-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }' --attribute-updates '{ "last_name": { "Action": "DELETE" } }'

データ更新した箇所の確認してみます。

aws dynamodb get-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }'
{
"Item": {
"first_name": {
"S": "JunJun"
},
"Score": {
"N": "60"
},
"id": {
"N": "1"
}
}
}

first_nameの変更、Scoreの+10、last_nameが想定通り削除されています。

アイテムの削除

アイテムを削除します。keyが1のデータを削除します。

aws dynamodb delete-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }'

aws dynamodb get-item --table-name hello-dynamodb --key '{ "id": {"N": "1" } }'

get-itemで表示されなくなりました。きちんと削除されていますね。

テーブルの削除

こんどは、テーブルごと削除します。

aws dynamodb delete-table --table-name hello-dynamodb
{
"TableDescription": {
"TableArn": "arn:aws:dynamodb:ap-northeast-1:123456789123:table/hello-dynamodb",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 5,
"ReadCapacityUnits": 5
},
"TableSizeBytes": 0,
"TableName": "hello-dynamodb",
"TableStatus": "DELETING",
"ItemCount": 0
}
}

マネジメントコンソールからも削除されていることが確認できました。

aws-re-entering-dynamodb-4

あわせて読みたい

公式情報

Developers.IO関連エントリ

紹介・入門エントリ

やってみた系

次のステップに進むためのエントリ

さいごに

以上、AWS サービス別 再入門アドベントカレンダー 15日目のエントリ『Amazon DynamoDB』編でした。 Amazon DynamoDBに少しでも近づけたと感じて頂けたら嬉しいです。 明日(12/16)はsuzuki.ryoのAmazon Kinesis編です。お楽しみに!