

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 优化无服务器环境的客户端驱动程序连接
<a name="connections"></a>

要与 Amazon Keyspaces 通信，您可以使用自己选择的任何现有 Apache Cassandra 客户端驱动程序。由于 Amazon Keyspaces 是一项无服务器服务，我们建议您针对应用程序的吞吐量需求优化客户端驱动程序的连接配置。本主题介绍一些最佳实践，包括如何计算应用程序需要的连接数，以及连接的监控和错误处理。

**Topics**
+ [连接如何在 Amazon Keyspaces 中运作](#connections.howtheywork)
+ [如何在 Amazon Keyspaces 中配置连接](#connections.howtoconfigure)
+ [如何在 Amazon Keyspaces 中配置连接的重试策略](#connections.retry-policies)
+ [如何在 Amazon Keyspaces 中通过 VPC 端点配置连接](#connections.VPCendpoints)
+ [如何监控 Amazon Keyspaces 中的连接](#connections.howtomonitor)
+ [如何处理 Amazon Keyspaces 中的连接错误](#connections.errorhandling)

## 连接如何在 Amazon Keyspaces 中运作
<a name="connections.howtheywork"></a>

本节概述客户端驱动程序连接在 Amazon Keyspaces 中的运作方式。由于 Cassandra 客户端驱动程序配置错误可能会导致 Amazon Keyspaces 中出现 `PerConnectionRequestExceeded` 事件，因此需要在客户端驱动程序配置中配置适当数量的连接，以避免这类连接错误和类似的连接错误。

连接到 Amazon Keyspaces 时，驱动程序需要种子端点来建立初始连接。Amazon Keyspaces 使用 DNS 将初始连接路由到众多可用端点之一。系统会将端点附加到网络负载均衡器，网络负载均衡器转而与实例集中的一个请求处理程序建立连接。建立初始连接后，客户端驱动程序将从 `system.peers` 表收集有关所有可用端点的信息。利用这些信息，客户端驱动程序可以创建与所列端点的其他连接。客户端驱动程序可以创建的连接数受客户端驱动程序设置中指定的本地连接数的限制。默认情况下，大多数客户端驱动程序会为每个端点建立一个连接并建立与 Cassandra 的连接池，然后对连接池查询进行负载均衡。尽管可以与同一个端点建立多个连接，但在网络负载均衡器后面，它们可能连接到许多不同的请求处理程序。通过公有端点进行连接时，如果与 `system.peers` 表中列出的 9 个端点中的每个端点建立了 1 个连接，则会导致与不同请求处理程序建立 9 个连接。

![\[显示由驱动程序建立的连接如何首先到达 Amazon Keyspaces 服务的端点，然后继续到达负载均衡器，并在经过身份验证和授权之后，CQL 请求如何到达存储层的示意图。\]](http://docs.aws.amazon.com/zh_cn/keyspaces/latest/devguide/images/keyspaces_bp-connections.png)


## 如何在 Amazon Keyspaces 中配置连接
<a name="connections.howtoconfigure"></a>

Amazon Keyspaces 支持每个 TCP 连接每秒最多 3000 次 CQL 查询。由于驱动程序可以建立的连接数没有限制，因此我们建议**每个连接每秒仅定向 500 个 CQL 请求**，为开销、流量暴增和负载均衡改进留出余地。请按照以下步骤操作，确保驱动程序的连接已根据应用程序的需求正确配置。

**增加驱动程序在其连接池中维护的每个 IP 地址的连接数。**
+ 大多数 Cassandra 驱动程序都会建立与 Cassandra 的连接池，并对连接池查询进行负载均衡。大多数驱动程序的默认行为是与每个端点建立单个连接。Amazon Keyspaces 向驱动程序公开了 9 个对等 IP 地址，因此根据大多数驱动程序的默认行为，这会导致建立 9 个连接。Amazon Keyspaces 支持每个 TCP 连接每秒最多 3000 次 CQL 查询，因此，使用默认设置的驱动程序的最大 CQL 查询吞吐量为每秒 27000 次 CQL 查询。如果使用了驱动程序的默认设置，那么单个连接可能必须处理超过最大 CQL 查询吞吐量“每秒 3000 次 CQL 查询”的查询量。这可能会导致 `PerConnectionRequestExceeded` 事件。
+ 为避免 `PerConnectionRequestExceeded` 事件，您必须将驱动程序配置为为每个端点创建额外连接以分配吞吐量。
+ 作为 Amazon Keyspaces 中的最佳实践，应假设每个连接可以支持**每秒 500 次 CQL 查询**。
+ 这意味着，对于需要支持分布在 9 个可用端点上的预计每秒 27000 次 CQL 查询的生产应用程序，您必须为每个端点配置 6 个连接。这样可以确保每个连接每秒处理的请求不超过 500 个。

**根据应用程序的需求，计算您需要为驱动程序配置的每个 IP 地址的连接数。**

要确定需要为应用程序配置的每个端点的连接数，请考虑以下示例。您有一个应用程序需要支持每秒 20000 次 CQL 查询，其中包括 10000 个 `INSERT` 操作、5000 个 `SELECT` 操作和 5000 个 `DELETE` 操作。Java 应用程序在 Amazon Elastic Container Service (Amazon ECS) 上的三个实例上运行，其中每个实例都与 Amazon Keyspaces 建立了一个会话。可用于估算您需要为驱动程序配置的连接数的计算使用以下输入。

1. 应用程序需要支持的每秒请求数。

1. 可用实例的数量减去 1（为维护或故障做准备）。

1. 可用端点的数量。如果您通过公有端点进行连接，则有 9 个可用端点。如果您使用 VPC 端点，则有 2 到 5 个可用端点，具体取决于区域。

1. 使用每个连接每秒 500 次 CQL 查询作为 Amazon Keyspaces 的最佳实践。

1. 将结果四舍五入。

在此示例中，公式如下所示。

```
20,000 CQL queries / (3 instances - 1 failure) / 9 public endpoints / 500 CQL queries per second = ROUND(2.22) = 3 
```

根据此计算，您需要在驱动程序配置中为每个端点指定 3 个本地连接。对于远程连接，为每个端点仅配置 1 个连接。

## 如何在 Amazon Keyspaces 中配置连接的重试策略
<a name="connections.retry-policies"></a>

在为 Amazon Keyspaces 连接配置重试策略时，建议您实施 Amazon Keyspaces 重试策略 `AmazonKeyspacesExponentialRetryPolicy`。与驱动程序的 `DefaultRetryPolicy` 相比，该重试策略更适合在与 Amazon Keyspaces 的不同连接中进行重试。

借助 `AmazonKeyspacesExponentialRetryPolicy`，您可以根据自己的需求配置连接重试次数。默认情况下，`AmazonKeyspacesExponentialRetryPolicy` 的重试次数设置为 3。

另一个优点是，Amazon Keyspaces 重试策略会传回服务返回的原始异常，其会指明请求尝试失败的原因。默认的重试策略仅返回通用 `NoHostAvailableException`，这可能会隐藏对请求失败的见解。

要使用 `AmazonKeyspacesExponentialRetryPolicy` 配置请求重试策略，建议您配置较少的重试次数，并处理应用程序代码中返回的所有异常。

 有关实施重试策略的代码示例，请参阅 Github 上的 [Amazon Keyspaces 重试策略](https://github.com/aws-samples/amazon-keyspaces-java-driver-helpers/tree/main/src/main/java/com/aws/ssa/keyspaces/retry)。

## 如何在 Amazon Keyspaces 中通过 VPC 端点配置连接
<a name="connections.VPCendpoints"></a>

通过私有 VPC 端点进行连接时，您的可用端点很可能是 3 个。每个区域的 VPC 端点数量可能会有所不同，具体取决于可用区的数量以及分配的 VPC 中的子网数量。美国东部（弗吉尼亚州北部）区域有五个可用区，您最多可以拥有五个 Amazon Keyspaces 端点。美国西部（北加利福尼亚）区域有两个可用区，您最多可以拥有两个 Amazon Keyspaces 端点。端点数不会影响规模，但会增加您需要在驱动程序配置中建立的连接数。考虑以下示例。您的应用程序需要支持 20000 个 CQL 查询，并且在 Amazon ECS 上的三个实例上运行，其中每个实例都与 Amazon Keyspaces 建立了一个会话。唯一的区别是不同端点中有多少可用 AWS 区域。

美国东部（弗吉尼亚州北部）区域所需的连接数：

```
20,000 CQL queries / (3 instances - 1 failure) / 5 private VPC endpoints / 500 CQL queries per second = 4 local connections
```

美国西部（北加利福尼亚）区域所需的连接数：

```
20,000 CQL queries / (3 instances - 1 failure) / 2 private VPC endpoints / 500 CQL queries per second = 10 local connections
```

**重要**  
使用私有 VPC 端点时，Amazon Keyspaces 需要额外的权限来动态发现可用的 VPC 端点和填充 `system.peers` 表。有关更多信息，请参阅 [使用接口 VPC 端点信息填充 `system.peers` 表条目](vpc-endpoints.md#system_peers)。

 使用其他终端节点通过私有 VPC 终端节点访问亚马逊密钥空间时 AWS 账户，您可能只能看到一个 Amazon Keyspaces 终端节点。再说一次，这不会影响 Amazon Keyspaces 的可能吞吐量的规模，但可能需要您增加驱动程序配置中的连接数。此示例显示了单个可用端点的相同计算。

```
20,000 CQL queries / (3 instances - 1 failure) / 1 private VPC endpoints / 500 CQL queries per second = 20 local connections
```

要了解有关使用共享 VPC 跨账户访问 Amazon Keyspaces 的更多信息，请参阅[使用共享 VPC 中的 VPC 端点配置 Amazon Keyspaces 的跨账户访问](access.cross-account.sharedVPC.md)。

## 如何监控 Amazon Keyspaces 中的连接
<a name="connections.howtomonitor"></a>

为了帮助确定应用程序连接到的端点数，您可以记录在 `system.peers` 表中发现的对等节点数。以下示例是 Java 代码的示例，该代码将在连接建立后打印对等节点的数量。

```
ResultSet result = session.execute(new SimpleStatement("SELECT * FROM system.peers"));

logger.info("number of Amazon Keyspaces endpoints:" + result.all().stream().count());
```

**注意**  
CQL 控制台或 AWS 控制台未部署在 VPC 内，因此使用公有终端节点。因此，从位于 VPCE 外部的应用程序运行 `system.peers` 查询通常会导致产生 9 个对等节点。打印每个对等节点的 IP 地址也可能很有帮助。

您还可以通过设置 VPCE Ama CloudWatch zon 指标来观察使用 VPC 终端节点时的对等节点数量。在中 CloudWatch，您可以看到与 VPC 终端节点建立的连接数量。Cassandra 驱动程序将为每个端点建立连接以发送 CQL 查询，并建立控制连接以收集系统表信息。下图显示了在驱动程序设置中配置了 1 个连接的情况下连接到 Amazon Keyspaces 后的 VPC 终端节点 CloudWatch 指标。该指标显示了六个活动连接，包括一个控制连接和五个常规连接（在可用区中每个端点 1 个连接）。

![\[一个屏幕截图，在 Cloudwatch 控制面板上显示了关于通过 VPC 端点进行连接的指标。使用的指标是 ActiveConnections 和 BytesProcessed。\]](http://docs.aws.amazon.com/zh_cn/keyspaces/latest/devguide/images/keyspaces_bp_cw.png)


要开始使用 CloudWatch 图表监控连接数，您可以在 [Amazon Keyspaces CloudFormation 模板存储库 GitHub 中部署此模板](https://github.com/aws-samples/amazon-keyspaces-cloudwatch-cloudformation-templates)。

## 如何处理 Amazon Keyspaces 中的连接错误
<a name="connections.errorhandling"></a>

当超出每个连接 3000 个请求的限额时，Amazon Keyspaces 会返回一个 `PerConnectionRequestExceeded` 事件，Cassandra 驱动程序会收到一个 `WriteTimeout` 或 `ReadTimeout` 异常。您应该在 Cassandra 重试策略或应用程序中使用指数回退重试此异常。您应该提供指数回退以避免发送额外请求。

默认重试策略会在查询计划中尝试 `try next host` 操作。由于 Amazon Keyspaces 在连接到 VPC 端点时可能有一到三个可用端点，因此除了 `WriteTimeout` 和 `ReadTimeout` 异常之外，您还可能在应用程序日志中看到 `NoHostAvailableException` 异常。您可以使用 Amazon Keyspaces 提供的重试策略，这些策略在同一端点上重试，但会跨越不同的连接。

你可以在 Amazon [Keyspaces](https://github.com/aws-samples/amazon-keyspaces-java-driver-helpers/blob/main/src/main/java/com/aws/ssa/keyspaces/retry/AmazonKeyspacesExponentialRetryPolicy.java) Java 代码示例存储库 GitHub 中找到 Java 指数重试策略的示例。您可以在 Github 上的 [Amazon Keyspaces 代码示例](https://github.com/aws-samples/amazon-keyspaces-examples)存储库中找到其他语言示例。