首頁 > 資料庫 > Redis > 主體

Redis鍵值設計使用的方法是什麼

PHPz
發布: 2023-05-28 16:44:46
轉載
784 人瀏覽過

    Redis使用中不規範的現象

    • #Redis 儲存的key命名不規範,比較隨意;

    • Redis 當成儲存庫使用,有資料遺失風險,且無重新載入方案;

    • Redis 快取key,未設定過期時間, 快取低頻資料佔用大量內存,進而導致服務崩潰;

    • Redis 快取大量big key, 應用取得時會佔用大量網路頻寬,刪除也容易造成阻塞;

    • #Redis 用戶端使用不當,導致其它客戶端連接timeout, 原因可能客戶端密碼錯誤,且沒有使用連接池,大量連接重試導致系統連接埠資源耗光;

    • ##Redis 用戶端命令使用不當,導致大量的慢查詢,影響其它應用業務,例如在業務高峰期時使用keys* 或flushall 這樣的命令;

    Redis 使用業務場景推薦與建議

    • 高並發場景:熱點資料緩存,可提升系統整體反應速度,降低資料庫IO壓力;

    • ##限時場景:利用Redis expire指令設定session過期與續期、手機驗證碼等;
    • #使用Redis的清單和有序集合資料結構可以實現多種複雜的排行榜應用程式
    • 資料集運算:利用Redis list、set、sorted set,方便進行資料計算, 如交集、並集、差集等;
    • 連續簽到:可以利用redis的bitmap資料結構實現簽到相關的業務;
    • 計數器:利用Redis incr、incrby指令實作api呼叫次數統計,api限流等場景;
    • 分散式鎖定:利用Redis 的setnx 功能來寫分散式的鎖定, 典型開源元件例如redisson;
    • 如何設計出優雅的key

    可以這麼說,線上關於redis的效能優化這個問題上,不合理的key的設計經常是引發問題的根因,究其本質,就個人看到的情況來說,大多數同學在對redis使用過程中,對於key的設計幾乎是沒有什麼概念的,因為大多數同學使用的場景就是key/val ,對應的資料結構就是字符串key/字符串val;

    #稍微對redis有更深入的了解的同學,在進行存儲時,可能會知道key的設計盡量短一點,中間最好有層次感,最好以: 進行分割......

    那麼如何才能設計出比較優雅的key呢?以下結合小編實際使用中的經驗以及踩過的坑,來具體談談;

    一、遵循以下幾個最佳實踐約定

      遵循基本格式:[業務名稱]:[資料名稱]:[id];
    1. key的長度不超過44位元組;
    2. ##不要包含特殊字元;
    3. 關於上面幾個建議,這樣做有以下幾點好處:

    可讀性強,例如當我們設計這樣的key結構, order:user:10,一眼看過去就知道這是關於用戶訂單相關的key;
    • 方便維護管理,不同的應用,或者不同的業務採用不同的前綴,在視覺化客戶端工具或命令列中很方便進行key的查找定位;
    • 避免key衝突,避免在使用過程中多個人都用userId這樣的值作為key引發的快取key衝突;
    • 使用string類型作為key,底層編碼包含int、embstr和raw三種,可以有效降低記憶體佔用。使用embstr可在記憶體佔用較小的情況下,處理小於44位元組的字串,因為它採用了連續記憶體空間
    • ##建議值:

    單一key的value小於10KB;

    • #對於集合型別的key,建議元素數小於1000;

    • #二、盡量避免bigkey

    • 1、什麼是bigkey呢

    BigKey通常以Key的大小和Key中成員的數量來綜合判定,例如:

    Key本身的資料量過大:一個String類型的Key,它的值為5 MB;

    • Key中的成員數過多:一個ZSET類型的Key,它的成員數量為10,000個;

    Key中成員的資料量過大:一個Hash類型的Key,它的成員數量雖然只有1,000個但這些成員的Value(值)總大小為100 MB;

      #2、BigKey的危害
    • 網絡阻塞

    對BigKey執行讀取請求時,少量的QPS就可能導致頻寬使用率被佔滿,導致Redis實例,甚至所在實體機變慢;#### ###########資料傾斜###############BigKey所在的Redis實例記憶體使用率遠超過其他實例,無法讓資料分片的記憶體資源達到均衡;###############Redis阻塞######
    • 對元素較多的hash、list、zset等做運算會耗時較舊,使主執行緒被阻塞;

    CPU壓力

    • 對BigKey的資料序列化和反序列化會導致CPU的使用率飆升,影響Redis實例和本機其它應用;

    3、如何發現BigKey

    在安裝的機器上執行redis-cli --bigkeys指令

    • 利用redis-cli提供的--bigkeys參數,可以遍歷分析所有key,並傳回Key的整體統計資料與每個資料的Top1的big key;

    透過scan掃描

    • 編寫程序,利用scan掃描Redis中的所有key,利用strlen、hlen等指令判斷key的長度(此處不建議使用MEMORY USAGE );

    使用第三方工具

    • #利用第三方工具,如Redis-Rdb-Tools 分析RDB快照文件,全面分析記憶體使用情況;

    使用網路監控

    • #自訂工具,監控進出Redis的網絡數據,超出預警值時主動警告;

    三、使用恰當的數據類型

    正如上面所說,很多初次使用redis的同學,對於很多業務場景,都是一個key/val的簡單的結構搞定,而不會深入思考這樣做是否合理,或者說這樣做以後會不會引發相關的性能方面的問題;

    #對於這個問題,從根本上來說,需要深入了解並掌握redis的常用的資料類型,在這個基礎上,才能針對不同的業務場景,設計出高效的儲存儲存結構資料;

    讓我們思考一下,如何緩存使用者物件列表這樣的資料呢?

    • 方案1:key為usrId,value為物件的序列化字串,資料結構類似下面這樣; 

    Redis鍵值設計使用的方法是什麼

    優點:訪問方便,簡單粗暴,訪問時只需要做下json和物件的互轉即可;

    缺點:資料耦合,不夠靈活,一旦物件新增了字段或刪減了字段,快取重建的成本非常大;

    • 方案2:使用一個list結構,快取用戶ID列表,資料結構如下;

    Redis鍵值設計使用的方法是什麼

    #優點:對記憶體的佔用小,操作高效;

    缺點:取得到val之後,需要進一步查庫才能得到完整的物件;

    方案3:使用hash結構,快取對象,資料如下所示;

    Redis鍵值設計使用的方法是什麼

    #優點:底層使用ziplist,空間佔用小,可以靈活存取對象的任意字段;

    缺點:編碼上相對複雜;

    Redis 快取在實際應用中的使用建議

    • 【建議】對快取進行預熱。在存取數據前,應先對快取進行預熱,避免大量請求直接進入數據儲存層;應根據業務情況劃分合適的冷熱數據,對熱點數據進行預熱。如許可授權訊息,apikey等;

    • 【推薦】 搭配使用本機快取。在分散式架構中,雖然本地快取可以提高資料存取的穩定性和速度,但需要謹慎使用以避免引入具有狀態的伺服器節點。避免本地快取過度佔用應用程式伺服器資源,導致應用程式節點崩潰

    • 【建議】快取變更策略,應先更新資料庫,再更新快取;

    • #【推薦】一次業務呼叫需要存取多次redis服務端,可採用pipleline或其它批次操作方式;

    • 【推薦】大List,Set,Hash,儲存的數量龐大。當獲取大量元素時會產生較大的延遲,從而阻塞其他命令的執行。建議將其拆分成多個小的列表、集合或哈希表

    使用業務規範

    不管是redis,還是其他開發中使用到的中間件,具體到開發使用時,最好都應該提前製定出一套合理的規範,這個規範應該是大多數開發人員認可並在實踐中得到檢驗,且能有效規避一些問題的,一旦指定為規範,應該成為指導內部開發人員日常的規則,這裡提如下幾點:

    • Redis 應該定位為快取數據, 不可用於儲存大規模資料(不可替代資料庫);

    • Redis 適合讀多寫少場景,如存在高頻寫入,低頻查詢場景,則不建議使用;

    • 在不確定key的存活時間時,最好設定過期時間,控制key 的生命週期;

    • 應該考慮冷熱資料分離,對於查詢, 高頻次業務查詢走Redis,低頻查詢考慮走資料庫;

    • 程式處理資料時,應該考慮Redis存在資料遺失的風險,因此需要實現從資料庫自動載入並快取遺失的資料到Redis

    • #謹慎使用O(N)指令, 如list, set, hash 數據結構操作時, hgetall、lrange、smembers、zrange等並非不能使用,優先考慮使用hscan、sscan、zscan 代替。

    #

    以上是Redis鍵值設計使用的方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    相關標籤:
    來源:yisu.com
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板