【redis前傳】 redis五大天王值list基本數據如何成長 | 由內以外深刻學習

這是我參與更文挑戰的第24天,活動詳情查看: 更文挑戰node

前言

  • 在【數據結構】學習中,繞不過的就是鏈表和數組的學習了!數組應該更容易理解點!由於他和咱們平時的邏輯同樣。可是鏈表在剛入門的同窗中應該算是比較抽象的了!尤爲是指針交換位置更是容一部分同窗望而卻步!
  • 今天咱們來學習下Redis中的經常使用的鏈表數據結構

list

  • Redis低版本(3.2以前)中list數據結構底層就是使用鏈表來進行串聯數據的!

image-20210621154225866

  • 上圖就是Redis中在操做List數據結構時的結構圖!在redis中並非僅僅使用這一種雙向的鏈表結構.關於ziplist等其餘結構咱們這裏暫時不討論。
  • 而針對一整條鏈條redis有將它 抽象化一個list對象

image-20210621154708172

  • node是鏈條中重要的組成部分,而list咱們能夠理解成對整個鏈條的描述。list中包含頭結點、尾結點、鏈條中節點個數、節點的複製釋放比對等功能!
typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

typedef struct list {
    listNode *head;
    listNode *tail;
    void *(*dup)(void *ptr);
    void (*free)(void *ptr);
    int (*match)(void *ptr, void *key);
    unsigned long len;
} list;
複製代碼
函數 做用
dup 複製鏈表節點值
free 釋放鏈表節點值
match 比對鏈表節點值與指定值是否想的相等

image-20210621155615574

小結

  • 很明顯在redis中鏈表是一種雙指針鏈表,能夠經過當前節點輕鬆定位先後節點!
  • list中能夠輕鬆獲取鏈表頭尾節點!這也就解釋redis中的lpush 、 rpush命令最終的實現了。就是經過改變頭、尾指針就能夠了。操做那是很是迅速的
  • list中len表示鏈表長度。就是一個節點計數器。對應着llen 命令
  • 瞭解數據結構後基本上就能夠理解redis對應的操做命令在內存中的結構了

list其餘數據結構

  • 上面咱們提到在3.2以前的版本中redis採用鏈表結構進行存儲list數據。在3.2以後開始出現一種ziplist結構的數據結構!
  • 首先咱們思考下listnode用的好好的爲何要改用ziplist結構。由於list結構中存儲了頭尾節點方便了咱們尋址可是犧牲了內存說白了就是空間換時間
  • ziplist就是針對內存浪費的問題進行了優化。
  • 我們看下ziplist的存儲內存分佈圖(如下圖片來源於網絡)

image-20210621173157390

位置 做用
zlbytes ziplist字節長度;長度最長爲(2^32)-1
zltail 整個ziplist偏移量;四個字節
zllen ziplist中存儲的元素個數;兩個字節
entryX ziplist中元素
zlend 結束位 。固定值0xFF=255
typedef struct zlentry {
    unsigned int prevrawlensize, prevrawlen;
    unsigned int lensize, len;
    unsigned int headersize;
    unsigned char encoding;
    unsigned char *p;
} zlentry;
複製代碼

小結

  • ziplist又稱爲壓縮列表本質上就是一個數組。除了list之外還有hash也都使用了ziplist. 壓縮列表雖然節省了內存的開銷可是隨之而來的問題就是連鎖更新。關於什麼是連鎖更新咱們之後在分析!本文是一篇入門級的文章。到這裏就結束啦

歡迎點個讚唄redis

相關文章
相關標籤/搜索