AWS SDK for PHP2を使ってAmazon DynamoDBのデータを読み書きするサンプル

Amazon DynamoDB

NoSQLデータベースはリレーショナルデータベースと性質が異なるため敬遠していましたが、AWSには「Amazon DynamoDB」という従量課金制NoSQLデータベースサービスがあります。

PHPからSDKを利用して使ってみたところ手軽にデータの読み書きができたので、利用方法をメモします。

Amazon DynamoDBとは

Amazonが提供するフルマネージド型のNoSQL型データベースサービスです。データ保存にはSSDが使われておりデータ読み出し・書き込み速度が速く、自動で同一リージョン内の3つの施設にレプリケーションされるためデータの耐久性と可用性がとても高いサービスとなっています。

公式サイト:Amazon DynamoDB (フルマネージドNo SQLデータベースサービス)

従量課金制で課金はプロビジョニングされたスループットの容量とデータ保存容量に対して行われます。わかりにくい表現ですが、単位時間あたりに読み書きできる予約容量を増やすごとに料金が高くなっていくという意味です。

しかし保存容量100 MB と書き込み最大5 回/秒、読み込み最大10 回/秒のスループット容量(毎日最大432,000回の書き込みと864,000回の読み込みができるだけのリソース予約)は毎月無料で利用できるため、試用やちょっとしたアプリケーションであればほとんど無料で使うことができます。

事前準備

PHPからDynamoDBの読み書きを行うため、データベースのテーブルの作成とDynamoDBへのアクセス権をもったIAMユーザを作成し、シークレットキーとアクセスキーを取得しておきます。

DynamoDB データベースのテーブル作成

AWSマネジメントコンソールからDynamoDBの画面を開き、「Create Table」ボタンを押します。
DynamoDB マネジメントコンソール

Table Nameには任意のテーブル名を入力します。またPrimary Keyではテーブルのプライマリキーを「Hash」(ハッシュのみ)または「Hash and Range」(ハッシュおよび範囲)のタイプで指定します。「Hash」を指定した場合はテーブルのキーは1つの属性のみとなり、「Hash and Range」を指定した場合は2つの属性で複合キーとなります。

今回はプライマリキータイプを「Hash and Range」とし、Hash属性をString型の「Id」Range属性をString型の「CreateDate」としました。
DynamoDB テーブルの作成

オプションでテーブルインデックスを設定可能です。通常テーブルに対するクエリはプライマリキーにしか実行できませんが、インデックスを設定するとプライマリキー以外の属性にもクエリを実行できます。今回はインデックスを設定せずそのまま「Continue」で次に進みます。
DynamoDB インデックスの作成

プロビジョニングスループットの設定です。値を変更すると読み書き速度の性能を向上できますが、無料利用枠に収めたいので「Read Capacity Units」と「Write Capacity Units」それぞれ1のままとしておきます。
DynamoDB プロビジョニングスループットの設定

テーブルの読み書きスループットが一定量を超えるとアラーム送信する設定が可能です。アラーム設定する場合は通知先メールアドレスを入力します。
DynamoDB アラームの設定

設定を確認して問題なければ「Create」ボタンを押します。
DynamoDB 設定の確認

マネジメントコンソールに戻るとテーブルが作成されています。Statusが「ACTIVE」になったら利用可能です。
DynamoDB テーブル作成完了

DynamoDBへのアクセス権を持つIAMユーザの作成

PHPのAWS SDKからDynamoDBを操作するためのアクセスキー・シークレットキーを取得します。既にDynamoDBへアクセス可能なアクセスキー・シークレットキーがある場合は本手順はスキップ可能です。

AWSマネジメントコンソールからIAM(dentity and Access Management)を開きます。

左メニューの「Users」を選び、「Create New Users」ボタンを押します。
IAM 新規ユーザ作成

任意のユーザ名を入力します。画面下部の「Generate an access key for each user」のチェックを入れておき、画面右下の「Create」ボタンを押します。
IAM 新規ユーザアクセスキー作成

ユーザが作成され、「Show User Security Credentials」をクリックするとアクセスキーIDとシークレットキーが表示されるためメモしておきます。
IAM アクセスキーとシークレットキー

IAMのユーザー一覧画面に戻り、新規作成したユーザを選択します。詳細画面の「Permissions」で「Attach User Policy」ボタンを押します。
IAM パーミッションの適用

「Amazon DynamoDB Full Access」を「Select」し、次の画面で「Apply Policy」ボタンを押すと新規作成したユーザにDynamoDBの読み書きアクセス権が付与されます。
IAM DynamoDB フルアクセス

AWS SDK for PHP2を使ったAmazon DynamoDBのデータ読み書き

やっと本題です。AWS SDK for PHPaws.pharこちらのページからダウンロードしておき、プログラムからインクルード可能な状態としておきます。

最初にconfig.phpという名前でアクセスキー・シークレットキー・リージョンを指定した認証情報のファイルを作成しておきます。このファイルをAws::factoryメソッドの引数に指定することでPHPクライアントの認証が可能となります。

<?php
return array(
    'includes' => array('_aws'),
    'services' => array(
        'default_settings' => array(
            'params' => array(
                'key' => 'YOUR_ACCESS_KEY',    //アクセスキー
                'secret' => 'YOUR_SECRET_ACCESS_KEY',    //シークレットキー
                'region' => 'ap-northeast-1'    // リージョン          
            )
        )
    )
);

Amazon DynamoDBへのデータ書き込み(putItem)

DynamoDBへの書き込みはputItemメソッドを使います。

以下は先ほど作成したSampleTableテーブルのキーIdに”0001″を、CreateDateに現在時刻を、その他2つの属性StringAttributeNumberAttributeにそれぞれ100と”String”を書き込むサンプルです。

<?php
require_once './aws.phar';

date_default_timezone_set('Asia/Tokyo');

use Aws\Common\Aws;
use Aws\DynamoDbException\DynamoDbException;

$aws = Aws::factory('./config.php');

try {
    $client = $aws->get('dynamodb');

    $result = $client->putItem(array(
        'TableName' => 'SampleTable',
        'Item' => $client->formatAttributes(array(
            'Id'        => '0001',
            'StringAttribute' => 'String',
            'NumberAttribute' => 100,
            'CreateDate' => date("Y-m-d H:i:s"),
        )),
    ));

} catch (DynamoDbException $e) {
    echo $e->getMessage();
}

実行後、DynamoDBのコンソールからテーブルを選択して詳細を見てみると確かに書き込みが実施されています。
DynamoDB putItem

Amazon DynamoDBのデータ読み出し(scan)

テーブルのデータ読み出しはscanメソッドで可能です。以下は先ほど作成したSampleTableテーブルの全てのレコードを取得するサンプルです。

<?php
require_once './aws.phar';

use Aws\Common\Aws;
use Aws\DynamoDbException\DynamoDbException;

$aws = Aws::factory('./config.php');

try {
    $client = $aws->get('dynamodb');

    $result = $client->scan(array(
        'TableName' => 'SampleTable',
    ));

    echo "<pre>";
    print_r($result);
    echo "</pre>";

} catch (DynamoDbException $e) {
    echo $e->getMessage();
}

実行結果は以下の通りです。先ほど書き込んだ値が表示されています。
DynamoDB Scan

APIリファレンス

AWS SDK for PHPのDynamoDBクライアントのAPIリファレンスは以下のページから参照可能です。

Class Aws\DynamoDb\DynamoDbClient | AWS SDK for PHP

おわりに

DynamoDBは高負荷耐性やスケールアウトの簡単さからソーシャルゲーム等での利用事例が多いようですが、初期費用が無いため様々な場面で利用しやすいと思います。

今回はシンプルな読み書きのみ試してみましたが、自前でデータベースを用意しなくてもSDKを使えば簡単にデータを保存できることがわかりました。