Redis 開發規範手冊

1、  數據庫選型

【建議】首先判斷業務類型是否必須使用Redis存儲數據,可否使用傳統關係性數據庫解決。使用Redis提早作好容量規劃,注意數據冷熱分離,避免將所有數據加載到Redis中。例如:redis

l   根據業務類型,選擇合適的最大內存及淘汰策略,設置好Key過時時間數據庫

 

2、  Key命名

Redis有兩層(key-value)或三層(key-field-value)結構,一般良好的Key命名習慣會爲平常的開發和運維工做帶來極大的便利性。安全

2.1     可讀性

【建議】可讀性高的Key命名有助於排查線上問題、方便的進行批量處理。建議使用業務名稱加冒號分割命名,"業務名/數據庫名:表名:id"做爲前綴,key的長度不超過100個字符。例如:網絡

l   當前redis內存暴漲,經過高頻key前綴能夠輕易的區分出是哪一個系統的哪一個模塊在頻繁操做,快速定位問題。架構

l   當定位到線上問題時,能夠經過模式匹配批量處理該類Key。併發

2.2     簡潔性

【建議】由於Redis中存儲的Key數量可能很是龐大,在保證可讀性的前提下,能夠適當縮短Key的長度,以減少內存開銷。例如:運維

l   建議key命名在64字符之內,在越龐大的系統中效果越明顯。異步

原Key:async

userid:{uid}:friends:messagesid:{mid}高併發

縮短後的Key,至少下降10字節的空間:

uid:{uid}:friends:mid:{mid}

2.3     規範性

【強制】Key命名需強制遵照如下規範,例如:

l   禁止包含特殊字符。例如:空格、換行、單雙引號以及其餘轉義字符

l   知足業務須要的狀況下,儘可能合理設置Key過時時間,建議過時時間打散,防止集中過時,而且越短越好

原Key:

redis> SET "userid:1:name" "Tom"  EX 90

redis> SET "userid:2:name" "Jack"  EX 90

redis> SET "userid:3:name" "Bob"  EX 90

優化過時時間後的Key:

redis> SET "userid:1:name" "Tom"  PX 60100

redis> SET "userid:2:name" "Jack"  PX 60200

redis> SET "userid:3:name" "Bob"  PX 60300

 

3、  Value設計

若是說Key規範命名極大的提升了開發運維的便利性,那麼Value設計規範更大的增長了Redis運行的高性能和可靠性

3.1     數據類型

【建議】Redis相比其它內存型數據庫具備更加豐富的數據類型可供應用選擇。例如:

l   Strings類型: 單個kv存儲、適用於如簡單計數等。

l   Hash類型: 多個相關屬性放到一個Hash中、適用於如存儲對象。

l   Set類型: 集合類型、適用於如歸類對象等

l   Sorted Set類型: 有序集合類型、適用於如榜單排行

l   Lists類型: 隊列類型、適用於如隊列、粉絲/關注列表等

l   特殊的數據類型:Hyperloglog、Geo、Scripting,須要提早跟DBA溝通

3.2     Bigkey

【強制】禁止Redis中出現Bigkey,防止出現高併發下網絡擁堵、阻塞超時發生切換、集羣內存空間不均衡、過時刪除、遷移困難及慢查詢。例如:

l   string類型控制在10KB之內,hash、list、set、zset元素個數不要超過5000(實際須要觀察元素的字節數),建議壓縮後存儲

l   非字符串的bigkey,不要使用del刪除,使用hscan、sscan、zscan方式漸進式刪除

l   注意bigkey過時時間,過時後會自動觸發del形成阻塞,而且該del不會記錄到慢查詢

3.3     定長更新

【建議】由於Redis內存使用具備預分配和惰性刪除的特性,所以Value內容的長度頻繁變化極易致使Redis內存碎片的產生。內存碎片風險以下:

l   當內存碎片較多時,會致使取少許數據掃描大量內存塊,嚴重拖慢Redis的運行

l   目前Redis內存碎片回收方式較困難,基本須要重啓Redis實例才能釋放碎片

 

4、  Redis安全

4.1   運行安全

【強制】防止Redis運行期間發生阻塞、崩潰、被入侵

l   Redis務必配置複雜度高的訪問密碼(requirepass、masterauth),64位以上,防止暴力破解

l   避免用root用戶啓動

l   禁止測試環境鏈接與生產環境混用

l   禁止壓測生產環境

l   禁止存儲圖片、音頻、視頻、文件等大數據

l   禁止不一樣業務使用相同Redis實例

l   優先選擇Redis 4.0.14版本,若對高版本功能有須要,也可選擇Redis 5.0.5版本

l   Redis單實例物理內存佔用儘可能保持在10G,最大不要超過20G

4.2   使用安全

l   高風險命令

【強制】數據清除:flushall、flushdb建議在Redis中禁用

【建議】Server運行:shutdown、monitor、config、save、bgsave、bgrewriteaof建議在Redis中rename-command

【建議】易阻塞:關注時間複雜度O(N)的命令:keys、smembers、lrange、hgetall、sinter等,使用時明確N的值。有遍歷的需求可使用hscan、sscan、zscan代替並在客戶端進行去重。此外,del bigkey、flushdb/flushall刪除大量數據時,也會形成Redis短期阻塞。Redis 4.0版本推出後臺異步刪除的方式(UNLINK、flushdb/flushall async)來避免該狀況

l   特性功能

【建議】select:Redis實例雖然支持多個庫,但由於Redis是單線程架構,同時多個業務使用多個庫仍然會相互干擾

【建議】批量操做提升效率:Redis原生支持mget、mset、hmset等命令批量操做,非原生批量操做可使用pipline提升效率,注意一次批量操做的元素個數不要太多,最好在100之內,以實際元素字節數大小爲準

n   原生命令爲原子操做,pipline能夠打包多個命令但爲非原子操做

n   pipline須要客戶端於服務端同時支持

【建議】事務:Redis事務功能支持較弱,不建議過多使用

【建議】消息隊列:Redis List常被用做消息隊列服務。由於功能相對簡單,不支持消息重傳、持久化等功能,當消費者崩潰時可能致使數據丟失。所以對於要求消息可靠性高的場景,建議使用更加專業的MQ軟件

【建議】Redis cluster限制:

n   只支持具備相同slot值的key執行批量操做

n   一次事務操做的Key必須在一個slot中,能夠hash tag實現定向分片(當一個key包含 {} 的時候,就不對整個key作hash,而僅對{}包括的字符串作hash)。

n   key是數據分區的最小粒度,所以不能將一個大的鍵值對象,如hash,list等映射到不一樣的節點上

n   不支持多數據庫,只能使用默認的0號庫

n   不能使用級聯複製

 

5、  集羣架構

【強制】Redis高可用相關規範

l   禁止將線下節點複製到線上主庫

l   主從集羣必須配置哨兵高可用

l   線上業務禁止使用級聯架構

l   Redis Cluster集羣架構至少三個分片

l   主從節點版本必須保持一致

 

6、  客戶端

【建議】Redis客戶端相關規範

l   使用帶有鏈接池的客戶端控制鏈接,提升通訊效率。經常使用客戶端好比Jedis、lettuce、Redisson

l   對於特別重要的數據、鏈接相關的操做須要保證捕獲異常,防止錯誤被淹沒、數據操做狀態不肯定

l   高併發下建議客戶端添加熔斷功能

相關文章
相關標籤/搜索