【新機能】インメモリ型キャッシュクラスタで超高速化!Amazon DynamoDB Accelerator (DAX) のプレビュー版で速さを体験してみた

DynamoDB 高速化のための新機能「Amazon DynamoDB Accelerator(DAX)」

Amazon DynamoDB Accelerator (DAX) は、先日 AWS Summit 2017 San Fransisco で発表された DynamoDB の高速化のための新機能です。

DynamoDB 専用のインメモリ型のキャッシュクラスタを構築し、キャッシュからのレスポンスをミリ秒単位からマイクロ秒単位になるように高速化することができます。既存の DynamoDB の API との互換性も保つよう設計されているため、すでに DynamoDB をお使いのシステムにおいてもシームレスに移行することができるようです。

クラスタは VPC 内で構築され、DAX のクライアントとなる SDK はローレベル TCP での通信を行うことで、高スループット&低レイテンシを実現できるようチューニングしてあります。現時点では Java 用の SDK のみ提供されていますが、今後他の言語でも対応される予定だそうです。

DAX Overview

DAX は現在はパブリックプレビューとして US East (N. Virginia) と US West (Oregon) と EU (Ireland) で提供されています。本記事では DAX を簡単に試すことができるサンプルアプリケーションを通して、どれほど高速になるか体験してみました。

本記事で紹介する機能はプレビュー版です。正式サービスとして公開されるまでに、仕様が変更される可能性があります。予めご留意の上お読みください。

検証環境

  • Amazon Linux 2017.03.0
  • AWS SDK for Java 1.11.123

クラスタの作成

本記事では US East (N. Virginia) リージョンで試します。まずは DynamoDB のマネジメントコンソールにアクセスし「Create cluster」をクリックします。

dax-01

作成するクラスタの設定を入力していきます。IAM role policy は「Create new」を選択すると、IAM Role の設定が表示されます。「Read/Write」に設定、Target DynamoDB table は「All tables」に設定します。

dax-02

Subnet group も同様に「Create new」を選択すると、Subnet Group の設定が表示されます。すでに VPC を作成済みであれば VPC ID に作成済みの VPC を選択し、Subnets の全てにチェックを入れます。Security group は「default」を選択しましょう。

dax-03

数分待つと、クラスタのステータスが「Available」になります。詳細を見てみると、作成した3つのノードが「Available」になっていることが確認できます。

dax-04

クラスタの構築が完了したら、 EC2 のマネジメントコンソールにて先ほど設定した Security Group の Inbound で 8111 を許可しておきます。

dax-05

EC2 インスタンスの起動

DAX の読み込み速度を体験するために、Java 製のサンプルアプリケーションが提供されています。こちらを試すために、DAX のクラスタを作成したリージョンと同じリージョンで EC2 インスタンスを起動します。

AMI は最新の Amazon Linux の AMI (執筆時点では 2017.03.0 が最新) を使います。

dax-06

特に必要な設定はありません。ご自身のマシンから SSH で接続できるように、パグリック IP の付与と SSH キー (pem) のダウンロードは行なってください。

dax-07

EC2 インスタンスへの IAM Role のアタッチ

先ほど起動した EC2 インスタンスに対して、IAM Role をアタッチします。DynamoDB と DAX の API へのアクセス権限を付与する必要があるためです。

IAM のマネジメントコンソールのロール一覧画面の「新しいロールの作成」をクリックします。

dax-08

AWS サービスロールは「Amazon EC2」を選択します。

dax-09

ポリシーは「Amazon DynamoDB Full Access」を選択します。

dax-10

IAM Role 作成後、インラインポリシーを設定します。作成した IAM Role の詳細画面から「ロールポリシーの作成」をクリックし、以下のカスタムポリシーを追加します。先ほど Amazon DynamoDB Full Access を指定しましたが、以下のカスタムポリシーでも同様のポリシーを指定していますので Amazon DynamoDB Full Access は消してしまっても構いません (IAM Role 作成時にいずれかのポリシーを指定する必要があったため、指定していました)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "dax:*"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        },
        {
            "Action": [
                "dynamodb:*"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        }
    ]
}

最後に、このロールを起動済みの EC2 インスタンスにアタッチします。起動済みの EC2 インスタンスへの IAM Role のアタッチは先日、マネジメントコンソールからもできるようになりました。

dax-11

以上で準備完了です。

サンプルアプリケーションをコンパイルする

先ほど起動した EC2 インスタンスに SSH で接続します。

$ ssh -i <EC2に設定したキーペア> ec2-user@<EC2インスタンスのパブリックIP>

Java をインストールします。

$ sudo yum install -y java-devel

AWS SDK と DAX のプレビュー用クライアントをダウンロードし、展開します。

$ wget http://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip
$ unzip aws-java-sdk.zip
$ wget http://dax-sdk.s3-website-us-west-2.amazonaws.com/java/DaxJavaClient-latest.jar

上記でダウンロードした Zip ファイルを展開すると、ログにSDKのバージョンが記載されています。こちらと、このバージョンを元にしたクラスパスを環境変数に設定します。

$ export SDKVERSION=<SDKのバージョン>
$ export CLASSPATH=.:./DaxJavaClient-latest.jar:aws-java-sdk-$SDKVERSION/lib/aws-java-sdk-$SDKVERSION.jar:aws-java-sdk-$SDKVERSION/third-party/lib/*

サンプルアプリケーションをダウンロードして展開し、コンパイルします。

$ wget http://s3.amazonaws.com/dynamodb-preview-dax/samples/TryDax.zip
$ unzip TryDax.zip
$ javac TryDax*.java

サンプルアプリケーションを実行する

コンパイルしたサンプルアプリケーションを実行してみましょう。

DynamoDB への通常のリクエスト

DAX の速さを体験するため、まずは普通の DynamoDB のリクエストを実行します。

$ java TryDax

結果は次の通りです。

Creating a DynamoDB client
Creating table...
Attempting to create table; please wait...
Successfully created table.  Table status: ACTIVE
Populating table...
Writing data to the table...
Writing 10 items for partition key: 1
Writing 10 items for partition key: 2
Writing 10 items for partition key: 3
Writing 10 items for partition key: 4
Writing 10 items for partition key: 5
Writing 10 items for partition key: 6
Writing 10 items for partition key: 7
Writing 10 items for partition key: 8
Writing 10 items for partition key: 9
Writing 10 items for partition key: 10
Running GetItem, Scan, and Query tests...
First iteration of each test will result in cache misses
Next iterations are cache hits

GetItem test - partition key 1 and sort keys 1-10
	Total time: 98.413 ms - Avg time: 9.841 ms
	Total time: 259.656 ms - Avg time: 25.966 ms
	Total time: 63.154 ms - Avg time: 6.315 ms
	Total time: 59.982 ms - Avg time: 5.998 ms
	Total time: 67.648 ms - Avg time: 6.765 ms
Query test - partition key 5 and sort keys between 2 and 9
	Total time: 17.109 ms - Avg time: 3.422 ms
	Total time: 16.213 ms - Avg time: 3.243 ms
	Total time: 7.510 ms - Avg time: 1.502 ms
	Total time: 7.579 ms - Avg time: 1.516 ms
	Total time: 7.240 ms - Avg time: 1.448 ms
Scan test - all items in the table
	Total time: 50.958 ms - Avg time: 10.192 ms
	Total time: 230.932 ms - Avg time: 46.186 ms
	Total time: 26.954 ms - Avg time: 5.391 ms
	Total time: 31.406 ms - Avg time: 6.281 ms
	Total time: 45.444 ms - Avg time: 9.089 ms

Attempting to delete table; please wait...
Successfully deleted table.

GetItem は約 5〜25 ミリ秒、Query は約 1.4〜3.4ミリ秒、Scan は約 5〜46ミリ秒となりました。

DAX へのリクエスト

次に、DAX へのリクエストを試します。すでに作成してある DAX のクラスタのエンドポイントをコピーします。

dax-12

このエンドポイントを先ほどのコマンドの引数に付けると、DAX のクラスタに対するリクエストが実行されます。

$ java TryDax <クラスタのエンドポイント>

結果は次の通りです。

Creating a DynamoDB client
Creating table...
Attempting to create table; please wait...
Successfully created table.  Table status: ACTIVE
Populating table...
Writing data to the table...
Writing 10 items for partition key: 1
Writing 10 items for partition key: 2
Writing 10 items for partition key: 3
Writing 10 items for partition key: 4
Writing 10 items for partition key: 5
Writing 10 items for partition key: 6
Writing 10 items for partition key: 7
Writing 10 items for partition key: 8
Writing 10 items for partition key: 9
Writing 10 items for partition key: 10
Running GetItem, Scan, and Query tests...
First iteration of each test will result in cache misses
Next iterations are cache hits

GetItem test - partition key 1 and sort keys 1-10
	Total time: 560.708 ms - Avg time: 56.071 ms
	Total time: 12.518 ms - Avg time: 1.252 ms
	Total time: 12.516 ms - Avg time: 1.252 ms
	Total time: 11.561 ms - Avg time: 1.156 ms
	Total time: 13.850 ms - Avg time: 1.385 ms
Query test - partition key 5 and sort keys between 2 and 9
	Total time: 153.863 ms - Avg time: 30.773 ms
	Total time: 2.080 ms - Avg time: 0.416 ms
	Total time: 1.740 ms - Avg time: 0.348 ms
	Total time: 2.827 ms - Avg time: 0.565 ms
	Total time: 1.777 ms - Avg time: 0.355 ms
Scan test - all items in the table
	Total time: 89.859 ms - Avg time: 17.972 ms
	Total time: 13.944 ms - Avg time: 2.789 ms
	Total time: 9.372 ms - Avg time: 1.874 ms
	Total time: 10.357 ms - Avg time: 2.071 ms
	Total time: 8.675 ms - Avg time: 1.735 ms

Attempting to delete table; please wait...
Successfully deleted table.

GetItem は約 1.1〜56 ミリ秒、Query は約 0.3〜30ミリ秒、Scan は約 1.7〜17ミリ秒となりました。2回目以降のリクエストが高速になっていることが分かりますね。

DAX は DynamoDB をフル活用している人のための新機能

本記事では、DAX のガイドに沿ってサンプルアプリケーションを試してみました。DAX は、DynamoDB へのアクセスが多ければ多いほど劇的な速度効果が期待できる機能です。現在のシステムで DynamoDB を利用されている方はぜひ導入を検討してみてはいかがでしょうか。

まずはプレビューに申し込みましょう!

参考サイト

本記事は、下記の記事を参考に執筆しました。