溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis數(shù)據(jù)結(jié)構(gòu)原理是什么

發(fā)布時間:2023-02-25 14:11:56 來源:億速云 閱讀:112 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Redis數(shù)據(jù)結(jié)構(gòu)原理是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    RedisDb

    Redis服務(wù)器默認(rèn)有16個數(shù)據(jù)庫,一個數(shù)據(jù)庫對應(yīng)一個RedisDB數(shù)據(jù)結(jié)構(gòu)。

    typedef struct redisDb {
        dict *dict;
        dict *expires;
        dict * blocking_keys;
        dict * ready_keys;
        dict * watched_keys;
        ......
    }
    • dict:鍵空間散列表,用于存放所有鍵值對

    • expires:過期時間散列表,存放鍵的過期時間

    • blocking_keys:處于阻塞狀態(tài)的鍵和對應(yīng)的client

    • ready_keys:解除阻塞狀態(tài)的鍵和對應(yīng)的client,與blocking_keys屬性相對

    • watched_keys:watch的鍵和對應(yīng)的client,主要用于事務(wù)

    RedisObject

    Redis的鍵值都是redisObject對象,每次當(dāng)我們在Redis的數(shù)據(jù)庫中新創(chuàng)建一個鍵值對時,會生成一個用于鍵名的redisObject對象和一個用于鍵值的redisObject對象

    trpedef struct RedisObject {
        int4 type;
        int4 encoding;
        void *ptr;
        int24 lru;
        int32 refcount;
    }
    字段描述說明
    type用于表示Redis對應(yīng)的類型string、list、hash、set、zset、stream等,用枚舉表示
    encoding內(nèi)部編碼int,embstr,raw,hashtable,quicklist, ziplist,intset,skiplist等,用枚舉表示
    lru24位,可選LFU或LRU當(dāng)為LRU時,表示最后一次訪問時間;當(dāng)為LFU時,高16位用來表示分鐘級別的訪問時間,低8位用來表示訪問頻次,頻次的增加使用的是概率算法,基數(shù)越大越難增加;訪問時間更新時,存在一定概率將訪問頻次衰減。(兩者共有)訪問時間是對一個數(shù)取模,當(dāng)前時間也取模, 當(dāng)前時間大于訪問時間,則為兩數(shù)之差;當(dāng)前時間小于訪問時間,則為當(dāng)前時間加上模數(shù)與訪問時間之差
    refcount引用計數(shù)初始值為1,實際應(yīng)用中參考意義不大
    ptr指針,占8個字節(jié),指向數(shù)據(jù)的地址dict、expires等,指針指向同一個地址

    object命令,就是對RedisObject的相關(guān)操作。

    修改內(nèi)存淘汰策略

    object idletime key # 返回key的空閑時間,即上次讀寫鍵以來經(jīng)過的近似描述,在lfu模式下不可用

    config set maxmemory-policy volatile-lfu # 修改內(nèi)存淘汰策略
    set name zhangsan
    object freq name # 獲取計數(shù)值,僅lfu模式下可用,初始化為5
    
    get name
    
    object freq name # 再次訪問,返回為6

    int

    當(dāng)string值為整數(shù)并且小于等于long的最大值時,encoding為int類型,ptr直接指向該int型地址

    embstr與raw

    Redis的字符串叫SDS(Simple Dynamic String,簡單字符串),對應(yīng)key,非整數(shù)型的String值

    trpedef struct SDS {
        int8 capacity; // 數(shù)組容量
        int8 len; // 實際長度
        int8 flags;
        byte[] content; // 數(shù)組內(nèi)容
    }

    可以看出,SDS與Java的ArrayList結(jié)構(gòu)類似,也是分配初始長度,長度超出時擴(kuò)容。Redis規(guī)定字符串的長度不能超過512M。

    當(dāng)長度特別短時,使用embstr形式存儲;當(dāng)長度超出44字節(jié)時,使用raw形式存儲。

    已知內(nèi)存分配器最大分配單位是64字節(jié),RedisObject占16個字節(jié),SDS標(biāo)識占3個字節(jié),字符串以NULL結(jié)尾需要占用一個字節(jié),因此當(dāng)字符串長度小于等于44時,只需要分配一次內(nèi)存。RedisObject與SDS在同一內(nèi)存單位,我們將這種數(shù)據(jù)結(jié)構(gòu)稱為embstr,而不在同一內(nèi)存單位的,稱為raw。

    dict

    dict(encoding編碼為hashtable類型,字典)對應(yīng)hash、set、zset(用于存儲value與score的映射)集合。

    dict與Java的HashMap結(jié)構(gòu)類似,不同的是HashMap擴(kuò)容是申請數(shù)組,然后遍歷,將舊數(shù)據(jù)重新hash后掛到數(shù)組下面,作為單線程的Redis很難承受這樣耗時的過程,所以它使用了兩個數(shù)組,先返回,然后空閑的時候一點一點搬數(shù)據(jù),搬完之后再將舊數(shù)據(jù)清空,我們將這樣的過程成為漸進(jìn)式rehash。

    typedef struct dict {
        dictht ht[2];
    }

    “Redis數(shù)據(jù)結(jié)構(gòu)原理是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI