搜尋

首頁  >  問答  >  主體

資料結構 - 關於 Redis 字串小於 39 位元組的疑惑

REDIS_ENCODING_EMBSTR_SIZE_LIMIT set to 39.

比如:

redis 127.0.0.1:2050> set massage "hello_world"
OK
redis 127.0.0.1:2050> object encoding massage
"raw"

為什麼這段字符串小於 39 編碼卻是 raw?另外,小於 39 字節 embstr 編碼,大於 39 raw 編碼的緣由是什麼?

PHP中文网PHP中文网2798 天前741

全部回覆(1)我來回復

  • ringa_lee

    ringa_lee2017-04-22 08:58:25

    這個和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,那一個位元組是'

    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就是這樣來的。

    回覆
    0
  • 取消回覆