為什麼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 面試題 : 把數組分成和大小一樣的集合
※如何看待偽代碼?