redis 備註回憶

1、數據結構

    string:int和sds,int針對數字存儲,sds針對字符串、浮點,根據長度的不同,存在不同的HDR上

    list : 雙向鏈表,通常的操作是向列表倆端添加元素或獲得列表的某個片段,在列表兩端的操作快

              quickList是鏈表,節點是zipList 壓縮

             可用於阻塞隊列,即消息隊列,左邊push,右邊get

   hash: ziplist--->hashtable,類似java中的hashmap

  set:用的hashtable,value爲空,O(1)

   zset:skipList + hashtable,這個跳躍表類似currenthashmao,進行了分段處理,有路由

             

2、原理分析

     過期時間設置

          expire、setNx()

          消極:get時,刪除

          積極:定時任務,定時輪訓隨機部分key刪除

   發佈、訂閱

   爲啥單進程:

                無需線程切換,使用的IO多路複用,異步非阻塞

  分爲

  1、哨兵模式(M-S 主備模式,只有master提供查詢,slave只提供備份):高可用

   2、 cluster模式(無中心化的分片集羣)

  

 

 

 

Redis的一些開發規範和建議(https://mp.weixin.qq.com/s/SGOyGGfA6GOzxwD5S91hLw)

1.冷熱數據分離,不要將所有數據全部都放到Redis中

雖然Redis支持持久化,但是Redis的數據存儲全部都是在內存中的,成本昂貴。建議根據業務只將高頻熱數據存儲到Redis中【QPS大於5000】,對於低頻冷數據可以使用MySQL/ElasticSearch/MongoDB等基於磁盤的存儲方式,不僅節省內存成本,而且數據量小在操作時速度更快、效率更高!

2.不同的業務數據要分開存儲

不要將不相關的業務數據都放到一個Redis實例中,建議新業務申請新的單獨實例。因爲Redis爲單線程處理,獨立存儲會減少不同業務相互操作的影響,提高請求響應速度;同時也避免單個實例內存數據量膨脹過大,在出現異常情況時可以更快恢復服務! 在實際的使用過程中,redis最大的瓶頸一般是CPU,由於它是單線程作業所以很容易跑滿一個邏輯CPU,可以使用redis代理或者是分佈式方案來提升redis的CPU使用率。

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可以用於排行榜等!

9.命名規範

雖然說Redis支持多個數據庫(默認32個,可以配置更多),但是除了默認的0號庫以外,其它的都需要通過一個額外請求才能使用。所以用前綴作爲命名空間可能會更明智一點。
另外,在使用前綴作爲命名空間區隔不同key的時候,最好在程序中使用全局配置來實現,直接在代碼裏寫前綴的做法要嚴格避免,這樣可維護性實在太差了。
如:系統名:業務名:業務數據:其他
但是注意,key的名稱不要過長,儘量清晰明瞭,容易理解,需要自己衡量

10.線上禁止使用monitor命令

禁止生產環境使用monitor命令,monitor命令在高併發條件下,會存在內存暴增和影響Redis性能的隱患

11.禁止大string

核心集羣禁用1mb的string大key(雖然redis支持512MB大小的string),如果1mb的key每秒重複寫入10次,就會導致寫入網絡IO達10MB;

12.redis容量

單實例的內存大小不建議過大,建議在10~20GB以內。
redis實例包含的鍵個數建議控制在1kw內,單實例鍵個數過大,可能導致過期鍵的回收不及時。

13 可靠性

需要定時監控redis的健康情況:使用各種redis健康監控工具,實在不行可以定時返回redis 的 info信息。
客戶端連接儘量使用連接池(長鏈接和自動重連)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章