object..." />

為什麼redis小等於39位元組的字元串是embstr編碼,大於39是raw編碼?

#define REDIS_ENCODING_EMBSTR_SIZE_LIMIT 39

為什麼是39?

===================

redis 127.0.0.1:6379&> set massage "hello"

OK

redis 127.0.0.1:6379&> object encoding massage

"raw"

--------------------------------------

為什麼我這小於39位元組的字元串編碼是raw?


這個和redis的版本有關係。

查看redis-3.0和最新的版本的object.c文件,可以發現在創建StringObject的時候,會和REIDS_ENCODING_EMBSTR_SIZE_LIMIT比較,這個的默認值是39。

查看一下redis-2.8版本的源碼,並沒有發現比較,而是直接創建了。

所以我猜測這個embstr編碼是3.0以上版本才出現的。

至於為什麼是39,這個講起來就比較複雜了,我就慢點說。

embstr是一塊連續的內存區域,由redisObject和sdshdr組成。其中redisObject佔16個位元組,當buf內的字元串長度是39時,sdshdr的大小為8+39+1=48,那一個位元組是。加起來剛好64。是不是發現了什麼?

typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
int refcount;
void *ptr;
} robj;

struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
};

從2.4版本開始,redis開始使用jemalloc內存分配器。這個比glibc的malloc要好不少,還省內存。在這裡可以簡單理解,jemalloc會分配8,16,32,64等位元組的內存。embstr最小為16+8+8+1=33,所以最小分配64位元組。當字元數小於39時,都會分配64位元組。

這個默認39就是這樣來的。


REDIS_ENCODING_EMBSTR_SIZE_LIMIT set to 39.

The new value is the limit for the robj + SDS header + string +
null-term to stay inside the 64 bytes Jemalloc arena in 64 bits
systems.

出處:https://gitcandy.com/Repository/Commit/redis/0b0f872f3f1536e30b2fab0b4297ea960d8247e1


推薦閱讀:

有沒有三維的數據結構?
為什麼說「滿二叉樹也是完全二叉樹」?
Map、Dictionary、Hash Table 有哪些異同?
九章演算法 | Ebay 面試題 : 把數組分成和大小一樣的集合
如何看待偽代碼?

TAG:Redis | 數據結構 |