最近在看redis相關的書籍,這裏將一些知識點做下總結,以免以後遺忘。
主要包含redis基礎數據結構、redis的一些策略以及redis的一些應用等內容。
String
實現
redis的字符串是簡單動態字符串,可以對其進行動態修改。
策略
- 空間預分配:
當對字符串進行append操作時,如果修改後的字符串長度len小於1MB,那麼redis會分配跟len大小相等的free空間,總分配空間是len*2。
當大於1MB時,redis會分配1MB的free空間,總分配空間是len + 1MB。需要注意字符串最大長度512MB。
- 惰性空間釋放
當對字符串進行縮短操作時,只是修改free和len的值,而不是使用內存分配來回收多餘的內存。
List
實現
redis中list是雙向鏈表,這樣添加和刪除的效率會非常高,但是隨機查找的效率會低一些。
由於雙向鏈表每個節點都需要兩個指針的空間,爲了節約內存,redis採用ziplist(壓縮列表)和鏈表相結合的策略實現list。
ziplist是redis爲了節約內存而設計的,是連續的內存塊組成的順序型數據結構,一個ziplist可以包含任意多個節點,每個節點可以包含一個字節數組或者一個整數值。ziplist是list和hash的底層實現之一。
當list中只包含少量元素,並且每個元素要麼就是小整數值,要麼就是長度比較小的字符串時,redis就會使用ziplist表來作爲list的底層實現。
redis會將雙向鏈表的每個元素變爲ziplist,這樣就節約了很多空間。
Hash
實現
hash的實現是數組+鏈表的二維結構,當兩個或者兩個以上的元素被分配到了哈希表的同一個索引上面時,redis會將衝突的元素添加到索引對應的鏈表上。爲了速度考慮,新添加的元素總是排在鏈表中其他元素的前面,即添加到鏈表的表頭位置。
Rehash
哈希表維護着一個負載因子,隨着哈希表中元素數量越來越多或者越來越少,負載因子可能偏離合理範圍,這時候redis會通過rehash的方式來擴大或者收縮哈希表,爲其重新分配哈希表的空間。
爲了不影響性能,redis採用漸進式rehash的方式,通過多次rehash來將舊的哈希表遷移到新的哈希表中,而在這期間,對哈希表的查找、更新、刪除等操作需要同時操作兩張表。當漸進式rehash完成之後,redis會回收舊錶的內存。
Set
實現
Set本身跟hash非常相似,其內部實現相當於一個hash,但是value都是null。
策略
Set能保證添加進來的每個元素都是唯一的,有去重的功能,注意遍歷Set時是亂序的。
當Set中最後一個元素被刪除,Set的空間會被redis回收。
SortedSet
實現
zset內部使用跳躍表來實現,跳躍表是一種有序的數據結構,支持平均log(N)、最差O(N)複雜度的節點查找,還可以通過順序性操作來批量處理節點。
策略
zset能保證內部每個元素的唯一性,同時也能保證所有元素的有序性,即可以根據元素的權重去排序。
當zset中最後一個元素被刪除時,zset的空間會被redis回收。
String類型的應用