

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Schritt 4: Ausführen einer Beispielanwendung
<a name="DAX.client.run-application"></a>

Um Sie beim Testen der Amazon-DynamoDB-Accelerator-(DAX)-Funktionalität zu unterstützen, können Sie eine der verfügbaren Beispielanwendungen auf der Amazon-EC2-Instance ausführen

**Topics**
+ [Node.js und DAX](DAX.client.run-application-nodejs-3.md)
+ [DAX SDK für Go](DAX.client.run-application-go-2.md)
+ [Java und DAX](DAX.client.run-application-java.md)
+ [.NET und DAX](DAX.client.run-application-dotnet.md)
+ [Python und DAX](DAX.client.run-application-python.md)

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

# Standard-Client-Konfiguration für Node.js
<a name="DAX-client-config-JS"></a>

Bei der Konfiguration des DAX JavaScript SDK-Clients können Sie verschiedene Parameter anpassen, um Leistung, Verbindungsbehandlung und Fehlerresistenz zu optimieren. In der folgenden Tabelle werden die Standardkonfigurationseinstellungen beschrieben, mit denen gesteuert wird, wie Ihr Client mit dem DAX-Cluster interagiert, u. a. Timeout-Werte, Wiederholungsmechanismen, Verwaltung von Anmeldeinformationen und Optionen zur Systemüberwachung. Weitere Informationen finden Sie unter [Dynamo DBClient Operations](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/).


**Standardeinstellungen für den DAX-JS-SDK-Client**  

| Parameter | Typ | Description | 
| --- | --- | --- | 
|  `region` optional  |  `string`  |  Der für den DAX-Client AWS-Region zu verwendende (Beispiel - 'us-east-1'). Dies ist ein erforderlicher Parameter, sofern er nicht über die Umgebungsvariable bereitgestellt wird.  | 
|  `endpoint` Erforderlich  |  `string`  | Der Endpunkt des Clusters, mit dem das SDK eine Verbindung herstellt. Beispiele: Unverschlüsselt — .region.amazonaws.com dax-cluster-name Verschlüsselt – daxs://Mein-Cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com  | 
|  `requestTimeout` Standard: 6 000 ms  |  `number`  | Dies definiert die maximale Zeit, die der Client auf eine Antwort von DAX wartet.  | 
|  `writeRetries` Standard: 1  |  `number`  | Die Anzahl der Wiederholungsversuche für fehlgeschlagene Schreibanforderungen.  | 
|  `readRetries` Standard: 1  |  `number`  | Die Anzahl der Wiederholungsversuche für fehlgeschlagene Leseanforderungen.  | 
|  `maxRetries` Standard: 1  |  `number`  | Die maximale Anzahl von Versuchen bei fehlgeschlagenen Anforderungen. Wenn festgelegt readRetries/writeRetries sind, hat die in ReadRetries und WriteRetries festgelegte Konfiguration Vorrang vor MaxRetries.  | 
|  `connectTimeout` Standard: 10 000 ms  |  `number`  | Das Timeout (in Millisekunden) für das Herstellen einer Verbindung zu einem der Cluster-Knoten.  | 
|  `maxConcurrentConnections` Standard: 100  |  `number`  | Beschränkt die Gesamtzahl der gleichzeitigen Verbindungen, die eine Client-Instance pro Knoten in einem DAX-Cluster herstellen kann.  | 
|  `maxRetryDelay` Standard: 7 000 ms  |  `number`  | Wenn der DAX-Server angibt, dass eine Wiederherstellung erforderlich ist, indem das `waitForRecoveryBeforeRetrying`-Flag auf „true“ gesetzt wird, hält der Client an, bevor er es erneut versucht. Während dieser Wiederherstellungsperioden bestimmt der `maxRetryDelay`-Parameter die maximale Wartezeit zwischen Wiederholungsversuchen. Diese für die Wiederherstellung spezifische Konfiguration gilt nur, wenn sich der DAX-Server im Wiederherstellungsmodus befindet. In allen anderen Szenarien folgt das Wiederholungsverhalten einem von zwei Mustern: entweder einer exponentiellen Verzögerung auf der Grundlage der Anzahl der Wiederholungen (bestimmt durch den Parameter `writeRetries`, `readRetries` oder `maxRetries`) oder einer sofortigen Wiederholung, abhängig vom Ausnahmetyp.  | 
|  `credentials` optional  |  `[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/)`  |  Die AWS Anmeldeinformationen, die für die Authentifizierung von Anfragen verwendet werden sollen. Dies kann als AwsCredentialIdentity oder als angegeben werden. AwsCredentialIdentityProvider Wenn nicht angegeben, verwendet das AWS -SDK automatisch die standardmäßige Anbieterkette für Anmeldeinformationen. Beispiel: `\$1 accessKeyId: 'AKIA... ' , secretAccessKey: ' ... ', sessionToken:'... '\$1 `\$1 @default Verwendet die Standard-Anbieterkette AWS für Anmeldeinformationen.  | 
|  `healthCheckInterval` Standard: 5 000 ms  |  `number`  | Das Intervall (in Millisekunden) zwischen den Cluster-Zustandsprüfungen. Bei einem kürzeren Intervall werden die Prüfungen häufiger durchgeführt.  | 
|  `healthCheckTimeout` Standard: 1 000 ms  |  `number`  | Das Timeout (in Millisekunden) für den Abschluss der Zustandsprüfung.  | 
|  `skipHostnameVerification` Standard: falsch  |  `boolean`  |  Die Hostnamen-Überprüfung von TLS-Verbindungen wird übersprungen. Dies hat keine Auswirkungen auf unverschlüsselte Cluster. Standardmäßig wird die Überprüfung des Hostnamens durchgeführt. Wenn Sie diesen Wert auf „True“ setzen, wird die Überprüfung übersprungen. Sie müssen sich bewusst sein, welche Folgen eine Deaktivierung hat, d. h. dass der Cluster, zu dem Sie eine Verbindung herstellen, nicht authentifiziert werden kann.   | 
|  `unhealthyConsecutiveErrorCount` Standard: 5  |  `number`  | Legt die Anzahl aufeinanderfolgender Fehler fest, die erforderlich sind, um innerhalb des Intervalls für die Zustandsprüfung zu signalisieren, dass der Knoten fehlerhaft ist.  | 
|  `clusterUpdateInterval` Standard: 4 000 ms  |  `number`  | Gibt das Intervall zwischen der Abfrage von Mitgliedschaftsänderungen bei Cluster-Mitgliedern zurück.  | 
|  `clusterUpdateThreshold` Standard: 125  |  `number`  | Gibt den Schwellenwert zurück, unter dem der Cluster nicht nach Mitgliedschaftsänderungen abgefragt wird.  | 
|  `credentailProvider` optional \$1 Standard null  |  `[AwsCredentialIdentityProvider](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/)`  | Benutzerdefinierter Anbieter für AWS Anmeldeinformationen, die zur Authentifizierung von Anfragen an DAX verwendet werden.  | 


**Paginierungskonfiguration für DaxDocument**  

| Name | Typ | Detail | 
| --- | --- | --- | 
|  `client`  |  DaxDocument  |  Instanz des DaxDocument Typs.  | 
|  `pageSize`  |  number  |  Bestimmt die Anzahl der Elemente pro Seite.  | 
|  `startingToken` Optional  |  any  |  LastEvaluatedKey aus der vorherigen Antwort kann für nachfolgende Anfragen verwendet werden.  | 

Informationen zur Verwendung der Paginierung finden Sie unter [TryDax.js](DAX.client.tutorial-TryDax.md).

# Migration zum DAX-Node.js-SDK V3
<a name="DAX.client.run-application-nodejs-3-migrating"></a>

Dieser Migrationsleitfaden hilft Ihnen bei der Umstellung Ihrer vorhandenen DAX-Node.js-Anwendungen. Das neue SDK erfordert Node.js 18 oder höher und führt mehrere wichtige Änderungen in der Strukturierung Ihres DynamoDB-Accelerator-Codes ein. Dieser Leitfaden führt Sie durch die wichtigsten Unterschiede, darunter Syntaxänderungen, neue Importmethoden und aktualisierte asynchrone Programmiermuster.

## Verwendung von 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);
    }
});
```

## Verwendung von V3 Node.js DAX
<a name="DAX.client.run-application-nodejs-3-migrating-V3-dax-usage"></a>

Für die Verwendung von DAX Node.js ist V3-Node-Version 18 oder höher die bevorzugte Version. Um zu Node 18 zu wechseln, verwenden Sie Folgendes:

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

Das DAX-SDK für Node.js v3.x ist mit dem [AWS -SDK für Node.js v3.x](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/) kompatibel. Das DAX-SDK für Node.js v3.x unterstützt die Verwendung [aggregierter](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts) Clients. Beachten Sie, dass DAX die Erstellung von Bare-Bone-Clients nicht unterstützt. Weitere Informationen zu nicht unterstützten Funktionen finden Sie unter [Funktionen, die nicht mit AWS SDK V3 identisch sind](#DAX.client.run-application-nodejs-3-not-in-parity).

Um die Node.js-Beispielanwendung auf Ihrer Amazon-EC2-Instance auszuführen, gehen Sie wie folgt vor.

**So führen Sie das Node.js-Beispiel für DAX aus**

1. Richten Sie Node.js auf Ihrer Amazon-EC2-Instance wie folgt ein:

   1. Installieren Sie den Node Version Manager (`nvm`).

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

   1. Installieren Sie Node.js mit dem nvm.

      ```
      nvm install 18
      ```

   1. Verwenden Sie nvm, um Node 18 zu verwenden.

      ```
      nvm use 18
      ```

   1. Testen Sie, ob Node.js installiert ist und ordnungsgemäß ausgeführt wird.

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

      Die folgende Meldung sollte angezeigt werden.

      `Running Node.js v18.x.x`

1. Installieren Sie den Client DaxDocument Node.js mit dem Node Package Manager (`npm`).

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

## TryDax Beispielcode
<a name="DAX.client.run-application-nodejs-3-TryDax-sample-code"></a>

Wenn Sie die Leistungsvorteile von DynamoDB Accelerator (DAX) bewerten möchten, gehen Sie wie folgt vor, um einen Beispieltest durchzuführen, bei dem die Lesevorgangszeiten zwischen Standard-DynamoDB und einem DAX-Cluster verglichen werden.

1. Nachdem Sie Ihren Workspace eingerichtet und `lib-dax` als Abhängigkeit hinzugefügt haben, kopieren Sie [TryDax.js](DAX.client.tutorial-TryDax.md) in Ihr Projekt.

1. Führen Sie das Programm für Ihren DAX-Cluster aus. Um den Endpunkt für Ihren DAX-Cluster zu bestimmen, wählen Sie einen der folgenden Schritte aus: 
   +  **Using the DynamoDB console** (Verwenden der DynamoDB-Konsole) — Wählen Sie Ihren DAX-Cluster aus. Der Cluster-Endpunkt wird auf der Konsole angezeigt, wie im folgenden Beispiel gezeigt.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **Verwenden** Sie AWS CLI— Geben Sie den folgenden Befehl ein.

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

     Der Cluster-Endpunkt wird in der Ausgabe angezeigt, wie im folgenden Beispiel gezeigt.

     ```
     {
         "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. Führen Sie jetzt das Programm aus, indem Sie den Cluster-Endpunkt als Befehlszeilenparameter angeben.

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

   Die Ausgabe sollte folgendermaßen oder ähnlich aussehen:

   ```
   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.
   ```

   Beachten Sie die Zeitinformationen. Die Anzahl der Mikrosekunden, die für die `GetItem`-, `Query`-, `Scan`-Tests benötigt werden.

1. In diesem Fall haben Sie die Programme für den DAX-Cluster ausgeführt. Jetzt führen Sie das Programm erneut aus, diesmal für DynamoDB.

1. Führen Sie nun das Programm erneut aus, diesmal aber ohne die Cluster-Endpunkt-URL als Befehlszeilenparameter.

   ```
   node TryDax.js
   ```

   Sehen Sie sich die Ausgabe an und notieren Sie die Zeitinformationen. Die verstrichene Zeit sollte für `GetItem`, `Query` und `Scan` mit DAX deutlich kürzer sein als mit DynamoDB.

## Funktionen, die nicht mit AWS SDK V3 identisch sind
<a name="DAX.client.run-application-nodejs-3-not-in-parity"></a>
+ [Bare-Bone](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/#high-level-concepts)-Clients: Dax Node.js V3 unterstützt keine Bare-Bone-Clients. 

  ```
  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);
  ```
+ [Middleware-Stack](https://aws.amazon.com/blogs/developer/middleware-stack-modular-aws-sdk-js/): Dax Node.js V3 unterstützt die Verwendung von Middleware-Funktionen nicht.

  ```
  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 für Go
<a name="DAX.client.run-application-go-2"></a>

Gehen Sie wie folgt vor, um die Amazon-DynamoDB-Accelerator-(DAX)-SDK für Go auf Ihrer Amazon-EC2-Instance auszuführen.

**So führen Sie das SDK-für-Go-Beispiel für DAX aus**

1. Richten Sie das SDK für Go auf Ihrer Amazon-EC2-Instance ein:

   1. Installieren Sie die Go-Programmiersprache (`Golang`).

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

   1. Testen Sie, ob Golang installiert ist und ordnungsgemäß ausgeführt wird.

      ```
      go version
      ```

      Eine Nachricht wie diese sollte erscheinen.

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

1. Installieren Sie die Golang-Beispielanwendung.

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

1. Führen Sie die folgenden Golang-Programme aus. Das erste Programm erstellt eine DynamoDB-Tabelle mit dem Namen `TryDaxGoTable`. Das zweite Programm schreibt Daten in die Tabelle.

   ```
   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. Führen Sie die folgenden Golang-Programme aus.

   ```
   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
   ```

   Beachten Sie die Zeitinformationen – die Anzahl der benötigten Millisekunden für den `GetItem`-, `Query`- und `Scan`-Test.

1. Im vorherigen Schritt haben Sie die Programme für den DynamoDB-Endpunkt ausgeführt. Führen Sie die Programme jetzt erneut aus. Dieses Mal werden die `GetItem`-, `Query`- und `Scan`-Operationen aber vom DAX-Cluster verarbeitet.

   Um den Endpunkt für Ihren DAX-Cluster zu bestimmen, wählen Sie einen der folgenden Schritte aus:
   + **Using the DynamoDB console** (Verwenden der DynamoDB-Konsole) — Wählen Sie Ihren DAX-Cluster aus. Der Cluster-Endpunkt wird auf der Konsole angezeigt, wie im folgenden Beispiel gezeigt.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **Verwenden von AWS CLI** — Geben Sie den folgenden Befehl ein.

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

     Der Cluster-Endpunkt wird wie im folgenden Beispiel in der Ausgabe angezeigt.

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

   Führen Sie jetzt die Programme erneut aus. Geben Sie dieses Mal jedoch den Cluster-Endpunkt als Befehlszeilenparameter an.

   ```
   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
   ```

   Sehen Sie sich den Rest der Ausgabe an und notieren Sie die Zeitinformationen. Die verstrichene Zeit sollte für `GetItem`, `Query` und `Scan` mit DAX deutlich kürzer sein als mit DynamoDB.

1. Führen Sie das folgende Golang-Programm aus, um `TryDaxGoTable` zu löschen:

   ```
   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
   ```

## Funktionen, die nicht mit AWS SDK für Go V2 gleichwertig sind
<a name="DAX.client.run-application-go-features-not-in-parity"></a>

Middleware Stack — DAX Go V2 unterstützt die Verwendung von Middleware Stacks bis jetzt nicht. APIoptions Weitere Informationen finden Sie unter [Anpassen](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) der v2-Client-Anfragen mit Middleware. AWS SDK für Go 

Beispiel:

```
// 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
}
```

Ausgabe:

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

# Standard-Client-Konfiguration für Go
<a name="DAX-client-config-Go"></a>

In diesem Handbuch werden Sie durch die Konfigurationsoptionen geführt, mit denen Sie die Leistung, das Verbindungsmanagement und das Protokollierungsverhalten Ihres DAX-Clients optimieren können. Wenn Sie sich mit den Standardeinstellungen und deren Anpassung vertraut machen, können Sie die Interaktion Ihrer Go-Anwendung mit DAX optimieren.

**Topics**
+ [Standardeinstellungen für den DAX-Go-SDK-Client](#DAX-client-config-Go-sdk-client-defaults)
+ [Client-Erstellung](#DAX-client-config-Go-client-creation)

## Standardeinstellungen für den DAX-Go-SDK-Client
<a name="DAX-client-config-Go-sdk-client-defaults"></a>


| Parameter | Typ | Description | 
| --- | --- | --- | 
|  `Region` Erforderlich  |  `string`  |  Der für den DAX-Client AWS-Region zu verwendende (Beispiel- 'us-east-1'). Dies ist ein erforderlicher Parameter, sofern er nicht über die Umgebung bereitgestellt wird.  | 
|  `HostPorts` Erforderlich  |  `[] string`  |  Liste der DAX-Cluster-Endpunkte, mit denen das SDK eine Verbindung herstellt.  Beispiel: Nicht verschlüsselt – dax://Mein-Cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com Verschlüsselt – daxs://Mein-Cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com  | 
|  `MaxPendingConnectionsPerHost` Standard: 10  |  `number`  | Die Anzahl der gleichzeitigen Verbindungsversuche. (Verbindungen können gleichzeitig hergestellt werden.)  | 
|  `ClusterUpdateThreshold` Standard: 125 \$1 time.Millisecond  |  `time.Duration`  | Die Mindestzeit, die zwischen Clusteraktualisierungen vergehen muss.  | 
|  `ClusterUpdateInterval` Standard: 4 \$1 time.Second  |  `time.Duration`  | Das Intervall, in dem der Client die DAX-Clusterinformationen automatisch aktualisiert.  | 
|  `IdleConnectionsReapDelay` Standard: 30 \$1 time.Second  |  `time.Duration`  | Das Intervall, in dem der Client inaktive Verbindungen im DAX-Client schließt.  | 
|  `ClientHealthCheckInterval` Standard: 5 \$1 time.Second  |  `time.Duration`  | Das Intervall, in dem der Client Zustandsprüfungen der DAX-Cluster-Endpunkte durchführt.  | 
|  `Credentials` default  |  `aws.CredentialsProvider`  | Die AWS Anmeldeinformationen, die vom DAX-Client zur Authentifizierung von Anfragen an den DAX-Dienst verwendet werden. Siehe [Credentials and Credential Providers](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/migrate-gosdk.html#credentials--credential-providers).  | 
|  `DialContext` default  |  `func`  | Eine benutzerdefinierte Funktion, die vom DAX-Client verwendet wird, um Verbindungen zum DAX-Cluster herzustellen.  | 
|  `SkipHostnameVerification` Standard: falsch  |  bool  |  Die Hostnamen-Überprüfung von TLS-Verbindungen wird übersprungen. Diese Einstellung wirkt sich nur auf verschlüsselte Cluster aus. Wenn sie auf „True“ gesetzt ist, wird die Überprüfung des Hostnamens deaktiviert. Wenn Sie die Überprüfung deaktivieren, können Sie die Identität des Clusters, zu dem Sie eine Verbindung herstellen, nicht authentifizieren, was ein Sicherheitsrisiko darstellt. Standardmäßig ist die Überprüfung des Hostnamens aktiviert.  | 
|  `RouteManagerEnabled` Standard: falsch  |  `bool`  | Dieses Flag wird verwendet, um Routen zu entfernen, bei denen Netzwerkfehler auftreten.  | 
|  `RequestTimeout` Standard: 60 \$1 time.Second  |  `time.Duration`  | Dies definiert die maximale Zeit, die der Client auf eine Antwort von DAX wartet. Priorität: Kontext-Timeout (falls festgelegt) > `RequestTimmeout` (falls festgelegt) > Standard von 60 s für `RequestTimeout`.  | 
|  `WriteRetries` Standard: 2  |  `number`  |  Die Anzahl der Wiederholungsversuche für fehlgeschlagene Schreibanforderungen.  | 
|  `ReadRetries` Standard: 2  |  `number`  | Die Anzahl der Wiederholungsversuche für fehlgeschlagene Leseanforderungen.  | 
|  `RetryDelay` Standard: 0  |  `time.Duration`  | Die Verzögerung bei nicht gedrosselten Fehlern (in Sekunden) bei Wiederholungsversuchen, wenn eine Anforderung fehlschlägt.  | 
|  `Logger` optional  |  `logging.Logger`  | Logger ist eine Schnittstelle zum Protokollieren von Einträgen bei bestimmten Klassifizierungen.  | 
|  `LogLevel` Standard-Utils. LogOff  |  `number`  | Dieses loglevel ist nur für DAX definiert. Es kann mit [Github importiert werden. 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>  | 

**Anmerkung**  
Für `time.Duration` ist die Standardeinheit Nanosekunde. Wenn für einen Parameter keine Einheit angegeben wird, wird dies als Nanosekunden betrachtet: `daxCfg.ClusterUpdateInterval = 10` bedeutet 10 Nanosekunden. (`daxCfg.ClusterUpdateInterval = 10 * time.Millisecond` bedeutet 10 Millisekunden).

## Client-Erstellung
<a name="DAX-client-config-Go-client-creation"></a>

**Erstellen Sie einen DAX-Client wie folgt:**
+ Erstellen Sie die DAX-Konfiguration und erstellen Sie dann den DAX-Client mithilfe der DAX-Konfiguration. Auf diese Weise können Sie eine DAX-Konfiguration bei Bedarf überschreiben.

  ```
  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)
  ```

# Migration zu DAX Go SDK V2
<a name="DAX.client.run-application-go-migrating"></a>

Dieser Migrationsleitfaden hilft Ihnen bei der Umstellung Ihrer vorhandenen DAX-Go-Anwendungen.

## Nutzung von 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)
}
```

## Nutzung von 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)
}
```

Weitere Informationen zur API-Nutzung finden Sie unter [AWS -Beispiele](https://github.com/aws-samples/sample-aws-dax-go-v2).

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

DAX SDK für Java 2.x ist kompatibel mit [AWS SDK für Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/). Es basiert auf Java 8\$1 und bietet Unterstützung für blockierungsfreie I/O. Informationen zur Verwendung von DAX mit AWS SDK for Java 1.x finden Sie unter. [Verwenden von DAX mit AWS SDK for Java 1.x](DAX.client.java-sdk-v1.md)

## Verwenden des Clients als Maven-Abhängigkeit
<a name="DAX.client.run-application-java.maven"></a>

Führen Sie die folgenden Schritte aus, um den Client für das DAX SDK for Java als Abhängigkeit in Ihrer Anwendung zu verwenden.

1. Laden Sie Apache Maven herunter und installieren Sie es. Weitere Informationen finden Sie unter [Downloading Apache Maven](https://maven.apache.org/download.cgi) und [Installing Apache Maven](https://maven.apache.org/install.html).

1. Fügen Sie die Client-Maven-Abhängigkeit der POM-Datei (Project Object Model) Ihrer Anwendung hinzu. In diesem Beispiel ersetzen Sie es *x.x.x* durch die tatsächliche Versionsnummer des Clients.

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

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

Nachdem Sie Ihren Workspace eingerichtet und das DAX-SDK als Abhängigkeit hinzugefügt haben, kopieren Sie [TryDax.java](DAX.client.TryDax.java.md) in Ihr Projekt.

Führen Sie den Code mit diesem Befehl aus.

```
java -cp classpath TryDax
```

Die Ausgabe sollte in etwa wie folgt aussehen:

```
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.
```

Beachten Sie die Zeitinformationen – die Anzahl der benötigten Millisekunden für die `GetItem`- und `Query`-Prüfungen. In diesem Fall führten Sie das Programm über den DynamoDB-Endpunkt aus. Jetzt führen Sie das Programm erneut aus, diesmal gegen Ihren DAX-Cluster.

Um den Endpunkt für Ihren DAX-Cluster zu bestimmen, wählen Sie einen der folgenden Schritte aus:
+ Wählen Sie in der DynamoDB-Konsole den DAX-Cluster aus. Der Cluster-Endpunkt wird auf der Konsole angezeigt, wie im folgenden Beispiel gezeigt.

  ```
  dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
  ```
+ Geben Sie mit dem AWS CLI den folgenden Befehl ein:

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

  Die Adresse, der Port und die URL des Clusterendpunkts werden wie im folgenden Beispiel in der Ausgabe angezeigt.

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

Führen Sie nun das Programm erneut aus, geben Sie jedoch diesmal die Clusterendpunkt-URL als Befehlszeilenparameter an.

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

Sehen Sie sich die Ausgabe an und notieren Sie die Zeitinformationen. Die verstrichene Zeit für `GetItem` und `Query` sollten mit DAX deutlich geringer sein als mit DynamoDB.

## SDK-Metriken
<a name="DAX.client.run-application-java.metrics"></a>

Mit dem DAX SDK for Java 2.x können Sie Metriken über die Service-Clients in Ihrer Anwendung sammeln und die Ergebnisse in Amazon CloudWatch analysieren. Weitere Informationen finden Sie unter [Aktivieren von SDK-Metriken](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html).

**Anmerkung**  
Das DAX-SDK für Java erfasst nur `ApiCallSuccessful`- und `ApiCallDuration`-Metriken.

# 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 und DAX
<a name="DAX.client.run-application-dotnet"></a>

Gehen Sie wie folgt vor, um das .NET-Beispiel auf Ihrer Amazon-EC2-Instance auszuführen.

**Anmerkung**  
In diesem Tutorial wird das.NET 9 SDK verwendet. Sie zeigt, wie Sie ein Programm in der Standard-Amazon VPC ausführen können, um auf den Amazon-DynamoDB-Accelerator-(DAX)-Cluster zuzugreifen. Es funktioniert mit dem [AWS SDK v4 für .NET](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html). Einzelheiten zu Änderungen in V4 und Informationen zur Migration finden Sie unter [Migration auf Version 4 des AWS SDK for .NET](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html). Wenn Sie möchten, können Sie die verwenden, AWS Toolkit for Visual Studio um eine.NET-Anwendung zu schreiben und sie in Ihrer VPC bereitzustellen.  
Weitere Informationen finden Sie unter [Erstellen und Bereitstellen von Elastic-Beanstalk-Anwendungen in .NET mit AWS -Toolkit for Visual Studio](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_NET.html) im *AWS Elastic Beanstalk -Entwicklerhandbuch*.

**So führen Sie das .NET-Beispiel für DAX aus**

1. Gehen Sie zur [Microsoft-Downloadseite](https://www.microsoft.com/net/download?initial-os=linux) und laden Sie das neueste.NET 9-SDK für Linux herunter. Der Name der heruntergeladenen Datei lautet `dotnet-sdk-N.N.N-linux-x64.tar.gz`.

1. Extrahieren Sie die SDK-Dateien.

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

   Ersetzen Sie `N.N.N` durch die tatsächliche Versionsnummer des .NET SDK (z. B.: `9.0.305`).

1. Überprüfen Sie die Installation.

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

   Damit sollte die Versionsnummer des .NET SDK ausgegeben werden.
**Anmerkung**  
Statt der Versionsnummer erhalten Sie möglicherweise die folgende Fehlermeldung:  
error: libunwind.so.8: cannot open shared object file: No such file or directory (Fehler: libunwind.so.8: Die freigegebene Datei kann nicht geöffnet werden: Datei oder Verzeichnis nicht vorhanden)  
Um den Fehler zu beheben, installieren Sie das `libunwind`-Paket.  

   ```
   sudo yum install -y libunwind
   ```
Anschließend sollte es möglich sein, den `dotnet --version`-Befehl fehlerfrei auszuführen.

1. Erstellen Sie ein neues .NET-Projekt.

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

   Dies dauert einige Minuten, um ein one-time-only Setup durchzuführen. Nachdem sie fertig ist, führen Sie das Beispielprojekt aus.

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

   Sie sollten die folgende Meldung erhalten: `Hello World!`

1. Die Datei `myApp/myApp.csproj` enthält Metadaten über Ihr Projekt. Um den DAX-Client in Ihrer Anwendung nutzen zu können, ändern Sie die Datei, sodass sie wie folgt aussieht.

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

1. Downloaden Sie den Quellcode des Beispielprogramms (`.zip`-Datei):

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

   Wenn der Download abgeschlossen ist, extrahieren Sie die Quelldateien.

   ```
   unzip TryDax.zip
   ```

1. Führen Sie nun nacheinander die Beispielprogramme von *DotNet* aus. Kopieren Sie für jedes Programm seinen Inhalt in die Datei `myApp/Program.cs` und führen Sie dann das `MyApp`-Projekt aus.

   Führen Sie die folgenden .NET-Programme aus. Das erste Programm erstellt eine DynamoDB-Tabelle mit dem Namen `TryDaxTable`. Das zweite Programm schreibt Daten in die Tabelle.

   ```
   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. Führen Sie jetzt einige Programme zur Durchführung von `GetItem`-, `Query`- und `Scan`-Operationen auf dem DAX-Cluster aus. Um den Endpunkt für Ihren DAX-Cluster zu bestimmen, wählen Sie einen der folgenden Schritte aus:
   +  **Using the DynamoDB console** (Verwenden der DynamoDB-Konsole) — Wählen Sie Ihren DAX-Cluster aus. Der Cluster-Endpunkt wird auf der Konsole angezeigt, wie im folgenden Beispiel gezeigt.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **Verwenden Sie den AWS CLI** — Geben Sie den folgenden Befehl ein.

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

     Der Clusterendpunkt wird wie im folgenden Beispiel in der Ausgabe angezeigt.

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

   Führen Sie jetzt die folgenden Programme aus und geben Sie den Cluster-Endpunkt als Befehlszeilenparameter an. (Ersetzen Sie den Beispiel-Endpunkt durch den tatsächlichen DAX-Cluster-Endpunkt.)

   ```
   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
   ```

   Beachten Sie die Zeitinformationen – die Anzahl der benötigten Millisekunden für den `GetItem`-, `Query`- und `Scan`-Test.

1. Führen Sie das folgende .NET-Programm aus, um `TryDaxTable` zu löschen.

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

Weitere Informationen zu diesen Programmen finden Sie in folgenden Abschnitten:
+ [0-1 CreateTable .cs](DAX.client.run-application-dotnet.01-CreateTable.md)
+ [02-Write-Data.cs](DAX.client.run-application-dotnet.02-Write-Data.md)
+ [03- -Test.cs GetItem](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)
+ [0-6. DeleteTable cs](DAX.client.run-application-dotnet.06-DeleteTable.md)

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

Das Programm `01-CreateTable.cs` erstellt eine Tabelle (`TryDaxTable`). Die restlichen .NET-Programme in diesem Abschnitt hängen von dieser Tabelle ab.

```
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>

Das Programm `02-Write-Data.cs` schreibt Testdaten in `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- -Test.cs GetItem
<a name="DAX.client.run-application-dotnet.03-GetItem-Test"></a>

Das Programm `03-GetItem-Test.cs` führt `GetItem`-Operationen für `TryDaxTable` aus.

```
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>

Das Programm `04-Query-Test.cs` führt `Query`-Operationen für `TryDaxTable` aus.

```
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>

Das Programm `05-Scan-Test.cs` führt `Scan`-Operationen für `TryDaxTable` aus.

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

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

Das `06-DeleteTable.cs`-Programm löscht `TryDaxTable`. Führen Sie dieses Programm aus, sobald Sie mit dem Testen fertig sind.

```
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 und DAX
<a name="DAX.client.run-application-python"></a>

Um die Python-Beispielanwendung auf Ihrer Amazon-EC2-Instance auszuführen, gehen Sie wie folgt vor.

**So führen Sie das Python-Beispiel für DAX aus**

1. Installieren Sie den DAX-Python-Client mit dem `pip`-Dienstprogramm.

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

1. Downloaden Sie den Quellcode des Beispielprogramms (`.zip`-Datei):

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

   Wenn der Download abgeschlossen ist, extrahieren Sie die Quelldateien.

   ```
   unzip TryDax.zip
   ```

1. Führen Sie die folgenden Python-Programme aus. Das erste Programm erstellt eine Amazon-DynamoDB-Tabelle mit dem Namen `TryDaxTable`. Das zweite Programm schreibt Daten in die Tabelle.

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

1. Führen Sie die folgenden Python-Programme aus.

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

    Beachten Sie die Zeitinformationen – die Anzahl der benötigten Millisekunden für den `GetItem`-, `Query`- und `Scan`-Test.

1. Im vorherigen Schritt haben Sie die Programme für den DynamoDB-Endpunkt ausgeführt. Führen Sie die Programme jetzt erneut aus. Dieses Mal werden die `GetItem`-, `Query`- und `Scan`-Operationen aber vom DAX-Cluster verarbeitet.

   Um den Endpunkt für Ihren DAX-Cluster zu bestimmen, wählen Sie einen der folgenden Schritte aus:
   + **Using the DynamoDB console** (Verwenden der DynamoDB-Konsole) — Wählen Sie Ihren DAX-Cluster aus. Der Cluster-Endpunkt wird auf der Konsole angezeigt, wie im folgenden Beispiel gezeigt.

     ```
     dax://my-cluster.l6fzcv.dax-clusters.us-east-1.amazonaws.com
     ```
   + **Verwenden** Sie AWS CLI— Geben Sie den folgenden Befehl ein.

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

     Der Cluster-Endpunkt wird wie in diesem Beispiel in der Ausgabe angezeigt.

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

   Führen Sie jetzt die Programme erneut aus. Geben Sie dieses Mal jedoch den Cluster-Endpunkt als Befehlszeilenparameter an.

   ```
   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
   ```

   Sehen Sie sich den Rest der Ausgabe an und notieren Sie die Zeitinformationen. Die verstrichene Zeit sollte für `GetItem`, `Query` und `Scan` mit DAX deutlich kürzer sein als mit DynamoDB.

1. Führen Sie das folgende Python-Programm aus, um `TryDaxTable` zu löschen:

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

Weitere Informationen zu diesen Programmen finden Sie in folgenden Abschnitten:
+ [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>

Das Programm `01-create-table.py` erstellt eine Tabelle (`TryDaxTable`). Die restlichen Python-Programme in diesem Abschnitt hängen von dieser Tabelle ab.

```
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>

Das Programm `02-write-data.py` schreibt Testdaten in `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>

Das Programm `03-getitem-test.py` führt `GetItem`-Operationen für `TryDaxTable` aus. Dieses Beispiel wird für die Region eu-west-1 gegeben. 

```
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>

Das Programm `04-query-test.py` führt `Query`-Operationen für `TryDaxTable` aus.

```
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>

Das Programm `05-scan-test.py` führt `Scan`-Operationen für `TryDaxTable` aus.

```
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>

Das `06-delete-table.py`-Programm löscht `TryDaxTable`. Führen Sie dieses Programm aus, sobald Sie mit dem Testen der Amazon-DynamoDB-Accelerator-(DAX)-Funktionalität fertig sind.

```
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!")
```