1.冷熱數據分離,不要將所有數據全部都放到Redis中
雖然Redis支持持久化,但是Redis的數據存儲全部都是在內存中的,成本昂貴。建議根據業務只將高頻熱數據存儲到Redis中【QPS大於5000】,對於低頻冷數據可以使用MySQL/ElasticSearch/MongoDB等基於磁盤的存儲方式,不僅節省內存成本,而且數據量小在操作時速度更快、效率更高!
2.不同的業務數據要分開存儲
不要將不相關的業務數據都放到一個Redis實例中,建議新業務申請新的單獨實例。因為Redis為單線程處理,獨立存儲會減少不同業務相互操作的影響,提高請求響應速度;同時也避免單個實例內存數據量膨脹過大,在出現異常情況時可以更快恢復服務!
3.存儲的Key一定要設置超時時間
如果應用將Redis定位為緩存Cache使用,對於存放的Key一定要設置超時時間!因為若不設置,這些Key會一直占用內存不釋放,造成極大的浪費,而且隨着時間的推移會導致內存占用越來越大,直到達到服務器內存上限!另外Key的超時長短要根據業務綜合評估,而不是越長越好!
4.對於必須要存儲的大文本數據一定要壓縮后存儲
對於大文本【超過500字節】寫入到Redis時,一定要壓縮后存儲!大文本數據存入Redis,除了帶來極大的內存占用外,在訪問量高時,很容易就會將網卡流量占滿,進而造成整個服務器上的所有服務不可用,並引發雪崩效應,造成各個系統癱瘓!
5.線上Redis禁止使用Keys正則匹配操作
Redis是單線程處理,在線上KEY數量較多時,操作效率極低【時間復雜度為O(N)】,該命令一旦執行會嚴重阻塞線上其它命令的正常請求,而且在高QPS情況下會直接造成Redis服務崩潰!如果有類似需求,請使用scan命令代替!
6.可靠的消息隊列服務
Redis List經常被用於消息隊列服務。假設消費者程序在從隊列中取出消息后立刻崩潰,但由於該消息已經被取出且沒有被正常處理,那么可以認為該消息已經丟失,由此可能會導致業務數據丟失,或業務狀態不一致等現象發生。為了避免這種情況,Redis提供了RPOPLPUSH命令,消費者程序會原子性的從主消息隊列中取出消息並將其插入到備份隊列中,直到消費者程序完成正常的處理邏輯后再將該消息從備份隊列中刪除。同時還可以提供一個守護進程,當發現備份隊列中的消息過期時,可以重新將其再放回到主消息隊列中,以便其它的消費者程序繼續處理。
7.謹慎全量操作Hash、Set等集合結構
在使用HASH結構存儲對象屬性時,開始只有有限的十幾個field,往往使用HGETALL獲取所有成員,效率也很高,但是隨着業務發展,會將field擴張到上百個甚至幾百個,此時還使用HGETALL會出現效率急劇下降、網卡頻繁打滿等問題【時間復雜度O(N)】,此時建議根據業務拆分為多個Hash結構;或者如果大部分都是獲取所有屬性的操作,可以將所有屬性序列化為一個STRING類型存儲!同樣在使用SMEMBERS操作SET結構類型時也是相同的情況!
8.根據業務場景合理使用不同的數據結構類型
目前Redis支持的數據庫結構類型較多:字符串(String),哈希(Hash),列表(List),集合(Set),有序集合(Sorted Set), Bitmap, HyperLogLog和地理空間索引(geospatial)等,需要根據業務場景選擇合適的類型,常見的如:String可以用作普通的K-V、計數類;Hash可以用作對象如商品、經紀人等,包含較多屬性的信息;List可以用作消息隊列、粉絲/關注列表等;Set可以用於推薦;Sorted Set可以用於排行榜等!