Redis使用規范
更新時間 2024-11-11 10:19:25
最近更新時間: 2024-11-11 10:19:25
分享文章
本節主要介紹Redis常見使用規范,包括業務使用規范、SDK使用規范等
業務使用規范
| 規范 | 規范說明 | 級別 | 備注 |
|---|---|---|---|
| 業務數據分離 | 防止由于Redis故障或不可用影響所有相關業務收到干擾 | 建議 | 業務數據分離,避免多個應用使用一個Redis實例,不相干的業務拆分,公共數據做服務化 |
| 完善redis的容錯處理 | 緩存可能會遇到基礎設施的故障或主備切換,應用需要對可能的故障和慢請求做容錯處理。 | 建議 | 緩存訪問失敗時,具備降級措施,從DB獲取數據;或者具備容災措施,自動切換到另一個Redis使用; |
| 避免redis內存使用量超過80% | 避云主機會有一定的內存冗余,但是redis內存過高時,redis全量持久化時引入的COPY-ON-WRITE機制帶來額外的內存消耗,再加上大內存帶來的內存碎片和云主機相關的管理進程消耗,容易觸發操作系統OOM KILL | 強制 | 建議及時做擴容處理 |
| 防止緩存擊穿 | 防止緩存擊穿,推薦搭配本地緩存使用Redis,對于熱點數據建立本地緩存。本地緩存數據使用異步方式進行刷新 | 建議 | - |
| 就近部署業務 | 避免網絡延遲將極大影響讀寫性能,如果對于時延較為敏感,請避免使用跨AZ Redis實例 | 建議 | - |
| 不當成消息隊列 | 發布訂閱場景下,不建議作為消息隊列使用。redis的PUB/SUB支持的性能有限。 | 強制 | 如果需要消息隊列,建議改用kafka或rabbitmq |
Key名稱的使用規范
| 規范 | 規范說明 | 級別 | 備注 |
|---|---|---|---|
| 使用統一的命名規范 | 一般使用業務名(或數據庫名)為前綴,用冒號分隔 | 建議 | 例如,業務名:表名:id |
| 控制key名稱的長度 | 在保證語義清晰的情況下,Key的長度越短越好。有些常用單詞可使用縮寫 | 建議 | 例如,user縮寫為u,messages縮寫為msg。建議長度不超過128字節。 |
| 名稱中不要包含特殊字符 | 禁止包含特殊字符,如空格、換行、單雙引號、中文或其他轉義字符 | 強制 | 大括號({})為Redis的hash tag語義,如果使用cluster集群實例, KEY名稱需要正確使用,避免引發數據傾斜,數據都分在同一個SLOT上。 |
Value值的使用規范
規范 規范說明 級別 備注 要避免大Key、熱Key 大Key會帶來網卡流量風暴和慢查詢,要避免出現大Key和熱KEY 強制 一般string類型控制在10KB以內,hash、list、set、zset元素個數不要超過1000 選擇合適的數據類 選擇合適的數據類型能夠節省內存、帶寬和提升性能。 建議 比如存儲用戶的信息,可用使用多個key,使用set u:1:name "X"、set u:1:age 20這樣存儲,也可以使用hash數據結構,存儲成1個key,設置用戶屬性時使用hmset一次設置多個,同時這樣存儲也能節省內存 設置合理的過期時間 最好是過期時間打散,不要集中在某個時間點過期。 建議 避免Redis因為處理大量過期KEY導致CPU使用率飆高導致性能不穩定。
Redis命令的常用規范
規范 規范說明 級別 備注 小心使用時間復雜度為O(N)的命令 對于時間復雜度為O(N)的命令如果N值較大,可能會導致Redis執行過慢,影響整體性能和穩定性 強制 例如:hgetall、lrange、smembers、zrange、sinter這些命令都是做全集操作,如果元素很多,是很耗性能的可使用hscan、sscan、zscan這些分批掃描的命令替代 命令禁用 部分命令是禁止使用的,需要最好提早了解清楚 強制 使用前,請參考Redis命令兼容性和WebCli命令兼容性 慎重使用select Redis多數據庫支持較弱,多業務用多數據庫實際還是單線程處理,會有干擾 建議 需要多DB的場合,建議拆分多個redis使用 CLUSTER集群實例不支持多DB 批量操作 如果有批量操作,可使用mget、mset或pipeline,提高效率,但要注意控制一次批量操作的元素個數免得導致執行過慢,占用Redis過多的資源 建議 如果有批量操作,可使用mget、mset或pipeline,提高效率,但要注意控制一次批量操作的元素個數mget、mset和pipeline的區別如下:
mget和mset是原子操作,pipeline是非原子操作
pipeline可以打包不同的命令,mget和mset做不到
使用pipeline,需要客戶端和服務端同時支持
lua腳本執行耗時 lua腳本的執行超時時間為5秒鐘,建議不要在lua腳本中使用比較耗時的代碼 強制 比如長時間的sleep、大的循環等語句 避免在lua腳本中使用隨機函數 調用lua腳本時,建議不要使用隨機函數去指定key,否則在主備節點上執行結果不一致,從而導致主備節點數據不一致 強制 - 遵循CLUSTER集群實例使用lua的限制 遵循CLUSTER集群實例使用lua的限制 強制 cluster集群實例使用lua有如下限制:
使用EVAL和EVALSHA命令時,命令參數中必須帶有至少1個key,否則客戶端會提示“ERR eval/evalsha numkeys must be bigger than zero in redis cluster mode”的錯誤
使用EVAL和EVALSHA命令時,cluster集群實例使用第一個key來計算slot,用戶代碼需要保證操作的key是在同一個slot
不要直接使用del命令刪除大Key 刪除大Key時,不要直接使用del命令因為del命令是阻塞的,也會同時阻塞其他客戶端請求無法正常執行 強制 Redis 4.0后的版本可以通過UNLINK命令安全地刪除大Key,該命令是異步非阻塞
對于 4.0之前的版本:
如果是Hash類型的大Key,推薦使用hscan + hdel
如果是List類型的大Key,推薦使用ltrim
如果是Set類型的大Key,推薦使用sscan + srem
如果是SortedSet類型的大Key,推薦使用zscan + zrem
的
控制pipeline命令個數 使用Pipeline時,建議不要一次太多命令因為會占用大量Redis資源和執行時間較長,可能會卡住其他請求無法執行 建議 單次建議不超過100,同時也需要考慮實際元素字節數大小情況 合理使用發布訂閱命令 不建議將 Redis 當作消息隊列使用Redis 當作消息隊列使用,會有容量、網絡、效率、功能方面的多種問題 建議 如需要消息隊列,可使用高吞吐的Kafka或者高可靠的RabbitMQ Redis事務限制 Redis事務是不支持回滾的如果事務在中途某個命令失敗了,那么前面的命令依然會執行成功 建議 -
SDK使用規范
規范 規范說明 等級 備注 使用連接池+長連接 短連接性能差,建議使用連接池+長連接,可以有效控制連接,同時提高效率 建議 推薦使用JedisPool或者JedisCluster連接實例。 避免使用Lettuce客戶端 Jedis客戶端在面對連接異常,網絡抖動等場景下的異常處理和檢測能力明顯強于Lettuce,可靠性更強 建議 建議使用Jedis 客戶端需要對可能的故障和慢請求做容錯處理 由于Redis服務可能因網絡波動或基礎設置故障的影響,引發主備切換、命令超時或慢請求等現象,需要在客戶端內設計合理的容錯重試機制 強制 - 合理設置重試時間和次數 根據業務要求合理設置容錯處理的重試時間和次數,避免不合適的設置導致對服務的可用性收到影響 強制
如果超時重試時間設置的非常短,可能引發重試風暴,極易引發業務層雪崩
如果重試時間設置得較長或者重試次數設置得較大,則可能導致在主備倒換情況下業務恢復較慢
運維管理規范
規范 規范說明 等級 備注 開啟密碼登錄 生產環境需要開啟Redis密碼登錄驗證 強制 - 驗證業務的故障處理能力或容災邏輯 在測試環境或者預生產環境中組織演練,驗證在Redis主備切換、宕機或者擴縮容場景下業務的可靠性 建議 - 監控實踐 關注Redis負載,在過載前提前擴容 強制 根據告警基線配置告警:配置節點cpu、內存、帶寬等告警 檢查各個節點的內存使用率 例行檢查各個節點的內存使用率,查看主節點內存使用率是否有不均衡的狀態 建議 內存使用率不均衡說明存在大Key問題,需要進行大Key拆分及優化 開啟熱Key分析 開啟熱Key例行分析,并分析是否有Key頻繁調用 建議 - Redis慢日志 例行巡檢Redis慢日志命令 建議 分析慢日志,并盡快從業務上進行修復