redis的embstr編碼


問題來了

今天在看書籍《Redis設計與實現》的時候,在8.2字符串對象里面寫到

  • 如果字符串對象保存的是一個字符串值, 並且這個字符串值的長度大於 39 字節, 那么字符串對象將使用一個簡單動態字符串(SDS)來保存這個字符串值, 並將對象的編碼設置為 raw 。
  • 如果字符串對象保存的是一個字符串值, 並且這個字符串值的長度小於等於 39 字節, 那么字符串對象將使用 embstr 編碼的方式來保存這個字符串值。

自己本地實驗的時候,就算字符小於39,也是raw類型的,不知道為什么。


原來是版本的原因

去查看源碼。才發現這個和redis的版本有關系。查看redis-3.0和最新的版本的object.c文件,可以發現在創建StringObject的時候,會和REIDS_ENCODING_EMBSTR_SIZE_LIMIT比較,這個的默認值是39。查看一下redis-2.8版本的源碼,並沒有發現比較,而是直接創建了。
所以我猜測這個embstr編碼是3.0以上版本才出現的。


39哪來的

至於為什么是39,這個講起來就比較復雜了,我就慢點說。
embstr是一塊連續的內存區域,由redisObject和sdshdr組成。其中redisObject占16個字節,當buf內的字符串長度是39時,sdshdr的大小為8+8+39+1=56,那一個字節是'\0'。加起來剛好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就是這樣來的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM