最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Redis中String數(shù)據(jù)類(lèi)型及其底層編碼

 更新時(shí)間:2023年05月25日 09:18:15   作者:WARRIOR  
這篇文章主要介紹?Redis?中?String?數(shù)據(jù)類(lèi)型及其底層編碼,文中有詳細(xì)的代碼示例,對(duì)大家的工作及學(xué)習(xí)有一定的幫助,需要的朋友可以參考下

從 RedisObject 說(shuō)起

在 Redis 中,任意數(shù)據(jù)類(lèi)型的鍵和值都會(huì)被封裝為一個(gè) RedisObject ,也叫做Redis對(duì)象,源碼如下

/*server.h*/
typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;

我們來(lái)看一下這個(gè)結(jié)構(gòu)體中的成員變量分別代表什么:

  • unsigned type:4 :對(duì)象類(lèi)型,分別是 string hash list set zset ,占 4 個(gè) bit 位,如下所示

#define OBJ_STRING 0    /* String object. */
#define OBJ_LIST 1      /* List object. */
#define OBJ_SET 2       /* Set object. */
#define OBJ_ZSET 3      /* Sorted set object. */
#define OBJ_HASH 4      /* Hash object. */
  • unsigned encoding:4: 底層編碼方式,共有 11 種,4 個(gè) bit 位

  • unsigned lru:LRU_BITS :該對(duì)象最后一次被訪問(wèn)的時(shí)間,占 24 個(gè) bit ,在 Redis 內(nèi)存回收中起到關(guān)鍵作用

  • int refcount :對(duì)象引用計(jì)數(shù)器,計(jì)數(shù)器為 0 則說(shuō)明對(duì)象無(wú)人引用,可以被回收

  • void *ptr:指針,指向存放實(shí)際數(shù)據(jù)的空間

我們注意到,在 Redis 中有 5 中數(shù)據(jù)結(jié)構(gòu)(用戶使用的),但在底層卻有 11 種編碼方式,Redis 會(huì)根據(jù)存儲(chǔ)的數(shù)據(jù)類(lèi)型、存儲(chǔ)數(shù)據(jù)的大小,選擇不同的編碼方式,以獲得最優(yōu)的性能。一種數(shù)據(jù)結(jié)構(gòu)會(huì)對(duì)應(yīng)多種數(shù)據(jù)結(jié)構(gòu),如下表所示。

數(shù)據(jù)類(lèi)型編碼方式
OBJ_STRINGint、embstr、raw
OBJ_LISTLinkedList和ZipList(3.2以前)、QuickList(3.2以后)
OBJ_SETintset、HT
OBJ_ZSETZipList、HT、SkipList
OBJ_HASHZipList、HT

下面,我們現(xiàn)在介紹以下 String 數(shù)據(jù)類(lèi)型,及其底層的編碼方式。

Redis 數(shù)據(jù)結(jié)構(gòu) -- String

String 類(lèi)型的基本介紹和命令

String 類(lèi)型,也就是字符串類(lèi)型,是Redis中最簡(jiǎn)單的存儲(chǔ)類(lèi)型。它可以存儲(chǔ)字符串、整數(shù)或浮點(diǎn)數(shù)。下面是一些 String 類(lèi)型常用的命令

  • SET key value:設(shè)置指定 key 的值為指定的字符串或數(shù)字。

  • GET key:獲取指定 key 的值。

本地虛擬機(jī)redis:0>set key01 value01
"OK"
本地虛擬機(jī)redis:0>get key01
"value01"

  • INCR key:將指定 key 的值加 1,如果該 key 不存在,則先將其設(shè)置為 0,再進(jìn)行加 1 操作。

  • DECR key:將指定 key 的值減 1,如果該 key 不存在,則先將其設(shè)置為 0,再進(jìn)行減 1 操作。

  • INCRBY key increment:將指定 key 的值增加指定的增量。

  • DECRBY key decrement:將指定 key 的值減少指定的減量。

  • APPEND key value:將指定的值追加到指定 key 的值的末尾。

  • STRLEN key:返回指定 key 的值的長(zhǎng)度。

  • GETRANGE key start end:返回指定 key 的值的子字符串,根據(jù)起始位置和結(jié)束位置指定。

  • SETRANGE key offset value:將指定 key 的值從指定偏移位置開(kāi)始,替換為指定的字符串。

  • MSET key1 value1 [key2 value2 ...]:同時(shí)設(shè)置多個(gè) key 的值。(”[ ]” 中括號(hào)內(nèi)表示可選)

  • MGET key1 [key2 ...]:獲取多個(gè) key 的值。

?? 這里僅給出 SET、GET 命令,其他的請(qǐng)自行測(cè)試。這些命令只是 Redis String 類(lèi)型命令的一小部分,Redis 還提供了其他更多的命令來(lái)處理 String 類(lèi)型的數(shù)據(jù)。你可以參考 Redis 官方文檔以獲取完整的命令列表和詳細(xì)的命令說(shuō)明。

String 類(lèi)型的底層實(shí)現(xiàn)

在 Redis 中,String 類(lèi)型的數(shù)據(jù)結(jié)構(gòu)并不是采用 C 語(yǔ)言中自帶的字符串類(lèi)型,C 語(yǔ)言中的數(shù)據(jù)結(jié)構(gòu)存在很多問(wèn)題,比如:

  • 獲取字符串長(zhǎng)度的需要通過(guò)運(yùn)算
  • 非二進(jìn)制安全
  • 不可修改

因此,String 在 Redis 中有其他三種編碼方式: int、embstr、raw 。其中, raw 和 embstr 類(lèi)型,都是基于動(dòng)態(tài)字符串(SDS)實(shí)現(xiàn)的,下面我們先來(lái)看看動(dòng)態(tài)字符串的結(jié)構(gòu)是怎樣的。

動(dòng)態(tài)字符串(SDS)

動(dòng)態(tài)字符串的結(jié)構(gòu)體如下

struct __attribute__ ((__packed__)) hisdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

這里解釋一下結(jié)構(gòu)體中各個(gè)成員變量的作用:

  • len:已經(jīng)保存的字符串字節(jié)數(shù),不包含結(jié)束標(biāo)示
  • alloc:申請(qǐng)的總的字節(jié)數(shù),不包含結(jié)束標(biāo)示
  • flags:不同的 SDS 的頭類(lèi)型,用來(lái)控制 SDS 的頭大小
  • buf[]:真正存儲(chǔ)數(shù)據(jù)

我們先來(lái)聊一下 flags 這個(gè)成員變量。在 redis 中其實(shí)定義了 5 個(gè) SDS結(jié)構(gòu)體(其中 hisdshdr5 已經(jīng)棄用)如圖所示。他們之間的主要區(qū)別在于 len 和 alloc 的長(zhǎng)度不同。

在 redis 中,為了盡可能地節(jié)省內(nèi)存空間,當(dāng)字符串長(zhǎng)度在不同的區(qū)間時(shí),會(huì)選擇不同的結(jié)構(gòu)體,例如:

  • 當(dāng)字符串長(zhǎng)度在 0~255 個(gè)字節(jié)之間時(shí),會(huì)選擇 hisdshdr8 ,這樣一來(lái),用于表示字符串字節(jié)數(shù)和申請(qǐng)的總字節(jié)數(shù)的空間就會(huì)被大大節(jié)省,以此類(lèi)推。

例如,一個(gè)包含字符串“name”的 sds 結(jié)構(gòu)如下:

SDS之所以叫做動(dòng)態(tài)字符串,是因?yàn)樗?strong>具備動(dòng)態(tài)擴(kuò)容的能力,例如一個(gè)內(nèi)容為 “hello” 的 SDS,假如我們要給這個(gè) SDS 追加一段字符串 ”world” ,這里首先會(huì)申請(qǐng)新內(nèi)存空間:

  • 如果新字符串小于1M,則新空間為擴(kuò)展后字符串長(zhǎng)度的兩倍+1
  • 如果新字符串大于1M,則新空間為擴(kuò)展后字符串長(zhǎng)度+1M+1。

這種機(jī)制稱(chēng)為內(nèi)存預(yù)分配。內(nèi)存預(yù)分配可以減少進(jìn)行內(nèi)存重新分配的開(kāi)銷(xiāo),減少內(nèi)存碎片,使得 redis 的性能得到提高,空間利用率也得到提高。

String 的三種編碼方式

RAW

  • raw 是 string 的基本編碼方式,基于簡(jiǎn)單動(dòng)態(tài)字符串(SDS)實(shí)現(xiàn),存儲(chǔ)上限為512mb。當(dāng)一個(gè)字符串采用 raw 的編碼方式的時(shí)候,它的結(jié)構(gòu)如圖所示。

EMBSTR

  • 如果存儲(chǔ)在 SDS 中的數(shù)據(jù)小于等于 44 字節(jié),則會(huì)采用 EMBSTR 編碼,此時(shí) **RedisObject 與 SDS 是一段連續(xù)空間。而不是像 RAW 的編碼方式一樣,由 ptr 指向另外一片空間,**申請(qǐng)內(nèi)存時(shí)只需要調(diào)用一次內(nèi)存分配函數(shù),效率更高。結(jié)構(gòu)如下,

?? 為什么是 44 字節(jié)?Redis 默認(rèn)的內(nèi)存分配器 jemalloc 分配內(nèi)存大小的單位是 $2^n$ ,因此,如果分配的空間大小為 2、4 、8 … 字節(jié)等 $2^n$ 字節(jié),就不會(huì)產(chǎn)生內(nèi)存碎片。

redisObjecthisdshdr8len alloc flags三個(gè)成員變量加起來(lái)剛剛好是 16 + 4 = 20 字節(jié),如果 char[] (數(shù)據(jù)大小)的大小為 44 字節(jié)時(shí),加起來(lái)剛剛好是 64 字節(jié),也即 262^626 不會(huì)產(chǎn)生內(nèi)存碎片。

  • RAW 和 EMBSTR 的編碼演示
/* 44個(gè)v,采用embstr編碼*/
本地虛擬機(jī)redis:0>set key vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
"OK"
本地虛擬機(jī)redis:0>object encoding key
"embstr"
/* 45個(gè)v,采用embstr編碼*/
本地虛擬機(jī)redis:0>set key vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
"OK"
本地虛擬機(jī)redis:0>object encoding key
"raw"

INT

  • 如果存儲(chǔ)的字符串是整數(shù)值,并且大小在 LONG MAX 范圍內(nèi),則會(huì)采用 INT 編碼
  • 直接將數(shù)據(jù)保存在 RedisObject 的 ptr 指針位置(剛好8字節(jié)),不再需要SDS了。

  • INT 編碼演示
本地虛擬機(jī)redis:0>set key 12
"OK"
本地虛擬機(jī)redis:0>object encoding key
"int"

寫(xiě)在最后:在使用 string 類(lèi)型時(shí),盡可能讓其長(zhǎng)度小于 44 字節(jié),或者使用整數(shù)表示,使其使用 EMBSTR 和 INT 編碼

以上就是淺析Redis中String數(shù)據(jù)類(lèi)型及其底層編碼的詳細(xì)內(nèi)容,更多關(guān)于Redis Redis數(shù)據(jù)類(lèi)型及編碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Redis分片集群存儲(chǔ)的搭建到使用

    Redis分片集群存儲(chǔ)的搭建到使用

    這篇文章主要介紹了Redis分片集群存儲(chǔ)的搭建到使用,分片集群顧名思義,將數(shù)據(jù)分開(kāi)存儲(chǔ)到Redis集群中,這樣能夠存儲(chǔ)更多的數(shù)據(jù),避免浪費(fèi)資源,需要的朋友可以參考下
    2022-06-06
  • Redis慢日志的實(shí)現(xiàn)示例

    Redis慢日志的實(shí)現(xiàn)示例

    慢查詢(xún)?nèi)罩臼荝edis提供的一個(gè)用于觀察系統(tǒng)性能的功能,本文主要介紹了Redis慢日志的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • redis yml配置的用法小結(jié)

    redis yml配置的用法小結(jié)

    RedisYML配置是Redis的一種配置文件格式,,對(duì)Redis的配置進(jìn)行統(tǒng)一管理,本文就來(lái)介紹了redis yml配置的用法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • redis中數(shù)據(jù)模糊查詢(xún)scan用法詳解

    redis中數(shù)據(jù)模糊查詢(xún)scan用法詳解

    Redis模糊查詢(xún)應(yīng)避免KEYS,改用SCAN非阻塞迭代,優(yōu)先優(yōu)化鍵結(jié)構(gòu)(如IndexSet、SortedSet),提升效率,復(fù)雜場(chǎng)景可結(jié)合外部搜索引擎,平衡內(nèi)存、延遲及實(shí)時(shí)性需求,本文給大家介紹redis中數(shù)據(jù)模糊查詢(xún)scan用法,感興趣的朋友一起看看吧
    2025-09-09
  • Redis數(shù)據(jù)結(jié)構(gòu)-跳躍表skiplist詳解

    Redis數(shù)據(jù)結(jié)構(gòu)-跳躍表skiplist詳解

    這篇文章主要介紹了Redis數(shù)據(jù)結(jié)構(gòu)-跳躍表skiplist,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-09-09
  • 基于redis+lua進(jìn)行限流的方法

    基于redis+lua進(jìn)行限流的方法

    這篇文章主要介紹了基于redis+lua進(jìn)行限流,通過(guò)實(shí)例代碼詳細(xì)介紹了lua+redis進(jìn)行限流的做法,開(kāi)發(fā)環(huán)境使用idea+redis+lua,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Redis哨兵機(jī)制的使用詳解

    Redis哨兵機(jī)制的使用詳解

    文章講解了Redis哨兵機(jī)制的基本原理、主庫(kù)和從庫(kù)自動(dòng)切換的過(guò)程、如何減少誤判、哨兵集群的組成和通信機(jī)制,以及哨兵在故障發(fā)生時(shí)如何選舉Leader進(jìn)行主從切換
    2025-01-01
  • Redis下載部署并加入idea應(yīng)用的小結(jié)

    Redis下載部署并加入idea應(yīng)用的小結(jié)

    這篇文章主要介紹了Redis下載部署并加入idea應(yīng)用,需要的朋友可以參考下
    2022-10-10
  • 基于Redis實(shí)現(xiàn)延時(shí)隊(duì)列的優(yōu)化方案小結(jié)

    基于Redis實(shí)現(xiàn)延時(shí)隊(duì)列的優(yōu)化方案小結(jié)

    本文主要介紹了基于Redis實(shí)現(xiàn)延時(shí)隊(duì)列的優(yōu)化方案小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸

    基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸

    這篇文章主要為大家詳細(xì)介紹了基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論

依安县| 孝昌县| 天镇县| 贡嘎县| 张家港市| 惠水县| 兖州市| 宁化县| 林芝县| 海门市| 冷水江市| 铁力市| 武义县| 福清市| 册亨县| 堆龙德庆县| 射阳县| 榆中县| 灵丘县| 扬中市| 厦门市| 灵台县| 兰西县| 三台县| 枣庄市| 黄平县| 红原县| 筠连县| 松阳县| 百色市| 偏关县| 家居| 化隆| 晋城| 滕州市| 连城县| 无为县| 北安市| 梅州市| 运城市| 慈利县|