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

redis數(shù)據(jù)結(jié)構(gòu)之String詳解

 更新時(shí)間:2025年08月15日 08:51:47   作者:ruan114514  
Redis以String為基礎(chǔ)類型,因C字符串效率低、非二進(jìn)制安全等問(wèn)題,采用SDS動(dòng)態(tài)字符串實(shí)現(xiàn)高效存儲(chǔ),通過(guò)RedisObject封裝,支持多種編碼方式(如RAW、EMBSTR、INT)和內(nèi)存優(yōu)化策略,靈活管理數(shù)據(jù)結(jié)構(gòu)與內(nèi)存使用

一、為什么Redis選String作為基礎(chǔ)類型?

redis中的所有key是字符串,所有value本質(zhì)上也是字符串,比如 集合set中的每一個(gè) 成員 都是一個(gè)獨(dú)立的字符串對(duì)象,列表中的每一個(gè) 元素 都是一個(gè)獨(dú)立的字符串對(duì)象,整個(gè)HASH是一個(gè)對(duì)象,它內(nèi)部的每一個(gè) 字段(field) 和一個(gè)字段值(value) 都是一個(gè)獨(dú)立的字符串對(duì)象

redis是通過(guò)c語(yǔ)言來(lái)實(shí)現(xiàn)的,但是沒有直接使用c語(yǔ)言中的字符串,有幾下幾點(diǎn)原因

  • 獲取字符串長(zhǎng)度需要通過(guò)運(yùn)算:C字符串以\0(空字符)結(jié)尾,要獲取長(zhǎng)度必須遍歷整個(gè)數(shù)組直到遇到\0,時(shí)間復(fù)雜度為O(n),這在高性能數(shù)據(jù)庫(kù)如Redis中效率低下。
  • 非二進(jìn)制安全:C字符串不能存儲(chǔ)任意二進(jìn)制數(shù)據(jù),因?yàn)樗蕾囉?code>\0作為結(jié)束符。如果數(shù)據(jù)中包含\0(如一些二進(jìn)制文件),會(huì)被錯(cuò)誤截?cái)?,破壞?shù)據(jù)完整性。
  • 不可修改:C語(yǔ)言字符串常量(如char* s = "hello")是只讀的,無(wú)法直接擴(kuò)展或修改其長(zhǎng)度,這在動(dòng)態(tài)數(shù)據(jù)存儲(chǔ)中不靈活。

Redis的解決方案:Redis因此構(gòu)建了自己的字符串結(jié)構(gòu)——SDS(簡(jiǎn)單動(dòng)態(tài)字符串),它通過(guò)設(shè)計(jì)一個(gè)智能結(jié)構(gòu)來(lái)支持查找、二進(jìn)制安全性和動(dòng)態(tài)修改。

二、SDS底層數(shù)據(jù)結(jié)構(gòu)

uint8_t (8位無(wú)符號(hào)整數(shù)),可表示的最大值是 255 (因?yàn)?2^8 - 1 = 255),因此 len 最多記錄 255 字節(jié) 的長(zhǎng)度,否則會(huì)溢出,如果一個(gè) SDS 字符串的實(shí)際長(zhǎng)度超過(guò) 255 字節(jié),Redis 會(huì)自動(dòng)選擇更大容量的結(jié)構(gòu)體(如 sdshdr16/sdshdr32)。

三、RedisObject是什么

通常我們了解的數(shù)據(jù)結(jié)構(gòu)有字符串、雙端鏈表、字典、壓縮列表、整數(shù)集合等,但是Redis為了加快讀寫速度,并沒有直接使用這些數(shù)據(jù)結(jié)構(gòu),而是在此基礎(chǔ)上又包裝了一層稱之為RedisObject。

RedisObject 有五種對(duì)象:字符串對(duì)象(String)、列表對(duì)象(List)、哈希對(duì)象(Hash)、集合對(duì)象(Set)和有序集合對(duì)象(ZSet)。

1.type:數(shù)據(jù)類型標(biāo)識(shí)(4 bit)就是redis基本類型

類型常量對(duì)應(yīng)數(shù)據(jù)結(jié)構(gòu)
OBJ_STRING0字符串
OBJ_LIST1列表
OBJ_SET2集合
OBJ_ZSET3有序集合
OBJ_HASH4哈希表

2.encoding:內(nèi)部編碼(4 bit)

同一數(shù)據(jù)類型可對(duì)應(yīng)不同底層實(shí)現(xiàn):

編碼常量適用類型底層結(jié)構(gòu)
OBJ_ENCODING_INT0String整數(shù)存儲(chǔ)
OBJ_ENCODING_EMBSTR1String短字符串優(yōu)化
OBJ_ENCODING_RAW2StringSDS動(dòng)態(tài)字符串
OBJ_ENCODING_HT3Hash/Set哈希表
OBJ_ENCODING_ZIPLIST4List/Hash/Zset壓縮列表
OBJ_ENCODING_QUICKLIST5List快速列表
OBJ_ENCODING_SKIPLIST6Zset跳表
OBJ_ENCODING_STREAM7Stream流數(shù)據(jù)結(jié)構(gòu)

動(dòng)態(tài)編碼轉(zhuǎn)換示例:

  • 當(dāng) Hash 的元素超過(guò) hash-max-ziplist-entries 時(shí)
  • OBJ_ENCODING_ZIPLIST → OBJ_ENCODING_HT

3.lru:緩存淘汰信息(24 bit)

  • LRU模式:記錄對(duì)象最后訪問(wèn)時(shí)間戳(精度:秒級(jí))
  • LFU模式(Redis 4.0+):
16 bits      8 bits
+------------+------+
| 訪問(wèn)時(shí)間戳   | 頻率 |
+------------+------+
  • 頻率(logc):基于概率遞增的訪問(wèn)計(jì)數(shù)器
  • 時(shí)間戳:解決冷數(shù)據(jù)滯留問(wèn)題

4.refcount:引用計(jì)數(shù)(4字節(jié))

  • 內(nèi)存回收refcount=0 時(shí)自動(dòng)釋放內(nèi)存
  • 對(duì)象共享:相同數(shù)據(jù)復(fù)用對(duì)象(如 SET key 100 共享整數(shù)對(duì)象)
  • 多客戶端引用:同一 key 被多個(gè)客戶端連接引用

5.ptr:數(shù)據(jù)指針(8字節(jié))

指向?qū)嶋H數(shù)據(jù)結(jié)構(gòu),如:

  • OBJ_ENCODING_INT → 直接存儲(chǔ)整數(shù)(void * 強(qiáng)轉(zhuǎn)為 long
  • OBJ_ENCODING_RAW → 指向 sds 結(jié)構(gòu)
  • OBJ_ENCODING_HT → 指向 dict 哈希表

四、String類型數(shù)據(jù)結(jié)構(gòu)

string類型在redis中有三種編碼方式

RAW編碼

分配兩次內(nèi)存 RedisObject和SDS的內(nèi)存不連續(xù) 兩個(gè)數(shù)據(jù)結(jié)構(gòu)申請(qǐng)了兩片內(nèi)存區(qū)域

EMBSTR編碼

INT編碼

為什么分界線是44字節(jié)?

44字節(jié)的臨界值源于內(nèi)存分配器的優(yōu)化策略,具體計(jì)算如下:

1. 內(nèi)存分配器的最小單位

  • Redis 默認(rèn)使用 jemalloc 或 glibc malloc
  • 這些分配器的最小分配單元通常是 64字節(jié)(CPU緩存行對(duì)齊)

2. EMBSTR 的總內(nèi)存占用公式

總大小 = RedisObject(16字節(jié)) + SDS頭部(3字節(jié)) + 字符串內(nèi)容(N字節(jié)) + 結(jié)束符\0(1字節(jié))
  • 最大允許占用:64字節(jié)(分配器最小單元)
  • 固定開銷:16(robj) + 3(sds) + 1(\0) = 20字節(jié)
  • 可用空間:64 - 20 = 44字節(jié)
編碼類型OBJ_ENCODING_INTOBJ_ENCODING_EMBSTROBJ_ENCODING_RAW
觸發(fā)條件數(shù)值類型且值在 [LONG_MIN, LONG_MAX]字符串長(zhǎng)度 ≤ 44字節(jié)字符串長(zhǎng)度 > 44字節(jié)
內(nèi)存分配次數(shù)1次(RedisObject內(nèi)聯(lián)存儲(chǔ))1次(連續(xù)內(nèi)存塊)2次(RedisObject + SDS分開)
適用場(chǎng)景計(jì)數(shù)器(如 INCR 操作)短字符串(如JSON片段、短URL)長(zhǎng)文本、二進(jìn)制數(shù)據(jù)
修改時(shí)的行為直接替換整數(shù)值自動(dòng)轉(zhuǎn)換為 RAW 編碼原地修改或重新分配
內(nèi)存占用示例存儲(chǔ) 100:16字節(jié)(RedisObject)存儲(chǔ) "hello":16+6=22字節(jié)存儲(chǔ)1KB文本:16+1024+9=1049字節(jié)

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Redis實(shí)現(xiàn)的分布式唯一編號(hào)生成工具類

    基于Redis實(shí)現(xiàn)的分布式唯一編號(hào)生成工具類

    這篇文章主要介紹了基于Redis實(shí)現(xiàn)的分布式唯一編號(hào)生成工具類,核心功能是生成格式為 業(yè)務(wù)編碼+日期+3位自增序號(hào)(如 JJ20250826001)的全局唯一編號(hào),適用于分布式系統(tǒng)中需要有序、不重復(fù)編號(hào)的場(chǎng)景(如訂單號(hào)、單據(jù)號(hào)等),以下是詳細(xì)解析,需要的朋友可以參考下
    2025-11-11
  • Redis集群水平擴(kuò)展、集群中添加以及刪除節(jié)點(diǎn)的操作

    Redis集群水平擴(kuò)展、集群中添加以及刪除節(jié)點(diǎn)的操作

    這篇文章主要介紹了Redis集群水平擴(kuò)展、集群中添加以及刪除節(jié)點(diǎn)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • redis緩存預(yù)熱的實(shí)現(xiàn)示例

    redis緩存預(yù)熱的實(shí)現(xiàn)示例

    本文主要介紹了Java中實(shí)現(xiàn)緩存預(yù)熱的多種策略,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • redis.clients.jedis.exceptions.JedisDataException:?NOAUTH?Authentication?required數(shù)據(jù)操作異常的解決方法

    redis.clients.jedis.exceptions.JedisDataException:?NOAUTH?

    本文主要介紹了redis.clients.jedis.exceptions.JedisDataException:?NOAUTH?Authentication?required數(shù)據(jù)操作異常的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • 淺談Redis主從復(fù)制以及主從復(fù)制原理

    淺談Redis主從復(fù)制以及主從復(fù)制原理

    在現(xiàn)有企業(yè)中80%公司大部分使用的是redis單機(jī)服務(wù),在實(shí)際的場(chǎng)景當(dāng)中單一節(jié)點(diǎn)的redis容易面臨風(fēng)險(xiǎn)。本文將介紹Redis主從復(fù)制以及主從復(fù)制原理。
    2021-05-05
  • Redis核心原理與實(shí)踐之字符串實(shí)現(xiàn)原理

    Redis核心原理與實(shí)踐之字符串實(shí)現(xiàn)原理

    這本書深入地分析了Redis常用特性的內(nèi)部機(jī)制與實(shí)現(xiàn)方式,內(nèi)容源自對(duì)Redis源碼的分析,并從中總結(jié)出設(shè)計(jì)思路、實(shí)現(xiàn)原理。對(duì)Redis字符串實(shí)現(xiàn)原理相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-09-09
  • Redis中的Lettuce使用詳解

    Redis中的Lettuce使用詳解

    Lettuce 是一個(gè)高級(jí)的、線程安全的 Redis 客戶端,用于與 Redis 數(shù)據(jù)庫(kù)交互,Lettuce 是一個(gè)功能強(qiáng)大、使用方便的 Redis 客戶端,適用于各種規(guī)模的 Java 項(xiàng)目,下面給大家介紹Redis中的Lettuce使用詳解,感興趣的朋友一起看看吧
    2025-05-05
  • 詳解如何清理redis集群的所有數(shù)據(jù)

    詳解如何清理redis集群的所有數(shù)據(jù)

    這篇文章主要介紹了詳解如何清理redis集群的所有數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Redis緩存高可用集群詳解

    Redis緩存高可用集群詳解

    Redis集群提供了哨兵模式和高可用集群模式兩種方案,前者適合低并發(fā),配置復(fù)雜,主從切換可能導(dǎo)致瞬斷;后者通過(guò)多主多從結(jié)構(gòu)提高可用性和性能,支持線性擴(kuò)展,配置簡(jiǎn)單,搭建Redis集群至少需要三個(gè)主節(jié)點(diǎn)
    2024-10-10
  • Redis+Caffeine實(shí)現(xiàn)高效兩級(jí)緩存架構(gòu)的詳細(xì)指南

    Redis+Caffeine實(shí)現(xiàn)高效兩級(jí)緩存架構(gòu)的詳細(xì)指南

    在現(xiàn)代高并發(fā)系統(tǒng)中,緩存是提升系統(tǒng)性能的關(guān)鍵組件之一,本文將介紹如何結(jié)合 Redis 和 Caffeine 構(gòu)建一個(gè)高效的兩級(jí)緩存系統(tǒng),需要的小伙伴可以了解下
    2025-07-07

最新評(píng)論

九龙县| 藁城市| 和硕县| 黄梅县| 鄂伦春自治旗| 哈巴河县| 古丈县| 安平县| 含山县| 和平县| 台江县| 阿勒泰市| 莎车县| 吉木乃县| 屏山县| 什邡市| 健康| 教育| 格尔木市| 苏尼特左旗| 鄯善县| 阿鲁科尔沁旗| 泉州市| 乐安县| 奉化市| 辽阳县| 拜城县| 赫章县| 竹山县| 嘉荫县| 民丰县| 太仓市| 加查县| 甘孜| 玉林市| 资溪县| 永寿县| 运城市| 新津县| 建宁县| 哈巴河县|