前言
關于redis,可由應用維度、系統維度來進行了解。
如下所示:
redis在緩存應用發揮著重要作用,不知道你有沒思考過Redis為什么這么快?
1、純內存訪問
為什么內存訪問比磁盤訪問更快,可參考:
操作系統的內核態和用戶態場景-CSDN博客https://blog.csdn.net/weixin_50055999/article/details/148189950?spm=1011.2415.3001.5331
2、單線程避免上下文切換
關于I/O多路復用,可參考:關于多線程的Redis模型_redis線程模型-CSDN博客https://blog.csdn.net/weixin_50055999/article/details/147977886?spm=1011.2415.3001.5331
3、漸進式ReHash、緩存時間戳
1、漸進式ReHash
1.1、全局哈希表
????????為了實現快速根據鍵訪問到值,Redis使用了一個全局哈希表來存儲所有的鍵值對。
一個哈希表其實就是一個數組,數組的每個元素稱為一個哈希桶。
如下圖所示:
1.2、核心流程
1、擴、縮容觸發條件:
- 擴容:當哈希表的負載因子(鍵數量/桶數量)超過閾值(默認 1.0,且無后臺保存任務;或 5.0,若有后臺保存任務)時觸發。
- 縮容:當負載因子過低(如低于 0.1)時觸發,以節省內存。
如下圖所示:
2、核心機制:
Redis 維護兩個哈希表:ht[0](舊表)和 ht[1](新表)。
1、當觸發 ReHash 時,Redis 創建一個更大的(或更小的)新哈希表 ht[1],并將數據從 ht[0] 逐步遷移到 ht[1]。
2、遷移過程通過 漸進式操作 分攤到每次讀寫操作中,而不是一次性完成。
3、Redis 使用一個 rehashidx 指針記錄當前遷移的桶(bucket)位置,逐步將 ht[0] 的桶遷移到 ht[1]。
4、遷移期間,Redis 會同時查詢 ht[0] 和 ht[1],確保數據訪問無中斷。
5、遷移完成后,ht[1] 成為新的主哈希表,ht[0] 被清空并釋放。
1.3、示例場景
假設 Redis 存儲了一個包含 100 萬鍵的哈希表:
1、一次性 ReHash:
????????需要一次性將 100 萬鍵重新計算哈希并遷移,可能導致數百毫秒甚至秒級的阻塞。
2、漸進式 ReHash:
????????每次操作遷移 1-10 個鍵,100 萬鍵分攤到多次操作中,可能只需幾秒到幾十秒完成,單次操作延遲僅增加微秒級。
1.4、注意事項
1、ReHash 性能影響:
????????雖然漸進式 ReHash 極大降低了阻塞風險,但在極端高并發場景下,頻繁觸發 ReHash 可能仍會帶來輕微性能波動。
2、監控 ReHash:
????????通過 INFO MEMORY 命令查看 rehashidx 值,判斷是否正在進行 ReHash(非 -1 表示進行中)。
3、優化策略:
????????合理設置初始哈希表大小或負載因子閾值(通過 hash-max-ziplist-entries 或 activerehashing 配置),減少不必要的 ReHash。
2、緩存時間戳
2.1、使用原因
redis 為什么要緩存系統時間戳?
????????平時使用系統時間戳時,都是直接調用系統函數(涉及到用戶態和內核態線程的上下文切換) 直接獲取時間戳。redis 不是這樣的。因為 每一次獲取系統時間戳都 一次系統調用。相對耗時。作為 高性能的 redis是承受不起的。
????????redis采用定時任務來獲取系統時間 每毫秒更新一次,需要獲取時間戳直接從緩存中拿。
2.2、Redis緩存過期機制
1、惰性刪除:
? ? ? ? 惰性刪除是指 Redis 只有在訪問一個鍵(比如 GET、SET 等操作)時,才會檢查該鍵是否已過期。如果鍵已過期,Redis 會立即刪除該鍵,并返回空(對客戶端來說就像鍵不存在)
優點:
????????節省 CPU 資源,只有在必要時才執行刪除操作。
????????適合訪問頻率較高的場景,過期鍵能被及時清理。
缺點:
????????如果某些鍵長期不被訪問,過期鍵可能占用內存,直到被定期刪除或其他機制清理。
2、定期刪除:?
? ? ? ??Redis 會定期(后臺)掃描數據庫中的鍵,隨機抽樣檢查部分鍵的過期狀態,并刪除已過期的鍵。
優點:
????????能清理不常訪問的過期鍵,防止內存浪費。
????????掃描是分批進行的,不會一次性占用過多 CPU。
缺點:
????????隨機抽樣可能漏掉一些過期鍵,導致內存清理不徹底。
????????高負載下,定期刪除可能不夠及時。
擴展點
redis 6.0 之前為什么一直不使用多線程?
- 在使用redis 過程中 cpu 一直不是瓶頸。受制于 內存 和 網絡
- 提高Redis, Pipeline(命令批量處理)? 每秒 100萬請求
- 單線程內部維護簡便 高效
參考文章:
1、redis高階2 高性能-CSDN博客https://blog.csdn.net/nicepainkiller/article/details/147308857?ops_request_misc=&request_id=&biz_id=102&utm_term=Redis%E7%9A%84%E6%B8%90%E8%BF%9B%E5%BC%8Fhash%E5%92%8C%E7%BC%93%E5%AD%98%E6%97%B6%E9%97%B4%E6%88%B3&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-147308857.142^v102^pc_search_result_base1&spm=1018.2226.3001.4187