本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
持續連線問題
疑難排解使用 ElastiCache 的持續連線問題時,必須驗證下列項目:
主題
安全群組
安全群組是保護 ElastiCache 用戶端 (EC2 執行個體、 AWS Lambda 函數、Amazon ECS 容器等) 和 ElastiCache 快取的虛擬防火牆。安全群組具有狀態,這表示允許傳入或傳出流量之後,該流量的回應將在該特定安全群組的內容中自動授權。
具狀態功能需要安全群組追蹤所有授權的連線,而且追蹤的連線數有限額。如果達到限額,新的連線將會失敗。請參閱疑難排解一節,以取得如何識別用戶端或 Elasticache 端是否已達到限制的說明。
您可以將單一安全群組同時指派給用戶端和 ElastiCache 叢集,或為兩者分別指派單獨的安全群組。
針對這兩種情況,您都需要允許來源 ElastiCache 連接埠上的 TCP 傳出流量,並允許同一連接埠上的傳入流量傳送至 ElastiCache。Memcached 的預設連接埠為 11211,Valkey 或 Redis OSS 為 6379。根據預設,安全群組允許所有對外流量。在此情況下,只需要目標安全群組中的傳入規則。
如需詳細資訊,請參閱用於存取 Amazon VPC 中 ElastiCache 叢集的存取模式。
網路 ACL
網路存取控制清單 (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。
路由表
類似於網路 ACL,每個子網路也可以有不同的路由表。如果用戶端和 ElastiCache 叢集位於不同的子網路中,請確定其路由表允許它們彼此連線。
較複雜的環境 (涉及多個 VPC、動態路由或網路防火牆) 可能會變得難以疑難排解。請參閱 網路連線能力驗證,確認您的網路設定是否適當。
DNS 解析
ElastiCache 提供以 DNS 名稱為基礎的服務端點。可用的端點為 Configuration
、Primary
、Reader
及 Node
端點。如需詳細資訊,請參閱 尋找連線端點。
在修改容錯移轉或叢集的情況下,與端點名稱相關聯的地址可能會變更且會自動更新。
自訂 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
透過伺服器端診斷識別問題
來自 ElastiCache 引擎的 CloudWatch 指標和執行時間資訊,是用來識別潛在連線問題來源的常見來源或資訊。優質的分析資料通常從下列項目開始:
CPU 用量:Valkey 和 Redis OSS 是多執行緒應用程式。但是每個命令的執行發生在單個 (主) 執行序中。因此,ElastiCache 提供指標
CPUUtilization
和EngineCPUUtilization
。EngineCPUUtilization
提供專用於 Valkey 或 Redis OSS 程序的 CPU 使用率,以及所有 vCPUsCPUUtilization
的使用率。具有多個 vCPU 的節點的CPUUtilization
和EngineCPUUtilization
值一般會不同,後者通常較高。出現高EngineCPUUtilization
,可能是由於需要大量 CPU 時間才能完成的請求或複雜作業數量增加所造成。您可以透過以下項目來識別兩者:請求數增加:檢查其他符合
EngineCPUUtilization
模式的指標是否增加。有用的指標包括:CacheHits
和CacheMisses
:成功請求或沒有在快取中找到有效項目的請求之數目。如果未命中與命中的比率很高,表示應用程式正在對無效果的請求浪費時間和資源。SetTypeCmds
和GetTypeCmds
:這些指標與EngineCPUUtilization
相關,有助於了解寫入請求 (由SetTypeCmds
測量) 或讀取請求 (由GetTypeCmds
測量) 的負載是否明顯高。如果負載主要是讀取作業,使用多個僅供讀取複本可以在多個節點之間平衡請求,並撥出主節點用於寫入作業。在停用叢集模式的叢集中,可以使用 ElastiCache 讀取者端點,在應用程式中建立額外的連線組態以使用僅供讀取複本。如需詳細資訊,請參閱 尋找連線端點。讀取作業必須提交至這個額外的連線。寫入作業將透過一般主要端點完成。在啟用叢集模式的情況下,建議您使用原生支援僅供讀取複本的程式庫。使用正確的旗標,程式庫將能夠自動探索叢集拓撲、複本節點、透過 READONLYValkey 或 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
則適用於資料複寫專屬的流量。
如需詳細資訊,請參閱網路相關限制。
複雜命令: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 OSS 上的 Lua 指令碼是在引擎層級執行,且依定義為原子,這表示指令碼執行時不允許執行其他命令或指令碼。Lua 指令碼可讓您直接在引擎上執行多個命令、決策演算法、資料剖析等。雖然這類指令碼的不可部分完成特性和卸載應用程式的機會很誘人,但將指令碼用於小型作業時必須小心。在 ElastiCache 上,Lua 指令碼的執行時間限制為 5 秒。未寫入 Keyspace 的指令碼將在 5 秒過後自動終止。為了避免資料損毀和不一致,如果指令碼執行沒有在 5 秒內完成,且執行期間有任何寫入,節點便會容錯移轉。交易
是確保 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 參數變更。對多個索引鍵上產生作用的命令:先前提到的
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 命令
。
網路連線能力驗證
檢閱與 DNS 解析、安全群組、網路 ACL 和路由表相關的網路組態之後,可以使用 VPC Reachability Analyzer 和系統工具來驗證連線。
Reachability Analyzer 會測試網路連線能力,並確認是否滿足所有的需求和許可。對於下面的測試,您將需要 VPC 中其中一個可用 ElastiCache 節點的 ENI ID (彈性網路介面識別)。若要取得此資料,請執行下列操作:
前往 https://console.aws.amazon.com/ec2/v2/home?#NIC:
依 ElastiCache 叢集名稱或先前 DNS 驗證取得的 IP 地址篩選介面清單。
寫下或以其他方式儲存 ENI ID。如果顯示多個介面,請檢閱描述,確認它們屬於正確的 ElastiCache 叢集,並選擇其中一個介面。
繼續下一個步驟。
於 https://console.aws.amazon.com/vpc/home?#ReachabilityAnalyzer
建立分析路徑,然後選擇下列選項: 來源類型:如果您的 ElastiCache 用戶端在 Amazon EC2 執行個體上執行,或如果它使用其他服務,例如 AWS Fargate Amazon ECS 搭配 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#DIAGNOSTICS
如果通過了所有基礎設施和作業系統測試,但您的應用程式仍然無法連線至 ElastiCache,請檢查應用程式組態是否符合 ElastiCache 設定。常見的錯誤包括:
應用程式不支援 ElastiCache 叢集模式,且啟用叢集模式;
應用程式不支援 TLS/SSL,且已啟用 ElastiCache 傳輸中加密功能;
應用程式支援 TLS/SSL,但沒有正確的組態標記或信任的憑證授權機構;
網路相關限制
連線數上限:同時連線數具有硬性限制。每個 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 指標,以識別 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-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 的情況。建議您將備份時段排定為使用率低的時段,盡量減少用戶端發生問題或備份失敗的可能性。
從伺服器端終止連線
預設的 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 執行個體的用戶端疑難排解
用戶端的負載和回應速度也可能會影響傳給 ElastiCache 的請求。疑難排解間歇性連線或逾時問題時,需要仔細檢閱 EC2 執行個體和作業系統限制。幾項需觀察的要點:
CPU:
EC2 執行個體 CPU 使用率:確定 CPU 尚未飽和或接近 100%。歷史分析可以透過 CloudWatch 完成,但請記得,資料點的精密度可為 1 分鐘 (啟用詳細監控時) 或 5 分鐘;
如果使用高載 EC2 執行個體,請確定其 CPU 餘額尚未耗盡。
CPUCreditBalance
CloudWatch 指標提供此資訊。短時間的高 CPU 使用率可能會導致逾時,而不會反映 CloudWatch 上的 100% 使用率。這種情況需使用作業系統工具 (如
top
、ps
和mpstat
) 進行即時監控。
網路
根據執行個體容量檢查網路輸送量是否低於可接受的值。如需詳細資訊,請參閱 Amazon EC2 執行個體類型
在具有
ena
增強型網路驅動程式的執行個體上,查看 ENA 統計數字以取得逾時或超出的限制。下列統計數字有助於確認網路限制飽和情況:bw_in_allowance_exceeded
/bw_out_allowance_exceeded
:因過量的傳入或傳出輸送量而造成的封包數;conntrack_allowance_exceeded
:由於安全群組連線追蹤限制而捨棄的封包數。當此限制飽和時,新的連線將會失敗;linklocal_allowance_exceeded
:由於透過 VPC DNS 對執行個體中繼資料 NTP 發出過多請求而捨棄的封包數。所有服務的限制都是每秒 1024 個封包;pps_allowance_exceeded
:由於每秒封包比率過高而捨棄的封包數。當網路流量包含每秒數千或數百萬個極小的請求時,便可能達到 PPS 限制。ElastiCache 流量可以進行最佳化,透過管道或一次執行多個作業的命令 (例如MGET
而不是GET
),藉此更妥善使用網路封包。
解析完成單個請求所花費的時間
在網路上:
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 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 微秒)。
將 nc 執行個體化並執行名稱解析花了約 20 毫秒的大量時間 (從 697712 到 717890),在這之後,花了 2 毫秒來建立 TCP 通訊端 (745659 到 747858),再花 0.4 毫秒 (747858 到 748330) 提交和接收請求的回應。