數據類型之 String List

Redis源碼解析4 – 數據類型之 String List STRING string類型的數據在redis中有兩種編碼方式: 1.RAW 這表示一個原始字符串對象,robj中的ptr指針指向一個sds類型的內存塊 sds是一個帶長度信息的內存塊,用于存儲 二進制安全 的字符串 2. INT 這表示一個編碼

Redis源碼解析4 – 數據類型之 String & List

STRING

string類型的數據在redis中有兩種編碼方式:

1.?RAW
? ? 這表示一個原始字符串對象,robj中的ptr指針指向一個sds類型的內存塊
? ? sds是一個帶長度信息的內存塊,用于存儲二進制安全的字符串

2. INT
? ? 這表示一個編碼為整數的字符串對象,robj中的ptr指針被強行轉化為一個long型變量以存儲整數
? ? 數字類型的字符串,比如“123456”,都會被編碼為整型
? ? 這樣做的目的就一點,節省內存。就以字符串“123456”為例,
? ? (1) 存為RAW類型,共消耗內存為:sizeof(robj) + sizeof(sdshdr) + strlen(“123456”)
? ? ? ? ?32位系統為26字節,64位系統下為30字節
? ? (2) 存為INT類型,共消耗內存為:sizeof(robj)
? ? ? ? ?32位系統為12字節,64位系統下為16字節

? ? 可以看出,節省的內存還是挺多的
? ? 如果字符串更長一些,比如“123456789”,節省的內存就可觀了

? ? 一點小提示,在Redis中,64位的bigint,香港虛擬主機,是按RAW格式存儲的
? ??之所以這么做,完全是為了兼容不同的系統
? ? 在實際使用中,如果你確定你的機器都是64位的(MS現在很少32位機了),可以改改源代碼,多節省一些內存
?

?

再加一幅圖,更直觀的說明一下

數據類型之 String List

? ?

OK,在Redis中,String是最基本的類型,也很簡單,從上圖可以較清晰的看出String的組織方式了

題外話,不知道有同學注意到沒有,robj中的ptr居然是指向sdshdr內存塊的中間部分,而不是指向內存頭

從這一點看,Redis的代碼也挺“野”的

?

LIST

list數據有兩種編碼方式:

?

1. linked_list
? ? 這就是一個傳統的雙向鏈表,帶頭尾指針,其頭尾操作都只有O(1)的復雜度
? ??

?

2. ziplist
? ? 這是一種壓縮編碼的鏈表,它將所有的鏈表數據全部整合進一整塊內存中,相比傳統的鏈表,節省很多內存

?

數據類型之 String List

簡要說明一下上圖:

(1) ziplist使用一整塊連續的內存,這塊內存由三部分組成:
? ? ?(a) head塊,鏈表的頭信息,包括有 totalsize(鏈表總長度)、tailoffset(尾部最后一個元素的偏移字節數)、entrycount(entry個數)
? ? ?(b) entry塊,由一系列的 entry node 組成。node之間緊湊排列
? ? ? ? ? 每個node有 prevsize字段,表示前一個node的長度,用以反方向索引
? ? ? ? ? 有selfsize字段,表示當前node的長度
? ? ? ? ? 以及data字段,存放當前node的實際數據
? ? ? ? ? 這些字段都按一種特殊的形式編碼,具體參考上圖,已經比較清晰了
? ? ?(c) tail塊,虛擬主機,鏈表的尾部。只有一個字節,是一個填充碼。

(2) 向ziplist中增刪元素時,有較頻繁的內存重分配操作,香港服務器,以及較復雜的數值運算
? ? ?所以,當鏈表長度增加時,整個數據結構就會不堪重負

(3) redis用兩個閥值來控制 ziplist 與 linked_list 之間的轉換
? ? ?(a)?list_max_ziplist_entries:當鏈表元素的個數超過該值,自動轉化為 linked_list,該值默認512
? ? ?(b)?list_max_ziplist_value:當鏈表中某個字符串元素的長度超過該值,自動轉化為 linked_list,該值默認64
? ? ?(c) 以上兩值均可通過配置文件修改

posted on

數據類型之 String List

? 版權聲明
THE END
喜歡就支持一下吧
點贊6 分享