-
Redis——“快”:μs速度找到KV並完成操作。依賴於
a. 內存
b. 數據結構 -
6種底層數據結構 & 5種Redis數據類型
- Redis的“快”中的“慢操作”
- KV用哈希表存儲,哈希表結構=數組+哈希桶
哈希表是一個指針數組,每個元素是一個指向entry結構體的指針(哈希桶)
entry包含兩個元素:
- *key——指向key的指針
- *value——指向value的指針
- 哈希表查找過程主要依賴於哈希計算,與數據量多少無直接關係
- 哈希表存儲要解決的問題
哈希衝突——鏈式哈希
rehash可能帶來的操作阻塞——漸進式rehash
- 哈希衝突
- 解決:鏈式哈希——同一個哈希桶中多個entry用鏈表連接
- entry結構體中增加
*next
指針指向下一個entry
- rehash可能帶來的操作阻塞
- 背景:鏈式哈希潛在問題——同一哈希桶內鏈接元素過多(同一桶內的衝突過多),導致查找KV時的時間消耗增加。
- 解決:rehash——增加現有哈希桶數量,對entries進行重排,以減少單個桶內的衝突
- rehash具體操作
Redis默認使用兩個全局哈希表,表1rehash時
a. 給表2分配比表1更大的空間(比如表1的2倍大小)
b. 將表1數據重映射©到表2
c. 釋放表1空間 - rehash中處理重映射©的時間會隨着entries的增加而增加,涉及到了大量的數據copy操作,數據量大的情況下,極有可能阻塞Redis主線程,因此Redis採用漸進式rehash。
- 漸進式rehash
原理:將表1每個桶的“重映射©”分散到Redis的每次請求上
- 集合數據的操作效率
集合數據的操作效率取決於兩個因素:集合類型的底層數據結構、具體的操作
-
集合類型的底層數據結構:整數數組、雙向鏈表、哈希表、壓縮列表、跳錶
-
壓縮列表:
有序數組
表頭增加3個字段:zlbytes——列表長度、zltail——列表尾偏移、zllen——列表中的entry個數
表尾用zlend——列表結束標誌
-
跳錶:
有序鏈表上加多級序列
通過索引位置的跳轉實現數據快速定位
索引通過鏈表連接
-
查找時,各個集合類型底層數據結構的時間複雜度表
底層數據結構 時間複雜度 哈希表 O(1) 跳錶 O(logN) 雙向鏈表 O(N) 壓縮列表 O(N) 整數數組 O(N)
-
-
不同操作的複雜度
單元素操作是基礎
範圍操作非常耗時
統計操作通常g高效
例外情況只有幾個- 範圍操作: 集合類型中的遍歷操作
- 統計操作:比如集合中元素個數的統計
圖片來源於極客時間專欄《Redis核心技術與實戰》