濮阳杆衣贸易有限公司

主頁 > 知識庫 > redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解

redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解

熱門標簽:臺灣電銷 四川穩(wěn)定外呼系統(tǒng)軟件 廊坊外呼系統(tǒng)在哪買 高碑店市地圖標注app 地圖標注工廠入駐 南京手機外呼系統(tǒng)廠家 b2b外呼系統(tǒng) 400電話辦理的口碑 一個地圖標注多少錢

redis中的數(shù)據(jù)結(jié)構(gòu)和編碼:

    背景:

  •         1>redis在內(nèi)部使用redisObject結(jié)構(gòu)體來定義存儲的值對象。
  •         2>每種類型都有至少兩種內(nèi)部編碼,Redis會根據(jù)當前值的類型和長度來決定使用哪種編碼實現(xiàn)。
  •         3>編碼類型轉(zhuǎn)換在Redis寫入數(shù)據(jù)時自動完成,這個轉(zhuǎn)換過程是不可逆的,轉(zhuǎn)換規(guī)則只能從小內(nèi)存編碼向大內(nèi)存編碼轉(zhuǎn)換。

    源碼:

        值對象redisObject:

            typedef struct redisObject {
                unsigned type:4;                /* 對象類型 */
                unsigned encoding:4;            /* 內(nèi)部編碼 */
                unsigned lru:LRU_BITS;     /* lru time (relative to server.lruclock) */
                int refcount;                    /* 引用計數(shù)器,內(nèi)存回收機制就是基于該值實現(xiàn)的 */
                void *ptr;                        /* 若要存儲的是整數(shù)值則直接存儲數(shù)據(jù),否則表示指向數(shù)據(jù)的指針 */
            } robj;

        類型type:

            說明:查看當前鍵的類型:type key

            #define OBJ_STRING 0     /*字符串對象*/
            #define OBJ_LIST 1        /*列表對象*/
            #define OBJ_SET 2        /*集合對象*/
            #define OBJ_ZSET 3        /*有序集合對象*/
            #define OBJ_HASH 4        /*哈希對象*/

        編碼encoding;

            說明:查看當前鍵的編碼:object encoding key

            #define OBJ_ENCODING_RAW 0             /*Raw representation 簡單動態(tài)字符串*/
            #define OBJ_ENCODING_INT 1             /*Encoded as integer long long類型整數(shù)*/
            #define OBJ_ENCODING_HT 2            /* Encoded as hash table 字典*/
            #define OBJ_ENCODING_ZIPMAP 3        /* Encoded as zipmap 壓縮map*/
            #define OBJ_ENCODING_LINKEDLIST 4     /* Encoded as regular linked list 雙端鏈表*/
            #define OBJ_ENCODING_ZIPLIST 5         /* Encoded as ziplist 壓縮列表*/
            #define OBJ_ENCODING_INTSET 6         /* Encoded as intset 整數(shù)集合*/
            #define OBJ_ENCODING_SKIPLIST 7     /* Encoded as skiplist 跳躍表*/
            #define OBJ_ENCODING_EMBSTR 8         /* Embedded sds string encoding embstr編碼的簡單動態(tài)字符串*/
            #define OBJ_ENCODING_QUICKLIST 9     /* 基于壓縮列表的雙端列表實現(xiàn)的 快速表*/

        最后被訪問的時間lru:

            概念:記錄對象最后一次被訪問的時間。
            說明:
                1>查看當前鍵的空閑時間(該命令不會更新lru字段);object idletime key ??梢酝ㄟ^scan + object idletime key 來收集長時間未被訪問的數(shù)據(jù),然后手動清理。
                2>當配置了maxmemory和maxmemory-policy=volatile-lru或者allkeys-lru時,若內(nèi)存超過了上限(maxmemory)后,則優(yōu)先回收長時間沒有被訪問的數(shù)據(jù),從而回收內(nèi)存。

        引用計數(shù)器refcount:    

            概念:記錄當前對象被引用的次數(shù),當refcount=0時,可以安全回收當前對象空間。
            說明:獲取當前對象引用:object refcount key

    類型對應(yīng)的編碼:

        字符串:
            int:存放整形值的字符串。
            embstr:存放字符的短字符串(大小不超過44個字節(jié))。
            raw:存放字符的長字符串(大小不超過44個字節(jié))。
           
            embstr和raw的比較:
                raw調(diào)用2次內(nèi)存分配函數(shù),釋放時當然也需要釋放兩次。
                embstr調(diào)用1次內(nèi)存分配函數(shù),分配一塊連續(xù)的內(nèi)存,釋放時只需釋放一次。

        列表(list):

            壓縮列表(ziplist):
                結(jié)構(gòu):所有數(shù)據(jù)都是采用線性連續(xù)的內(nèi)存結(jié)構(gòu)(大致可類比數(shù)組),目的是為了減少內(nèi)存的占用,追求空間和時間的平衡。
                    1>以O(shè)(1)時間復(fù)雜度入隊和出隊。
                    2>讀寫操作涉及復(fù)雜的指針移動,最壞時間復(fù)雜度為O(n2),故列表的元素不易太多。
                    3>新增刪除操作涉及內(nèi)存重新分配,加大了操作的復(fù)雜性。

                優(yōu)點:占用內(nèi)存較少,且占用的是一塊連續(xù)的內(nèi)存,故加載的速度相對更快一些。
                缺點:當元素的個數(shù)較大時,訪問元素的時間較長。

                應(yīng)用:

                   適合存儲小對象和長度有限(即使O(n2)的復(fù)雜度也不會太大)的數(shù)據(jù)。
                    當元素個數(shù)小于list-max-ziplist-entries(默認512) 且 所有元素值的大小都小于list-max-ziplist-value(默認64字節(jié))時,使用ziplist作為列表的內(nèi)部實現(xiàn)。

            雙端鏈表(linkedlist):

                優(yōu)點:元素的個數(shù)較多時,訪問元素的時間比壓縮列表更快一些。
                缺點:因為是雙向鏈表,故維護了前置指針、后置指針等結(jié)構(gòu),占用了更多的內(nèi)存,且內(nèi)存不是連續(xù)的,容易產(chǎn)生內(nèi)存碎片。
                說明:當無法滿足ziplist的條件時,使用linkedlist作為列表的內(nèi)部實現(xiàn)。
                應(yīng)用:當列表對象元素較多時,壓縮列表就會轉(zhuǎn)化為更適合存儲大量元素的雙端鏈表。
               
            注意:只能小內(nèi)存編碼向大內(nèi)存編碼轉(zhuǎn)換。(若當元素增刪頻繁時,數(shù)據(jù)向壓縮編碼轉(zhuǎn)換是非常消耗CPU的,得不償失)

            快速列表(quicklist):

                結(jié)構(gòu):一個雙向鏈表,鏈表的每一個節(jié)點都是一個ziplist,故quicklist結(jié)合了雙向鏈表和壓縮列表的優(yōu)點。
                Redis3.2開始,列表采用quicklist進行編碼。

        哈希(hash):

            壓縮列表(ziplist):

                應(yīng)用:當元素個數(shù)小于hash-max-ziplist-entries(默認512) 且 所有元素value的大小都小于hash-max-ziplist-value(默認64字節(jié))時,使用ziplist作為哈希的內(nèi)部實現(xiàn)。

            哈希表(hashtable):

                優(yōu)點:讀寫時間復(fù)雜度O(1)
                缺點:占用內(nèi)存較多。
                應(yīng)用:當無法滿足ziplist的條件時,hashtable作為哈希的內(nèi)部實現(xiàn)。

            hash算法:與傳統(tǒng)hash算法類似,根據(jù)key計算得到在哈希表中的位置,采用單鏈表解決沖突,達到加載因子時進行擴展,進而引發(fā)重哈希。

            rehash:采用增量式重哈希:

                概念:在擴容時不會一次性對所有的key進行rehash,而是將key的rehash操作分散延遲到其它操作(哈希表的查找、更新、刪除)中。
                優(yōu)點:避免由于大量的key在同一時間段進行rehash操作導(dǎo)致服務(wù)短暫無響應(yīng)的問題。
                過程:在增量式的rehash過程中,會使用到兩張哈希表:
                    查找:先從老表中查找,再從新表中查找,此外還會對一些key進行rehash操作。
                    新增:新增的鍵值對添加到新表中。

        集合(set):

            整數(shù)集合(intset):
                結(jié)構(gòu):有序、不重復(fù)的整數(shù)集。
                    1>查找時間復(fù)雜度為O(logn)
                    2>插入時間復(fù)雜度為O(n)
                優(yōu)點:占用的內(nèi)存遠小于hashtable,
                應(yīng)用:當元素都是整數(shù) 且 元素個數(shù)小于set-max-intset-entries(默認512)時,使用intset作為集合的內(nèi)部實現(xiàn)。

            哈希表(hashtable):當無法滿足intset的條件時,使用hashtable作為集合的內(nèi)部實現(xiàn)。

        有序集合(zset):

            說明:redis給有序集合中的每個元素設(shè)置一個分數(shù)(score)作為排序的依據(jù)。
           
            壓縮列表(ziplist):
                應(yīng)用:當元素個數(shù)小于zset-max-ziplist-entries(默認128個) 且 每個元素的值都小于zset-max-ziplist-value(默認64字節(jié))時,使用ziplist作為有序集合的內(nèi)部實現(xiàn)。
               
            跳躍表(skiplist):
                結(jié)構(gòu):跳躍表通過在每個節(jié)點中(基于層和跨度等)維持多個指向其它節(jié)點的指針來實現(xiàn)快速訪問。
                    查找時間復(fù)雜度平均O(logn)、最壞O(n)。
                應(yīng)用:當不滿足ziplist條件時,使用skiplist作為內(nèi)部實現(xiàn)。

    內(nèi)存優(yōu)化:

        場景:有海量key和value都比較小的數(shù)據(jù),在redis中如何存儲才更省內(nèi)存。
        原理:通過大幅減少key的數(shù)量來降低內(nèi)存的消耗。
        實現(xiàn):在客戶端通過分組將海量的key根據(jù)一定的策略映射到一組hash對象中,由于value較小,故hash類型的對象會使用占用內(nèi)存較小的ziplist編碼。
            eg:如存在100萬個鍵,可以映射到1000個hash中,每個hash保存1000個元素。

以上就是redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解的詳細內(nèi)容,更多關(guān)于redis中的數(shù)據(jù)結(jié)構(gòu)和編碼的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • Redis底層數(shù)據(jù)結(jié)構(gòu)詳解
  • 詳解Redis數(shù)據(jù)結(jié)構(gòu)之跳躍表
  • redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)之SDS簡單動態(tài)字符串詳解
  • redis數(shù)據(jù)結(jié)構(gòu)之intset的實例詳解
  • 詳解redis數(shù)據(jù)結(jié)構(gòu)之sds
  • 詳解redis數(shù)據(jù)結(jié)構(gòu)之壓縮列表
  • Redis中5種數(shù)據(jù)結(jié)構(gòu)的使用場景介紹
  • Redis底層數(shù)據(jù)結(jié)構(gòu)之dict、ziplist、quicklist詳解

標簽:泰州 伊春 甘南 拉薩 畢節(jié) 南寧 河源 定州

巨人網(wǎng)絡(luò)通訊聲明:本文標題《redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解》,本文關(guān)鍵詞  redis,中的,數(shù)據(jù)結(jié)構(gòu),和,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于redis中的數(shù)據(jù)結(jié)構(gòu)和編碼詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    阳江市| 三门县| 宁河县| 连江县| 呼玛县| 武宁县| 睢宁县| 樟树市| 兴城市| 蚌埠市| 吴旗县| 凤山县| 辽宁省| 延川县| 德安县| 旬阳县| 将乐县| 比如县| 依安县| 红桥区| 灌云县| 甘孜县| 察隅县| 淮北市| 五莲县| 盐源县| 子长县| 阿克| 达日县| 清苑县| 大埔区| 汝城县| 容城县| 东乌| 沅江市| 木里| 罗定市| 汤原县| 黑水县| 雅江县| 屏东县|