redis支持的數據結構
個人讀書筆記
- 簡單動態字符串 (String)
- 鏈表(list)
- 字典
- 跳躍表
- 整數集合
- 壓縮列表
- 對象
- sds(簡單動態字符串)
定義:
//記錄buf數組中已使用字節的數量
int len
//記錄buf數組中未使用字節的數量
int free
//字節數組 用於保存字符串
char buf []
使用sds的好處是:1.方便獲取當前字符串的長度
2.杜絕緩衝區溢出
3.減少字符串修改帶來的內存重分配次數.修改之後的空間,預分配的字空間大小和已 使用的空間大小相等.但是最大爲1M.
4.二進制安全.redis api讀進去的是一系列二進制
2.鏈表
鏈表提供了高效的節點重排能力,以及順序性的節點訪問方式,並且可以通過只能刪節點來靈活的調整鏈表的長度.
3.字典
字典又稱爲符號表.,關聯數組活映射(map),是一中用於保存鍵值對的抽象數據結構.
字典的底層是由哈希表實現的,一個哈希表裏面可以有很多個哈希表節點,而每個哈希表節點就保存了字典表中的一個鍵值對.
1.1.哈希表
結構定義:
table:哈希表數組.數組中的每個元素都是一個指向dictEntry結構的指針,每個dictEntry結構保存着一個鍵值對
size:哈希表大小
sizemask:哈希表掩碼,用於計算索引值.總是等於size-1
used:該哈希表已有節點的數量
1.2.哈希表節點
哈希表節點使用dictEntry結構表示,每個dictEntry結構都保存着一個鍵值對;
定義:
key:鍵
v:值
dictEntry *next :指向下個哈希表節點的指針,形成鏈表
1.3.字典(dict)
redis中的字典由dict結構表示
dict{
type:類型特定函數
privdata:私有數據
ht[2]:哈希表
trehashidx:rehash索引.當rehash不在進行時,值爲-1.
}
ht是一個包含兩個項的數組,數組中的每個項都是一個dictht哈希表,一般情況下,字典只是用ht[0]哈希表,ht[1]哈希表指揮對ht[0]哈希表進行rehash時使用
rehashidx,記錄了rehash目前的進度.
3.解決哈希衝突
當有兩個或兩個以上的鍵分配到了同一個索引上面,我們就稱這些鍵觸發了hash衝突.
redis使用鏈地址法解決衝突。每個哈希表節點都有一個next指針,多個哈希表節點可以用next指針構成一個單項鍊表,被分配到同一個索引上的多個節點可以使用這個單向鏈表連接起來,這就解決了鍵衝突的問題。(個人感覺和map差不多)
1.4.rehash
隨着操作的不斷執行,哈希表保存的鍵值會逐漸的增多或者減少,程序需要對哈希表的大下進行相應的擴展或者收縮。這些需要rehash來完成。
rehash的步驟:
1.爲ht[1]分配空間,空間的大小取決於執行的操作以及ht[0]當前包含的鍵值對的數量(即ht[0].user屬性的值)
- 如果執行的是擴展操作,那麼ht[1]的大小爲 第一個大於等於ht[0].user*2的2的那次方
- 如果是收縮,那麼ht[1]的大小爲第一個大於等於ht[0].user的2的n次方
2.將保存保存在ht[0]的值全部rehash到ht[1]上,rehash是指重新計算鍵的哈希值和索引值,然後將鍵值對放置到ht[1]哈希表的制定位置上。
3.當ht[0]全部放置到ht[1]上,就要釋放ht[0]的空間,將ht[1]置爲ht[0],並在ht[1]新建一個空白的哈希表,爲下一次rehash做準備。
哈希表的寬展與收縮觸發因素:
1)服務器目前沒有執行BGSAVE命令或者BGREWRITEAOF命令,並且哈希表的負載因子大於 等於1.
2)服務器目前正在執行BGSAVE命令或者BGREWRITEAOF命令,並且哈希表的負載因子大於等於5
哈希表的負載因子通過公式計算
load_factor=ht[0].user/ht[0].size
3)當哈希表的負載因子小於0.1,會自動執行收縮。
1.5漸進式rehash
rehash不是一次性完成的,二十分多次,漸進式地將ht0裏面的鍵值對rehash到ht1.在此期間rehashidx記錄遷移的結果
在rehash期間,字典的delete,update,find等操作會在兩個哈希表上進行。
而增加只會在ht1上執行。
5 跳躍表(skiplist)
跳躍表是一種有序的數據結構,它通過在節點中維持多個指向其他節點的指針,草那個人達到快速訪問節點的目的。
跳躍表主要用在有序集合鍵。
6整數集合
7 壓縮列表
壓縮列表是列表鍵和哈希鍵的底層實現之一。當一個列表鍵只包含少量列表項,並且每個列表項要麼就是小整數值,要麼就是長度較短的字符串,那麼redis就會使用壓縮列表來做列表鍵的底層實現。
同時如果哈希表的哈希鍵也是少量的,且每個鍵值對的鍵和值要麼就是小整數值,要麼就是長度較短的字符串,那麼哈希鍵的底層實現也是壓縮列表。
壓縮列表節點的構成
每個壓縮列表節點可以保存一個字節數組,或者一個整數值。