業務場景:
即通過hash的方式來存儲每一天用戶訂單次數。那么key = order_20200102, field = order_id, value = 10。那么如果一天有百萬千萬甚至上億訂單的時候,key后面的值是很多,存儲空間也很大,造成所謂的大key。
大key的風險:
1.讀寫大key會導致超時嚴重,甚至阻塞服務。
2.如果刪除大key,DEL命令可能阻塞Redis進程數十秒,使得其他請求阻塞,對應用程序和Redis集群可用性造成嚴重的影響。
redis使用會出現大key的場景:
1.單個簡單key的存儲的value過大;
2.hash、set、zset、list中存儲過多的元素。
解決問題:
1.單個簡單key的存儲的value過大的解決方案:
將大key拆分成對個key-value,使用multiGet方法獲得值,這樣的拆分主要是為了減少單台操作的壓力,而是將壓力平攤到集群各個實例中,降低單台機器的IO操作。
2.hash、set、zset、list中存儲過多的元素的解決方案:
1).類似於第一種場景,使用第一種方案拆分;
2).以hash為例,將原先的hget、hset方法改成(加入固定一個hash桶的數量為10000),先計算field的hash值模取10000,確定該field在哪一個key上。
將大key進行分割,為了均勻分割,可以對field進行hash並通過質數N取余,將余數加到key上面,我們取質數N為997。
那么新的key則可以設置為:
newKey = order_20200102_String.valueOf( Math.abs(order_id.hashcode() % 997) )
field = order_id
value = 10
hset (newKey, field, value) ;
hget(newKey, field)