在Redis中,對於大key並沒有標準的定義,更多的是根據業務而定,如果一個key對應的value所佔用的記憶體比較大,那這個key就可以看作是大key。通常對於大key的定義,有如下兩種情況:
1、String型別的value對記憶體的佔用超過一定大小。
2、複合型別(List、Hash、Set、Sorted Set 等)的value包含的元素超過一定數量。
要檢測Redis中的大key,可以使用Redis自身的cli命令,也可以使用第三方的一些工具來檢測(redis-rdb-tools、rdb_bigkeys、雲產品提供的監控工具)。使用下面的命令,Redis會幫我們羅列出當前快取中的大key,但並不是所有的大key
。
redis-cli -h 127.0.0.1 -p 6379 --bigkeys
這裏需要注意的是,在一些集合型別中,如果key的數量比較多,並非是大key。大key最終的判斷標準還是在於對記憶體的佔用。使用Redis自帶的工具,當同一種類型存在多個大key時,Redis只會返回佔用記憶體最大的key。
大key原因:對於Redis中的大key存在的原因,可能有多種,這裏總結幾種常見的因素。
1、程式設計不當,例如使用String型別儲存較大的檔案資料。例如儲存圖片二進制的格式。
2、對業務資料規模的考慮不周,例如未預見到集合型別資料量的快速增長,隨著系統執行的時間越長,集合內的元素不斷增加。
3、未及時清理垃圾資料,例如雜湊中堆積了大量無用的鍵值對,這種無效資料佔用大量的記憶體。
4、儲存大量資料的容器,例如list、set等。
5、大型數據結構,例如bitmap、hyperloglog資料型別來儲存資料,隨著業務的不斷增加,對應的資料儲存越來越多。
大key影響:針對大key的問題,在一些高併發、大流量的業務系統中,影響是非常大,因此我們在開發過程中應該重點關注該問題,這裏總結常見的幾種影響。
1、記憶體消耗:大key佔用大量記憶體,可能導致Redis例項記憶體不足。
2、效能下降:操作大key會導致命令執行時間增加。
3、持久化和備份:大key處理時間增加,可能導致Redis持久化效率降低。
4、網路延遲:大key傳輸消耗較多網路頻寬和時間,影響客戶端響應時間。
大key解決方案:針對大key的問題,這裏羅列幾種常見的解決方案。
1、拆分大key:將一個大key拆分為多個小key,例如將大的列表或雜湊表拆分成多個小的。
2、物件壓縮:使用壓縮演算法減小物件的大小。
3、直接刪除:使用UNLINK命令非同步刪除大key(Redis 4.0+)。
4、採用合適的數據結構:例如,對於統計UV可以使用HyperLogLog,對於狀態資訊可以使用Bitmap。
5、開啟lazy-free(惰性刪除/延遲釋放):Redis 4.0引入的特性,非同步延遲釋放key使用的記憶體,避免阻塞主執行緒 。
6、使用Redis叢集:透過分片技術將資料分散到多個節點上,實現水平擴充套件。
7、定期監控和清理:定期監控Redis例項中的大key,並根據需要進行清理。