Redis開發最佳實踐

緩存在咱們平常開發中佔據着舉足輕重的地位,經過緩存組件可讓咱們的系統有着多方位的提高空間。而Redis就一個表明性的緩存組件。正巧最近使用Redis比較頻繁,因此打算經過文章記錄一下在Redis開發中遇到的問題和一些開發規範。文章已發佈在Github,將會持續保持更新,歡迎star和補充git

Key的設計

易於管理

即能經過名稱大概知道所涉及業務。一般咱們會以service:characteristics來進行命名,如pubg_chat:uid:room_id的形式,這樣能夠儘量避免衝突(固然,不一樣業務使用不一樣的Redis是更好的)github

儘可能簡潔

Redis本質上是一個內存數據庫,而內存的大小是遠小於硬盤的。若是Key過大的話,會致使Redis所能存儲的內容變少。因此在平常中推薦Key可以儘量的簡介明瞭,用縮寫來代替完整的單詞redis

避免特殊字符

如逗號、換行、空格和引號等轉義字符都是不該該使用的算法

設置生命週期

  • Redis不該當成爲一個永久存儲的組件,爲每個Key都設置他的過時時間
  • 若是確實須要Redis永久存儲某類內容,那麼因當採用異步「續命」的方式來進行,而不該該在一開始就爲其設置永久的生命週期,避免後續須要變動時帶來的維護災難

Value的使用

規避大Key!

  • Redis單線程的,它會在執行完一個命令後纔會執行其餘命令
  • 首先大Key在傳輸鍵值對時,會對網絡形成壓力(帶寬問題),而且有的proxy會將大內容分片傳輸,進而再次增長了網絡傳輸時間
  • 其次,如list、hash這類結構,若是使用O(n)的指令或者使用del命令,那麼會形成嚴重的阻塞
  • 因此一般而言,string 類型控制在 10KB 之內,hash、list、set、zset 元素個數不要超過 5000
  • ps:一般可採用hash的方式分割大key

value的壓縮

可考慮使用protobuf、MessagePack等方式進行序列化,這樣一能夠提高redis的利用率,二提升了序列化的效率,三是能提供value跨語言的能力數據庫

命令使用

避免頻繁對string作append

能夠考慮使用list進行替代數組

集合類操做

  • O(n)指令應注意。對於set,zset,list,hash等集合類,應注意O(n)命令對於性能的影響。一般應該避免直接使用O(n)指令,可用HSCAN,SSCAN,ZSCAN進行漸進操做,防止命令的阻塞
  • 漸進式刪除。不該該直接使用del,而應該本身寫腳本一點點的刪除

禁用危險命令

keys、flushall、flushdb......這種不用多說,一來直接Redis就懵圈了,人也楞了緩存

合理利用Pipeline模式

  • 在mget大量數據時,proxy會拆包和解包,會致使proxy層的壓力增長,而pipeline模式會直接轉發。因此在批量獲取的狀況下,pipeline的效率通常都會優於mget
  • 同時應該注意兩點:
    • mget是原子操做,pipeline不是。因此業務上不可盲目採用
    • pipeline是能夠發送不一樣命令的,固然使用lua也能夠實現這一點

避免沒必要要的指令

如部分Redis Client會有TestOnBorrow之類的探測指令,在沒有特殊要求的狀況下應當避免此類指令,以減少redis負載和網絡壓力安全

對Lua應當作特殊要求

  • 全部key都應該由KEYS數組來傳遞
  • 全部value都應該由ARGS數組來傳遞
  • 全部key,必須在1個slot上

性能查詢指令

  • slowlog get,查詢慢命令
  • info commandstats,查詢執行過的命令信息,包含用時和次數等
  • client list,查詢引發阻塞的命令

客戶端使用

避免混用實例

不一樣的業務線應該作到實例的拆分,避免混用致使的連鎖問題:如key重合、命令阻塞等網絡

使用鏈接池

每次使用都新建鏈接會有幾個問題:app

  • 形成redis的負擔增長
  • 浪費網絡資源
  • 影響執行效率
  • 難以維護

熔斷

Redis本質也是一個「服務」,因此熔斷機制不可少

鑑權

避免無關服務的濫用或致使數據出錯

避免做爲消息隊列

Redis其實還可以支持消息隊列的應用,但其讀寫效率是不及其餘MQ如Kafka、RabbitMQ等。且因爲其結構的設置,不太可以支撐MQ的一些主要特性,因此應當避免使用。

其餘

淘汰策略

根據⾃⾝業務類型,選好maxmemory-policy(最⼤內存淘汰策略),設置好過時時間 默認策略是volatile-lru,即超過最⼤內存後,在過時鍵中使⽤lru算法進⾏key的剔除,保證不過時數據不被 刪除,可是可能會出現OOM問題

  • allkeys-lru:根據LRU算法刪除鍵,無論數據有沒有設置超時屬性,直到騰出⾜夠空間爲⽌
  • allkeys-random:隨機刪除全部鍵,直到騰出⾜夠空間爲⽌。
  • volatile-random:隨機刪除過時鍵,直到騰出⾜夠空間爲⽌
  • volatile-ttl:根據鍵值對象的ttl屬性,刪除最近將要過時數據。若是沒有,回退到noeviction策略
  • noeviction:不會剔除任何數據,拒絕全部寫⼊操做並返回客⼾端錯誤信息"(error) OOM command not allowed when used memory",此時Redis只響應讀操做
  • 4.0後推出的allkey-lfu和volatile-lfu
    • 能夠認爲這是對於lru算法的進一步改進
    • allkey-lfu:從全部鍵中驅逐使用頻率最少的鍵
    • volatile-lfu:從全部配置了過時時間的鍵中驅逐使用頻率最少的鍵

不濫用Redis事務

Redis事務不像DB的事務這麼「安全」,也不支持回滾,因此不該當過多的使用。由於這塊我沒怎麼使用過,詳見官方文檔

參考資料

相關文章
相關標籤/搜索