【新機能】Amazon DynamoDBのスキャンに「読み取り一貫性(Consistent Read)」サポートのパラメータが増えました

2015.08.06

こんにちは、せーのです。今日はDynamoDBに加わった、かゆいところに手が届くアップデートをご紹介致します。読み取り一貫性のサポートです。

読み取り一貫性とは

DynamoDBに代表されるNoSQLデータストアは可用性を保つためにデータを分散して保持します。DynamoDBも同じデータを3箇所にコピーして保持しています。万が一データのあるサーバーがダウンしたとしても他に保持しているサーバーからデータを読み書きできるようにするためです。 データを3箇所にコピーしている、ということは登録する時は3回分書き込むわけで、更新する時は3箇所を更新することになります。これを待っているとレスポンスが遅くなるのでDynamoDBは2箇所を書き込んだ時点で「書き込みOK」という返答をします。残り1箇所は「そのうち時間が経てば(DynamoDBの場合は1秒以内)結果的に書き込まれる」という考え方です。これを「結果整合性」と言います。読み取り時には3箇所に書き込まれているデータのどこから読み取るかはわからないので書き込まれていないデータからは読み取れないことになりますし、更新前のデータからは古いデータが読み取れてしまいます。 読み取り一貫性とはこのような読み取りによる差がないことを保証するもので、今回はスキャン時にこのオプションをつけることでスキャン前に登録、変更された値は確実に読み取る事ができます。具体的には書き込まれている3箇所より2箇所の値を読み取り、一致すればその値を、一致しなければもう1箇所の値を読んで2箇所に書き込まれている値を返す、という仕組みになります。 一点注意しなくてはいけないのは今回のスキャンの読み取り一貫性オプションはグローバルセカンダリインデックスはサポート外となります。グローバルセカンダリインデックスをスキャンする時にこの読み取り一貫性オプションを選択するとValidateExceptionエラーとなりますので気をつけて下さい。

やってみる

今回のオプションはまだマネージメントコンソールには実装されていないのでAPIを叩いて使います。Scan APIの引数に"ConsistentRead"という項目をセットし、Boolean値をセットします。デフォルトは"false"になっています。 例えばPHPで言えば

$client = DynamoDbClient::factory(array(
    'profile' => 'default',
    'region' => 'us-west-2' #replace with your desired region     
));

$response = $client->scan(array(
    'TableName' => 'Reply',
    'ConsistentRead' => true
));

foreach ($response['Items'] as $key => $value) {
    echo 'Id: ' . $value['Id']['S'] .    PHP_EOL;
    echo 'ReplyDateTime: ' . $value['ReplyDateTime']['S'] . PHP_EOL;
    echo 'Message: ' . $value['Message']['S'] . PHP_EOL;
    echo 'PostedBy: ' . $value['PostedBy']['S'] . PHP_EOL;
    echo PHP_EOL;
}

というような書き方をします。簡単ですね。

まとめ

DynamoDBは今までアイテムの読み込みには読み取り一貫性がサポートされていましたが、今回スキャンにも読み取り一貫性がサポートされたことでより一層メインのデータストアとして信頼性の高い使い方もできるようになりました。このオプションを効果的に使ってDynamoDBを上手に扱いましょう!

参考サイト