redis 數據結構與對象
1 動態字符串 SDS (redis中字符串值、AOF緩衝區以及客戶端輸入緩衝區)
2 鏈表 linkedlist(發佈與訂閱、慢查詢、監視器、redis本身保存多客戶端的狀態信息、構建客戶端輸出緩衝區)
3 字典 HashTable(又稱爲符號表、關聯數組、映射、保存鍵值對抽象數據結構) 是hash鍵的底層
4 跳躍表 skiplist(有序集合鍵、集羣節點中用作內部數據結構)
1 字符串對象(String) int raw embstr(專門保存短字符串的一種優化編碼方式)
2 列表對象(List) ziplist linkedlist
3 哈希對象(Hash) ziplist hashtable
5 有序集合對象(Zet) ziplist skiplist
1 動態字符串 SDS (redis中字符串值、AOF緩衝區以及客戶端輸入緩衝區)
1 常數複雜度獲取字符串長度
2 杜絕緩衝區溢出(api 會檢查SDS是否滿足需求)
3 減少字符串帶來的內存重分配次數
(空間預分配、小於1MB 13+13+1 大於1MB 30MB+1MB+1) 惰性空間釋放
4 二進制安全 使用len來判斷字符串是否結束
5 兼容部分C字符串函數
2 鏈表 linkedlist(發佈與訂閱、慢查詢、監視器、redis本身保存多客戶端的狀態信息、構建客戶端輸出緩衝區)
3 字典 HashTable(又稱爲符號表、關聯數組、映射、保存鍵值對抽象數據結構) 是hash鍵的底層
哈希表
哈希表節點
字典
Ht[1]會在rehash的時候使用
哈希表的擴展與收縮
漸進性rehash
4 跳躍表 skiplist(有序集合鍵、集羣節點中用作內部數據結構)
(平均O(logN))、最壞O(N)複雜度 效率可以和平衡樹來媲美)
跳躍表 skiplist 就是受到這種多層鏈表結構的啓發而設計出來的。按照上面生成鏈表的方式,上面每一層鏈表的節點個數,是下面一層的節點個數的一半,這樣查找過程就非常類似於一個二分查找,使得查找的時間複雜度可以降低到 O(logn)。
但是,這種方法在插入數據的時候有很大的問題。新插入一個節點之後,就會打亂上下相鄰兩層鏈表上節點個數嚴格的 2:1 的對應關係。如果要維持這種對應關係,就必須把新插入的節點後面的所有節點 (也包括新插入的節點) 重新進行調整,這會讓時間複雜度重新蛻化成 O(n)。刪除數據也有同樣的問題。
skiplist 爲了避免這一問題,它不要求上下相鄰兩層鏈表之間的節點個數有嚴格的對應關係,而是 爲每個節點隨機出一個層數(level)。比如,一個節點隨機出的層數是 3,那麼就把它鏈入到第 1 層到第 3 層這三層鏈表中。
說一下跳錶的缺點:
1.內存佔用比紅黑樹大(每個節點4指針);
2.由於插入時是隨機選擇level,cache友好性不夠好;
https://blog.csdn.net/brillianteagle/article/details/52206261跳躍表原理與java實現
https://blog.csdn.net/DERRANTCM/article/details/79063312跳躍表Skip List的原理和實現
https://www.cnblogs.com/tong-yuan/p/skiplist.html 跳錶的插入刪除
5 整數集合 Intset(集合鍵的底層實現)
6 壓縮列表 ziplist(列表鍵和哈希鍵的底層實現)
7 對象
0字符串對象、列表對象、哈希對象、集合對象、有序集合對象
1 字符串對象(String) int raw embstr(專門保存短字符串的一種優化編碼方式)
2 列表對象(List) ziplist linkedlist
3 哈希對象(Hash) ziplist hashtable
4 集合對象(Set) intset hashtable
5 有序集合對象(Zet) ziplist skiplist