Amazon Web Services ブログ
Cassandra 開発者向け Amazon DynamoDB 入門
このブログは、Amazon DynamoDB を Cassandra 開発者にご紹介する投稿です。DynamoDB の開始がスムーズに行えるよう、Cassandra を使った基本操作を説明しています。また、AWS CLI を使えば、DynamoDB で同じ操作が実行できます。
Amazon DynamoDB は完全マネージド型のマルチリージョンマルチマスター NoSQL データベースで、あらゆる規模でも安定した 10 ミリ秒未満のレイテンシーを実現します。ビルトインのセキュリティ、バックアップと復元、およびメモリ内キャッシュを含んでいます。さらに、分散型データベースの運用とスケーリングの管理負担を軽減できます。
こうした機能を搭載しているため、DynamoDB は Apache Cassandra のような他の NoSQL データベースからの移行が必要となります。DynamoDB クライアントと SDK を使用して、IoTや ゲームなどのさまざまなアプリケーションを構築できます。詳細については、「API の使用」をご参照ください。
次のテーブルは、重要な Cassandra と DynamoDB コンポーネント、およびこれらの概念を DynamoDB に関連付ける方法をまとめたものです。DynamoDB は完全マネージド型サービスのため、テーブルが取り扱う最上位のコンポーネントとなります。
| Cassandra | DynamoDB | 説明 |
| ノード | NA | データが保存される場所。 |
| データセンター | NA | レプリケーション戦略に使用。 AWS のアベイラビリティーゾーンに類似。 |
| クラスター | NA | 単一のノード、単一のデータセンター、またはデータセンターのコレクションを持つことが可能。 |
| キースペース | NA | リレーショナルデータベースのスキーマに類似。 |
| テーブル | テーブル | |
| 行 | 項目 | |
| 列 | 属性 | |
| プライマリキー | プライマリキー | |
| パーティションキー | パーティションキー | |
| クラスタリング列 | ソートキー |
Cassandra のコアコンポーネント
Cassandra は Amazon EC2 などのインフラストラクチャサービス上にインストールし、そこで管理する必要があります。これで、Cassandra の基盤インフラストラクチャコンポーネントであるノード、クラスター、データセンターの管理上の負担を軽減できます。ここで使用するデータセンターという用語は Cassandra 固有の用語です。データセンターの一般的な定義と混同しないよう注意してください。ノードがデータを保存します。データセンターが集合したものをクラスターといいます。Cassandra データセンターは関連するノードの集合で、物理データセンターまたは仮想データセンターのいずれかです。ワークロードごとにそれぞれ別のデータセンターを使用し、ワークロードのトランザクションが相互に影響しないようにする必要があります。
Cassandra はレプリケーションを使用して、可用性と耐久性を獲得します。これは、レプリカを配置するノードと、クラスター全体で作成するレプリカの数を決定するレプリケーション係数を決定するレプリケーション戦略を通じて行います。これらのインフラストラクチャコンポーネントのセットアップに加えて、最適化、容量の計画、設定、更新、セキュリティ、オペレーティングシステムのパッチ、バックアップといった要素も考慮する必要があります。
Cassandra のデータ構造コンポーネントには、キースペース、テーブル、行、および列が含まれます。キースペースは、リレーショナルデータベースのスキーマに類似したデータの最も外側のグループで、テーブルはすべてキースペースに属します。キースペースレベルでレプリケーションを設定します。つまり、そのキースペース内のすべてのテーブルは、同じレプリケーション戦略とレプリケーション係数に従います。テーブルには、プライマリキーに基づいてデータが格納されます。プライマリキーは、パーティションキーと、各パーティションキーのパーティション内の行の並べ替え順序を定義するオプションのクラスタリング列で構成されています。
DynamoDB のコアコンポーネント
DynamoDB のデータ構造コンポーネントには、テーブル、項目、属性が含まれます。テーブル名は、単一アカウントの AWS リージョン内で一意である必要があります。項目と属性は、Cassandra の行と列にそれぞれ類似しています。DynamoDB は定義済みスキーマを必要とせず、アプリケーションレベルでその場で新しい属性を追加できますが、テーブルのプライマリキー、ソートキー、ローカルセカンダリインデックスの属性名とデータ型を識別する必要があります。Cassandra と同様、プライマリキーにはパーティションキーが含まれます。ソートキーは、Cassandra のクラスタリング列に類似しています。グローバルセカンダリインデックスはテーブルにいつでも追加でき、さまざまな異なる属性をクエリ条件として使用できます。
DynamoDB の完全マネージド型機能
DynamoDB の使用で得られる主な利点に、DynamoDB の完全マネージド型機能があります。DynamoDB のサーバーレスという性質のため、インフラストラクチャのメンテナンスに関する管理上の負担がなくなり、アプリケーション機能のリソースに集中できます。データは AWS リージョンの複数のアベイラビリティーゾーンに自動的にレプリケートされるため、ビルトインの高可用性とデータ耐久性を実現できます。詳細については、「Amazon DynamoDB Service Level Agreement」をご参照ください。
グローバルテーブルを使用し、AWS リージョンのセットを指定することで、レプリケーションソリューションの構築および保守の必要がなくなり、マルチリージョンデータベース、マルチマスターデータベースのデプロイが可能となります。詳細については、「DynamoDB グローバルテーブル」をご参照ください。
DynamoDB は、指定された AWS リージョンへ継続的にデータ変更を処理します。これは、Cassandra データベースを複数のデータセンターにデプロイすることに似ています。
DynamoDB は、バックアップとリカバリのためのソリューションも複数提供しています。オンデマンドバックアップを使用すると、テーブルの完全バックアップを作成し、規定のコンプライアンスニーズに合わせて長期保存およびアーカイブを行うことができます。ポイントインタイムリカバリは、テーブルの増分バックアップを維持することにより、誤った書き込みや削除操作から DynamoDB テーブルを保護するのに役立ちます。過去 35 日間の任意の時点に、テーブルを復元できます。AWS Backup は AWS のサービス全体のデータバックアップを自動化する、DynamoDB と統合した新しい完全マネージド型バックアップサービスです。テーブルのパフォーマンスや可用性に影響を与えることなく、バックアップと復元のアクションを実行できます。
Amazon DynamoDB に保存されているすべてのユーザーデータは完全に暗号化されているため、機密データの保護に伴う運用上の負担と複雑さが軽減されます。保管時の暗号化により、厳密な暗号化コンプライアンスと規制要件を満たす必要のあるセキュリティ重視のアプリケーションを構築できます。
最後に、Cassandra の場合のように、圧縮による保持記録の削除を計画する必要はありません。
データモデリング
Cassandra は、データにアクセスするための Cassandra Query Language(CQL) と呼ばれる SQL に類似した言語を用意しています。CQL の使用方法は、SQL の使用方法とは異なる場合があります。RDBMS はデータベースを設計する際に正規化する従来のアプローチに従っているため、冗長性が減少し、データの整合性が向上します。JOIN とサブクエリをサポートしており、データの柔軟なクエリを行うことが可能です。しかしクエリは比較的高価なため、トラフィックの多い状況ではうまくスケーリングされません。
一方で、Cassandra は JOIN とサブクエリをサポートしていません。データが正規化されておらず、データをできるだけ少ないテーブルに格納している場合、および実行する最も一般的かつ重要なクエリを中心にテーブル、マテリアライズドビュー、およびインデックスが設計されている場合には、パフォーマンスが向上します。データのクエリ方法は限られていますが、それ以外の方法だとクエリは高価となり、稼働が遅くなります。そのため、Cassandra のデータをモデリングする際には、2 つの言語の主な違いと設計アプローチを理解しておくことが重要です。Cassandra のデータのモデリングは、DynamoDB のデータモデリングと多くの類似点があります。
NoSQL データベースのデータモデリングの原則は、データベースへの書き込みが比較的安価であることに依存しており、ディスクスペースは一般的に最も安価なリソースです。データベースを設計するとき、最も効率的な読み込みを行うために、データの複製が必要になる場合があります。Cassandra では追加のテーブルを作成できるため、さまざまなクエリパターンに対応できます。Cassandra 3.0 にはマテリアライズドビュー機能があり、追加のテーブルを作成することなく、様々なクエリパターンに効率的に対処できます。
DynamoDB ではグローバルなセカンダリインデックスを提供しています。このため、単一のテーブルからさまざまなクエリパターンに対応できます。グローバルセカンダリインデックスを使用すると、代替パーティションキーとオプションのソートキーを指定できます。異なるアクセスパターンを許可するために、パーティションキーに基づいてデータを個別にパーティション化できます。ベーステーブルのプライマリキー属性は常にグローバルセカンダリインデックスの一部で、あるインデックスに投影するテーブルの他の属性を選択できます。グローバルセカンダリインデックスに属性を投影することにより、メインテーブルを参照する必要がなくなり、またインデックスからのみ読み込みを行うため、データベースの読み込みを最小限に抑えることができます。詳細については、「DynamoDB のベストプラクティス」をご参照ください。
DynamoDB で AWS CLI を使用する
この投稿では、DynamoDB の使用を開始するのに役立ついくつかの基本的なテーブル操作をご紹介します。DynamoDB コマンドは aws dynamodb で始まり、その後に操作名、その操作のパラメータが続きます。サポートされているさまざまな操作の詳細については、dynamodb (AWS CLI コマンドリファレンス内) をご参照ください。この投稿では、これらの操作に関する Cassandra と DynamoDB の DB を比較するため、両方の例をご紹介します。
次のテーブルは、Cassandra のステートメントタイプと、それに相当するの DynamoDB 操作をまとめたものです。
| Cassandra ステートメント | DynamoDB 操作 | 説明 |
| CREATE KEYSPACE | N/A | |
| CREATE TABLE | create-table | |
| INSERT | put-item | |
| SELECT | get-item/scan/query | |
| UPDATE | update-item | |
| DELETE FROM TABLE | delete-item | |
| DELETE COLUMN FROM TABLE | update-item | –update-expression “REMOVE COLUMN” |
テーブルの作成
まず、Cassandra と DynamoDB の両方でテーブルを作成し、そのテーブルを使用していくつかの基本的な DML 操作を実行しましょう。
Cassandra
Cassandra では、テーブルを作成する前に、キースペースを作成し、レプリケーション係数とレプリケーション戦略を指定する必要があります。
CREATE KEYSPACE MusicKeySpace ステートメントは最上位の名前空間を作成し、キースペース名を MusicKeySpace として設定します。このステートメントにある WITH replication 句は、このキースペースのレプリケーション戦略とレプリケーション係数を表すプロパティと値のマップを定義します。
USE MusicKeySpace ステートメントで、この名前空間に切り替わります。後に続くオブジェクトに対するすべての操作は、MusicKeySpace キースペースのコンテキスト内にあります。
CREATE TABLE ステートメントを使用して、MusicKeySpace キースペースの下にテーブル MusicCollection を作成します。このステートメントの PRIMARY KEY 句は、Artist をパーティションキー、SongTitle をクラスタリングキーとして表します。
DESCRIBE tables コマンドは、MusicKeySpace キースペースの下のテーブルのリストを表示します。この投稿では、MusicCollection です。
これらのステートメントについては、次のコード例をご参照ください。
DynamoDB
DynamoDB では、まずテーブルを作成します。この投稿では、属性 Artist と SongTitle をそれぞれパーティションキーおよびソートキーとして、MusicCollection というテーブルを作成します。テーブルを作成するには、“create-table” 操作を使って、必要なパラメータを指定します。
“-Table-name” パラメータはテーブルの名前を表し、この投稿では MusicCollection です。“-Key-schema” は値としてリストを取ります。リストの要素は、属性名とプライマリキーの属性のキータイプを表します。
次の例の AttributeName=Artist、KeyType=HASH は、Artist 属性がパーティションキーであることを示しています。AttributeName=SongTitle,KeyType=RANGE は、SongTitle がソートキーであることを示します。これは、パラメータ値について AWS CLI でサポートされている短縮構文の例でもあります。AWS CLI はパラメータ値の JSON もサポートしています。-key-schema の値を次のようなコードとして表すことができます。
さらに、KeySchema (-key-schema で表される) の属性 (AttributeDefinitions 配列 (-attribute- で表される) 内にある) も定義す-attribute-definitions は、テーブルのキースキーマを記述する属性の配列を表します。る必要があります。本来、属性 Artist および SongTitle は、テーブルのキースキーマを記述します。
-provisioned-throughput は、テーブルに割り当てられた 1 秒あたりの読み込み容量と書き込み容量を表します。読み書き容量とプロビジョニング済みスループットの詳細な説明は、この投稿の対象外です。 DynamoDB は指定されたプロビジョニング済みスループットに基づいて、アプリケーションで必要な読み書きアクティビティを満たすために必要なリソースを割り当てる、と言うだけにとどめておきます。詳細については、「読み込み/書き込みキャパシティーモード」をご参照ください。
テーブルへのトラフィックに応じて、スループットを手動で増減できます。DynamoDB コンソールからテーブルを作成すると、プロビジョニング済みスループット設定はデフォルトで自動スケーリングになります。詳細については、Amazon DynamoDB auto scaling: Performance and cost optimization at any scale をご参照ください。AWS CLI を使用した DynamoDB Auto Scaling の管理を行うことも可能です。 ただし、自動スケーリングを使用しても、読み書き容量の最小最大レベルは指定する必要があります。代わりに、アプリケーションが実行すると予想される読み書きスループットを指定せず、アプリケーションがテーブルで実行するデータの読み書きのリクエストごとのお支払いを希望しない場合は、値 PAY_PER_REQUEST で -billing-mode パラメータを使うと、オンデマンド請求オプションを使用できます。
テーブルの説明がこのコマンドの出力です。
TableArn は、このテーブルを AWS リソースとして一意に識別するリソース名です。ARN は Amazon Resource Name の略です。
TableStatus はテーブルの現在のステータスを指し、次のいずれかになります。
- CREATING – テーブルを作成中です。
- UPDATING – テーブルを更新中です。
- DELETING – テーブルを削除中です。
- ACTIVE – テーブルを使用する準備ができました。
テーブルの作成中、TableStatus は初め CREATINGで、後に ACTIVE に変わります。 読み書き操作は ACTIVE テーブルでのみ実行できます。
加えて、テーブルの説明には、キースキーマ、プロビジョニング済みスループット、属性定義、バイト単位のテーブルサイズ、テーブル名、項目数、作成日時などの情報が含まれ、UNIX エポック時間形式で表示されます。次のコード例を参照してください。
読み込みおよび書き込み操作を実行する前に、describe-table コマンドを使用して、テーブルが ACTIVE 状態にあるかどうかを確認できます。現在、TableStatus が ACTIVE として表示されています。次のコード例を参照してください。
データの挿入
DynamoDB と Cassandra はどちらも、テーブルに項目を挿入する際に完全なプライマリキー値を指定する必要があります。デフォルトでは、同じライマリキーを持つ行がすでに存在する場合、新しい INSERT は古い項目を新しい項目に置き換えます。同じプライマリキーを持つ行がまだ存在しない場合、この動作を上書きして新しい行を挿入できます。
Cassandra
作成後にテーブルに新しい列を追加するには、データを挿入する前に ALTER TABLE コマンドで列定義を追加する必要があります。次のコードはテーブルを変更して、新しい列 AlbumTitle を追加し、Artist、SongTitle、および AlbumTitle 列の値を持つ新しい行をテーブルに挿入し、新しい行を表示します。
DynamoDB
DynamoDB では、データの挿入または更新中に、属性を追加できます。属性は、項目間で異なるタイプを持つことができます。次のコマンドは put-item 操作を使用して、MusicCollection テーブルに Artist、SongTitle、および AlbumTitle 列の値のある 1 行を挿入します。
-item パラメータは、その値として JSON マップを取ります。マップの要素は、属性の名前と値のペアを表します。次の例の "Artist": {"S": "No One You Know"} は、項目にある Artist 属性の値が String 型であることを意味します。これは “S” で表され、その値は “No One You Know” となります。
プライマリのすべての属性を指定する必要があります。次のコード例では、Artist および SongTitle を提供する必要があります。
get-item API を使って、テーブルをクエリできます。-key パラメータの値は、取得する項目のプライマリキーを表す属性値に対する属性名のマップです。たとえば、“No One You Know” は Artist の属性値であり、コマンド {"Artist"{"S":"No One You Know"} で表されます。コマンドの出力は取得した項目です。次のコード例を参照してください。
TTL を使用して古いデータを削除する
有効期限 (TTL) を使用すると、一定期間後にテーブルから項目を自動的に削除できます。Cassandra は、行を作成または更新してから行の有効期限が切れるまでの秒数として TTL を指定します。DynamoDB の TTL は項目の有効期限が切れる日時を表すタイムスタンプ値です。
Cassandra
この例では、MusicCollection テーブルに新しい行を挿入し、USING TTL 句を使用して行に 86,400 秒の TTL を指定します。この例では、INSERT ステートメントがプライマリキーの各コンポーネントの値を必要としているが、他の列の値には必要としていないことも示しています。この投稿では、Artist と SongTitle の値を提供していますが、AlbumTitle の値は提供していません。次のコード例を参照してください。
DynamoDB
DynamoDB では、TTL 属性を識別することで、テーブルで TTL を明示的に有効にする必要があります。この属性には、項目がエポック時間形式で期限切れになるときのタイムスタンプが含まれている必要があり、またそれを数値として保存しておかなければなりません。TTL の詳細については、「有効期限: 仕組み」をご参照ください。削除した項目を Amazon S3 などの低コストのストレージサービス、Amazon Redshift、または Amazon ES などのデータウェアハウスに自動的にアーカイブすることもできます。詳細については、「Automatically Archive Items to S3 Using DynamoDB Time to Live (TTL) with AWS Lambda and Amazon Kinesis Firehose」をご参照ください。
この例のコードはテーブル MusicCollection の TTL を有効にし、項目の TTL を指定して項目をテーブルに挿入します。Update-time-to-live 操作で、テーブル MusicCollection の TTL を有効にできます。 -time-to-live-specification パラメータは、テーブルの TTL を有効または無効にするための設定を表します。エポック時間形式のタイムスタンプ値である TTL 値を保持する属性として、ttl という名前の属性を指定すると、[Enabled as True] に設定できます。次のコード例を参照してください。
date コマンドを使用して、現在の日時から 86,400 秒を表す日時のエポック時刻形式でタイムスタンプ値を取得します。次のコード例を参照してください。
後に続く put-item 操作で、新しい項目をテーブルに挿入し、EXP で表される値を属性 ttl に割り当てます。次のコード例を参照してください。
macOS を使用するクライアントの場合、EXP=`date -v +1d '+%s'`を使用します (EXP=`date -d '+86400 secs' +%s` の代替として)。
次のコード例を参照してください。
データの更新
更新する必要がある項目の場合、Update 操作で、プライマリキーの各列の値を指定する必要があります。この操作を使って、更新で指定した列または属性を変更します。
Cassandra
この例は、AlbumTitle 列の値 (Artist と SongTitle) の値がそれぞれ “No One You Know” および “Call Me Today” である行を更新することを示しています。列の新しい値は “New Album” です。以下のコードを参照してください。
DynamoDB
この例では、DynamoDB の update-item 操作で更新を実行し、後に get-item 操作で更新した行を取得して更新を示します。
パラメータ -update-expression を使用して、更新する属性の新しい値を指定できます。以下のコードを参照してください。
:ngewval は、AlbumTitle 値のプレースホルダーです。パラメータ -expression-attribute-values を使って表す必要があります。ここでは、:newval は値 “New Album” を表し、String 型であることを意味します。以下のコードを参照してください。
次のコードの get-item を使用して、更新したアイテムを取得します。
行が存在しない場合の動作の更新
指定したパーティションとソートキーを持つ項目が存在しない場合、新しい項目が追加され、Update が強力なデータ変更操作となります。
Cassandra
この例では、存在しないプライマリキー列 Artist と SongTitle の値を指定することにより、行の更新を実行します。これらの値をプライマリキー列の値として、新しい行が作成されます。次の SELECT ステートメントは、新しく追加された行を表します。以下のコードを参照してください。
DynamoDB
同様に、次のコードでは指定したキー属性を持つ項目が存在しないため、DynamoDB は新しい項目を追加します。
get-item 操作 (udate-item 操作で使用したものと同じキー属性値を持つ) を使用して、新しい行を挿入するように設定できます。以下のコードを参照してください。
指定された条件を満たす場合にのみデータを更新する
指定されたキーを持つ項目が存在しない場合、新しい項目が追加されないように、条件付き更新を実行できます。
Cassandra
Artist='This should fail' および SongTitle='Throw Error' の行は存在しません。ただし、句 IF EXISTS を UPDATE ステートメントに追加すると、新しい行がテーブルに追加されず、操作は失敗します。以下のコードを参照してください。
DynamoDB
この例の -key は、更新する項目を識別します。このパラメータには属性の 1 つとしての Artist があるため、結果の項目に Artist 属性を持ちます。-condition-expression パラメータは、UPDATE 操作が成功するために満たす必要のある条件を指定します。パラメータ値 "attribute_exists(Artist)" は、項目が存在する場合にのみ条件が満たされるようにします。次のコード例を参照してください。
データの削除
Cassandra では DELETE コマンドを使用して、選択した 1 つ以上の列から行全体またはデータを削除できます。DynamoDB では、update-item API を使用して列からデータを削除し、delete-item で行全体を削除します。
Cassandra
DELETE 句の後に列、または列のコンマ区切りリストを指定して、指定した列からデータを削除できます。この例では、DELETE 句の後に列 AlbumTitle を指定します。SELECT ステートメントの結果セット (DELETE ステートメントの後) は、null を列 AlbumTitle (Artist='No One You Know' と SongTitle='Call Me Today' を持つ行) に対して表示します。値は、'New Album' でした (DELETE 操作前)。以下のコードを参照してください。
Cassandra の行全体を削除するには、次のコードを使用します。この例では、Artist 値 'No One You Know' と SongTitle 値 'Call Me Today' の行が削除されることを示しています。以下のコードを参照してください。
DynamoDB
update-item 操作で、項目から属性を削除できます。-update-expression オプション (update-item にある) は、更新する 1 つ以上の属性、それらに対して実行するアクション、およびそれらの新しい値を定義する式を表します。次のコードで、REMOVE アクションを AlbumTitle で実行します。
get-item 操作を update-item 操作の前に実行して返された項目には、AlbumTitle 属性が含まれています。get-item を update-item 操作の後に再度呼び出すと、AlbumTitle が存在しないことがわかります。以下のコードを参照してください。
delete-item 操作で、行全体を削除できます。次のコードは、行を削除し、get-item 操作を実行して、項目が削除されたことを示しています。
Summary
この投稿では、広く使用されている Cassandra API と、それに相当する DynamoDB API について考察しました。Cassandra 開発者が DynamoDB の使用を開始する際に役立つコマンドについて説明しました。DynamoDB の詳細や、自動スケーリング、グローバルテーブル、TTL、トランザクションなどの高度な機能については、「Amazon DynamoDB とは」をご参照ください。
著者について

Sravan Kumar は、アマゾン ウェブ サービスのコンサルタントです。 AWS DMS 開発チームと連携し、拡張フレームワークのソフトウェアインフラストラクチャの開発を支援しています。