

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# ElastiCache 的常見故障診斷步驟和最佳實務
<a name="wwe-troubleshooting"></a>

下列主題提供使用 ElastiCache 時可能遇到的錯誤和問題的疑難排解建議。如果您發現未列在此處的問題，您可以使用此頁面上的 Feedback (意見回饋) 按鈕來報告。

如需常見支援問題的更多疑難排解建議和解答，請造訪 [AWS知識中心](https://aws.amazon.com/premiumsupport/knowledge-center/)

**Topics**
+ [連線問題](#wwe-troubleshooting.connection)
+ [Valkey 或 Redis OSS 用戶端錯誤](#wwe-troubleshooting.clienterrors)
+ [對 ElastiCache Serverless 中的高延遲進行故障診斷](#wwe-troubleshooting.latency)
+ [故障診斷 ElastiCache Serverless 中的限流問題](#wwe-troubleshooting.throttling)
+ [持續連線問題](TroubleshootingConnections.md)
+ [相關主題](#wwe-troubleshooting.related)

## 連線問題
<a name="wwe-troubleshooting.connection"></a>

如果您無法連線至 ElastiCache 快取，請考慮下列其中一項：

1. **使用 TLS：**如果您在嘗試連線至 ElastiCache 端點時遇到掛載連線，則可能不會在用戶端中使用 TLS。如果您使用的是 ElastiCache Serverless，傳輸中的加密一律會啟用。請確定您的用戶端使用 TLS 連線到快取。[進一步了解如何連線至已啟用 TLS 的快取](connect-tls.md)。

1. **VPC：**ElastiCache 快取只能從 VPC 內存取。確定您從中存取快取和 ElastiCache 快取的 EC2 執行個體是在相同的 VPC 中建立。或者，您必須在 EC2 執行個體所在的 VPC 與您要建立快取的 VPC 之間啟用 VPC [對等](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)互連。

1. **安全群組：**ElastiCache 使用安全群組來控制對快取的存取。考慮下列各項：

   1. 請確定 ElastiCache 快取所使用的安全群組允許從 EC2 執行個體進行傳入存取。請參閱[此處](https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html)，了解如何在安全群組中正確設定傳入規則。

   1. 請確定 ElastiCache 快取使用的安全群組允許存取快取的連接埠 （無伺服器 6379 和 6380，節點型叢集 6379)。ElastiCache 使用這些連接埠來接受 Valkey 或 Redis OSS 命令。在此處進一步了解如何設定連接埠存取[授予從 Amazon VPC 安全群組透過網路存取快取的權限](set-up.md#elasticache-install-grant-access-VPN)。

如果連線仍然很困難，請參閱 [持續連線問題](TroubleshootingConnections.md) 以取得其他步驟。

## Valkey 或 Redis OSS 用戶端錯誤
<a name="wwe-troubleshooting.clienterrors"></a>

ElastiCache Serverless 只能使用支援 Valkey 或 Redis OSS 叢集模式通訊協定的用戶端存取。節點型叢集可透過任一模式的用戶端存取，視叢集組態而定。

如果您的用戶端發生錯誤，請考慮下列事項：

1. **叢集模式：**如果您使用 [SELECT](https://valkey.io/commands/select/) 命令遇到 CROSSLOT 錯誤或錯誤，您可能會嘗試使用不支援叢集通訊協定的 Valkey 或 Redis OSS 用戶端存取啟用叢集模式快取。ElastiCache Serverless 僅支援 Valkey 或 Redis OSS 叢集通訊協定的用戶端。如果您想要在「停用叢集模式」(CMD) 中使用 Valkey 或 Redis OSS，則必須建立節點型叢集。

1. **CROSSLOT 錯誤：**如果您遇到`ERR CROSSLOT Keys in request don't hash to the same slot`錯誤，您可能會嘗試存取不屬於叢集模式快取中相同插槽的金鑰。提醒您，ElastiCache Serverless 一律以叢集模式運作。只有在所有涉及的金鑰都位於相同的雜湊槽中時，才允許涉及多個金鑰的多金鑰操作、交易或 Lua 指令碼。

如需設定 Valkey 或 Redis OSS 用戶端的其他最佳實務，請參閱此[部落格文章](https://aws.amazon.com/blogs/database/best-practices-redis-clients-and-amazon-elasticache-for-redis/)。

## 對 ElastiCache Serverless 中的高延遲進行故障診斷
<a name="wwe-troubleshooting.latency"></a>

如果您的工作負載似乎發生高延遲，您可以分析 CloudWatch `SuccessfulReadRequestLatency`和`SuccessfulWriteRequestLatency`指標，以檢查延遲是否與 ElastiCache Serverless 相關。這些指標會測量 ElastiCache Serverless 內部的延遲 - 不包括用戶端與 ElastiCache Serverless 端點之間的用戶端延遲和網路跳脫時間。

**對用戶端延遲進行故障診斷**

如果您在用戶端注意到延遲增加，但 ``CloudWatch `SuccessfulReadRequestLatency`和測量伺服器端延遲的`SuccessfulWriteRequestLatency`指標沒有對應的增加，請考慮下列事項：
+ **確保安全群組允許存取連接埠 6379 和 6380：**ElastiCache Serverless 使用主要端點的 6379 連接埠，以及讀取器端點的 6380 連接埠。有些用戶端會為每個新連線建立與兩個連接埠的連線，即使您的應用程式未使用僅供讀取複本功能。如果您的安全群組不允許兩個連接埠的傳入存取，則建立連線可能需要更長的時間。在此處進一步了解如何設定連接埠存取[ 授予從 Amazon VPC 安全群組透過網路存取快取的權限授予網路存取權  ElastiCache 節點型叢集針對 Valkey 和 Redis OSS 命令使用連接埠 6379，而 ElastiCache Serverless 同時使用連接埠 6379 和連接埠 6380。為了從 EC2 執行個體成功連接和執行 Valkey 或 Redis OSS 命令，您的安全群組必須允許視需要存取這些連接埠。 ElastiCache for Memcached 使用 11211 和 11212 連接埠來接受 Memcached 命令。為了從 EC2 執行個體成功連線和執行 Memcached 命令，您的安全群組必須允許存取這些連接埠。  登入AWS Command Line Interface並開啟 [Amazon EC2 主控台](https://console.aws.amazon.com/ec2/)。 在導覽窗格中，在 **Network & Security (網路與安全)** 下，選擇 **Security Groups (安全群組)**。 從安全群組的清單中，選擇要用於 Amazon VPC 的安全群組。除非您建立了安全群組供 ElastiCache 使用，否則此安全群組將會命名為 *default*。 選擇「傳入」索引標籤，然後：   選擇**編輯**。   選擇**新增規則**。   在「類型」欄中，選擇**自訂 TCP 規則**。  如果使用 Valkey 或 Redis OSS，請在**連接埠範圍**方塊中輸入 `6379`。 如果使用 Memcached，請在**連接埠範圍**方塊中輸入 `11211`。   在**來源**方塊中，選擇具有連接埠範圍 (0.0.0.0/0) 的**隨處**，讓任何您在 Amazon VPC 內啟動的 Amazon EC2 執行個體都能連線至您的快取。   如果您使用的是 ElastiCache 無伺服器，請選擇新增規則來**新增另一個規則**。  在 **Type (類型)** 欄中，選擇 **Custom TCP rule (自訂 TCP 規則)**。   如果使用 ElastiCache for Redis OSS，請在**連接埠範圍**方塊中輸入 `6380`。 如果使用 ElastiCache for Memcached，請在**連接埠範圍**方塊中輸入 `11212`。   在**來源**方塊中，選擇具有連接埠範圍 (0.0.0.0/0) 的**隨處**，讓任何您在 Amazon VPC 內啟動的 Amazon EC2 執行個體都能連線至您的快取。  選擇**儲存**    ](set-up.md#elasticache-install-grant-access-VPN)。

**對伺服器端延遲進行故障診斷**

某些變異性和偶爾峰值不應造成疑慮。不過，如果`Average`統計資料顯示急劇增加並持續，您應該檢查Health 儀板表和個人運作狀態儀表板以取得詳細資訊。如有必要，請考慮使用 開啟支援案例支援。

請考慮下列最佳實務和策略，以減少延遲：
+ **啟用僅供讀取複本：**如果您的應用程式允許，建議您在 Valkey 或 Redis OSS 用戶端中啟用「僅供讀取複本」功能，以擴展讀取並實現更低的延遲。啟用時，ElastiCache Serverless 會嘗試將您的讀取請求路由至與用戶端位於相同可用區域 (AZ) 的複本快取節點，以避免跨可用區域網路延遲。請注意，在用戶端中啟用僅供讀取複本功能表示您的應用程式接受資料中的最終一致性。如果您在寫入金鑰後嘗試讀取，您的應用程式可能會收到較舊的資料一段時間。
+ **確保您的應用程式部署在與快取相同的 AZs 中：**如果您的應用程式未部署在與快取相同的 AZs 中，您可能會觀察到更高的用戶端延遲。當您建立無伺服器快取時，您可以提供應用程式存取快取的子網路，而 ElastiCache Serverless 會在這些子網路中建立 VPC 端點。確保您的應用程式部署在相同的 AZs 中。否則，您的應用程式在存取快取時可能會產生跨可用區跳轉，進而產生更高的用戶端延遲。
+ **重複使用連線：**ElastiCache Serverless 請求是透過啟用 TLS 的 TCP 連線使用 RESP 通訊協定提出。啟動連線 （包括驗證連線，如果已設定） 需要一些時間，因此第一個請求的延遲高於一般。透過已初始化連線的請求可提供 ElastiCache 一致的低延遲。因此，您應該考慮使用連線集區或重複使用現有的 Valkey 或 Redis OSS 連線。
+ **擴展速度：**ElastiCache Serverless 會隨著請求率增加而自動擴展。請求率突然大幅增加，速度比 ElastiCache Serverless 擴展的速度快，可能會導致延遲增加一段時間。ElastiCache Serverless 通常可以快速提高其支援的請求率，最多需要 10-12 分鐘才能將請求率加倍。
+ **檢查長時間執行的命令：**某些 Valkey 或 Redis OSS 命令，包括大型資料結構上的 Lua 指令碼或命令，可能會長時間執行。為了識別這些命令，ElastiCache 會發佈命令層級指標。透過 [ElastiCache Serverless](serverless-metrics-events-redis.md#serverless-metrics)，您可以使用 `BasedECPUs`指標。
+ **限流請求：**在 ElastiCache Serverless 中限流請求時，您可能會遇到應用程式的用戶端延遲增加。在 ElastiCache Serverless 中調節請求時，您應該會看到 `ThrottledRequests` [ElastiCache Serverless](serverless-metrics-events-redis.md#serverless-metrics) 指標增加。檢閱以下章節，以針對節流請求進行故障診斷。
+ **金鑰和請求的統一分佈：**在 ElastiCache for Valkey 和 Redis OSS 中，每個插槽的金鑰或請求分佈不均可能會導致熱槽，進而導致延遲增加。ElastiCache Serverless 在單一插槽上最多支援 30，000 ECPUs/秒 （使用僅供讀取複本時為 90，000 個 ECPUs/秒）。我們建議評估您的金鑰和請求分佈到各個插槽，並確保在請求率超過此限制時分佈一致。

## 故障診斷 ElastiCache Serverless 中的限流問題
<a name="wwe-troubleshooting.throttling"></a>

在服務導向架構和分散式系統中，限制各種服務元件處理 API 呼叫的速率稱為限流。這可平滑峰值、控制元件輸送量不相符，並在發生非預期的操作事件時允許更可預測的復原。ElastiCache Serverless 專為這些類型的架構而設計，大多數 Valkey 或 Redis OSS 用戶端已針對限流請求內建重試。某種程度的限流對應用程式來說不一定是問題，但資料工作流程中對延遲敏感的部分如果持續遭到限流，可能會對使用者體驗造成負面影響，並降低系統的整體效率。

在 ElastiCache Serverless 中調節請求時，您應該會看到 `ThrottledRequests` [ElastiCache Serverless](serverless-metrics-events-redis.md#serverless-metrics) 指標增加。如果您注意到有大量限流請求，請考慮下列事項：
+ **擴展速度：**ElastiCache Serverless 會在您擷取更多資料或增加請求率時自動擴展。如果您的應用程式擴展速度比 ElastiCache Serverless 擴展的速度快，則您的請求可能會在 ElastiCache Serverless 擴展以容納工作負載時受到調節。ElastiCache Serverless 通常可以快速增加儲存體大小，最多需要 10-12 分鐘才能將快取中的儲存體大小加倍。
+ **金鑰和請求的統一分佈：**在 ElastiCache for Valkey 和 Redis OSS 中，每個槽的金鑰或請求分佈不均可能會導致熱槽。如果單一槽的請求率超過每秒 30，000 個 ECPUs且位於執行簡單 SET/GET 命令的工作負載中，熱槽可能會導致請求限流。同樣地，使用 ElastiCache for Memcached 時，如果請求速率超過每秒 30，000 個 ECPUs熱金鑰可能會導致請求限流。
+ **從複本讀取：**如果您的應用程式允許，請考慮使用「從複本讀取」功能。大多數 Valkey 或 Redis OSS 用戶端可以設定為「擴展讀取」，將讀取導向複本節點。此功能可讓您擴展讀取流量。此外，ElastiCache Serverless 會自動將從複本請求讀取路由到與您應用程式相同可用區域中的節點，進而降低延遲。啟用僅供讀取複本時，對於具有簡單 SET/GET 命令的工作負載，您可以在單一插槽上達到每秒高達 90，000 ECPUs。

# 持續連線問題
<a name="TroubleshootingConnections"></a>

疑難排解使用 ElastiCache 的持續連線問題時，必須驗證下列項目：

**Topics**
+ [安全群組](#Security_groups)
+ [網路 ACL](#Network_ACLs)
+ [路由表](#Route_tables)
+ [DNS 解析](#DNS_Resolution)
+ [透過伺服器端診斷識別問題](#Diagnostics)
+ [網路連線能力驗證](#Connectivity)
+ [網路相關限制](#Network-limits)
+ [CPU 使用率](#CPU-Usage)
+ [從伺服器端終止連線](#Connections-server)
+ [Amazon EC2 執行個體的用戶端疑難排解](#Connections-client)
+ [解析完成單個請求所花費的時間](#Dissecting-time)

## 安全群組
<a name="Security_groups"></a>

安全群組是保護 ElastiCache 用戶端 (EC2 執行個體、 AWS Lambda 函數、Amazon ECS 容器等） 和 ElastiCache 快取的虛擬防火牆。安全群組具有狀態，這表示允許傳入或傳出流量之後，該流量的回應將在該特定安全群組的內容中自動授權。

具狀態功能需要安全群組追蹤所有授權的連線，而且追蹤的連線數有限額。如果達到限額，新的連線將會失敗。請參閱疑難排解一節，以取得如何識別用戶端或 Elasticache 端是否已達到限制的說明。

您可以將單一安全群組同時指派給用戶端和 ElastiCache 叢集，或為兩者分別指派單獨的安全群組。

針對這兩種情況，您都需要允許來源 ElastiCache 連接埠上的 TCP 傳出流量，並允許同一連接埠上的傳入流量傳送至 ElastiCache。Memcached 的預設連接埠為 11211，Valkey 或 Redis OSS 的預設連接埠為 6379。根據預設，安全群組允許所有對外流量。在此情況下，只需要目標安全群組中的傳入規則。

如需詳細資訊，請參閱[用於存取 Amazon VPC 中 ElastiCache 叢集的存取模式](elasticache-vpc-accessing.md)。

## 網路 ACL
<a name="Network_ACLs"></a>

網路存取控制清單 (ACL) 是無狀態規則。必須允許雙向 (傳入和傳出) 的流量才能成功。網路 ACL 會指派給子網路，而非特定資源。可以將相同的 ACL 指派給 ElastiCache 和用戶端資源，特別是如果它們位於相同的子網路中。

根據預設，網路 ACL 允許所有流量。不過，您可以自訂為拒絕或允許流量。此外，ACL 規則的評估會依序進行，這表示符合流量的數字最小規則將會予以允許或拒絕。允許 Valkey 或 Redis OSS 流量的最低組態為：

用戶端網路 ACL：
+ **傳入規則：**
+ Rule number (規則編號)：最好低於任何拒絕規則；
+ Type (類型)：Custom TCP Rule (自訂 TCP 規則)；
+ Protocol (通訊協定)：TCP
+ Port Range (連接埠範圍)：1024-65535
+ Source (來源)：0.0.0.0/0 (或為 ElastiCache 叢集子網路建立個別規則)
+ Allow/Deny (允許/拒絕)：Allow (允許)
+ **傳出規則：**
+ Rule number (規則編號)：最好低於任何拒絕規則；
+ Type (類型)：Custom TCP Rule (自訂 TCP 規則)；
+ Protocol (通訊協定)：TCP
+ Port Range (連接埠範圍)：6379
+ Source (來源)：0.0.0.0/0 (或 ElastiCache 叢集子網路。請記得，使用特定 IP 可能會在容錯移轉或擴展叢集時產生問題)
+ Allow/Deny (允許/拒絕)：Allow (允許)

ElastiCache 網路 ACL：
+ **傳入規則：**
+ Rule number (規則編號)：最好低於任何拒絕規則；
+ Type (類型)：Custom TCP Rule (自訂 TCP 規則)；
+ Protocol (通訊協定)：TCP
+ Port Range (連接埠範圍)：6379
+ Source (來源)：0.0.0.0/0 (或為 ElastiCache 叢集子網路建立個別規則)
+ Allow/Deny (允許/拒絕)：Allow (允許)
+ **傳出規則：**
+ Rule number (規則編號)：最好低於任何拒絕規則；
+ Type (類型)：Custom TCP Rule (自訂 TCP 規則)；
+ Protocol (通訊協定)：TCP
+ Port Range (連接埠範圍)：1024-65535
+ Source (來源)：0.0.0.0/0 (或 ElastiCache 叢集子網路。請記得，使用特定 IP 可能會在容錯移轉或擴展叢集時產生問題)
+ Allow/Deny (允許/拒絕)：Allow (允許)

如需詳細資訊，請參閱[網路 ACL](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html)。

## 路由表
<a name="Route_tables"></a>

類似於網路 ACL，每個子網路也可以有不同的路由表。如果用戶端和 ElastiCache 叢集位於不同的子網路中，請確定其路由表允許它們彼此連線。

較複雜的環境 (涉及多個 VPC、動態路由或網路防火牆) 可能會變得難以疑難排解。請參閱 [網路連線能力驗證](#Connectivity)，確認您的網路設定是否適當。

## DNS 解析
<a name="DNS_Resolution"></a>

ElastiCache 提供以 DNS 名稱為基礎的服務端點。可用的端點為 `Configuration`、`Primary`、`Reader` 及 `Node` 端點。如需詳細資訊，請參閱 [尋找連線端點](Endpoints.md)。

在修改容錯移轉或叢集的情況下，與端點名稱相關聯的地址可能會變更且會自動更新。

自訂 DNS 設定 (亦即不使用 VPC DNS 服務) 可能不知道 ElastiCache 提供的 DNS 名稱。請確認您的系統可以使用系統工具 (像是 `dig` (如下所示) 或 `nslookup`) 來成功解析 ElastiCache 端點。

```
$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com
example-001.xxxxxx.0001.use1.cache.amazonaws.com.
1.2.3.4
```

您也可以透過 VPC DNS 服務強制執行名稱解析：

```
$ dig +short example.xxxxxx.ng.0001.use1.cache.amazonaws.com @169.254.169.253
example-001.tihewd.0001.use1.cache.amazonaws.com.
1.2.3.4
```

## 透過伺服器端診斷識別問題
<a name="Diagnostics"></a>

來自 ElastiCache 引擎的 CloudWatch 指標和執行時間資訊，是用來識別潛在連線問題來源的常見來源或資訊。優質的分析資料通常從下列項目開始：
+ CPU 用量：Valkey 和 Redis OSS 是多執行緒應用程式。但是每個命令的執行發生在單個 (主) 執行序中。因此，ElastiCache 提供指標 `CPUUtilization`和 `EngineCPUUtilization`。 `EngineCPUUtilization`提供專用於 Valkey 或 Redis OSS 程序的 CPU 使用率，以及所有 vCPUs`CPUUtilization`的使用量。具有多個 vCPU 的節點的 `CPUUtilization` 和 `EngineCPUUtilization` 值一般會不同，後者通常較高。出現高 `EngineCPUUtilization`，可能是由於需要大量 CPU 時間才能完成的請求或複雜作業數量增加所造成。您可以透過以下項目來識別兩者：
  + 請求數增加：檢查其他符合 `EngineCPUUtilization` 模式的指標是否增加。有用的指標包括：
    + `CacheHits` 和 `CacheMisses`：成功請求或沒有在快取中找到有效項目的請求之數目。如果未命中與命中的比率很高，表示應用程式正在對無效果的請求浪費時間和資源。
    + `SetTypeCmds` 和 `GetTypeCmds`：這些指標與 `EngineCPUUtilization` 相關，有助於了解寫入請求 (由 `SetTypeCmds` 測量) 或讀取請求 (由 `GetTypeCmds` 測量) 的負載是否明顯高。如果負載主要是讀取作業，使用多個僅供讀取複本可以在多個節點之間平衡請求，並撥出主節點用於寫入作業。在停用叢集模式的叢集中，可以使用 ElastiCache 讀取者端點，在應用程式中建立額外的連線組態以使用僅供讀取複本。如需詳細資訊，請參閱 [尋找連線端點](Endpoints.md)。讀取作業必須提交至這個額外的連線。寫入作業將透過一般主要端點完成。在啟用叢集模式的情況下，建議您使用原生支援僅供讀取複本的程式庫。使用正確的旗標，程式庫將能夠自動探索叢集拓撲、複本節點、透過 [READONLY](https://valkey.io/commands/readonly) Valkey 或 Redis OSS 命令啟用讀取操作，並將讀取請求提交至複本。
  + 連線數增加：
    + `CurrConnections` 和 `NewConnections`：`CurrConnection` 是收集資料點時的已建立連線數，而 `NewConnections` 會顯示這段期間內建立的連線數。

      建立和處理連線意味著可觀的 CPU 額外負荷。此外，成立新連線所需的 TCP 三向交握會對整體回應時間產生負面影響。

      一個每分鐘有數以千計 `NewConnections` 的 ElastiCache 節點，表示成立的連線只供幾個命令使用，這並非最佳做法。保持連線的成立狀態，並重複使用這些連線來進行新作業是最佳實務。當用戶端應用程式支援並妥善實作連線集區或持續連線時，此情況有可能實現。使用連線集區時，`currConnections` 數不會有很大的變化，而 `NewConnections` 應盡可能壓低。Valkey 和 Redis OSS 透過少量 currConnections 提供最佳效能。讓 CurrConnection 數量維持在大約數十或數百個，可最大限度壓低資源的使用量，以支援個別連線，例如供連線使用的用戶端緩衝區和 CPU 週期。
  + 網路輸送量：
    + 判斷頻寬：ElastiCache 節點的網路頻寬與節點大小成比例。由於應用程式具有不同的特性，結果可能會根據工作負載而有所不同。舉例來說，小型請求率高的應用程式，對 CPU 使用率造成的影響往往高於網路輸送量，而索引鍵較大則會造成網路使用率較高。因此，建議您使用實際工作負載來測試節點，以便更深入了解限制。

      模擬來自應用程式的負載會提供更準確的結果。但是，基準化分析工具可讓您更妥善了解限制。
    + 針對請求主要都是讀取的情況，使用複本進行讀取作業將能減輕主節點上的負載。如果使用案例主要是寫入，則使用許多複本將會提高網路使用量。針對寫入主節點的每個位元組，系統會將 N 個位元組傳送到複本 (N 即複本的數量)。寫入密集型工作負載的最佳實務是使用啟用叢集模式的 ElastiCache for Redis OSS，以便跨多個碎片平衡寫入，或擴展到具有更多網路功能的節點類型。
    + CloudWatch 指標 `NetworkBytesIn` 和 `NetworkBytesOut` 分別提供傳入或傳出節點的資料量。`ReplicationBytes` 則適用於資料複寫專屬的流量。

    如需詳細資訊，請參閱[網路相關限制](#Network-limits)。
  + 複雜命令：Redis OSS 命令會在單一執行緒上提供，這表示請求會依序提供。單一緩慢命令可能會影響其他請求和連線，最終導致逾時。使用作用於多個值、索引鍵或資料類型的命令時必須小心。根據參數的數量或其輸入或輸出值的大小，可能會封鎖或終止連線。

    一個惡名昭彰的例子是 `KEYS` 命令。它會掃描整個 Keyspace，搜尋指定的模式，並在其執行過程中阻止其他命令的執行。Redis OSS 使用「Big O」表示法來描述其命令複雜性。

    索引鍵命令帶有 O(N) 時間複雜度，N 是資料庫中索引鍵的數量。因此，索引鍵數越多，命令執行速度就會越慢。`KEYS` 可能會以不同的方式造成問題：如果沒有使用搜尋模式，該命令將會傳回所有可用的索引鍵名稱。在具有數千個或數百萬個項目的資料庫中，系統會建立巨大的輸出並淹沒網路緩衝區。

    如果使用搜尋模式，則只會將符合該模式的索引鍵傳回用戶端。但是，引擎仍然會掃描整個 Keyspace 搜尋它，且完成命令的時間相同。

    `KEYS` 的替代方案是 `SCAN` 命令。它會反覆運算 Keyspace，限制在特定數量的項目中執行反覆運算，避免延長引擎上區塊的執行時間。

    掃描具有 `COUNT` 參數，用來設定反覆運算區塊的大小。預設值為 10 (每個反覆運算 10 個項目)。

    根據資料庫中項目數的不同，`COUNT` 值小的區塊需執行更多的反覆運算才能完成完整掃描，而較大的值每次反覆運算時會讓引擎維持忙碌狀態更久。小計數值會使 `SCAN` 執行速度較慢，而較大的值可能會對 `KEYS` 造成上述相同問題。

    範例是以計數值 10 執行 `SCAN` 命令，將需要在具有 1 百萬個索引鍵的資料庫上進行 100,000 次重複作業。如果平均網路封包來回時間為 0.5 毫秒，則傳輸請求會花費大約 50,000 毫秒 (50 秒)。

    另一方面，如果計數值為 100,0000，則需要執行單次反覆運算，且傳輸只會花 0.5 毫秒。不過，引擎會完全封鎖其他作業，直到該命令完成掃描所有的 Keyspace。

    除了 `KEYS` 以外，如果未正確使用，其他幾個命令可能有害。若要查看所有命令及其個別時間複雜性的清單，請前往 [Valkey 和 Redis OSS 命令](https://valkey.io/commands)。

    潛在問題範例：
    + Lua 指令碼：Valkey 和 Redis OSS 提供內嵌 Lua 解譯器，允許在伺服器端執行指令碼。Valkey 和 Redis OSS 上的 Lua 指令碼是在引擎層級執行，依定義為原子，這表示指令碼執行時不允許執行其他命令或指令碼。Lua 指令碼可讓您直接在引擎上執行多個命令、決策演算法、資料剖析等。雖然這類指令碼的不可部分完成特性和卸載應用程式的機會很誘人，但將指令碼用於小型作業時必須小心。在 ElastiCache 上，Lua 指令碼的執行時間限制為 5 秒。未寫入 Keyspace 的指令碼將在 5 秒過後自動終止。為了避免資料損毀和不一致，如果指令碼執行沒有在 5 秒內完成，且執行期間有任何寫入，節點便會容錯移轉。[交易](https://valkey.io/topics/transactions)是保證 Redis OSS 中多個相關金鑰修改一致性的替代方案。交易允許執行一個命令區塊，觀察現有的索引鍵修改項目。如果觀察的任何索引鍵在交易完成之前有所變更，系統會捨棄所有修改。
    + 大量刪除項目：`DEL` 命令接受多個參數，這些參數是要刪除的索引鍵名稱。刪除作業會同步進行，如果參數清單很大，或是包含大型清單、集合、排序集合或雜湊 (包含多個子項目的資料結構)，則需花費大量的 CPU 時間。換句話說，如果單一索引鍵有許多元素，即使只是刪除單一索引鍵，也可能需要花相當長的時間。的替代方案`DEL`是 `UNLINK`，這是可用的非同步命令，因為 Redis OSS 4。 `UNLINK` 必須`DEL`盡可能優先於 。從 ElastiCache for Redis OSS 6x 開始， `lazyfree-lazy-user-del` 參數會讓`DEL`命令的行為與啟用`UNLINK`時類似。如需詳細資訊，請參閱 [Redis OSS 6.0 參數變更。](ParameterGroups.Engine.md#ParameterGroups.Redis.6-x)
    + 對多個索引鍵上產生作用的命令：先前提到的 `DEL` 是接受多個參數的命令，且其執行時間將直接與此成正比。不過，Redis OSS 提供更多類似運作的命令。範例為 `MSET` 和 `MGET` 允許一次插入或檢索多個字串索引鍵。使用它們可能有助於減少許多個別 `SET` 或 `GET` 命令的固有網路延遲。不過，廣泛的參數清單會影響 CPU 使用率。

       雖然單獨 CPU 使用率並不是連線問題的原因，但花太多時間對多個索引鍵處理單一或幾個命令，可能會造成其他請求失敗，並增加整體 CPU 使用率。

      索引鍵的數量和大小會影響命令的複雜性，進而影響完成時間。

      可以作用於多個索引鍵的其他命令範例有：`HMGET`、`HMSET`、`MSETNX`、`PFCOUNT`、`PFMERGE`、`SDIFF`、`SDIFFSTORE`、`SINTER`、`SINTERSTORE`、`SUNION`、`SUNIONSTORE`、`TOUCH`、`ZDIFF`、`ZDIFFSTORE`、`ZINTER` 或 `ZINTERSTORE`。
    + 作用於多種資料類型的命令：Redis OSS 也提供作用於一或多個金鑰的命令，無論其資料類型為何。ElastiCache for Redis OSS 提供`KeyBasedCmds`監控此類命令的指標。此指標會加總在所選期間內執行下列命令的次數：
      + O(N) 複雜性：
        + `KEYS`
      + O(1)
        + `EXISTS`
        + `OBJECT`
        + `PTTL`
        + `RANDOMKEY`
        + `TTL`
        + `TYPE`
        + `EXPIRE`
        + `EXPIREAT`
        + `MOVE`
        + `PERSIST`
        + `PEXPIRE`
        + `PEXPIREAT`
        + `UNLINK (O(N)` 用於回收記憶體。但是，記憶體回收任務發生在單獨一個執行序中，且不會阻止引擎
      + 根據資料類型而不同的複雜性時間：
        + `DEL`
        + `DUMP`
        + `RENAME` 視為具有 O(1) 複雜性的命令，但在 `DEL` 內部執行。執行時間會依重新命名索引鍵的大小而變動。
        + `RENAMENX`
        + `RESTORE`
        + `SORT`
      + 大雜湊：雜湊是一種資料類型，允許單個索引鍵具有多個鍵值子項目。每個雜湊都可以存放 4.294.967.295 個項目，且大雜湊上的作業可能會變得非常昂貴。與 `KEYS` 類似，雜湊具有帶有 O(N) 時間複雜度的 `HKEYS` 命令，N 是雜湊中的項目數。`HSCAN` 必須優先於 `HKEYS` 以避免長時間執行命令。`HDEL`、`HGETALL`、`HMGET`、`HMSET` 和 `HVALS` 命令應在大雜湊上謹慎使用。
    + 其他大數據結構：除了雜湊之外，其他資料結構可能是 CPU 密集型。集合、清單、排序集合和 Hyperloglog 也可能需要花大量時間來操作，取決於其大小和使用的命令。如需這些命令的詳細資訊，請參閱 [Valkey 和 Redis OSS 命令](https://valkey.io/commands)。

## 網路連線能力驗證
<a name="Connectivity"></a>

檢閱與 DNS 解析、安全群組、網路 ACL 和路由表相關的網路組態之後，可以使用 VPC Reachability Analyzer 和系統工具來驗證連線。

Reachability Analyzer 會測試網路連線能力，並確認是否滿足所有的需求和許可。對於下面的測試，您將需要 VPC 中其中一個可用 ElastiCache 節點的 ENI ID (彈性網路介面識別)。若要取得此資料，請執行下列操作：

1. 前往 [https://console.aws.amazon.com/ec2/v2/home?\$1NIC:](https://console.aws.amazon.com/ec2/v2/home?#NIC)

1. 依 ElastiCache 叢集名稱或先前從 DNS 驗證取得的 IP 地址篩選介面清單。

1. 寫下或以其他方式儲存 ENI ID。如果顯示多個介面，請檢閱描述，確認它們屬於正確的 ElastiCache 叢集，並選擇其中一個介面。

1. 繼續下一個步驟。

1. 於 [https://console.aws.amazon.com/vpc/home?\$1ReachabilityAnalyzer](https://console.aws.amazon.com/vpc/home?#ReachabilityAnalyzer) 建立分析路徑，然後選擇下列選項：
   + **來源類型**：****如果您的 ElastiCache 用戶端在 Amazon EC2 執行個體上執行，則選擇****執行個體；如果 ElastiCache 用戶端使用其他服務，例如 Amazon ECS AWS Fargate 搭配 awsvpc 網路等），以及各自的資源 ID (EC2 執行個體或 ENI ID) AWS Lambda；
   + **Destination Type (目的地類型)**：選擇 **Network Interface (網路介面)**，然後從清單中選取 **ElastiCache ENI**。
   + **目的地連接埠**：針對 ElastiCache for Redis OSS 指定 6379，或針對 ElastiCache for Memcached 指定 11211。這些是使用預設組態定義的連接埠，此範例假設未加以變更。
   + **Protocol (通訊協定)**：TCP

建立分析路徑，並等待一段時間產生結果。如果狀態為無法連線，請開啟分析詳細資料並檢閱**分析總管**，取得遭封鎖請求的詳細資訊。

如果通過可連線性測試，請繼續執行作業系統層級的驗證。

若要驗證 ElastiCache 服務連接埠上的 TCP 連線能力：在 Amazon Linux 上，`Nping`可用於 `nmap` 套件，且可以測試 ElastiCache 連接埠上的 TCP 連線能力，以及提供成立連線所需的網路封包來回時間。使用此項來驗證 ElastiCache 叢集的網路連線能力和目前的延遲，如下所示：

```
$ sudo nping --tcp -p 6379 example.xxxxxx.ng.0001.use1.cache.amazonaws.com

Starting Nping 0.6.40 ( http://nmap.org/nping ) at 2020-12-30 16:48 UTC
SENT (0.0495s) TCP ...
(Output suppressed )

Max rtt: 0.937ms | Min rtt: 0.318ms | Avg rtt: 0.449ms
Raw packets sent: 5 (200B) | Rcvd: 5 (220B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 4.08 seconds
```

根據預設，`nping` 每傳送 5 次探查會延遲 1 秒。您可以使用「-c」選項來增加探查數，並使用「--delay」來變更傳送新測試的時間。

如果測試出現 `nping` 失敗，且通過了 *VPC Reachability Analyzer* 測試，請您的系統管理員檢閱可能的主機式防火牆規則、非對稱式路由規則，或是作業系統層級任何其他可能的限制。

在 ElastiCache 主控台上，檢查 ElastiCache 叢集詳細資訊中的**傳輸中加密**是否已啟用。如果已啟用傳輸中加密，請確認是否可以使用下列命令建立 TLS 工作階段：

```
openssl s_client -connect example.xxxxxx.use1.cache.amazonaws.com:6379
```

如果連線和 TLS 交涉成功，預期會有密集的傳出。檢查最後一行中可用的傳回碼，該值必須是 `0 (ok)`。如果 openssl 傳回不同的內容，請前往以下頁面查看錯誤原因：[https://www.openssl.org/docs/man1.0.2/man1/verify.html\$1DIAGNOSTICS](https://www.openssl.org/docs/man1.0.2/man1/verify.html#DIAGNOSTICS)。

如果通過了所有基礎設施和作業系統測試，但您的應用程式仍然無法連線至 ElastiCache，請檢查應用程式組態是否符合 ElastiCache 設定。常見的錯誤包括：
+ 應用程式不支援 ElastiCache 叢集模式，且啟用叢集模式；
+ 應用程式不支援 TLS/SSL，且已啟用 ElastiCache 傳輸中加密功能；
+ 應用程式支援 TLS/SSL，但沒有正確的組態標記或信任的憑證授權機構；

## 網路相關限制
<a name="Network-limits"></a>
+ 連線數上限：同時連線數具有硬性限制。每個 ElastiCache 節點在所有用戶端間的同時連線數上限為 65,000 個。此限制可透過 CloudWatch 上的 `CurrConnections` 指標進行監控。不過，用戶端也有自己的傳出連線限制。在 Linux 上，請使用下列命令檢查允許的暫時性連接埠範圍：

  ```
  # sysctl net.ipv4.ip_local_port_range
  net.ipv4.ip_local_port_range = 32768 60999
  ```

  在前面的例子中，允許來自相同來源的 28231 個連線連至相同的目的地 IP (ElastiCache 節點) 和連接埠。下列命令顯示特定 ElastiCache 節點 (IP 1.2.3.4) 的連線數量：

  ```
  ss --numeric --tcp state connected "dst 1.2.3.4 and dport == 6379" | grep -vE '^State' | wc -l
  ```

  如果數字太高，您的系統可能會因為嘗試處理連線請求而過載。建議考慮實作適用技術，例如連線集區或持續連線，以便更妥善處理連線。盡可能設定連線集區，將連線數上限限制為幾百個。此外，用於處理逾時或其他連線例外狀況的退避邏輯是明智的做法，可避免發生問題的情況下連線流失。
+ 網路流量限制：檢查 [Redis OSS 的下列 CloudWatch 指標](CacheMetrics.Redis.md)，以識別 ElastiCache 節點上可能達到的網路限制：
  + `NetworkBandwidthInAllowanceExceeded`/`NetworkBandwidthOutAllowanceExceeded`：因為輸送量超過彙總頻寬限制而形成的網路封包。

    請務必注意，寫入主節點的每個位元組都會複寫到 N 個複本 (N 是複本數)。具有小型節點類型、多個複本以及密集寫入型請求的叢集，可能無法處理複寫待處理項目。對於這種情況，最佳實務是擴充規模 (更改節點類型)、水平擴展 (在啟用叢集模式的叢集中增加碎片)，減少複本數或最大限度減少寫入次數。
  + `NetworkConntrackAllowanceExceeded`：因為超過指派給節點的連線數 (在所有安全群組之間追蹤) 上限而形成的封包。這段期間內，新的連線可能會失敗。
  + `NetworkPackets PerSecondAllowanceExceeded`：超過每秒的封包數上限。以高極小型請求率為基礎的工作負載，可能會在達到頻寬上限之前達到此限制。

  上述指標是確認節點達到網路限制的理想方式。但是，限制也可以藉由網路指標維持平穩來識別。

  如果觀察到很長時間都維持平穩，接著可能會出現複寫延遲、用於快取的位元組增加、可釋出的記憶體減少，高交換和 CPU 使用率。Amazon EC2 執行個體也有網路限制，可透過 [ENA 驅動程式指標](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html)追蹤。搭配增強型網路支援和 ENA 驅動程式 2.2.10 或更新版本的 Linux 執行個體，可以使用下列命令檢閱限制計數器：

  ```
  # ethtool -S eth0 | grep "allowance_exceeded"
  ```

## CPU 使用率
<a name="CPU-Usage"></a>

CPU 使用率指標是調查的起點，下列項目有助於縮小 ElastiCache 端的可能問題範圍：
+ Redis OSS SlowLogs：ElastiCache 預設組態會保留最後 128 個需要超過 10 毫秒才能完成的命令。慢速命令的歷史記錄會在引擎執行時間內保留，且會在故障或重新啟動的情況下遺失。如果清單達到 128 個項目，將會刪除舊活動，為新的活動騰出空間。慢速事件清單的大小和視為緩慢的執行時間，可以透過[自訂參數群組](ParameterGroups.md)中的 `slowlog-max-len` 和 `slowlog-log-slower-than` 參數加以修改。慢速日誌清單可以透過在引擎上執行 `SLOWLOG GET 128` 來擷取，其中 128 是最後回報的 128 個慢速命令。每個項目都有下列欄位：

  ```
  1) 1) (integer) 1 -----------> Sequential ID
     2) (integer) 1609010767 --> Timestamp (Unix epoch time)of the Event
     3) (integer) 4823378 -----> Time in microseconds to complete the command.
     4) 1) "keys" -------------> Command
        2) "*" ----------------> Arguments 
     5) "1.2.3.4:57004"-> Source
  ```

  上述事件發生在 12 月 26 日 19:26:07 (UTC)，花了 4.8 秒 (4.823 毫秒) 完成，其原因是從用戶端 1.2.3.4 請求的 `KEYS` 命令。

  在 Linux 上，時間戳記可以使用命令日期轉換：

  ```
  $ date --date='@1609010767'
  Sat Dec 26 19:26:07 UTC 2020
  ```

  使用 Python：

  ```
  >>> from datetime import datetime
  >>> datetime.fromtimestamp(1609010767)
  datetime.datetime(2020, 12, 26, 19, 26, 7)
  ```

  或在 Windows 上使用 PowerShell：

  ```
  PS D:\Users\user> [datetimeoffset]::FromUnixTimeSeconds('1609010767')
  DateTime      : 12/26/2020 7:26:07 PM
  UtcDateTime  
                  : 12/26/2020 7:26:07 PM
  LocalDateTime : 12/26/2020 2:26:07 PM
  Date          : 12/26/2020 12:00:00 AM
  Day           : 26
  DayOfWeek    
                  : Saturday
  DayOfYear     : 361
  Hour          : 19
  Millisecond   : 0
  Minute        : 26
  Month        
                  : 12
  Offset        : 00:00:00Ticks         : 637446075670000000
  UtcTicks     
                  : 637446075670000000
  TimeOfDay     : 19:26:07
  Year          : 2020
  ```

  在短時間內 (一分鐘以內) 出現許多緩慢命令是值得關注的原因。檢閱命令的性質及如何最佳化 (請參閱前面的範例)。如果經常回報具有 O(1) 時間複雜性的命令，請檢查之前提到出現高 CPU 使用率的其他因素。
+ 延遲指標：ElastiCache for Redis OSS 提供 CloudWatch 指標，以監控不同類別命令的平均延遲。資料點的計算方式是將類別中命令的執行總次數除以期間的總執行時間。請務必了解，延遲指標結果是多個命令的彙總結果。單一命令可能會導致非預期的結果 (例如逾時)，而不會對指標造成重大影響。針對這種情況，慢速事件會是更準確的資訊來源。下列清單包含可用的延遲指標，以及影響這些指標的各別命令。
  + EvalBasedCmdsLatency：與 Lua 指令碼命令、`eval`、`evalsha` 有關；
  + GeoSpatialBasedCmdsLatency：`geodist`、`geohash`、`geopos`、`georadius`、`georadiusbymember`、`geoadd`；
  + GetTypeCmdsLatency：讀取命令，不論資料類型為何；
  + HashBasedCmdsLatency：`hexists`、`hget`、`hgetall`、`hkeys`、`hlen`、`hmget`、`hvals`、`hstrlen`、`hdel`、`hincrby`、`hincrbyfloat`、`hmset`、`hset`、`hsetnx`；
  + HyperLogLogBasedCmdsLatency：`pfselftest`、`pfcount`、`pfdebug`、`pfadd`、`pfmerge`；
  + KeyBasedCmdsLatency：可作用於不同資料類型的命令：`dump`、`exists`、`keys`、`object`、`pttl`、`randomkey`、`ttl`、`type`、`del`、`expire`、`expireat`、`move`、`persist`、`pexpire`、`pexpireat`、`rename`、`renamenx`、`restoreK`、`sort`、`unlink`；
  + ListBasedCmdsLatency：lindex、llen、lrange、blpop、brpop、brpoplpush、linsert、lpop、lpush、lpushx、lrem、lset、ltrim、rpop、rpoplpush、rpush、rpushx；
  + PubSubBasedCmdsLatency：psubscribe、publish、pubsub、punsubscribe、subscribe、unsubscribe；
  + SetBasedCmdsLatency：`scard`、`sdiff`、`sinter`、`sismember`、`smembers`、`srandmember`、`sunion`、`sadd`、`sdiffstore`、`sinterstore`、`smove`、`spop`、`srem`、`sunionstore`；
  + SetTypeCmdsLatency：寫入命令，無論資料類型為何；
  + SortedSetBasedCmdsLatency：`zcard`、`zcount`、`zrange`、`zrangebyscore`、`zrank`、`zrevrange`、`zrevrangebyscore`、`zrevrank`、`zscore`、`zrangebylex`、`zrevrangebylex`、`zlexcount`、`zadd`。`zincrby`、`zinterstore`、`zrem`、`zremrangebyrank`、`zremrangebyscore`、`zunionstore`、`zremrangebylex`、`zpopmax`、`zpopmin`、`bzpopmin`、`bzpopmax`；
  + StringBasedCmdsLatency：`bitcount`、`get`、`getbit`、`getrange`、`mget`、`strlen`、`substr`、`bitpos`、`append`、`bitop`、`bitfield`、`decr`、`decrby`、`getset`、`incr`、`incrby`、`incrbyfloat`、`mset`、`msetnx`、`psetex`、`set`、`setbit`、`setex`、`setnx`、`setrange`；
  + StreamBasedCmdsLatency：`xrange`、`xrevrange`、`xlen`、`xread`、`xpending`、`xinfo`、`xadd`、`xgroup`、`readgroup`、`xack`、`xclaim`、`xdel`、`xtrim`、`xsetid`；
+ Redis OSS 執行期命令：
  + info commandstats：提供自引擎啟動以來執行的命令清單、其累積執行次數、總執行時間和每個命令的平均執行時間；
  + client list：提供目前連線的用戶端和相關資訊的清單，如緩衝區使用率、上次執行的命令等；
+ 備份和複寫：2.8.22 之前的 ElastiCache for Redis OSS 版本使用分支程序來建立備份，並處理與複本的完整同步。這種方法可能會在寫入密集型使用案例中產生顯著的記憶體額外負荷。

  從 ElastiCache Redis OSS 2.8.22 開始， AWS 推出了無分支備份和複寫方法。新方法可能會延遲寫入以防止失敗。這兩種方法都會造成某些時段的 CPU 使用率較高，導致更長的回應時間，進而引發用戶端在執行期間逾時。請一律檢查是否在備份期間內發生用戶端故障或 `SaveInProgress` 指標為 1 的情況。建議您將備份時段排定為使用率低的時段，盡量減少用戶端發生問題或備份失敗的可能性。

## 從伺服器端終止連線
<a name="Connections-server"></a>

預設的 ElastiCache for Redis OSS 組態會無限期地建立用戶端連線。不過在某些情況下可能需終止連線。例如：
+ 用戶端應用程式中的錯誤可能會造成連線遭遺忘，並以閒置狀態保持成立。這就是所謂的「連線流失」，結果會發現 `CurrConnections` 指標中已成立的連線數穩定增加。這種行為可能會導致用戶端或 ElastiCache 端飽和。當無法從用戶端進行立即修正時，有些系統管理員會在其 ElastiCache 參數群組中設定「逾時」值。逾時是讓閒置連線持續存在的時間 (以秒為單位)。如果用戶端在此期間未提交任何請求，一旦連線達到逾時值，引擎就會立即終止連線。較小的逾時值可能會導致不必要的連線中斷，屆時用戶端需要妥善處理並重新連線，進而導致延遲。
+ 用於存放索引鍵的記憶體與用戶端緩衝區共用。具有大型請求或回應的慢速用戶端，可能需要大量的記憶體來處理其緩衝區。預設 ElastiCache for Redis OSS 組態不會限制一般用戶端輸出緩衝區的大小。如果達到 `maxmemory` 上限，引擎將會嘗試移出項目以滿足緩衝區使用量。在極低的記憶體條件下，ElastiCache for Redis OSS 可能會選擇中斷連接使用大型用戶端輸出緩衝區的用戶端，以釋放記憶體並保留叢集的運作狀態。

  可以使用自訂組態來限制用戶端緩衝區的大小，且用戶端達到限制時將會中斷連線。不過用戶端應該能處理未預期的中斷連線。處理一般用戶端的緩衝區大小的參數如下：
  + client-query-buffer-limit：單一輸入請求的大小上限；
  + client-output-buffer-limit-normal-soft-limit：用戶端連線數的軟限制。如果高於軟限制的持續時間超過 client-output-buffer-limit-normal-soft-seconds 定義的時間 (以秒為單位)，或者達到硬限制，則連線將會終止；
  + client-output-buffer-limit-normal-soft-seconds：允許連線超過 client-output-buffer-limit-normal-soft-limit 的時間；
  + client-output-buffer-limit-normal-hard-limit：達到此限制的連線將立即終止。

  除了一般用戶端緩衝區，下列選項也可控制複本節點和 Pub/Sub (發佈/訂閱) 用戶端的緩衝區：
  + client-output-buffer-limit-replica-hard-limit；
  + client-output-buffer-limit-replica-soft-seconds；
  + client-output-buffer-limit-replica-hard-limit；
  + client-output-buffer-limit-pubsub-soft-limit；
  + client-output-buffer-limit-pubsub-soft-seconds；
  + client-output-buffer-limit-pubsub-hard-limit；

## Amazon EC2 執行個體的用戶端疑難排解
<a name="Connections-client"></a>

用戶端的負載和回應速度也可能會影響傳給 ElastiCache 的請求。疑難排解間歇性連線或逾時問題時，需要仔細檢閱 EC2 執行個體和作業系統限制。幾項需觀察的要點：
+ CPU：
  + EC2 執行個體 CPU 使用率：確定 CPU 尚未飽和或接近 100%。歷史分析可以透過 CloudWatch 完成，但請記得，資料點的精密度可為 1 分鐘 (啟用詳細監控時) 或 5 分鐘；
  + 如果使用[高載 EC2 執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html)，請確定其 CPU 餘額尚未耗盡。`CPUCreditBalance` CloudWatch 指標提供此資訊。
  + 短時間的高 CPU 使用率可能會導致逾時，而不會反映 CloudWatch 上的 100% 使用率。這種情況需使用作業系統工具 (如 `top`、`ps` 和 `mpstat`) 進行即時監控。
+ 網路
  + 根據執行個體容量檢查網路輸送量是否低於可接受的值。如需詳細資訊，請參閱 [Amazon EC2 執行個體類型](https://aws.amazon.com/ec2/instance-types/)
  + 在具有 `ena` 增強型網路驅動程式的執行個體上，查看 [ENA 統計數字](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/troubleshooting-ena.html#statistics-ena)以取得逾時或超出的限制。下列統計數字有助於確認網路限制飽和情況：
    + `bw_in_allowance_exceeded`/`bw_out_allowance_exceeded`：因過量的傳入或傳出輸送量而造成的封包數；
    + `conntrack_allowance_exceeded`：由於安全群組[連線追蹤限制](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html#connection-tracking-throttling)而捨棄的封包數。當此限制飽和時，新的連線將會失敗；
    + `linklocal_allowance_exceeded`：由於透過 VPC DNS 對執行個體中繼資料 NTP 發出過多請求而捨棄的封包數。所有服務的限制都是每秒 1024 個封包；
    + `pps_allowance_exceeded`：由於每秒封包比率過高而捨棄的封包數。當網路流量包含每秒數千或數百萬個極小的請求時，便可能達到 PPS 限制。ElastiCache 流量可以進行最佳化，透過管道或一次執行多個作業的命令 (例如 `MGET` 而不是 `GET`)，藉此更妥善使用網路封包。

## 解析完成單個請求所花費的時間
<a name="Dissecting-time"></a>
+ 在網路上：`Tcpdump` 和 `Wireshark` (命令列上的 tshark) 是便利的工具，可用於了解請求在網路上傳輸、命中 ElastiCache 引擎並取得傳回資料所花的時間。下列範例說明如何使用下列命令建立單一請求：

  ```
  $ echo ping | nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com 6379
  +PONG
  ```

  tcpdump 與上面的命令同時執行並傳回了：

  ```
  $ sudo tcpdump -i any -nn port 6379 -tt
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  1609428918.917869 IP 172.31.11.142.40966
      > 172.31.11.247.6379: Flags [S], seq 177032944, win 26883, options [mss 8961,sackOK,TS val 27819440 ecr 0,nop,wscale 7], length 0
  1609428918.918071 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [S.], seq 53962565, ack 177032945, win
      28960, options [mss 1460,sackOK,TS val 3788576332 ecr 27819440,nop,wscale 7], length 0
  1609428918.918091 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0
  1609428918.918122
      IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [P.], seq 1:6, ack 1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 5: RESP "ping"
  1609428918.918132 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [F.], seq 6, ack
      1, win 211, options [nop,nop,TS val 27819440 ecr 3788576332], length 0
  1609428918.918240 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [.], ack 6, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0
  1609428918.918295
      IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [P.], seq 1:8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 7: RESP "PONG"
  1609428918.918300 IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 8, win
      211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0
  1609428918.918302 IP 172.31.11.247.6379 > 172.31.11.142.40966: Flags [F.], seq 8, ack 7, win 227, options [nop,nop,TS val 3788576332 ecr 27819440], length 0
  1609428918.918307
      IP 172.31.11.142.40966 > 172.31.11.247.6379: Flags [.], ack 9, win 211, options [nop,nop,TS val 27819441 ecr 3788576332], length 0
  ^C
  10 packets captured
  10 packets received by filter
  0 packets dropped by kernel
  ```

  從上方的輸出中，我們可以確認 TCP 三向交握花了 222 微秒 (918091 - 917869) 完成，並且花 173 微秒 (918295 - 918122) 提交並傳回 Ping 命令。

   從請求到關閉連線花了 438 微秒 (918307 - 917869)。這些結果可以確認網路和引擎的回應時間良好，而且可以專注於其他元件進行調查。
+ 在作業系統上：`Strace` 有助於識別作業系統層級的時間落差。實際應用程式的分析會更廣泛，建議使用專門的應用程式剖析工具或除錯工具。下列範例只會顯示基礎作業系統元件是否正常運作，若不正常則可能需要進一步調查。使用相同的 Redis OSS `PING`命令搭配`strace`我們取得：

  ```
  $ echo ping | strace -f -tttt -r -e trace=execve,socket,open,recvfrom,sendto nc example.xxxxxx.ng.0001.use1.cache.amazonaws.com (http://example.xxxxxx.ng.0001.use1.cache.amazonaws.com/)
      6379
  1609430221.697712 (+ 0.000000) execve("/usr/bin/nc", ["nc", "example.xxxxxx.ng.0001.use"..., "6379"], 0x7fffede7cc38 /* 22 vars */) = 0
  1609430221.708955 (+ 0.011231) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
  1609430221.709084
      (+ 0.000124) socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
  1609430221.709258 (+ 0.000173) open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
  1609430221.709637 (+ 0.000378) open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
  1609430221.709923
      (+ 0.000286) open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
  1609430221.711365 (+ 0.001443) open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
  1609430221.713293 (+ 0.001928) socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
  1609430221.717419
      (+ 0.004126) recvfrom(3, "\362|\201\200\0\1\0\2\0\0\0\0\rnotls20201224\6tihew"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 155
  1609430221.717890 (+ 0.000469) recvfrom(3, "\204\207\201\200\0\1\0\1\0\0\0\0\rnotls20201224\6tihew"...,
      65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.31.0.2")}, [28->16]) = 139
  1609430221.745659 (+ 0.027772) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
  1609430221.747548 (+ 0.001887) recvfrom(0, 0x7ffcf2f2ca50, 8192,
      0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK (Socket operation on non-socket)
  1609430221.747858 (+ 0.000308) sendto(3, "ping\n", 5, 0, NULL, 0) = 5
  1609430221.748048 (+ 0.000188) recvfrom(0, 0x7ffcf2f2ca50, 8192, 0, 0x7ffcf2f2c9d0, [128]) = -1 ENOTSOCK
      (Socket operation on non-socket)
  1609430221.748330 (+ 0.000282) recvfrom(3, "+PONG\r\n", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 7
  +PONG
  1609430221.748543 (+ 0.000213) recvfrom(3, "", 8192, 0, 0x7ffcf2f2c9d0, [128->0]) = 0
  1609430221.752110
      (+ 0.003569) +++ exited with 0 +++
  ```

   在上面的例子中，該命令花費超過 54 毫秒才完成 (752110 - 697712 = 54398 微秒)。

   將 nc 執行個體化並執行名稱解析花了約 20 毫秒的大量時間 (從 697712 到 717890)，在這之後，花了 2 毫秒來建立 TCP 通訊端 (745659 到 747858)，再花 0.4 毫秒 (747858 到 748330) 提交和接收請求的回應。

## 相關主題
<a name="wwe-troubleshooting.related"></a>
+ [ElastiCache 最佳實務和快取策略](BestPractices.md)