持續性連線問題 - Amazon ElastiCache

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

持續性連線問題

使用 疑難排解持續性連線問題時,必須驗證下列項目 ElastiCache:

安全群組

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

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

您可以同時將單一安全群組指派給用戶端和 ElastiCache 叢集,或為每個群組指派個別安全群組。

對於這兩種情況,您需要允許來自來源的 ElastiCache 連接埠上的TCP傳出流量,以及相同連接埠上的傳入流量到 ElastiCache。Memcached 的預設連接埠為 11211,Valkey 或 Redis 為 6379OSS。根據預設,安全群組允許所有對外流量。在此情況下,只需要目標安全群組中的傳入規則。

如需詳細資訊,請參閱存取 Amazon 中 ElastiCache 叢集的存取模式VPC

網路 ACLs

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

根據預設,網路ACLs允許所有交易。不過,您可以自訂為拒絕或允許流量。此外,ACL規則的評估是依序的,這表示符合流量的最低數字的規則將允許或拒絕它。允許 Valkey 或 Redis OSS流量的最小組態為:

用戶端網路ACL:

  • 傳入規則:

  • Rule number (規則編號):最好低於任何拒絕規則;

  • 類型:自訂TCP規則;

  • 通訊協定: TCP

  • Port Range (連接埠範圍):1024-65535

  • 來源:0.0.0.0/0 (或建立 ElastiCache 叢集子網路的個別規則)

  • Allow/Deny (允許/拒絕):Allow (允許)

  • 傳出規則:

  • Rule number (規則編號):最好低於任何拒絕規則;

  • 類型:自訂TCP規則;

  • 通訊協定: TCP

  • Port Range (連接埠範圍):6379

  • 來源:0.0.0.0/0 (或 ElastiCache 叢集子網路。 請記住,使用特定 IPs可能會在容錯移轉或擴展叢集時產生問題)

  • Allow/Deny (允許/拒絕):Allow (允許)

ElastiCache 網路ACL:

  • 傳入規則:

  • Rule number (規則編號):最好低於任何拒絕規則;

  • 類型:自訂TCP規則;

  • 通訊協定: TCP

  • Port Range (連接埠範圍):6379

  • 來源:0.0.0.0/0 (或建立 ElastiCache 叢集子網路的個別規則)

  • Allow/Deny (允許/拒絕):Allow (允許)

  • 傳出規則:

  • Rule number (規則編號):最好低於任何拒絕規則;

  • 類型:自訂TCP規則;

  • 通訊協定: TCP

  • Port Range (連接埠範圍):1024-65535

  • 來源:0.0.0.0/0 (或 ElastiCache 叢集子網路。 請記住,使用特定 IPs可能會在容錯移轉或擴展叢集時產生問題)

  • Allow/Deny (允許/拒絕):Allow (允許)

如需詳細資訊,請參閱網路 ACLs

路由表

與 Network 類似ACLs,每個子網路可以有不同的路由表。如果用戶端和 ElastiCache 叢集位於不同的子網路中,請確保其路由表允許它們彼此互相連接。

涉及多個 VPCs、動態路由或網路防火牆的更複雜環境可能難以進行故障診斷。請參閱 網路連線能力驗證,確認您的網路設定是否適當。

DNS 解析度

ElastiCache 會根據DNS名稱提供服務端點。可用的端點為 ConfigurationPrimaryReaderNode 端點。如需詳細資訊,請參閱 尋找連線端點

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

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

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

您也可以透過 VPCDNS服務強制名稱解析:

$ 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

透過伺服器端診斷識別問題

CloudWatch 來自 ElastiCache 引擎的指標和執行期資訊是常見的來源或資訊,用於識別連線問題的潛在來源。優質的分析資料通常從下列項目開始:

  • CPU 用量:Valkey 和 Redis OSS是多執行緒應用程式。但是每個命令的執行發生在單個 (主) 執行序中。因此, ElastiCache 會提供指標 CPUUtilizationEngineCPUUtilizationEngineCPUUtilization提供專用於 Valkey 或 Redis 程序的使用CPU率OSS,以及所有 CPUUtilization的使用率vCPUs。具有多個 vCPU 的節點通常具有不同的 CPUUtilization和 值EngineCPUUtilization,第二個值通常較高。高的原因EngineCPUUtilization可能是請求數量增加,或需要大量CPU時間才能完成的複雜操作。您可以透過以下項目來識別兩者:

    • 請求數增加:檢查其他符合 EngineCPUUtilization 模式的指標是否增加。有用的指標包括:

      • CacheHitsCacheMisses:成功請求或沒有在快取中找到有效項目的請求之數目。如果未命中與命中的比率很高,表示應用程式正在對無效果的請求浪費時間和資源。

      • SetTypeCmdsGetTypeCmds:這些指標與 EngineCPUUtilization 相關,有助於了解寫入請求 (由 SetTypeCmds 測量) 或讀取請求 (由 GetTypeCmds 測量) 的負載是否明顯高。如果負載主要是讀取作業,使用多個僅供讀取複本可以在多個節點之間平衡請求,並撥出主節點用於寫入作業。在停用叢集模式的叢集中,可以使用 ElastiCache 讀取器端點在應用程式中建立額外的連線組態,以使用僅供讀取複本。如需詳細資訊,請參閱 尋找連線端點。讀取作業必須提交至這個額外的連線。寫入作業將透過一般主要端點完成。在啟用叢集模式的情況下,建議您使用原生支援僅供讀取複本的程式庫。使用正確的旗標,程式庫將能夠自動探索叢集拓撲、複本節點、透過 READONLY Valkey 或 Redis OSS命令啟用讀取操作,並將讀取請求提交至複本。

    • 連線數增加:

      • CurrConnectionsNewConnectionsCurrConnection 是收集資料點時的已建立連線數,而 NewConnections 會顯示這段期間內建立的連線數。

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

        NewConnections 每分鐘數千個 ElastiCache 節點表示只有幾個命令建立和使用連線,這並非最佳狀態。保持連線的成立狀態,並重複使用這些連線來進行新作業是最佳實務。當用戶端應用程式支援並妥善實作連線集區或持續連線時,此情況有可能實現。使用連線集區時,currConnections 數不會有很大的變化,而 NewConnections 應盡可能壓低。Valkey 和 Redis 使用少量 OSS提供最佳效能currConnections。 currConnection 保持數十或數百的順序,可將資源的使用降至最低,以支援用戶端緩衝區和CPU循環等個別連線,以提供連線。

    • 網路輸送量:

      • 判斷頻寬: ElastiCache 節點具有與節點大小成比例的網路頻寬。由於應用程式具有不同的特性,結果可能會根據工作負載而有所不同。例如,具有高速率小請求的應用程式往往影響比網路輸送量更多的CPU用量,而較大的金鑰會導致更高的網路使用率。因此,建議您使用實際工作負載來測試節點,以便更深入了解限制。

        模擬來自應用程式的負載會提供更準確的結果。但是,基準化分析工具可讓您更妥善了解限制。

      • 針對請求主要都是讀取的情況,使用複本進行讀取作業將能減輕主節點上的負載。如果使用案例主要是寫入,則使用許多複本將會提高網路使用量。針對寫入主節點的每個位元組,系統會將 N 個位元組傳送到複本 (N 即複本的數量)。寫入密集型工作負載的最佳實務是搭配啟用叢集模式的 ElastiCache (Redis OSS) 使用,因此可以平衡多個碎片的寫入,或擴展到具有更多網路功能的節點類型。

      • 和 CloudWatchmetrics NetworkBytesIn分別NetworkBytesOut提供進出節點的資料量。 ReplicationBytes是專用於資料複寫的流量。

      如需詳細資訊,請參閱網路相關限制

    • 複雜命令: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命令

      潛在問題範例:

      • Lua 指令碼:Valkey 和 Redis OSS提供內嵌 Lua 解譯器,允許在伺服器端執行指令碼。Valkey 和 Redis 上的 Lua 指令碼OSS是在引擎層級上執行,且依定義為原子,這表示指令碼正在執行時不允許執行其他命令或指令碼。Lua 指令碼提供直接在引擎上執行多個命令、決策演算法、資料剖析等的可能性。雖然這類指令碼的不可部分完成特性和卸載應用程式的機會很誘人,但將指令碼用於小型作業時必須小心。在 上 ElastiCache,Lea 指令碼的執行時間限制為 5 秒。未寫入 Keyspace 的指令碼將在 5 秒過後自動終止。為了避免資料損毀和不一致,如果指令碼執行沒有在 5 秒內完成,且執行期間有任何寫入,節點便會容錯移轉。交易是確保 Redis 中多個相關金鑰修改一致性的替代方案OSS。交易允許執行一個命令區塊,觀察現有的索引鍵修改項目。如果觀察的任何索引鍵在交易完成之前有所變更,系統會捨棄所有修改。

      • 大量刪除項目:DEL 命令接受多個參數,這些參數是要刪除的索引鍵名稱。刪除操作是同步的,如果參數清單很大,或包含大清單、集、排序集或雜湊 (包含數個子項目的資料結構),則需要很長CPU的時間。換句話說,如果單一索引鍵有許多元素,即使只是刪除單一索引鍵,也可能需要花相當長的時間。的替代方案DELUNLINK,這是可用的非同步命令,因為 Redis OSS 4。 UNLINK 必須DEL盡可能優先於 。從 ElastiCache (Redis OSS) 6x 開始, lazyfree-lazy-user-del 參數會讓DEL命令的行為與啟用UNLINK時類似。如需詳細資訊,請參閱 Redis OSS 6.0 參數變更。

      • 對多個索引鍵上產生作用的命令:先前提到的 DEL 是接受多個參數的命令,且其執行時間將直接與此成正比。不過,Redis OSS提供更多類似運作的命令。範例為 MSETMGET 允許一次插入或檢索多個字串索引鍵。使用它們可能有助於減少許多個別 SETGET 命令的固有網路延遲。不過,廣泛的參數清單會影響CPU用量。

        雖然僅CPU利用率不是造成連線問題的原因,但花太多時間處理多個金鑰上的單一或少量命令,可能會導致其他請求失敗並提高整體CPU使用率。

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

        可以作用於多個索引鍵的其他命令範例有:HMGETHMSETMSETNXPFCOUNTPFMERGESDIFFSDIFFSTORESINTERSINTERSTORESUNIONSUNIONSTORETOUCHZDIFFZDIFFSTOREZINTERZINTERSTORE

      • 對多種資料類型執行的命令:Redis OSS也提供對一或多個金鑰執行動作的命令,無論其資料類型為何。 ElastiCache (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 以避免長時間執行命令。HDELHGETALLHMGETHMSETHVALS 命令應在大雜湊上謹慎使用。

      • 其他大數據結構:除了雜湊之外,其他資料結構也可能是密集CPU的。集合、清單、排序集合和 Hyperloglog 也可能需要花大量時間來操作,取決於其大小和使用的命令。如需這些命令的詳細資訊,請參閱 Valkey 和 Redis OSS命令

網路連線能力驗證

檢閱與DNS解析度、安全群組ACLs、網路和路由表相關的網路組態後,可以使用可VPC連線性分析器和系統工具驗證連線。

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

  1. 前往 https://console.aws.amazon.com/ec2/v2/home?#NIC:

  2. 根據 ElastiCache 叢集名稱或先前DNS驗證的 IP 地址來篩選介面清單。

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

  4. 繼續下一個步驟。

  5. 在家中https://console.aws.amazon.com/vpc/建立分析路徑?#ReachabilityAnalyzer 並選擇下列選項:

    • 來源類型:如果您的 ElastiCache 用戶端在 Amazon EC2執行個體上執行,或者如果用戶端使用其他服務,例如 AWS Fargate Amazon ECS搭配 awsvpc 網路等),以及各自的資源 ID (EC2執行個體或 ENI ID) AWS Lambda,請選擇執行個體;

    • 目的地類型 :選擇網路介面,然後從清單中選擇 ElasticacheENI

    • 目的地連接埠 :為 ElastiCache (Redis OSS) 指定 6379,或為 ElastiCache (Memcached) 指定 11211。這些是使用預設組態定義的連接埠,此範例假設未加以變更。

    • 通訊協定: 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了連線能力分析工具測試,請您的系統管理員檢閱可能的主機型防火牆規則、非對稱路由規則,或作業系統層級的任何其他可能限制。

在 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#DIAGNOSTICS 檢查錯誤的原因。

如果所有基礎設施和作業系統測試都通過,但您的應用程式仍無法連線至 ElastiCache,請檢查應用程式組態是否符合 ElastiCache 設定。常見的錯誤包括:

  • 您的應用程式不支援 ElastiCache 叢集模式,且 ElastiCache 已啟用叢集模式;

  • 您的應用程式不支援 TLS/SSL,且 ElastiCache 已啟用傳輸中加密;

  • 應用程式支援 TLS/SSL,但沒有正確的組態旗標或受信任的憑證授權機構;

網路相關限制

  • 連線數上限:同時連線數具有硬性限制。每個 ElastiCache 節點允許所有用戶端之間最多 65,000 個同時連線。此限制可以透過 上的CurrConnections指標進行監控 CloudWatch。不過,用戶端也有自己的傳出連線限制。在 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

    如果數字太高,您的系統可能會因為嘗試處理連線請求而過載。建議考慮實作適用技術,例如連線集區或持續連線,以便更妥善處理連線。盡可能設定連線集區,將連線數上限限制為幾百個。此外,用於處理逾時或其他連線例外狀況的退避邏輯是明智的做法,可避免發生問題的情況下連線流失。

  • 網路流量限制:檢查下列 CloudWatch Redis 指標OSS,以識別節點上可能命中的網路限制 ElastiCache :

    • NetworkBandwidthInAllowanceExceeded/NetworkBandwidthOutAllowanceExceeded:因為輸送量超過彙總頻寬限制而形成的網路封包。

      請務必注意,寫入主節點的每個位元組都會複寫到 N 個複本 (N 是複本數)。具有小型節點類型、多個複本以及密集寫入型請求的叢集,可能無法處理複寫待處理項目。對於這種情況,最佳實務是擴充規模 (更改節點類型)、水平擴展 (在啟用叢集模式的叢集中增加碎片),減少複本數或最大限度減少寫入次數。

    • NetworkConntrackAllowanceExceeded:因為超過指派給節點的連線數 (在所有安全群組之間追蹤) 上限而形成的封包。這段期間內,新的連線可能會失敗。

    • NetworkPackets PerSecondAllowanceExceeded:超過每秒的封包數上限。以高極小型請求率為基礎的工作負載,可能會在達到頻寬上限之前達到此限制。

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

    如果長時間觀察到高原期,則可能會隨後出現複寫延遲、用於快取的位元組增加、釋放可用記憶體減少、高交換和CPU用量。Amazon EC2執行個體也有網路限制,可透過ENA驅動程式指標 追蹤。具有增強型聯網支援和ENA驅動程式 2.2.10 或更新版本的 Linux 執行個體可以使用 命令檢閱限制計數器:

    # ethtool -S eth0 | grep "allowance_exceeded"

CPU 用量

CPU 使用量指標是調查的起點,下列項目有助於縮小 ElastiCache 可能的問題範圍:

  • Redis OSS SlowLogs: ElastiCache 預設組態會保留最後 128 個命令,這些命令需要超過 10 毫秒的時間才能完成。慢速命令的歷史記錄會在引擎執行時間內保留,且會在故障或重新啟動的情況下遺失。如果清單達到 128 個項目,將會刪除舊活動,為新的活動騰出空間。慢速事件清單的大小和視為緩慢的執行時間,可以透過自訂參數群組中的 slowlog-max-lenslowlog-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:07UTC,需要 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 (RedisOSS) 提供 CloudWatch 指標來監控不同類別命令的平均延遲。資料點的計算方式是將類別中命令的執行總次數除以期間的總執行時間。請務必了解,延遲指標結果是多個命令的彙總結果。單一命令可能會導致非預期的結果 (例如逾時),而不會對指標造成重大影響。針對這種情況,慢速事件會是更準確的資訊來源。下列清單包含可用的延遲指標,以及影響這些指標的各別命令。

    • EvalBasedCmdsLatency:與 Lua Script 命令、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:可對不同資料類型採取動作的命令:dumpexistskeysobjectpttlrandomkeyttltypedelexpireexpireatmovepersist、、pexpirepexpireat、、renamerenamenx、、restoreKsort、、、、、、、、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、subsubscribe;

    • 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:提供自 Redis OSS引擎啟動以來執行的命令清單、累積執行次數、總執行時間和每個命令的平均執行時間;

    • client list:提供目前連線的用戶端和相關資訊的清單,如緩衝區使用率、上次執行的命令等;

  • 備份和複寫:2.8.22 之前的 ElastiCache (Redis OSS) 版本使用叉式程序來建立備份,並處理與複本的完整同步。這種方法可能會在寫入密集型使用案例中產生顯著的記憶體額外負荷。

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

從伺服器端終止連線

預設 ElastiCache (Redis OSS) 組態會無限期建立用戶端連線。不過在某些情況下可能需終止連線。例如:

  • 用戶端應用程式中的錯誤可能會造成連線遭遺忘,並以閒置狀態保持成立。這就是所謂的「連線流失」,結果會發現 CurrConnections 指標中已成立的連線數穩定增加。此行為可能會導致用戶端或 ElastiCache 端的飽和。當無法從用戶端立即修正時,有些管理員會在其 ElastiCache 參數群組中設定「逾時」值。逾時是讓閒置連線持續存在的時間 (以秒為單位)。如果用戶端在此期間未提交任何請求,則 Redis OSS引擎會在連線達到逾時值時立即終止連線。較小的逾時值可能會導致不必要的連線中斷,屆時用戶端需要妥善處理並重新連線,進而導致延遲。

  • 用於存放索引鍵的記憶體與用戶端緩衝區共用。具有大型請求或回應的慢速用戶端,可能需要大量的記憶體來處理其緩衝區。預設 ElastiCache (Redis OSS) 組態不會限制一般用戶端輸出緩衝區的大小。如果達到 maxmemory 上限,引擎將會嘗試移出項目以滿足緩衝區使用量。在極端低記憶體情況下, ElastiCache (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執行個體的用戶端疑難排解

用戶端的負載和回應能力也會影響對 的請求 ElastiCache。EC2 執行個體和作業系統限制需要仔細檢閱,同時疑難排解間歇性連線或逾時問題。幾項需觀察的要點:

  • CPU:

    • EC2 執行個體CPU用量:確定 CPU 尚未飽和或接近 100%。歷史分析可以透過 完成 CloudWatch,但請記住,資料點精細度為 1 分鐘 (啟用詳細監控) 或 5 分鐘;

    • 如果使用爆量EC2執行個體 ,請確定其CPU點數餘額尚未耗盡。此資訊可在 CPUCreditBalance CloudWatch 指標上取得。

    • 短期高CPU用量可能會導致逾時,而不會反映 上的 100% 使用率 CloudWatch。這種情況需使用作業系統工具 (如 toppsmpstat) 進行即時監控。

  • 網路

    • 根據執行個體容量檢查網路輸送量是否低於可接受的值。如需詳細資訊,請參閱 Amazon EC2執行個體類型

    • 在具有 ena 增強型網路驅動程式的執行個體上,查看 ENA 統計數字以取得逾時或超出的限制。下列統計數字有助於確認網路限制飽和情況:

      • bw_in_allowance_exceeded/bw_out_allowance_exceeded:因過量的傳入或傳出輸送量而造成的封包數;

      • conntrack_allowance_exceeded:由於安全群組連線追蹤限制而捨棄的封包數。當此限制飽和時,新的連線將會失敗;

      • linklocal_allowance_exceeded:透過 對執行個體中繼資料提出過多請求而捨棄NTPVPC的封包數量DNS。所有服務的限制都是每秒 1024 個封包;

      • pps_allowance_exceeded:由於每秒封包比率過高而捨棄的封包數。當網路流量每秒包含在數千或數百萬個非常小的請求上時,就會達到此PPS限制。 ElastiCache 流量可透過管道或命令來最佳化,以便能夠像 一樣同時執行多個操作,MGET以更好地使用網路封包GET

解析完成單個請求所花費的時間

  • 在網路上: TcpdumpWireshark(命令列上的 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 OSSPING命令,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 微秒)。

    大約需要 20 毫秒的時間來實例化 nc 並執行名稱解析 (從 697712 到 717890),之後需要 2 毫秒才能建立TCP通訊端 (745659 到 747858),以及 0.4 毫秒 (747858 到 748330) 來提交和接收請求的回應。