

# ステップ 4: サンプルアプリケーションの実行
<a name="DAX.client.run-application"></a>

Amazon DynamoDB Accelerator (DAX) の機能をテストしやすくするため、Amazon EC2 インスタンスで、使用可能なサンプルアプリケーションの 1 つを実行できます。

**Topics**
+ [Node.js および DAX](DAX.client.run-application-nodejs-3.md)
+ [DAX SDK for Go](DAX.client.run-application-go-2.md)
+ [Java および DAX](DAX.client.run-application-java.md)
+ [.NET および DAX](DAX.client.run-application-dotnet.md)
+ [Python および DAX](DAX.client.run-application-python.md)

# Node.js および DAX
<a name="DAX.client.run-application-nodejs-3"></a>

# Node.js のデフォルトのクライアント構成
<a name="DAX-client-config-JS"></a>

DAX JavaScript SDK クライアントを構成する際には、さまざまなパラメータをカスタマイズすることでパフォーマンス、接続処理、エラー耐性を最適化できます。次の表は、タイムアウト値、再試行メカニズム、認証情報管理、ヘルスモニタリングオプションなど、クライアントが DAX クラスターとやり取りする方法をコントロールするデフォルト構成設定をまとめたものです。詳細については、「[DynamoDBClient Operations](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/)」を参照してください。


**DAX JS SDK クライアントのデフォルト**  

| パラメータ | Type | 説明 | 
| --- | --- | --- | 
|  `region` オプション  |  `string`  |  DAX クライアントに使用する AWS リージョン (例 - 'us-east-1')。環境変数を介して指定されていない場合は必須のパラメータとなります。  | 
|  `endpoint` 必須  |  `string`  | SDK が接続するクラスターのエンドポイント。 例: 暗号化されていない場合 – dax-cluster-name.region.amazonaws.com 暗号化されている場合 – daxs://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com  | 
|  `requestTimeout` デフォルトは 6000 ミリ秒  |  `number`  | クライアントが DAX からのレスポンスを待機する最大時間を定義します。  | 
|  `writeRetries` デフォルトは 1  |  `number`  | 書き込みリクエスト失敗時の再試行回数。  | 
|  `readRetries` デフォルトは 1  |  `number`  | 読み取りリクエスト失敗時の再試行回数。  | 
|  `maxRetries` デフォルトは 1  |  `number`  | リクエスト失敗時の最大再試行回数。 readRetries/writeRetries が設定されている場合、readRetries と writeRetries の構成セットが maxRetries よりも優先されます。  | 
|  `connectTimeout` デフォルトは 10000 ミリ秒  |  `number`  | いずれかのクラスターノードへの接続を確立するためのタイムアウト (ミリ秒単位)。  | 
|  `maxConcurrentConnections` デフォルトは 100  |  `number`  | クライアントインスタンスが DAX クラスター内のノードごとに作成できる同時接続の最大数を制限します。  | 
|  `maxRetryDelay` デフォルトは 7000 ミリ秒  |  `number`  | `waitForRecoveryBeforeRetrying` フラグを true に設定してリカバリが必要であることを DAX サーバーが示すと、クライアントは再試行前に一時停止します。これらのリカバリ期間中は、`maxRetryDelay` パラメータによってある再試行から次の再試行までの最大待機時間が決定されます。このリカバリ固有の構成は、DAX サーバーがリカバリモードになっている場合にのみ適用されます。他のすべてのシナリオでは、再試行回数に基づく指数関数的な遅延 (`writeRetries`、`readRetries`、`maxRetries` のいずれかのパラメータによって制御)、または例外タイプに応じた即時再試行のいずれかのパターンの再試行動作に従います。  | 
|  `credentials` オプション  |  `[AwsCredentialIdentity](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)` \$1 `[AwsCredentialIdentityProvider](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)`  |  リクエストの認証に使用する AWS 認証情報。AwsCredentialIdentity または AwsCredentialIdentityProvider として指定できます。指定しなかった場合、AWS SDK ではデフォルトの認証情報プロバイダーチェーンを自動的に使用します。例: `\$1 accessKeyId: 'AKIA...', secretAccessKey: '...', sessionToken: '...' \$1` \$1 @default ではデフォルトの AWS 認証情報プロバイダーチェーンを使用します。  | 
|  `healthCheckInterval` デフォルトは 5000 ミリ秒  |  `number`  | クラスターヘルスチェックの間隔 (ミリ秒単位)。間隔を短くするほどより頻繁にチェックされます。  | 
|  `healthCheckTimeout` デフォルトは 1000 ミリ秒  |  `number`  | ヘルスチェックが完了するまでのタイムアウト (ミリ秒単位)。  | 
|  `skipHostnameVerification` デフォルトは false  |  `boolean`  |  TLS 接続のホスト名検証をスキップします。暗号化されていないクラスターには影響しません。デフォルトではホスト名検証が実行されます。これを True に設定すると検証がスキップされます。オフにすると接続先のクラスターを認証できなくなるため注意してください。  | 
|  `unhealthyConsecutiveErrorCount` デフォルトは 5  |  `number`  | エラーが何回連続で発生したらヘルスチェック間隔内でノードの異常を通知するかを設定します。  | 
|  `clusterUpdateInterval` デフォルトは 4000 ミリ秒  |  `number`  | メンバーシップ変更についてクラスターメンバーをポーリングする間隔を返します。  | 
|  `clusterUpdateThreshold` デフォルトは 125  |  `number`  | メンバーシップ変更についてクラスターがポーリングされない下限しきい値を返します。  | 
|  `credentailProvider` 省略可 \$1 デフォルトは null  |  `[AwsCredentialIdentityProvider](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)`  | DAX へのリクエストを認証するために使用される AWS 認証情報のユーザー定義プロバイダー。  | 


**DaxDocument のページ分割構成**  

| 名前 | 型 | 詳細 | 
| --- | --- | --- | 
|  `client`  |  DaxDocument  |  DaxDocument タイプのインスタンス。  | 
|  `pageSize`  |  数値  |  ページごとの項目数を指定します。  | 
|  `startingToken` オプションです。  |  すべて  |  前のレスポンスの LastEvaluatedKey を後続のリクエストに使用できます。  | 

ページ分割の使用については、「[TryDax.js](DAX.client.tutorial-TryDax.md)」を参照してください。

# DAX Node.js SDK V3 への移行
<a name="DAX.client.run-application-nodejs-3-migrating"></a>

この移行ガイドは、既存の DAX Node.js アプリケーションの移行に役立ちます。新しい SDK には Node.js 18 以降が必要で、DynamoDB Accelerator コードの作成方法にいくつかの重要な変更が導入されています。このガイドでは、構文の変更、新しいインポート方法、更新された非同期プログラミングパターンなど、主な違いについて説明します。

## V2 Node.js DAX の使用方法
<a name="DAX.client.run-application-nodejs-3-migrating-V2-usage"></a>

```
const AmazonDaxClient = require('amazon-dax-client');
const AWS = require('aws-sdk');

var region = "us-west-2";

AWS.config.update({
  region: region,
});

var client = new AWS.DynamoDB.DocumentClient();

if (process.argv.length > 2) {
  var dax = new AmazonDaxClient({
    endpoints: [process.argv[2]],
    region: region,
  });
  client = new AWS.DynamoDB.DocumentClient({ service: dax });
}

// Make Get Call using Dax
var params = {
    TableName: 'TryDaxTable',
    pk: 1,
    sk: 1
}
client.get(params, function (err, data) {
    if (err) {
        console.error(
            "Unable to read item. Error JSON:",
            JSON.stringify(err, null, 2)
          );
    } else {
        console.log(data);
    }
});
```

## V3 Node.js DAX の使用方法
<a name="DAX.client.run-application-nodejs-3-migrating-V3-dax-usage"></a>

DAX Node.js V3 ノードバージョン 18 以降を使用することをお勧めします。ノード 18 に移行するには以下を使用します。

```
import { DaxDocument } from '@amazon-dax-sdk/lib-dax';
import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

let client: DynamoDBDocument | DaxDocument = DynamoDBDocument.from(
  new DynamoDBClient({ region: 'us-west-2' })
);

if (process.argv.length > 2) {
  client = new DaxDocument({
    endpoints: [process.argv[2]],
    region: 'us-west-2',
  });
}

const params = {
  TableName: 'TryDaxTable',
  Key: { pk: 1, sk: 1 },
};

try {
  const results = await client.get(params);
  console.log(results);
} catch (err) {
  console.error(err);
}
```

DAX SDK for Node.js v3.x は [AWS SDK for Node.js v3.x](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) と互換性があります。DAX SDK for Node.js v3.x では[集約](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts)クライアントの使用をサポートしています。DAX では必要最低限のクライアントの作成をサポートしていないことに注意してください。サポートされていない機能の詳細については、「[AWS SDK V3 と同等のものがない機能](#DAX.client.run-application-nodejs-3-not-in-parity)」を参照してください。

このステップに従って、Amazon EC2 インスタンスで Node.js サンプルアプリケーションを実行します。

**DAX の Node.js サンプルを実行するには**

1. 以下のように、Amazon EC2 インスタンスで Node.js を設定します。

   1. ノードバージョンマネージャー (`nvm`) をインストールします。

      ```
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
      ```

   1. nvm を使用して Node.js をインストールします。

      ```
      nvm install 18
      ```

   1. nvm を使用して Node 18 を使用する

      ```
      nvm use 18
      ```

   1. Node.js が正しくインストールおよび実行されているかテストします。

      ```
      node -e "console.log('Running Node.js ' + process.version)"
      ```

      これにより次のメッセージが表示されるはずです。

      `Running Node.js v18.x.x`

1. ノードパッケージマネージャー (`npm`) を使用して、DaxDocument Node.js クライアントをインストールします。

   ```
   npm install @amazon-dax-sdk/lib-dax
   ```

## TryDax サンプルコード
<a name="DAX.client.run-application-nodejs-3-TryDax-sample-code"></a>

DynamoDB Accelerator (DAX) のパフォーマンス上の利点を評価するには、以下の手順に従って、標準の DynamoDB クラスターと DAX クラスター間の読み取り操作時間を比較するサンプルテストを実行します。

1. ワークスペースを設定し、`lib-dax` を依存関係としてインストールしたら、[TryDax.js](DAX.client.tutorial-TryDax.md) をプロジェクトにコピーします。

1. 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"
     }
     ```

1. 次に、クラスターエンドポイントをコマンドラインパラメータとして指定してプログラムを実行します。

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

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

   ```
   Attempting to create table; please wait...
   Successfully created table. Table status: ACTIVE
   Writing data to the table...
   Writing 20 items for partition key:  1
   Writing 20 items for partition key:  2
   Writing 20 items for partition key:  3
   ...
   Running GetItem Test
           Total time: 153555.10 µs - Avg time: 383.89 µs
           Total time: 44679.96 µs - Avg time: 111.70 µs
           Total time: 36885.86 µs - Avg time: 92.21 µs
           Total time: 32467.25 µs - Avg time: 81.17 µs
           Total time: 32202.60 µs - Avg time: 80.51 µs
   Running Query Test
           Total time: 14869.25 µs - Avg time: 2973.85 µs
           Total time: 3036.31 µs - Avg time: 607.26 µs
           Total time: 2468.92 µs - Avg time: 493.78 µs
           Total time: 2062.53 µs - Avg time: 412.51 µs
           Total time: 2178.22 µs - Avg time: 435.64 µs
   Running Scan Test
           Total time: 2395.88 µs - Avg time: 479.18 µs
           Total time: 2207.16 µs - Avg time: 441.43 µs
           Total time: 2443.14 µs - Avg time: 488.63 µs
           Total time: 2038.24 µs - Avg time: 407.65 µs
           Total time: 1972.17 µs - Avg time: 394.43 µs
   Running Pagination Test
   Scan Pagination
   [
     { pk: 1, sk: 1, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 2, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 3, someData: 'XXXXXXXXXX' }
   ]
   [
     { pk: 1, sk: 4, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 5, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 6, someData: 'XXXXXXXXXX' }
   ]
   ...
   Query Pagination
   [
     { pk: 1, sk: 1, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 2, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 3, someData: 'XXXXXXXXXX' }
   ]
   [
     { pk: 1, sk: 4, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 5, someData: 'XXXXXXXXXX' },
     { pk: 1, sk: 6, someData: 'XXXXXXXXXX' }
   ]
   ...
   Attempting to delete table; please wait...
   Successfully deleted table.
   ```

   タイミング情報を書き留めます。`GetItem`、`Query`、`Scan` の各テストに必要なマイクロ秒数。

1. このケースでは、DAX クラスターに対してプログラムを実行しました。次に、プログラムを再度実行します。今回は DynamoDB に対して実行します。

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

   ```
   node TryDax.js
   ```

   出力を見て、タイミング情報を書き留めます。`GetItem`、`Query` および `Scan` の経過時間は、DynamoDB と比較して DAX の方が大幅に低いはずです。

## AWS SDK V3 と同等のものがない機能
<a name="DAX.client.run-application-nodejs-3-not-in-parity"></a>
+ [必要最低限の](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts)クライアント – Dax Node.js V3 では必要最低限のクライアントをサポートしていません。

  ```
  const dynamoDBClient = new DynamoDBClient({ region: 'us-west-2' });
  const regularParams = {
      TableName: 'TryDaxTable',
      Key: {
          pk: 1,
          sk: 1
      }
  };
  // The DynamoDB client supports the send operation.
  const dynamoResult = await dynamoDBClient.send(new GetCommand(regularParams));
  
  // However, the DaxDocument client does not support the send operation.
  const daxClient = new DaxDocument({
      endpoints: ['your-dax-endpoint'],
      region: 'us-west-2',
  });
  
  const params = {
      TableName: 'TryDaxTable',
      Key: {
          pk: 1,
          sk: 1
      }
  };
  
  // This will throw an error - send operation is not supported for DAX. Please refer to documentation.
  const result = await daxClient.send(new GetCommand(params));
  console.log(result);
  ```
+ [ミドルウェアスタック](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/) – Dax Node.js V3 ではミドルウェア関数の使用をサポートしていません。

  ```
  const dynamoDBClient = new DynamoDBClient({ region: 'us-west-2' });
  // The DynamoDB client supports the middlewareStack.
  dynamoDBClient.middlewareStack.add(
    (next, context) =>> async (args) => {
      console.log("Before operation:", args);
      const result = await next(args);
      console.log("After operation:", result);
      return result;
    },
    {
      step: "initialize", // or "build", "finalizeRequest", "deserialize"
      name: "loggingMiddleware",
    }
  );
  
  // However, the DaxDocument client does not support the middlewareStack.
  const daxClient = new DaxDocument({
      endpoints: ['your-dax-endpoint'],
      region: 'us-west-2',
  });
  
  // This will throw an error - custom middleware and middlewareStacks are not supported for DAX. Please refer to documentation.
  daxClient.middlewareStack.add(
    (next, context) => async (args) => {
      console.log("Before operation:", args);
      const result = await next(args);
      console.log("After operation:", result);
      return result;
    },
    {
      step: "initialize", // or "build", "finalizeRequest", "deserialize"
      name: "loggingMiddleware",
    }
  );
  ```

# TryDax.js
<a name="DAX.client.tutorial-TryDax"></a>

```
import { DynamoDB, waitUntilTableExists, waitUntilTableNotExists } from "@aws-sdk/client-dynamodb";
import { DaxDocument, daxPaginateScan, daxPaginateQuery } from "@amazon-dax-sdk/lib-dax";
import { DynamoDBDocument, paginateQuery, paginateScan } from "@aws-sdk/lib-dynamodb";

const region = "us-east-1";
const tableName = "TryDaxTable";

// Determine the client (DynamoDB or DAX)
let client = DynamoDBDocument.from(new DynamoDB({ region }));
if (process.argv.length > 2) {
  client = new DaxDocument({ region, endpoint: process.argv[2] });
}

// Function to create table
async function createTable() {
  const dynamodb = new DynamoDB({ region });
  const params = {
    TableName: tableName,
    KeySchema: [
      { AttributeName: "pk", KeyType: "HASH" },
      { AttributeName: "sk", KeyType: "RANGE" },
    ],
    AttributeDefinitions: [
      { AttributeName: "pk", AttributeType: "N" },
      { AttributeName: "sk", AttributeType: "N" },
    ],
    ProvisionedThroughput: { ReadCapacityUnits: 25, WriteCapacityUnits: 25 },
  };

  try {
    console.log("Attempting to create table; please wait...");
    await dynamodb.createTable(params);
    await waitUntilTableExists({ client: dynamodb, maxWaitTime: 30 }, { TableName: tableName });
    console.log("Successfully created table. Table status: ACTIVE");
  } catch (err) {
    console.error("Error in table creation:", err);
  }
}

// Function to insert data
async function writeData() {
  console.log("Writing data to the table...");
  const someData = "X".repeat(10);
  for (let ipk = 1; ipk <= 20; ipk++) {
    console.log("Writing 20 items for partition key: ", ipk)
    for (let isk = 1; isk <= 20; isk++) {
      try {
        await client.put({ TableName: tableName, Item: { pk: ipk, sk: isk, someData } });
      } catch (err) {
        console.error("Error inserting data:", err);
      }
    }
  }
}

// Function to test GetItem
async function getItemTest() {
  console.log("Running GetItem Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let ipk = 1; ipk <= 20; ipk++) {
      for (let isk = 1; isk <= 20; isk++) {
        promises.push(client.get({ TableName: tableName, Key: { pk: ipk, sk: isk } }));
      }
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 400).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Query
async function queryTest() {
  console.log("Running Query Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let pk = 1; pk <= 5; pk++) {
      const params = {
        TableName: tableName,
        KeyConditionExpression: "pk = :pkval and sk between :skval1 and :skval2",
        ExpressionAttributeValues: { ":pkval": pk, ":skval1": 1, ":skval2": 2 },
      };
      promises.push(client.query(params));
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 5).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Scan
async function scanTest() {
  console.log("Running Scan Test");
  for (let i = 0; i < 5; i++) {
    const startTime = performance.now();
    const promises = [];
    for (let pk = 1; pk <= 5; pk++) {
      const params = {
        TableName: tableName,
        FilterExpression: "pk = :pkval and sk between :skval1 and :skval2",
        ExpressionAttributeValues: { ":pkval": pk, ":skval1": 1, ":skval2": 2 },
      };
      promises.push(client.scan(params));
    }
    await Promise.all(promises);
    const endTime = performance.now();
    const iterTime = (endTime - startTime) * 1000;
    const totalTime = iterTime.toFixed(2).padStart(3, ' ');
    const avgTime = (iterTime / 5).toFixed(2).padStart(3, ' ');
    console.log(`\tTotal time: ${totalTime} \u00B5s - Avg time: ${avgTime} \u00B5s`);
  }
}

// Function to test Pagination
async function paginationTest() {
  console.log("Running Pagination Test");
  console.log("Scan Pagination");
  const scanParams = { TableName: tableName };
  const paginator = process.argv.length > 2 ? daxPaginateScan : paginateScan;
  for await (const page of paginator({ client, pageSize: 3 }, scanParams)) {
    console.log(page.Items);
  }

  console.log("Query Pagination");
  const queryParams = {
    TableName: tableName,
    KeyConditionExpression: "pk = :pkval and sk between :skval1 and :skval2",
    ExpressionAttributeValues: { ":pkval": 1, ":skval1": 1, ":skval2": 10 },
  };
  const queryPaginator = process.argv.length > 2 ? daxPaginateQuery : paginateQuery;
  for await (const page of queryPaginator({ client, pageSize: 3 }, queryParams)) {
    console.log(page.Items);
  }
}

// Function to delete the table
async function deleteTable() {
  const dynamodb = new DynamoDB({ region });
  console.log("Attempting to delete table; please wait...")
  try {
    await dynamodb.deleteTable({ TableName: tableName });
    await waitUntilTableNotExists({ client: dynamodb, maxWaitTime: 30 }, { TableName: tableName });
    console.log("Successfully deleted table.");
  } catch (err) {
    console.error("Error deleting table:", err);
  }
}

// Execute functions sequentially
(async function () {
  await createTable();
  await writeData();
  await getItemTest();
  await queryTest();
  await scanTest();
  await paginationTest();
  await deleteTable();
})();
```

# DAX SDK for Go
<a name="DAX.client.run-application-go-2"></a>

この手順に従って、Amazon EC2 インスタンスで Go 対応 Amazon DynamoDB Accelerator (DAX) SDK for Go サンプルアプリケーションを実行します。

**DAX の SDK for Go サンプルを実行するには**

1. Amazon EC2 インスタンスで SDK for Go をセットアップします。

   1. Go プログラミング言語をインストール (`Golang`) します。

      ```
      sudo yum install -y golang
      ```

   1. Golang が正しくインストールおよび実行されているかテストします。

      ```
      go version
      ```

      次のようなメッセージが表示されます。

      ```
      go version go1.23.4 linux/amd64
      ```

1. サンプル Golang アプリケーションをインストールします。

   ```
   go get github.com/aws-samples/sample-aws-dax-go-v2
   ```

1. 以下の Golang プログラムを実行します。最初のプログラムは、`TryDaxGoTable` という DynamoDB テーブルを作成します。2 番目のプログラムは、テーブルにデータを書き込みます。

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command create-table
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command put-item
   ```

1. 以下の Golang プログラムを実行します。

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command get-item
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command query
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command scan
   ```

   タイミング情報を書き留めます。これは `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"
     }
     ```

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

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command get-item -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command query -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command scan -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-scan -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-query -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dax -command paginated-batch-get -endpoint my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com:8111
   ```

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

1. 次の Golang プログラムを実行して `TryDaxGoTable` を削除します。

   ```
   go run ~/go/pkg/mod/github.com/aws-samples/sample-aws-dax-go-v2@v1.0.0/try_dax.go -service dynamodb -command delete-table
   ```

## AWS SDK for Go V2 と同等のものがない機能
<a name="DAX.client.run-application-go-features-not-in-parity"></a>

ミドルウェアスタック – DAX Go V2 では APIoptions を通じたミドルウェアスタックの使用をサポートしていません。詳細については、「[ミドルウェアを使用した AWS SDK for Go v2 クライアントリクエストのカスタマイズ](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/middleware.html#:~:text=You%20can%20customize%20AWS%20SDK,step's%20input%20and%20output%20types)」を参照してください。

例:

```
// Custom middleware implementation
type customSerializeMiddleware struct{}
// ID returns the identifier for the middleware
func (m *customSerializeMiddleware) ID() string {
    return "CustomMiddleware"
}
// HandleSerialize implements the serialize middleware handler
func (m *customSerializeMiddleware) HandleSerialize(
    ctx context.Context,
    in middleware.SerializeInput,
    next middleware.SerializeHandler,
) (
    out middleware.SerializeOutput,
    metadata middleware.Metadata,
    err error,
) {
    // Add your custom logic here before the request is serialized
    fmt.Printf("Executing custom middleware for request: %v\n", in)
    // Call the next handler in the middleware chain
    return next.HandleSerialize(ctx, in)
}

func executeGetItem(ctx context.Context) error {
    client, err := initItemClient(ctx)
    if err != nil {
        os.Stderr.WriteString(fmt.Sprintf("failed to initialize client: %v\n", err))
        return err
    }

    st := time.Now()
    for c := 0; c < iterations; c++ {
        for i := 0; i < pkMax; i++ {
            for j := 0; j < skMax; j++ {
                // Create key using attributevalue.Marshal for type safety
                pk, err := attributevalue.Marshal(fmt.Sprintf("%s_%d", keyPrefix, i))
                if err != nil {
                    return fmt.Errorf("error marshaling pk: %v", err)
                }
                sk, err := attributevalue.Marshal(fmt.Sprintf("%d", j))
                if err != nil {
                    return fmt.Errorf("error marshaling sk: %v", err)
                }
                key := map[string]types.AttributeValue{
                    "pk": pk,
                    "sk": sk,
                }
                in := &dynamodb.GetItemInput{
                    TableName: aws.String(table),
                    Key:       key,
                }

                // Custom middleware option
                customMiddleware := func(o *dynamodb.Options) {
                    o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
                        // Add custom middleware to the stack
                        return stack.Serialize.Add(&customSerializeMiddleware{}, middleware.After)
                    })
                }

                // Apply options to the GetItem call
                out, err := client.GetItem(ctx, in, customMiddleware)
                if err != nil {
                    return err
                }
                writeVerbose(out)
            }
        }
    }
    d := time.Since(st)
    os.Stdout.WriteString(fmt.Sprintf("Total Time: %v, Avg Time: %v\n", d, d/iterations))
    return nil
}
```

出力:

```
failed to execute command: custom middleware through APIOptions is not supported in DAX client
exit status 1
```

# Go のデフォルトのクライアント構成
<a name="DAX-client-config-Go"></a>

このガイドでは、DAX クライアントのパフォーマンス、接続管理、ログ記録の動作を微調整できる構成オプションについて説明します。デフォルト設定とそれをカスタマイズする方法を理解することで、Go アプリケーションと DAX とのやり取りを最適化できます。

**Topics**
+ [DAX Go SDK クライアントのデフォルト](#DAX-client-config-Go-sdk-client-defaults)
+ [クライアント作成](#DAX-client-config-Go-client-creation)

## DAX Go SDK クライアントのデフォルト
<a name="DAX-client-config-Go-sdk-client-defaults"></a>


| パラメータ | Type | 説明 | 
| --- | --- | --- | 
|  `Region` 必須  |  `string`  |  DAX クライアントに使用する AWS リージョン (例 - 'us-east-1')。環境を介して指定されていない場合は必須のパラメータとなります。  | 
|  `HostPorts` 必須  |  `[] string`  |  SDK が接続する DAX クラスターエンドポイントのリスト。 例えば、次のようになります。 暗号化されていない場合 – dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com 暗号化されている場合 – daxs://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com  | 
|  `MaxPendingConnectionsPerHost` デフォルトは 10  |  `number`  | 連続接続試行の数 (複数の接続が同時に確立されている最中である場合があります)。  | 
|  `ClusterUpdateThreshold` デフォルトは 125 \$1 time.Millisecond  |  `time.Duration`  | あるクラスター更新から次のクラスター更新までの最小経過時間。  | 
|  `ClusterUpdateInterval` デフォルトは 4 \$1 time.Second  |  `time.Duration`  | クライアントが DAX クラスター情報を自動的に更新する間隔。  | 
|  `IdleConnectionsReapDelay` デフォルトは 30 \$1 time.Second  |  `time.Duration`  | クライアントが DAX クライアントのアイドル接続を閉じる間隔。  | 
|  `ClientHealthCheckInterval` デフォルトは 5 \$1 time.Second  |  `time.Duration`  | クライアントが DAX クラスターエンドポイントでヘルスチェックを実行する間隔。  | 
|  `Credentials` デフォルト  |  `aws.CredentialsProvider`  | DAX サービスへのリクエストを認証するために DAX クライアントが使用する AWS 認証情報。「[認証情報と認証情報プロバイダー](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/migrate-gosdk.html#credentials--credential-providers)」を参照してください。  | 
|  `DialContext` デフォルト  |  `func`  | DAX クラスターへの接続を確立するために DAX クライアントが使用するカスタム関数。  | 
|  `SkipHostnameVerification` デフォルトは false  |  ブール  |  TLS 接続のホスト名検証をスキップします。この設定は暗号化されたクラスターにのみ影響します。True に設定すると、ホスト名検証が無効になります。検証を無効にすると、接続先のクラスターの ID を認証できないため、セキュリティリスクが生じます。デフォルトではホスト名検証が有効になっています。  | 
|  `RouteManagerEnabled` デフォルトは false  |  `bool`  | このフラグは、ネットワークエラーに直面するルートを削除するために使用されます。  | 
|  `RequestTimeout` デフォルトは 60 \$1 time.Second  |  `time.Duration`  | クライアントが DAX からのレスポンスを待機する最大時間を定義します。 優先順位: コンテキストタイムアウト (設定されている場合) > `RequestTimmeout` (設定されている場合) > デフォルトの 60 秒の `RequestTimeout`。  | 
|  `WriteRetries` デフォルトは 2  |  `number`  |  書き込みリクエスト失敗時の再試行回数。  | 
|  `ReadRetries` デフォルトは 2  |  `number`  | 読み取りリクエスト失敗時の再試行回数。  | 
|  `RetryDelay` デフォルトは 0  |  `time.Duration`  | リクエストが失敗したときの再試行のスロットリングされていないエラーの遅延 (秒単位)。  | 
|  `Logger` オプション  |  `logging.Logger`  | ロガーは、特定の分類でエントリをログ記録するためのインターフェイスです。  | 
|  `LogLevel` デフォルトは utils.LogOff  |  `number`  | このログレベルは DAX に対してのみ定義されます。[github.com/aws/aws-dax-go-v2/tree/main/dax/utils](https://github.com/aws/aws-dax-go-v2/tree/main/dax/utils) を使用してインポートできます。 <pre>const (    <br /> LogOff LogLevelType = 0   <br /> LogDebug LogLevelType = 1   <br /> LogDebugWithRequestRetries<br /> LogLevelType = 2<br />)</pre>  | 

**注記**  
`time.Duration` の場合、デフォルトの単位はナノ秒です。どのパラメータにも単位を指定しない場合はナノ秒とみなされます。`daxCfg.ClusterUpdateInterval = 10` は 10 ナノ秒 (`daxCfg.ClusterUpdateInterval = 10 * time.Millisecond` は 10 ミリ秒) を意味します。

## クライアント作成
<a name="DAX-client-config-Go-client-creation"></a>

**DAX クラスターを作成するには:**
+ DAX 構成を作成してから、DAX 構成を使用して DAX クライアントを作成します。これを使用すると、必要に応じて DAX 構成を上書きできます。

  ```
  import (
  "github.com/aws/aws-dax-go-v2/dax/utils"
  "github.com/aws/aws-dax-go-v2/dax"
  )
  
  // Non - Encrypted : 'dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com'.
  // Encrypted : daxs://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com'.
  
  config := dax.DefaultConfig()
  config.HostPorts = []string{endpoint}
  config.Region = region
  config.LogLevel = utils.LogDebug
  daxClient, err := dax.New(config)
  ```

# DAX Go SDK V2 への移行
<a name="DAX.client.run-application-go-migrating"></a>

この移行ガイドは、既存の DAX Go アプリケーションの移行に役立ちます。

## V1 DAX Go SDK の使用方法
<a name="DAX.client.run-application-go-V1-usage"></a>

```
package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-dax-go/dax"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
)

func main() {
    region := "us-west-2"
    endpoint := "dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com"
    
    // Create session
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String(region),
    })
    if err != nil {
        fmt.Printf("Failed to create session: %v\n", err)
        os.Exit(1)
    }
    
    // Configure DAX client
    cfg := dax.DefaultConfig()
    cfg.HostPorts = []string{endpoint} 
    cfg.Region = region

    // Create DAX client
    daxClient, err := dax.New(cfg)
    if err != nil {
        fmt.Printf("Failed to create DAX client: %v\n", err)
        os.Exit(1)
    }
    defer daxClient.Close() // Don't forget to close the client

    // Create GetItem input
    input := &dynamodb.GetItemInput{
        TableName: aws.String("TryDaxTable"),
        Key: map[string]*dynamodb.AttributeValue{
            "pk": {
                N: aws.String("1"),
            },
            "sk": {
                N: aws.String("1"),
            },
        },
    }

    // Make the GetItem call
    result, err := daxClient.GetItem(input)
    if err != nil {
        fmt.Printf("Failed to get item: %v\n", err)
        os.Exit(1)
    }

    // Print the result
    fmt.Printf("GetItem succeeded: %+v\n", result)
}
```

## V2 DAX Go SDK の使用方法
<a name="DAX.client.run-application-go-V2-usage"></a>

```
package main

import (
    "context"
    "fmt"
    "os"

    "github.com/aws/aws-dax-go-v2/dax"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    ctx := context.Background()
    region := "us-west-2"
    endpoint := "dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com"
   
    // Create DAX config
    config := dax.DefaultConfig()
    // Specify Endpoint and Region
    config.HostPorts = []string{endpoint}
    config.Region = region
    // Enabling logging
    config.LogLevel = utils.LogDebug
    // Create DAX client
    daxClient, err := dax.New(config) 
    if err != nil {
        fmt.Printf("Failed to create DAX client: %v\n", err)
        os.Exit(1)
    }
    defer daxClient.Close() // Don't forget to close the client

    // Create key using attributevalue.Marshal for type safety
    pk, err := attributevalue.Marshal(fmt.Sprintf("%s_%d", keyPrefix, i))
    if err != nil {
        return fmt.Errorf("error marshaling pk: %v", err)
    }
    sk, err := attributevalue.Marshal(fmt.Sprintf("%d", j))
    if err != nil {
        return fmt.Errorf("error marshaling sk: %v", err)
    }
                
    // Create GetItem input
    input := &dynamodb.GetItemInput{
        TableName: aws.String("TryDaxTable"),
        Key: map[string]types.AttributeValue{
             "pk": pk,
             "sk": sk,
        },
    }

    // Make the GetItem call
    result, err := daxClient.GetItem(ctx, input)
    if err != nil {
        fmt.Printf("Failed to get item: %v\n", err)
        os.Exit(1)
    }

    // Print the result
    fmt.Printf("GetItem succeeded: %+v\n", result)
}
```

API の使用方法の詳細については、[AWS のサンプル](https://github.com/aws-samples/sample-aws-dax-go-v2)を参照してください。

# Java および DAX
<a name="DAX.client.run-application-java"></a>

DAX SDK for Java 2.x は [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/) と互換性があります。Java 8 以降をベースに構築されており、非ブロック I/O がサポートされています。AWS SDK for Java 1.x での DAX の使用については、「[DAX を AWS SDK for Java 1.x で使用する](DAX.client.java-sdk-v1.md)」を参照してください。

## クライアントを Maven 依存関係として使用する
<a name="DAX.client.run-application-java.maven"></a>

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

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* を クライアントの実際のバージョン番号に置き換えます。

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

## TryDax サンプルコード
<a name="DAX.client.run-application-java.sample"></a>

ワークスペースを設定し、DAX SDK を依存関係として追加したら、[TryDax.java](DAX.client.TryDax.java.md) をプロジェクトに追加します。

このコマンドを使用してコードを実行します。

```
java -cp classpath 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
...

Running GetItem and Query tests...
First iteration of each test will result in cache misses
Next iterations are cache hits

GetItem test - partition key 1-100 and sort keys 1-10
  Total time: 4390.240 ms - Avg time: 4.390 ms
  Total time: 3097.089 ms - Avg time: 3.097 ms
  Total time: 3273.463 ms - Avg time: 3.273 ms
  Total time: 3353.739 ms - Avg time: 3.354 ms
  Total time: 3533.314 ms - Avg time: 3.533 ms
Query test - partition key 1-100 and sort keys between 2 and 9
  Total time: 475.868 ms - Avg time: 4.759 ms
  Total time: 423.333 ms - Avg time: 4.233 ms
  Total time: 460.271 ms - Avg time: 4.603 ms
  Total time: 397.859 ms - Avg time: 3.979 ms
  Total time: 466.644 ms - Avg time: 4.666 ms

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

タイミング情報を書き留めます。これは、`GetItem` および `Query` テストに必要なミリ秒の数字です。このケースでは、DynamoDB エンドポイントに対してプログラムを実行しました。次に、プログラムを再度実行します。今回は DAX クラスターに対して実行します。

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

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

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

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

  ```
  {
      "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"
  }
  ```

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

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

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

## SDK のメトリクス
<a name="DAX.client.run-application-java.metrics"></a>

DAX SDK for Java 2.x を使用すると、アプリケーションのサービスクライアントに関するメトリクスを収集し、Amazon CloudWatch で出力を分析できます。詳細については、「[メトリクスを有効にする](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html)」を参照してください。

**注記**  
DAX SDK for Java は `ApiCallSuccessful` および `ApiCallDuration` メトリクスのみを収集します。

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

```
import java.util.Map;

import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.BillingMode;
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
import software.amazon.awssdk.services.dynamodb.model.KeyType;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
import software.amazon.dax.ClusterDaxAsyncClient;
import software.amazon.dax.Configuration;

public class TryDax {
    public static void main(String[] args) throws Exception {
        DynamoDbAsyncClient ddbClient = DynamoDbAsyncClient.builder()
                .build();

        DynamoDbAsyncClient daxClient = null;
        if (args.length >= 1) {
            daxClient = ClusterDaxAsyncClient.builder()
                    .overrideConfiguration(Configuration.builder()
                            .url(args[0]) // e.g. dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
                            .build())
                    .build();
        }

        String tableName = "TryDaxTable";

        System.out.println("Creating table...");
        createTable(tableName, ddbClient);

        System.out.println("Populating table...");
        writeData(tableName, ddbClient, 100, 10);

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

        System.out.println("Running GetItem 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
        getItemTest(tableName, testClient, 100, 10, 5);

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

        System.out.println("Deleting table...");
        deleteTable(tableName, ddbClient);
    }

    private static void createTable(String tableName, DynamoDbAsyncClient client) {
        try {
            System.out.println("Attempting to create table; please wait...");

            client.createTable(CreateTableRequest.builder()
                    .tableName(tableName)
                    .keySchema(KeySchemaElement.builder()
                            .keyType(KeyType.HASH)
                            .attributeName("pk")
                            .build(), KeySchemaElement.builder()
                            .keyType(KeyType.RANGE)
                            .attributeName("sk")
                            .build())
                    .attributeDefinitions(AttributeDefinition.builder()
                            .attributeName("pk")
                            .attributeType(ScalarAttributeType.N)
                            .build(), AttributeDefinition.builder()
                            .attributeName("sk")
                            .attributeType(ScalarAttributeType.N)
                            .build())
                    .billingMode(BillingMode.PAY_PER_REQUEST)
                    .build()).get();
            client.waiter().waitUntilTableExists(DescribeTableRequest.builder()
                    .tableName(tableName)
                    .build()).get();
            System.out.println("Successfully created table.");

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

    private static void deleteTable(String tableName, DynamoDbAsyncClient client) {
        try {
            System.out.println("\nAttempting to delete table; please wait...");
            client.deleteTable(DeleteTableRequest.builder()
                    .tableName(tableName)
                    .build()).get();
            client.waiter().waitUntilTableNotExists(DescribeTableRequest.builder()
                    .tableName(tableName)
                    .build()).get();
            System.out.println("Successfully deleted table.");

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

    private static void writeData(String tableName, DynamoDbAsyncClient client, int pkmax, int skmax) {
        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 (int ipk = 1; ipk <= pkmax; ipk++) {
                System.out.println(("Writing " + skmax + " items for partition key: " + ipk));
                for (int isk = 1; isk <= skmax; isk++) {
                    client.putItem(PutItemRequest.builder()
                            .tableName(tableName)
                            .item(Map.of("pk", attr(ipk), "sk", attr(isk), "someData", attr(someData)))
                            .build()).get();
                }
            }
        } catch (Exception e) {
            System.err.println("Unable to write item:");
            e.printStackTrace();
        }
    }

    private static AttributeValue attr(int n) {
        return AttributeValue.builder().n(String.valueOf(n)).build();
    }

    private static AttributeValue attr(String s) {
        return AttributeValue.builder().s(s).build();
    }

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

        for (int i = 0; i < iterations; i++) {
            startTime = System.nanoTime();
            try {
                for (int ipk = 1; ipk <= pk; ipk++) {
                    for (int isk = 1; isk <= sk; isk++) {
                        client.getItem(GetItemRequest.builder()
                                .tableName(tableName)
                                .key(Map.of("pk", attr(ipk), "sk", attr(isk)))
                                .build()).get();
                    }
                }
            } catch (Exception e) {
                System.err.println("Unable to get item:");
                e.printStackTrace();
            }
            endTime = System.nanoTime();
            printTime(startTime, endTime, pk * sk);
        }
    }

    private static void queryTest(String tableName, DynamoDbAsyncClient client, int pk, int sk1, int sk2, int iterations) {
        long startTime, endTime;
        System.out.println("Query test - partition key 1-" + pk + " and sort keys between " + sk1 + " and " + sk2);

        for (int i = 0; i < iterations; i++) {
            startTime = System.nanoTime();
            for (int ipk = 1; ipk <= pk; ipk++) {
                try {
                    // Pagination API for Query.
                    client.queryPaginator(QueryRequest.builder()
                            .tableName(tableName)
                            .keyConditionExpression("pk = :pkval and sk between :skval1 and :skval2")
                            .expressionAttributeValues(Map.of(":pkval", attr(ipk), ":skval1", attr(sk1), ":skval2", attr(sk2)))
                            .build()).items().subscribe((item) -> {
                    }).get();
                } catch (Exception e) {
                    System.err.println("Unable to query table:");
                    e.printStackTrace();
                }
            }
            endTime = System.nanoTime();
            printTime(startTime, endTime, pk);
        }
    }

    private static 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));
    }
}
```

# .NET および DAX
<a name="DAX.client.run-application-dotnet"></a>

次のステップに従って、Amazon EC2 インスタンスで .NET サンプルを実行します。

**注記**  
このチュートリアルでは .NET 9 SDK を使用します。ここでは、デフォルト Amazon VPC のプログラムを実行して、Amazon DynamoDB Accelerator (DAX) クラスターにアクセスする方法を示しています。[AWS SDK v4 for .NET](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html) で動作します。V4 の変更と移行に関する詳細については、「[AWS SDK for .NET のバージョン 4 への移行](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)」を参照してください。必要に応じて、AWS Toolkit for Visual Studio を使用して .NET アプリケーションを記述し、VPC 内にデプロイできます。  
詳細については、「*AWS Elastic Beanstalk デベロッパーガイド*」の「[AWS Toolkit for Visual Studio を使用した .NET での Elastic Beanstalk アプリケーションの作成とデプロイ](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_NET.html)」を参照してください。

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

1. [Microsoft ダウンロードページ](https://www.microsoft.com/net/download?initial-os=linux) にアクセスし、最新の .NET 9 SDK for Linux をダウンロードします。ダウンロードされたファイルは、`dotnet-sdk-N.N.N-linux-x64.tar.gz` です。

1. SDK ファイルを展開します。

   ```
   mkdir dotnet
   tar zxvf dotnet-sdk-N.N.N-linux-x64.tar.gz -C dotnet
   ```

   `N.N.N` を .NET SDK の実際のバージョン番号 (例: `9.0.305`) で置き換えます。

1. インストールを確認します。

   ```
   alias dotnet=$HOME/dotnet/dotnet
   dotnet --version
   ```

   これにより、.NET SDK のバージョン番号が表示されます。
**注記**  
バージョン番号ではなく、以下のエラーが表示される場合があります。  
error: libunwind.so.8: 共有オブジェクトファイルを開けません: そのようなファイルまたはディレクトリは存在しません  
このエラーを解決するには、`libunwind` パッケージをインストールします。  

   ```
   sudo yum install -y libunwind
   ```
この操作を行うと、`dotnet --version` コマンドがエラーなしで実行されます。

1. 新しい .NET プロジェクトを作成します。

   ```
   dotnet new console -o myApp 
   ```

   この 1 回限りの設定には数分かかります。設定が完了したら、サンプルプロジェクトを実行します。

   ```
   dotnet run --project myApp
   ```

   `Hello World!` というメッセージが表示されます。

1. `myApp/myApp.csproj` ファイルにはプロジェクトに関するメタデータが含まれています。アプリケーションで DAX クライアントを使用するには、このファイルを次のように変更します。

   ```
   <Project Sdk="Microsoft.NET.Sdk">
       <PropertyGroup>
           <OutputType>Exe</OutputType>
           <TargetFramework>net9.0</TargetFramework>
       </PropertyGroup>
       <ItemGroup>
           <PackageReference Include="AWSSDK.DAX.Client" Version="*" />
       </ItemGroup>
   </Project>
   ```

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

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

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

   ```
   unzip TryDax.zip
   ```

1. 次に、サンプルプログラム「*dotNet*」を一度に 1 つずつ実行します。プログラムごとにそのコンテンツを `myApp/Program.cs` 内にコピーし、`MyApp` プロジェクトを実行します。

   以下の .NET プログラムを実行します。最初のプログラムは、`TryDaxTable` という DynamoDB テーブルを作成します。2 番目のプログラムは、テーブルにデータを書き込みます。

   ```
   cp TryDax/dotNet/01-CreateTable.cs myApp/Program.cs
   dotnet run --project myApp
   
   cp TryDax/dotNet/02-Write-Data.cs myApp/Program.cs
   dotnet run --project myApp
   ```

1. 次に、いくつかのプログラムを実行し、`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"
     }
     ```

   次に、以下のプログラムを実行し、クラスターエンドポイントをコマンドラインパラメータとして指定します (サンプルのエンドポイントを実際の DAX クラスターエンドポイントに置き換えてください)。

   ```
   cp TryDax/dotNet/03-GetItem-Test.cs myApp/Program.cs
   dotnet run --project myApp dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   
   cp TryDax/dotNet/04-Query-Test.cs myApp/Program.cs
   dotnet run --project myApp dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
                           
   cp TryDax/dotNet/05-Scan-Test.cs myApp/Program.cs
   dotnet run --project myApp dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   ```

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

1. 次の .NET プログラムを実行し、`TryDaxTable` を削除します。

   ```
   cp TryDax/dotNet/06-DeleteTable.cs myApp/Program.cs
   dotnet run --project myApp
   ```

これらのプログラムの詳細については、以下のセクションを参照してください。
+ [01-CreateTable.cs](DAX.client.run-application-dotnet.01-CreateTable.md)
+ [02-Write-Data.cs](DAX.client.run-application-dotnet.02-Write-Data.md)
+ [03-GetItem-Test.cs](DAX.client.run-application-dotnet.03-GetItem-Test.md)
+ [04-Query-Test.cs](DAX.client.run-application-dotnet.04-Query-Test.md)
+ [05-Scan-Test.cs](DAX.client.run-application-dotnet.05-Scan-Test.md)
+ [06-DeleteTable.cs](DAX.client.run-application-dotnet.06-DeleteTable.md)

# 01-CreateTable.cs
<a name="DAX.client.run-application-dotnet.01-CreateTable"></a>

`01-CreateTable.cs` プログラムはテーブル (`TryDaxTable`) を作成します。このセクションの残りの .NET プログラムは、このテーブルに依存します。

```
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            AmazonDynamoDBClient client = new AmazonDynamoDBClient();

            var tableName = "TryDaxTable";

            var request = new CreateTableRequest()
            {
                TableName = tableName,
                KeySchema = new List<KeySchemaElement>()
                {
                    new KeySchemaElement{ AttributeName = "pk",KeyType = "HASH"},
                    new KeySchemaElement{ AttributeName = "sk",KeyType = "RANGE"}
                },
                AttributeDefinitions = new List<AttributeDefinition>() {
                    new AttributeDefinition{ AttributeName = "pk",AttributeType = "N"},
                    new AttributeDefinition{ AttributeName = "sk",AttributeType  = "N"}
                },
                ProvisionedThroughput = new ProvisionedThroughput()
                {
                    ReadCapacityUnits = 10,
                    WriteCapacityUnits = 10
                }
            };

            var response = await client.CreateTableAsync(request);

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# 02-Write-Data.cs
<a name="DAX.client.run-application-dotnet.02-Write-Data"></a>

`02-Write-Data.cs` プログラムはテストデータを `TryDaxTable` に書き込みます。

```
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            AmazonDynamoDBClient client = new AmazonDynamoDBClient();

            var tableName = "TryDaxTable";

            string someData = new string('X', 1000);
            var pkmax = 10;
            var skmax = 10;

            for (var ipk = 1; ipk <= pkmax; ipk++)
            {
                Console.WriteLine($"Writing {skmax} items for partition key: {ipk}");
                for (var isk = 1; isk <= skmax; isk++)
                {
                    var request = new PutItemRequest()
                    {
                        TableName = tableName,
                        Item = new Dictionary<string, AttributeValue>()
                       {
                            { "pk", new AttributeValue{N = ipk.ToString() } },
                            { "sk", new AttributeValue{N = isk.ToString() } },
                            { "someData", new AttributeValue{S = someData } }
                       }
                    };

                    var response = await client.PutItemAsync(request);
                }
            }

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# 03-GetItem-Test.cs
<a name="DAX.client.run-application-dotnet.03-GetItem-Test"></a>

`03-GetItem-Test.cs` プログラムは、`GetItem` で `TryDaxTable` オペレーションを実行します。

```
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.DAX;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            string endpointUri = args[0];
            Console.WriteLine($"Using DAX client - endpointUri={endpointUri}");

            var clientConfig = new DaxClientConfig(endpointUri)
            {
                AwsCredentials = FallbackCredentialsFactory.GetCredentials()
            };
            var client = new ClusterDaxClient(clientConfig);

            var tableName = "TryDaxTable";

            var pk = 1;
            var sk = 10;
            var iterations = 5;

            var startTime = System.DateTime.Now;

            for (var i = 0; i < iterations; i++)
            {
                for (var ipk = 1; ipk <= pk; ipk++)
                {
                    for (var isk = 1; isk <= sk; isk++)
                    {
                        var request = new GetItemRequest()
                        {
                            TableName = tableName,
                            Key = new Dictionary<string, AttributeValue>() {
                            {"pk", new AttributeValue {N = ipk.ToString()} },
                            {"sk", new AttributeValue {N = isk.ToString() } }
                        }
                        };
                        var response = await client.GetItemAsync(request);
                        Console.WriteLine($"GetItem succeeded for pk: {ipk},sk: {isk}");
                    }
                }
            }

            var endTime = DateTime.Now;
            TimeSpan timeSpan = endTime - startTime;
            Console.WriteLine($"Total time: {timeSpan.TotalMilliseconds} milliseconds");

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# 04-Query-Test.cs
<a name="DAX.client.run-application-dotnet.04-Query-Test"></a>

`04-Query-Test.cs` プログラムは、`Query` で `TryDaxTable` オペレーションを実行します。

```
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.DAX;
using Amazon.DynamoDBv2.Model;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            string endpointUri = args[0];
            Console.WriteLine($"Using DAX client - endpointUri={endpointUri}");


            var clientConfig = new DaxClientConfig(endpointUri)
            {
                AwsCredentials = FallbackCredentialsFactory.GetCredentials()
            };
            var client = new ClusterDaxClient(clientConfig);

            var tableName = "TryDaxTable";

            var pk = 5;
            var sk1 = 2;
            var sk2 = 9;
            var iterations = 5;

            var startTime = DateTime.Now;

            for (var i = 0; i < iterations; i++)
            {
                var request = new QueryRequest()
                {
                    TableName = tableName,
                    KeyConditionExpression = "pk = :pkval and sk between :skval1 and :skval2",
                    ExpressionAttributeValues = new Dictionary<string, AttributeValue>() {
                            {":pkval", new AttributeValue {N = pk.ToString()} },
                            {":skval1", new AttributeValue {N = sk1.ToString()} },
                            {":skval2", new AttributeValue {N = sk2.ToString()} }
                    }
                };
                var response = await client.QueryAsync(request);
                Console.WriteLine($"{i}: Query succeeded");

            }

            var endTime = DateTime.Now;
            TimeSpan timeSpan = endTime - startTime;
            Console.WriteLine($"Total time: {timeSpan.TotalMilliseconds} milliseconds");

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# 05-Scan-Test.cs
<a name="DAX.client.run-application-dotnet.05-Scan-Test"></a>

`05-Scan-Test.cs` プログラムは、`Scan` で `TryDaxTable` オペレーションを実行します。

```
using System;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.DAX;
using Amazon.DynamoDBv2.Model;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            string endpointUri = args[0];
            Console.WriteLine($"Using DAX client - endpointUri={endpointUri}");

            var clientConfig = new DaxClientConfig(endpointUri)
            {
                AwsCredentials = FallbackCredentialsFactory.GetCredentials()
            };
            var client = new ClusterDaxClient(clientConfig);

            var tableName = "TryDaxTable";

            var iterations = 5;

            var startTime = DateTime.Now;

            for (var i = 0; i < iterations; i++)
            {
                var request = new ScanRequest()
                {
                    TableName = tableName
                };
                var response = await client.ScanAsync(request);
                Console.WriteLine($"{i}: Scan succeeded");
            }

            var endTime = DateTime.Now;
            TimeSpan timeSpan = endTime - startTime;
            Console.WriteLine($"Total time: {timeSpan.TotalMilliseconds} milliseconds");

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# 06-DeleteTable.cs
<a name="DAX.client.run-application-dotnet.06-DeleteTable"></a>

`06-DeleteTable.cs` プログラムは `TryDaxTable` を削除します。テストが完了してから、このプログラムを実行します。

```
using System;
using System.Threading.Tasks;
using Amazon.DynamoDBv2.Model;
using Amazon.DynamoDBv2;

namespace ClientTest
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            AmazonDynamoDBClient client = new AmazonDynamoDBClient();

            var tableName = "TryDaxTable";

            var request = new DeleteTableRequest()
            {
                TableName = tableName
            };

            var response = await client.DeleteTableAsync(request);

            Console.WriteLine("Hit <enter> to continue...");
            Console.ReadLine();
        }
    }
}
```

# Python および DAX
<a name="DAX.client.run-application-python"></a>

この手順に従って、Amazon EC2 インスタンスで Python サンプルアプリケーションを実行します。

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

1. `pip` ユーティリティを使用して DAX Python クライアントをインストールします。

   ```
   pip install amazon-dax-client
   ```

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

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

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

   ```
   unzip TryDax.zip
   ```

1. 以下の Python プログラムを実行します。最初のプログラムは、`TryDaxTable` という Amazon DynamoDB テーブルを作成します。2 番目のプログラムは、テーブルにデータを書き込みます。

   ```
   python 01-create-table.py
   python 02-write-data.py
   ```

1. 以下の Python プログラムを実行します。

   ```
   python 03-getitem-test.py
   python 04-query-test.py
   python 05-scan-test.py
   ```

    タイミング情報を書き留めます。これは `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"
     }
     ```

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

   ```
   python 03-getitem-test.py dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   python 04-query-test.py dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   python 05-scan-test.py dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
   ```

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

1. 次の Python プログラムを実行して `TryDaxTable` を削除します。

   ```
   python 06-delete-table.py
   ```

これらのプログラムの詳細については、以下のセクションを参照してください。
+ [01-create-table.py](DAX.client.run-application-python.01-create-table.md)
+ [02-write-data.py](DAX.client.run-application-python.02-write-data.md)
+ [03-getitem-test.py](DAX.client.run-application-python.03-getitem-test.md)
+ [04-query-test.py](DAX.client.run-application-python.04-query-test.md)
+ [05-scan-test.py](DAX.client.run-application-python.05-scan-test.md)
+ [06-delete-table.py](DAX.client.run-application-python.06-delete-table.md)

# 01-create-table.py
<a name="DAX.client.run-application-python.01-create-table"></a>

`01-create-table.py` プログラムはテーブル (`TryDaxTable`) を作成します。このセクションの残りの Python プログラムは、このテーブルに依存します。

```
import boto3


def create_dax_table(dyn_resource=None):
    """
    Creates a DynamoDB table.

    :param dyn_resource: Either a Boto3 or DAX resource.
    :return: The newly created table.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource("dynamodb")

    table_name = "TryDaxTable"
    params = {
        "TableName": table_name,
        "KeySchema": [
            {"AttributeName": "partition_key", "KeyType": "HASH"},
            {"AttributeName": "sort_key", "KeyType": "RANGE"},
        ],
        "AttributeDefinitions": [
            {"AttributeName": "partition_key", "AttributeType": "N"},
            {"AttributeName": "sort_key", "AttributeType": "N"},
        ],
        "BillingMode": "PAY_PER_REQUEST",
    }
    table = dyn_resource.create_table(**params)
    print(f"Creating {table_name}...")
    table.wait_until_exists()
    return table


if __name__ == "__main__":
    dax_table = create_dax_table()
    print(f"Created table.")
```

# 02-write-data.py
<a name="DAX.client.run-application-python.02-write-data"></a>

`02-write-data.py` プログラムはテストデータを `TryDaxTable` に書き込みます。

```
import boto3


def write_data_to_dax_table(key_count, item_size, dyn_resource=None):
    """
    Writes test data to the demonstration table.

    :param key_count: The number of partition and sort keys to use to populate the
                      table. The total number of items is key_count * key_count.
    :param item_size: The size of non-key data for each test item.
    :param dyn_resource: Either a Boto3 or DAX resource.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource("dynamodb")

    table = dyn_resource.Table("TryDaxTable")
    some_data = "X" * item_size

    for partition_key in range(1, key_count + 1):
        for sort_key in range(1, key_count + 1):
            table.put_item(
                Item={
                    "partition_key": partition_key,
                    "sort_key": sort_key,
                    "some_data": some_data,
                }
            )
            print(f"Put item ({partition_key}, {sort_key}) succeeded.")


if __name__ == "__main__":
    write_key_count = 10
    write_item_size = 1000
    print(
        f"Writing {write_key_count*write_key_count} items to the table. "
        f"Each item is {write_item_size} characters."
    )
    write_data_to_dax_table(write_key_count, write_item_size)
```

# 03-getitem-test.py
<a name="DAX.client.run-application-python.03-getitem-test"></a>

`03-getitem-test.py` プログラムは、`GetItem` で `TryDaxTable` オペレーションを実行します。この例は、リージョン eu-west-1 の場合に使用できます。

```
import argparse
import sys
import time
import amazondax
import boto3


def get_item_test(key_count, iterations, dyn_resource=None):
    """
    Gets items from the table a specified number of times. The time before the
    first iteration and the time after the last iteration are both captured
    and reported.

    :param key_count: The number of items to get from the table in each iteration.
    :param iterations: The number of iterations to run.
    :param dyn_resource: Either a Boto3 or DAX resource.
    :return: The start and end times of the test.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource('dynamodb')

    table = dyn_resource.Table('TryDaxTable')
    start = time.perf_counter()
    for _ in range(iterations):
        for partition_key in range(1, key_count + 1):
            for sort_key in range(1, key_count + 1):
                table.get_item(Key={
                    'partition_key': partition_key,
                    'sort_key': sort_key
                })
                print('.', end='')
                sys.stdout.flush()
    print()
    end = time.perf_counter()
    return start, end


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'endpoint_url', nargs='?',
        help="When specified, the DAX cluster endpoint. Otherwise, DAX is not used.")
    args = parser.parse_args()

    test_key_count = 10
    test_iterations = 50
    if args.endpoint_url:
        print(f"Getting each item from the table {test_iterations} times, "
              f"using the DAX client.")
        # Use a with statement so the DAX client closes the cluster after completion.
        with amazondax.AmazonDaxClient.resource(endpoint_url=args.endpoint_url, region_name='eu-west-1') as dax:
            test_start, test_end = get_item_test(
                test_key_count, test_iterations, dyn_resource=dax)
    else:
        print(f"Getting each item from the table {test_iterations} times, "
              f"using the Boto3 client.")
        test_start, test_end = get_item_test(
            test_key_count, test_iterations)
    print(f"Total time: {test_end - test_start:.4f} sec. Average time: "
          f"{(test_end - test_start)/ test_iterations}.")
```

# 04-query-test.py
<a name="DAX.client.run-application-python.04-query-test"></a>

`04-query-test.py` プログラムは、`Query` で `TryDaxTable` オペレーションを実行します。

```
import argparse
import time
import sys
import amazondax
import boto3
from boto3.dynamodb.conditions import Key


def query_test(partition_key, sort_keys, iterations, dyn_resource=None):
    """
    Queries the table a specified number of times. The time before the
    first iteration and the time after the last iteration are both captured
    and reported.

    :param partition_key: The partition key value to use in the query. The query
                          returns items that have partition keys equal to this value.
    :param sort_keys: The range of sort key values for the query. The query returns
                      items that have sort key values between these two values.
    :param iterations: The number of iterations to run.
    :param dyn_resource: Either a Boto3 or DAX resource.
    :return: The start and end times of the test.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource("dynamodb")

    table = dyn_resource.Table("TryDaxTable")
    key_condition_expression = Key("partition_key").eq(partition_key) & Key(
        "sort_key"
    ).between(*sort_keys)

    start = time.perf_counter()
    for _ in range(iterations):
        table.query(KeyConditionExpression=key_condition_expression)
        print(".", end="")
        sys.stdout.flush()
    print()
    end = time.perf_counter()
    return start, end


if __name__ == "__main__":
    # pylint: disable=not-context-manager
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "endpoint_url",
        nargs="?",
        help="When specified, the DAX cluster endpoint. Otherwise, DAX is not used.",
    )
    args = parser.parse_args()

    test_partition_key = 5
    test_sort_keys = (2, 9)
    test_iterations = 100
    if args.endpoint_url:
        print(f"Querying the table {test_iterations} times, using the DAX client.")
        # Use a with statement so the DAX client closes the cluster after completion.
        with amazondax.AmazonDaxClient.resource(endpoint_url=args.endpoint_url) as dax:
            test_start, test_end = query_test(
                test_partition_key, test_sort_keys, test_iterations, dyn_resource=dax
            )
    else:
        print(f"Querying the table {test_iterations} times, using the Boto3 client.")
        test_start, test_end = query_test(
            test_partition_key, test_sort_keys, test_iterations
        )

    print(
        f"Total time: {test_end - test_start:.4f} sec. Average time: "
        f"{(test_end - test_start)/test_iterations}."
    )
```

# 05-scan-test.py
<a name="DAX.client.run-application-python.05-scan-test"></a>

`05-scan-test.py` プログラムは、`Scan` で `TryDaxTable` オペレーションを実行します。

```
import argparse
import time
import sys
import amazondax
import boto3


def scan_test(iterations, dyn_resource=None):
    """
    Scans the table a specified number of times. The time before the
    first iteration and the time after the last iteration are both captured
    and reported.

    :param iterations: The number of iterations to run.
    :param dyn_resource: Either a Boto3 or DAX resource.
    :return: The start and end times of the test.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource("dynamodb")

    table = dyn_resource.Table("TryDaxTable")
    start = time.perf_counter()
    for _ in range(iterations):
        table.scan()
        print(".", end="")
        sys.stdout.flush()
    print()
    end = time.perf_counter()
    return start, end


if __name__ == "__main__":
    # pylint: disable=not-context-manager
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "endpoint_url",
        nargs="?",
        help="When specified, the DAX cluster endpoint. Otherwise, DAX is not used.",
    )
    args = parser.parse_args()

    test_iterations = 100
    if args.endpoint_url:
        print(f"Scanning the table {test_iterations} times, using the DAX client.")
        # Use a with statement so the DAX client closes the cluster after completion.
        with amazondax.AmazonDaxClient.resource(endpoint_url=args.endpoint_url) as dax:
            test_start, test_end = scan_test(test_iterations, dyn_resource=dax)
    else:
        print(f"Scanning the table {test_iterations} times, using the Boto3 client.")
        test_start, test_end = scan_test(test_iterations)
    print(
        f"Total time: {test_end - test_start:.4f} sec. Average time: "
        f"{(test_end - test_start)/test_iterations}."
    )
```

# 06-delete-table.py
<a name="DAX.client.run-application-python.06-delete-table"></a>

`06-delete-table.py` プログラムは `TryDaxTable` を削除します。Amazon DynamoDB Accelerator (DAX) 機能のテストが完了してから、このプログラムを実行します。

```
import boto3


def delete_dax_table(dyn_resource=None):
    """
    Deletes the demonstration table.

    :param dyn_resource: Either a Boto3 or DAX resource.
    """
    if dyn_resource is None:
        dyn_resource = boto3.resource("dynamodb")

    table = dyn_resource.Table("TryDaxTable")
    table.delete()

    print(f"Deleting {table.name}...")
    table.wait_until_not_exists()


if __name__ == "__main__":
    delete_dax_table()
    print("Table deleted!")
```