前文 redis 設計與實現 2:redis 物件 說到,五大資料型別都會封裝成redisobject
。
typedef struct redisobject robj;
不同資料型別的主要區別就是type
和encoding
屬性的差異,同一種資料型別,有不同的編碼。
字串的編碼有raw
、embstr
、int
三種。
定義在server.h
中,這裡只列出string
型別的編碼
#define obj_encoding_raw 0
#define obj_encoding_int 1
#define obj_encoding_embstr 8
raw
編碼主要用來儲存長度超過 44 的字串。其真實資料,由sdshdr
結構來表示儲存,外層還是由 redisobject 包裝。
sdshdr
的結構在前文 redis 設計與實現 3:字串 sds 中有講到。
sdshdr
結構大致如下:
redisobject 中的ptr
指標,就是指向sds
。
embstr
編碼是專門用於儲存短字串的一種優化編碼方式。當字串的長度小於等於44的時候,將採用embstr
編碼。
建立字串物件的**如下(object.c
):
#define obj_encoding_embstr_size_limit 44
robj *createstringobject(const char *ptr, size_t len)
embstr
有個顯著的特點,就是redisobject
跟sds
的記憶體是挨在一起的。挨在一起的好處:
其結構示意圖如下:
embstr 問題一:那麼為什麼 embstr 跟 raw 的界限是44呢?
struct __attribute__ ((__packed__)) sdshdr8 ;
typedef struct redisobject robj;
redisobject + sdshdr8
至少需要3 + 16 = 19
位元組。
redis 認為如果超過64
位元組就是大字串,所以在redisobject+ sdshdr8
的總長度是64
位元組的情況下,留給buf
的長度就只剩下45
位元組,由於字串結尾需要乙個\0
占用乙個位元組,所以留個字串的長度就只有44
位元組了。
公式:64 - 3(sdshdr8) - 16(redisobject) - 1(\0) = 44
embstr 問題二:為什麼網上有的博文說 embstr 跟 raw 的界限是 39
在 redis 3.2 版本之前,這個界限的確是 39,為什麼後面改成 44 了呢?
那是因為sdshdr
的結構在 3.2 版本的時候修改了。3.2 之前的sdshdr
結構是:
struct sdshdr ;
舊版本的sdshdr
的頭占用了 8 個位元組,比新版本的多了5個位元組,所以界限就是44 - 5 = 39
啦!
如果乙個字串物件儲存的是整數值,並且這個整數值可以用long
型別來表示,那麼這個整數值將會儲存在字串物件結構的ptr
屬性裡面(將void*
轉換成long
),並將字串物件的編碼設定為int
。
相對於用raw
編碼,int
編碼既節省了指標占用的記憶體,也節省了sds
結構的記憶體。
redis> set int_key 12345
okredis> object encoding int_key
"int"
下圖為存著12345
的string
示例結構:
127.0.0.1:6379> set num 1
ok127.0.0.1:6379> object encoding num
"int"
(integer) 2
127.0.0.1:6379> object encoding num
"raw"
127.0.0.1:6379> set num 12
ok127.0.0.1:6379> object encoding num
"int"
一旦編碼變為raw
之後,將不會再轉成embstr
本文的分析沒有特殊說明都是基於 redis 6.0 版本原始碼redis 6.0 原始碼:
redis五大資料型別
redis支援五種資料型別 string 字串 hash 雜湊 list 列表 set 集合 及zset sorted set 有序集合 127.0 0.1 6379 set name yzl ok127.0 0.1 6379 get name yzl 127.0 0.1 6379 hmset my...
redis五大資料型別
string是redis最基本的型別 string型別是二進位制安全的,可以包含任何資料,或者序列化的物件 string型別是redis最基本的資料型別,乙個redis中字串value最多可以是512mhash是乙個鍵值對集合 hash是乙個string型別的field和value的對映表,hash...
redis五大資料型別
string是redis最基本的型別 string型別是二進位制安全的,可以包含任何資料,或者序列化的物件 string型別是redis最基本的資料型別,乙個redis中字串value最多可以是512mhash是乙個鍵值對集合 hash是乙個string型別的field和value的對映表,hash...