大Key/熱Key分析
更新(xin)時間 2023-10-19 13:57:52
最(zui)近更(geng)新時間(jian): 2023-10-19 13:57:52
分享(xiang)文(wen)章
本節主要介紹大Key/熱(re)Key分(fen)析 類問題
什么是大Key/熱Key?
| 名詞 | 定義 |
|---|---|
| 大Key | 大Key可以分為兩種情況: Key的Value較大,例如一個String類型的Key大小達到10MB,或者一個集合類型(Hash,List,Set等)的元素總大小達到了100MB。一般單個String類型的Key大小達到10KB,或者集合類型的Key總大小達到50MB,則定義其為大Key。 Key的元素較多,例如一個Hash類型的Key,其元素數量達到了10000。一般定義集合類型的Key中元素超過5000個,則認為其為大Key。 |
| 熱Key | 通常以一個Key被操作的頻率和占用的資源來判定其是否為熱Key,例如: 某個集群實例一個分片每秒處理10000次請求,其中有3000次都是操作同一個Key。 某個集群實例一個分片的總帶寬使用(入帶寬+出帶寬)為100Mbits/s,其中80Mbits是由于對某個Hash類型的Key執行HGETALL所占用。 |
存在大Key/熱Key,有什么影響?
類別 影響 大Key 造成規格變更失敗。
Redis集群變更規格過程中會進行數據rebalance(節點間遷移數據),單個Key過大的時候會觸發Redis內核對于單Key的遷移限制,造成數據遷移超時失敗,Key越大失敗的概率越高,大于512MB的Key可能會觸發該問題。造成數據遷移失敗。
數據遷移過程中,如果一個大Key的元素過多,則會阻塞后續Key的遷移,后續Key的數據會放到遷移機的內存Buffer中,如果阻塞時間太久,則會導致遷移失敗。容易造成集群分片不均的情況。
?各分片內存使用不均。例如某個分片占用內存較高甚至首先使用滿,導致該分片Key被逐出,同時也會造成其他分片的資源浪費。
?各分片的帶寬使用不均。例如某個分片被頻繁流控,其他分片則沒有這種情況。客戶端執行命令的時延變大。
對大Key進行的慢操作會導致后續的命令被阻塞,從而導致一系列慢查詢。導致實例流控。
對大Key高頻率的讀會使得實例出方向帶寬被打滿,導致流控,產生大量命令超時或者慢查詢,業務受損。導致主備倒換。
對大Key執行危險的DEL操作可能會導致主節點長時間阻塞,從而導致主備倒換。熱Key 容易造成集群分片不均的情況。
造成熱Key所在的分片有大量業務訪問而同時其他的分片壓力較低。這樣不僅會容易產生單分片性能瓶頸,還會浪費其他分片的計算資源。使得CPU沖高。
對熱Key的大量操作可能會使得CPU沖高,如果表現在集群單分片中就可以明顯地看到熱Key所在的分片CPU使用率較高。這樣會導致其他請求受到影響,產生慢查詢,同時影響整體性能。業務量突增場景下甚至會導致主備切換。易造成緩存擊穿。
熱Key的請求壓力過大,超出Redis的承受能力易造成緩存擊穿,即大量請求將被直接指向后端的數據庫,導致數據庫訪問量激增甚至宕機,從而影響其他業務。
為了減少大Key和熱Key過大,有什么使用建議?
- string類型控制在10KB以內 ,hash、list、set、zset 元素盡量不超過5000 。
- Key的命名前綴為業務縮寫,禁止包含特殊字符(比如空格、換行、單雙引號以及其他轉義字符)。
- Redis事務功能較弱,不建議過多使用。
- 短連接性能差,推薦使用帶有連接池的客戶端。
- 如果只是用于數據緩存,容忍數據丟失,建議關閉持久化。
- 大Key/熱Key的優化方法,請參考下表。
類別 方法 大Key 進行大Key拆分。
分為以下幾種場景
該對象為String類型的大Key:可以嘗試將對象分拆成幾個Key-Value, 使用MGET或者多個GET組成的pipeline獲取值,分拆單次操作的壓力,對于集群來說可以將操作壓力平攤到多個分片上,降低對單個分片的影響。
該對象為集合類型的大Key,并且需要整存整取:**在設計上嚴格禁止這種場景的出現,因為無法拆分。有效的方法是將該大Key從Redis去除,單獨放到其余存儲介質上。
該對象為集合類型的大Key,每次只需操作部分元素:**將集合類型中的元素分拆。以Hash類型為例,可以在客戶端定義一個分拆Key的數量N,每次對HGET和HSET操作的field計算哈希值并取模N,確定該field落在哪個Key上,實現上類似于Redis Cluster的計算slot的算法。將大Key單獨轉移到其余存儲介質。
無法拆分的大Key建議使用此方法,將不適用Redis能力的數據存至其它存儲介質,并在Redis中刪除該大Key。
注意
禁止使用DEL直接刪除大Key,可能會造成Redis阻塞,甚至主備倒換。熱Key 使用客戶端緩存/本地緩存。
該方案需要提前了解業務的熱點Key有哪些,設計客戶端/本地和遠端Redis的兩級緩存架構,熱點數據優先從本地緩存獲取,寫入時同時更新,這樣能夠分擔熱點數據的大部分讀壓力。缺點是需要修改客戶端架構和代碼,改造成本較高。設計熔斷/降級機制。
熱Key極易造成緩存擊穿,高峰期請求都直接透傳到后端數據庫上,從而導致業務雪崩。因此熱Key的優化一定需要設計系統的熔斷/降級機制,在發生擊穿的場景下進行限流和服務降級,保護系統的可用性。
如何分析Redis 3.0實例的熱Key?
由(you)于Redis 3.0本身不提供熱Key能力,您(nin)可以參(can)考(kao)以下方法進行分析。
- 方法1:進行業務結構和業務實現分析,找到可能的熱Key。
例如(ru),某(mou)商品在秒殺,或者用戶登錄,對業(ye)務代碼分析,很容易找到熱Key。
優點:簡單易行。
缺(que)點:需(xu)要對(dui)業務(wu)代(dai)碼比較了解,另外對(dui)于一些復雜的業務(wu)場(chang)景(jing),不太容(rong)易分析。
- 方法2:在客戶端代碼中,調用Redis的函數中,進行訪問Key的記錄,進而統計出熱Key。
缺(que)點:需(xu)要代碼進行(xing)侵入式修(xiu)改。
- 方法3:抓包分析
優點:簡單易行
如何提前發現大Key和熱Key?
| 方法 | 說明 |
|---|---|
| 使用DCS自帶的大Key和熱Key分析工具進行分析 | 請參考緩存分析。 |
| 通過redis-cli的bigkeys和hotkeys參數查找大Key和熱Key | Redis-cli提供了bigkeys參數,能夠使redis-cli以遍歷的方式分析Redis實例中的所有Key,并返回Key的整體統計信息與每個數據類型中Top1的大Key,bigkeys僅能分析并輸入六種數據類型(STRING、LIST、HASH、SET、ZSET、STREAM),命令示例為:redis-cli -h <實例的連接地址> -p <端口> -a <密碼> --bigkeys。 自Redis 4.0版本起,redis-cli提供了hotkeys參數,可以快速幫您找出業務中的熱Key,該命令需要在業務實際運行期間執行,以統計運行期間的熱Key。命令示例為:redis-cli -h <實例的連接地址> -p <端口> -a <密碼> --hotkeys。熱Key的詳情可以在結果中的summary部分獲取到。 |
對于Redis 3.0實例,由于Redis 3.0本身不支持熱Key分析,推薦可以使用配置告警的(de)方(fang)法,幫(bang)助(zhu)您發現熱Key。
- 配置節點級別的內存利用率監控指標的告警
如果某個節點存在大key,這(zhe)個節點比其他(ta)節點內存使用率高很多,會(hui)觸發(fa)告警,便于用戶發(fa)現潛在的大key。
- 配置節點級別的 入網最大帶寬、出網最大帶寬 、CPU利用率監控指標的告警
如果某(mou)個(ge)(ge)節(jie)點存在(zai)熱key,這個(ge)(ge)節(jie)點的帶寬占用、CPU利用率都比其他節(jie)點高,該節(jie)點會容易觸(chu)發告警,便于用戶發現潛在(zai)熱key。