

# DAX を AWS SDK for Java 1.x で使用する
<a name="DAX.client.java-sdk-v1"></a>

この手順に従って、Amazon EC2 インスタンスで Amazon DynamoDB Accelerator (DAX) の Java サンプルを実行します。

**注記**  
これらの手順は、AWS SDK for Java 1.x を使用するアプリケーション向けです。AWS SDK for Java 2.x を使用するアプリケーションの場合は、「[Java および DAX](DAX.client.run-application-java.md)」を参照してください。

**DAX の Java サンプルを実行するには**

1. Java 開発キット (JDK) をインストールします。

   ```
   sudo yum install -y java-devel
   ```

1. AWS SDK for Java (`.zip` ファイル) をダウンロードして解凍します。

   ```
   wget http://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip
   
   unzip aws-java-sdk.zip
   ```

1. DAX Java クライアント (`.jar` ファイル) の最新バージョンをダウンロードします。

   ```
   wget http://dax-sdk.s3-website-us-west-2.amazonaws.com/java/DaxJavaClient-latest.jar
   ```
**注記**  
DAX SDK for Java のクライアントは、Apache Maven で利用可能です。詳細については、「[クライアントを Apache Maven 依存関係として使用する](#DAXClient.Maven)」を参照してください。

1. `CLASSPATH` 変数を設定します。この例では、`sdkVersion` を AWS SDK for Java の実際のバージョン番号に置き換えます (例: `1.11.112`)。

   ```
   export SDKVERSION=sdkVersion
   
   export CLASSPATH=$(pwd)/TryDax/java:$(pwd)/DaxJavaClient-latest.jar:$(pwd)/aws-java-sdk-$SDKVERSION/lib/aws-java-sdk-$SDKVERSION.jar:$(pwd)/aws-java-sdk-$SDKVERSION/third-party/lib/*
   ```

1. サンプルプログラムソースコード (`.zip` ファイル) をダウンロードします。

   ```
   wget http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/samples/TryDax.zip
   ```

   ダウンロードが完了したら、ソースファイルを解凍します。

   ```
   unzip TryDax.zip
   ```

1. Java コードディレクトリに移動し、次のようにコードをコンパイルします。

   ```
   cd TryDax/java/
   javac TryDax*.java
   ```

1. プログラムを実行します。

   ```
   java TryDax
   ```

   次のような出力が表示されます。

   ```
   Creating a DynamoDB client
   
   Attempting to create table; please wait...
   Successfully created table.  Table status: ACTIVE
   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: 136.681 ms - Avg time: 13.668 ms
   	Total time: 122.632 ms - Avg time: 12.263 ms
   	Total time: 167.762 ms - Avg time: 16.776 ms
   	Total time: 108.130 ms - Avg time: 10.813 ms
   	Total time: 137.890 ms - Avg time: 13.789 ms
   Query test - partition key 5 and sort keys between 2 and 9
   	Total time: 13.560 ms - Avg time: 2.712 ms
   	Total time: 11.339 ms - Avg time: 2.268 ms
   	Total time: 7.809 ms - Avg time: 1.562 ms
   	Total time: 10.736 ms - Avg time: 2.147 ms
   	Total time: 12.122 ms - Avg time: 2.424 ms
   Scan test - all items in the table
   	Total time: 58.952 ms - Avg time: 11.790 ms
   	Total time: 25.507 ms - Avg time: 5.101 ms
   	Total time: 37.660 ms - Avg time: 7.532 ms
   	Total time: 26.781 ms - Avg time: 5.356 ms
   	Total time: 46.076 ms - Avg time: 9.215 ms
   
   Attempting to delete table; please wait...
   Successfully deleted table.
   ```

   タイミング情報を書き留めます。これは `GetItem`、`Query`、`Scan` テストに必要なミリ秒の数字です。

1. 前のステップで、DynamoDB エンドポイントに対してプログラムを実行しました。ここでプログラムを再度実行しますが、今度は `GetItem`、`Query`、`Scan` オペレーションが DAX クラスターによって処理されます。

   DAX クラスターのエンドポイントを確認するには、次のいずれかを選択します。
   + **DynamoDB コンソールの使用** — DAX クラスターを選択します。次の例のように、クラスターエンドポイントがコンソールに表示されます。

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **AWS CLI の使用** — 次のコマンドを入力します。

     ```
     aws dax describe-clusters --query "Clusters[*].ClusterDiscoveryEndpoint"
     ```

     次の例のように、クラスターエンドポイントが出力に表示されます。

     ```
     {
         "Address": "my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com",
         "Port": 8111,
         "URL": "dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com"
     }
     ```

   ここでプログラムを再度実行しますが、今度はクラスターエンドポイントをコマンドラインパラメータとして指定します。

   ```
   java TryDax dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   ```

   出力の残りの部分を見て、タイミング情報を書き留めます。`GetItem`、`Query` および `Scan` の経過時間は、DynamoDB を使用した場合より DAX を使用した方が大幅に低いはずです。

このプログラムの詳細については、以下のセクションを参照してください。
+ [TryDax.java](DAX.client.run-application-java.TryDax.md)
+ [TryDaxHelper.java](DAX.client.run-application-java.TryDaxHelper.md)
+ [TryDaxTests.java](DAX.client.run-application-java.TryDaxTests.md)

## クライアントを Apache Maven 依存関係として使用する
<a name="DAXClient.Maven"></a>

これらのステップに従って、アプリケーションで DAX SDK for Java のクライアントを依存関係として使用します。

**クライアントを Maven 依存関係として使用するには**

1. Apache Maven をダウンロードし、インストールします。詳細については、「[Apache Maven のダウンロード](https://maven.apache.org/download.cgi)」および「[Apache Maven のインストール](https://maven.apache.org/install.html)」を参照してください。

1. Maven 依存関係クライアントをアプリケーションのプロジェクトオブジェクトモデル (POM) ファイルに追加します。この例では、`x.x.x.x` をクライアントの実際のバージョン番号に置き換えます (例: `1.0.200704.0`)。

   ```
   <!--Dependency:-->
   <dependencies>
       <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>amazon-dax-client</artifactId>
        <version>x.x.x.x</version>
       </dependency>
   </dependencies>
   ```

# TryDax.java
<a name="DAX.client.run-application-java.TryDax"></a>

`TryDax.java` ファイルには、`main` メソッドが含まれています。コマンドラインパラメータを指定しないでプログラムを実行すると、Amazon DynamoDB クライアントが作成され、すべての API オペレーションでそのクライアントが使用されます。コマンドラインで DynamoDB Accelerator (DAX) クラスターエンドポイントを指定すると、プログラムは DAX クライアントも作成し、`GetItem`、`Query`、`Scan` オペレーションでこれを使用します。

さまざまな方法でプログラムを変更できます。
+ DynamoDB クライアントではなく、DAX クライアントを使用します。詳細については、「[Java および DAX](DAX.client.run-application-java.md)」を参照してください。
+ テストテーブルに別の名前を付けます。
+ `helper.writeData` パラメータを変更して書き込まれる項目の数を変更する。2 番目のパラメータはパーティションキーの数、3 番目のパラメータはソートキーの数です。デフォルトでは、プログラムはパーティションキーの値に 1～10 を使用し、ソートキーの値に 1～10 を使用し、合計で 100 個の項目がテーブルに書き込まれます。詳細については、「[TryDaxHelper.java](DAX.client.run-application-java.TryDaxHelper.md)」を参照してください。
+ `GetItem`、`Query` および `Scan` テストの数を変更し、そのパラメータを変更する。
+ `helper.createTable` および `helper.deleteTable` を含むラインをコメントアウトする (プログラムを実行するたびにテーブルを作成および削除しない場合)。

**注記**  
このプログラムを実行するには、DAX SDK for Java のクライアント、および AWS SDK for Java を依存関係として使用するように Maven を設定できます。詳細については、「[クライアントを Apache Maven 依存関係として使用する](DAX.client.java-sdk-v1.md#DAXClient.Maven)」を参照してください。  
また、DAX Java クライアントと AWS SDK for Java の両方をダウンロードして、クラスパスに含めることもできます。`CLASSPATH` 変数の設定例については、「[Java および DAX](DAX.client.run-application-java.md)」を参照してください。

```
public class TryDax {

    public static void main(String[] args) throws Exception {

        TryDaxHelper helper = new TryDaxHelper();
        TryDaxTests tests = new TryDaxTests();

        DynamoDB ddbClient = helper.getDynamoDBClient();
        DynamoDB daxClient = null;
        if (args.length >= 1) {
            daxClient = helper.getDaxClient(args[0]);
        }

        String tableName = "TryDaxTable";

        System.out.println("Creating table...");
        helper.createTable(tableName, ddbClient);
        System.out.println("Populating table...");
        helper.writeData(tableName, ddbClient, 10, 10);

        DynamoDB testClient = null;
        if (daxClient != null) {
            testClient = daxClient;
        } else {
            testClient = ddbClient;
        }

        System.out.println("Running GetItem, Scan, and Query tests...");
        System.out.println("First iteration of each test will result in cache misses");
        System.out.println("Next iterations are cache hits\n");

        // GetItem
        tests.getItemTest(tableName, testClient, 1, 10, 5);

        // Query
        tests.queryTest(tableName, testClient, 5, 2, 9, 5);

        // Scan
        tests.scanTest(tableName, testClient, 5);

        helper.deleteTable(tableName, ddbClient);
    }

}
```

# TryDaxHelper.java
<a name="DAX.client.run-application-java.TryDaxHelper"></a>

`TryDaxHelper.java` ファイルにはユーティリティメソッドが含まれています。

`getDynamoDBClient` および `getDaxClient` メソッドは、Amazon DynamoDB および Amazon DynamoDB Accelerator (DAX) クライアントを提供します。コントロールプレーンオペレーション (`CreateTable`、`DeleteTable`) および書き込みオペレーションでは、プログラムは DynamoDB クライアントを使用します。DAX クラスターエンドポイントを指定すると、メインプログラムは読み込みオペレーション (`GetItem`、`Query`、`Scan`) 用に DAX クライアントを作成します。

他の `TryDaxHelper` メソッド (`createTable`、`writeData`、`deleteTable`) は、DynamoDB テーブルとそのデータのセットアップおよび解体用です。

さまざまな方法でプログラムを変更できます。
+ テーブルで別のプロビジョニングされたスループット設定を使用する。
+ 書き込まれた各項目のサイズを変更する (`writeData` メソッドの `stringSize` 変数を参照してください)。
+ `GetItem`、`Query`、および `Scan` テストの数とそのパラメータを変更する。
+ `helper.CreateTable` および `helper.DeleteTable` を含むラインをコメントアウトする (プログラムを実行するたびにテーブルを作成および削除しない場合)。

**注記**  
 このプログラムを実行するには、DAX SDK for Java のクライアント、および AWS SDK for Java を依存関係として使用するように Maven を設定できます。詳細については、「[クライアントを Apache Maven 依存関係として使用する](DAX.client.java-sdk-v1.md#DAXClient.Maven)」を参照してください。  
または、DAX Java クライアントと AWS SDK for Java の両方をダウンロードして、クラスパスに含めることもできます。`CLASSPATH` 変数の設定例については、「[Java および DAX](DAX.client.run-application-java.md)」を参照してください。

```
import com.amazon.dax.client.dynamodbv2.AmazonDaxClientBuilder;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.util.EC2MetadataUtils;

public class TryDaxHelper {

    private static final String region = EC2MetadataUtils.getEC2InstanceRegion();

    DynamoDB getDynamoDBClient() {
        System.out.println("Creating a DynamoDB client");
        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withRegion(region)
                .build();
        return new DynamoDB(client);
    }

    DynamoDB getDaxClient(String daxEndpoint) {
        System.out.println("Creating a DAX client with cluster endpoint " + daxEndpoint);
        AmazonDaxClientBuilder daxClientBuilder = AmazonDaxClientBuilder.standard();
        daxClientBuilder.withRegion(region).withEndpointConfiguration(daxEndpoint);
        AmazonDynamoDB client = daxClientBuilder.build();
        return new DynamoDB(client);
    }

    void createTable(String tableName, DynamoDB client) {
        Table table = client.getTable(tableName);
        try {
            System.out.println("Attempting to create table; please wait...");

            table = client.createTable(tableName,
                    Arrays.asList(
                            new KeySchemaElement("pk", KeyType.HASH), // Partition key
                            new KeySchemaElement("sk", KeyType.RANGE)), // Sort key
                    Arrays.asList(
                            new AttributeDefinition("pk", ScalarAttributeType.N),
                            new AttributeDefinition("sk", ScalarAttributeType.N)),
                    new ProvisionedThroughput(10L, 10L));
            table.waitForActive();
            System.out.println("Successfully created table.  Table status: " +
                    table.getDescription().getTableStatus());

        } catch (Exception e) {
            System.err.println("Unable to create table: ");
            e.printStackTrace();
        }
    }

    void writeData(String tableName, DynamoDB client, int pkmax, int skmax) {
        Table table = client.getTable(tableName);
        System.out.println("Writing data to the table...");

        int stringSize = 1000;
        StringBuilder sb = new StringBuilder(stringSize);
        for (int i = 0; i < stringSize; i++) {
            sb.append('X');
        }
        String someData = sb.toString();

        try {
            for (Integer ipk = 1; ipk <= pkmax; ipk++) {
                System.out.println(("Writing " + skmax + " items for partition key: " + ipk));
                for (Integer isk = 1; isk <= skmax; isk++) {
                    table.putItem(new Item()
                            .withPrimaryKey("pk", ipk, "sk", isk)
                            .withString("someData", someData));
                }
            }
        } catch (Exception e) {
            System.err.println("Unable to write item:");
            e.printStackTrace();
        }
    }

    void deleteTable(String tableName, DynamoDB client) {
        Table table = client.getTable(tableName);
        try {
            System.out.println("\nAttempting to delete table; please wait...");
            table.delete();
            table.waitForDelete();
            System.out.println("Successfully deleted table.");

        } catch (Exception e) {
            System.err.println("Unable to delete table: ");
            e.printStackTrace();
        }
    }

}
```

# TryDaxTests.java
<a name="DAX.client.run-application-java.TryDaxTests"></a>

`TryDaxTests.java` ファイルには、Amazon DynamoDB のテストテーブルに対して読み込みオペレーションを実行するメソッドが含まれています。これらのメソッドはデータへのアクセス方法 (DynamoDB クライアントを使用するか DAX クライアントを使用するか) は問わないため、アプリケーションロジックを変更する必要はありません。

さまざまな方法でプログラムを変更できます。
+ `queryTest` メソッドを変更して異なる `KeyConditionExpression` を使用する。
+ `ScanFilter` を `scanTest` メソッドに追加し、項目の一部のみが返されるようにします。

**注記**  
 このプログラムを実行するには、DAX SDK for Java のクライアント、および AWS SDK for Java を依存関係として使用するように Maven を設定できます。詳細については、「[クライアントを Apache Maven 依存関係として使用する](DAX.client.java-sdk-v1.md#DAXClient.Maven)」を参照してください。  
または、DAX Java クライアントと AWS SDK for Java の両方をダウンロードして、クラスパスに含めることもできます。`CLASSPATH` 変数の設定例については、「[Java および DAX](DAX.client.run-application-java.md)」を参照してください。

```
import java.util.Iterator;

import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.ItemCollection;
import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
import com.amazonaws.services.dynamodbv2.document.ScanOutcome;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;

public class TryDaxTests {

    void getItemTest(String tableName, DynamoDB client, int pk, int sk, int iterations) {
        long startTime, endTime;
        System.out.println("GetItem test - partition key " + pk + " and sort keys 1-" + sk);
        Table table = client.getTable(tableName);

        for (int i = 0; i < iterations; i++) {
            startTime = System.nanoTime();
            try {
                for (Integer ipk = 1; ipk <= pk; ipk++) {
                    for (Integer isk = 1; isk <= sk; isk++) {
                        table.getItem("pk", ipk, "sk", isk);
                    }
                }
            } catch (Exception e) {
                System.err.println("Unable to get item:");
                e.printStackTrace();
            }
            endTime = System.nanoTime();
            printTime(startTime, endTime, pk * sk);
        }
    }

    void queryTest(String tableName, DynamoDB client, int pk, int sk1, int sk2, int iterations) {
        long startTime, endTime;
        System.out.println("Query test - partition key " + pk + " and sort keys between " + sk1 + " and " + sk2);
        Table table = client.getTable(tableName);

        HashMap<String, Object> valueMap = new HashMap<String, Object>();
        valueMap.put(":pkval", pk);
        valueMap.put(":skval1", sk1);
        valueMap.put(":skval2", sk2);

        QuerySpec spec = new QuerySpec()
                .withKeyConditionExpression("pk = :pkval and sk between :skval1 and :skval2")
                .withValueMap(valueMap);

        for (int i = 0; i < iterations; i++) {
            startTime = System.nanoTime();
            ItemCollection<QueryOutcome> items = table.query(spec);

            try {
                Iterator<Item> iter = items.iterator();
                while (iter.hasNext()) {
                    iter.next();
                }
            } catch (Exception e) {
                System.err.println("Unable to query table:");
                e.printStackTrace();
            }
            endTime = System.nanoTime();
            printTime(startTime, endTime, iterations);
        }
    }

    void scanTest(String tableName, DynamoDB client, int iterations) {
        long startTime, endTime;
        System.out.println("Scan test - all items in the table");
        Table table = client.getTable(tableName);

        for (int i = 0; i < iterations; i++) {
            startTime = System.nanoTime();
            ItemCollection<ScanOutcome> items = table.scan();
            try {

                Iterator<Item> iter = items.iterator();
                while (iter.hasNext()) {
                    iter.next();
                }
            } catch (Exception e) {
                System.err.println("Unable to scan table:");
                e.printStackTrace();
            }
            endTime = System.nanoTime();
            printTime(startTime, endTime, iterations);
        }
    }

    public void printTime(long startTime, long endTime, int iterations) {
        System.out.format("\tTotal time: %.3f ms - ", (endTime - startTime) / (1000000.0));
        System.out.format("Avg time: %.3f ms\n", (endTime - startTime) / (iterations * 1000000.0));
    }
}
```