Redis的BigKey問題
什么是大Key問題?
大key問題其實可以說是大value問題,就是某個key對應的value所占據的存儲空間太大了,所以導致我們在操作這個key的時候花費的時間過長(序列化\反序列化),從而降低了redis性能。
- Key對應的value本身的數據量過大:一個Strring類型的value,值為5MB。
- Key對應的value的成員數量過多:一個ZSet類型的key,對應的成員數量有10000個。
- key中成員的數據量過大:一個Hash類型的key,成員數量雖然只有1000個,但是這些成員的總大小太大了。比如達到100MB或者10MB。
單個key的value大小要建議小于10kb,集合類型的key元素數量要小于1000。
帶來的問題
網絡阻塞: 對大Key執行讀請求的時候,少量的QPS就可能導致 帶寬使用率 被占滿了,導致Redis性能下降,甚至可能導致整個物理機變慢了。
數據傾斜: BigKey所在的Redis實例內存使用率會遠超其它實例,無法使數據分片的內存資源達到均衡。
Redis阻塞: 對于元素較多的hash、list、zset等做運算的時候會很耗時,redis又是單線程的,其它請求不會被處理,就會導致主線程阻塞。
CPU壓力: Redis中的的數據序列化和反序列化的時候都需要CPU運算,BigKey會導致CPU的使用率飆升,影響Redis實例和本機其它應用的使用。
如何刪除BigKey?
由于Redis是單線程的,所以刪除一個鍵值對的時候,如果是bigkey也需要耗費很長時間,導致redis主線程阻塞。 Redis4.0 之后,Redis提供了一個命令unlink,會把該鍵值對先標記成已刪除,然后會去異步地刪除該key。如果是 Redis3.0 以前,刪除集合類型的話,就先遍歷該集合元素,依次刪除元素,最后再刪除BigKey。
選擇合適的數據結構
對于存儲一個 對象 ,如果使用json字符串,那么就不夠靈活,可以使用Hash結構,既靈活,空間占用也不是很大。
數據量太大的時候,單個hash可能會導致大key問題,hash結構的entry數量盡量不要超過1000;單獨用string來存儲的話,大量的key又會導致占用太多空間,所以要學會使用 分片哈希 。既節省空間,也避免了大key問題。