阿里雲 Redis 開發規範深入解讀,別只會 set、get!

 

  • Key命名設計:可讀性、可管理性、簡介性
  • Value設計:拒絕bigkey
  • 控制Key的生命周期:設定過期時間
  • 時間複雜度為O(n)的命令需要注意N的數量
  • 禁用命令:KEYS、FLUSHDB、FLUSHALL等
  • 推薦使用批量操作提升操作效率
  • monitor命令控制使用時間
  • 寫在最後

Key命名設計:可讀性、可管理性、簡介性

規範建議使用冒號即:進行分割拼接,因為很多Redis客戶端是根據冒號分類的。比如有幾個Key:apps:app:1、apps:app:2和apps:app:3。Redis Desktop Manager能自動歸類到apps目錄下。如下圖所示:

Value設計:拒絕bigkey

規範建議String類型的Value控制在10KB範圍以內。這是因為Redis隨著Value不斷增長,在超過10KB后,有一個非常奇妙的性能拐點,如下圖所示(圖片來自Redis官網:http://redis.cn/topics/benchmarks.html

假設內網帶寬是千兆網卡,即1000MB。假設你的Redis中有一個大Key的Value長度是10KB,並且這個Key的QPS是10W,那麼這一個Key就會把帶寬打滿:10KB*100000=1000MB。

控制Key的生命周期:設定過期時間

儘可能對每一個Key都設置過期時間,這個是非常有益處的。否則,你想想一下,半年以後,一年以後,你的Redis集群中有上百G甚至更多的數據,誰都不知道這些數據哪些是有價值的,哪些已經成為垃圾。如果你的每個Key都設置了過期時間,那麼就不會出現這個問題了。集群在運行過程中,或自動淘汰那些已經不再使用的垃圾緩存數據。

時間複雜度為O(n)的命令需要注意N的數量

這個建議的意思是,以List類型為例,LINDEX、LREM等命令的時間複雜度就是O(n)。也就是說,隨著List中元素數量越來越多,這些命令的性能越來越差。而Redis又是單線程的,如果出現一個慢命令,會導致在這個命令之後執行的命令耗時也會增長,這是使用Redis的大忌。

事實上這也是JDK8為什麼要對HashMap進行鏈條衝突優化:當entry數量不少於64時,如果衝突鏈表長度達到8,就會將其轉成紅黑樹。因為鏈表長度越長,性能會越來越差。

禁用命令:KEYS、FLUSHDB、FLUSHALL等

這些命令應該在搭建Redis環境的時候就要禁用掉(在config配置文件中通過rename-command禁用)。FLUSHDB和FLUSHALL這兩個命令會清空數據,後果可想而知。

至於KEYS命令,還記得那個由於使用這個命令導致幾百萬損失的案例嘛?而且,這個命令的不當使用導致的損失,會隨著你的業務並大越大價值越大而導致損失越大:

推薦使用批量操作提升操作效率

批量命令主要分為兩類,原生命令和非原生命令:

  • 原生命令包括:例如mget、mset、hmget、hmset、LPUSH key value集合等。
  • 非原生命令包括:Pipeline。

合理使用這些命令對操作性能提升是極其巨大 的,尤其在單機Redis或者Sentinel模式下。因為這兩種架構不涉及跨Slot,Redis集群性能也有提升,但是使用會受到一些限制,例如不支持跨Slot的操作。

當然批量雖好,但不要貪多。俗話說的好,貪多嚼不爛。一般不要超過1000,具體限制還與操作數據大小有關。

monitor命令控制使用時間

monitor命令一般是用來觀察redis服務端都在執行哪些命令並實時輸出。例如在其他redis-cli中執行兩個set命令,在monitor中監控結果如下:

afeiMacBook-Pro:redis-3.2.11 afei$ src/redis-cli monitor
OK
1573915193.053188 [0 127.0.0.1:55357] "COMMAND"
1573915197.087383 [0 127.0.0.1:55357] "set" "name" "afei"
1573915217.938838 [0 127.0.0.1:55357] "set" "公 眾 號" "阿飛的博客"

之所以規範建議控制monitor命令的使用時間,是因為隨著monitor命令執行時間越來越長,會導致越來越多的數據積壓在輸出緩衝區,從而導致輸出緩衝區佔用內存越來越大。而且,這種影響會由於Redis併發越高,而更加放大。關於這個問題,美團有一個很經典的案例,感興趣的同學可以搜索關鍵詞:「美團在REDIS上踩過的一些坑-3.REDIS內存佔用飆升 」。

寫在最後

總而言之,任何一門技術都有利有弊,技術的世界里沒有銀彈 。所以,我們對使用到生產環境的任何一個技術,都要非常熟悉:知道它所擅長的和它的弱點,這樣才能結合自己的項目特點,設計出更合理的架構,編寫出最合理的代碼,不給生產環境造成影響,不給公司帶來損失 — 千萬不要成為那個執行KEYS命令導致給公司造成金錢損失的人!