精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Redis 為什么不直接使用C語言的 string,而是重新造了個 SDS ?

數據庫
為什么 Redis 的 String 可以存放這么多類型的數據?Redis 底層到底是如何實現 String 的呢?今天我們就來聊一聊。

使用過 Redis 的小伙伴肯定對 String 這種數據對象并不陌生, 它即可以存放普通的字符串,也可以存放對象,同樣可以存圖片,視頻等二進制數據,使用頻次特別高,真可謂是一個萬精油。

為什么 Redis 的 String 可以存放這么多類型的數據?Redis 底層到底是如何實現 String 的呢?今天我們就來聊一聊。

申明:本文源碼基于redis-6.2。

一、String的特性 

String 的特性主要包含下面4點:

  • String 是Redis中最基本的數據類型;
  • String 是二進制安全,存入和獲取的數據相同;
  • Redis 字符串存儲字節序列,包括文本、序列化對象和二進制數組;
  • String 存儲的 value值最大為 512MB;

二、String常用指令 

String 高頻指令如下表:

指令

舉例

說明

set

set key value

設置值

get

get key

獲取值

getset

getset key

先獲取之前的值,然后設置一個新的值

del

del key

刪除key

incr

incr key

從0開始自增1

incrby

incrby key n

自增指定的步長

decr

decr key 

自減1

decrby

decrby key n

自減指定的步長

append

append key

追加內容

如下圖,展示了 String常用指令:

三、實現原理 

上文介紹了 String數據對象的一些基礎知識,接下來進入核心內容:String 的 Redis 底層實現。

1. SDS 結構

Redis 底層是 C語言實現的,但是 Redis 的 String數據對象并沒有直接使用 C語言傳統的字符串,而是自創了一套 SDS,用于 Redis 默認字符串表示。SDS(simple dynamic string),簡單動態字符串。

SDS 的結構定義在 sds.h 文件中,每個 sds.h/sdshdr 結構表示一個 SDS 值,在 Redis 3.2 版本之后,SDS 由一種數據結構變成了 5 種數據結構,如下源碼截圖:

  • sdshdr5:存儲大小為 32 byte = 2^ 5 ,被棄用;
  • sdshdr8:存儲大小為 256 byte = 2^ 8;
  • sdshdr16:存儲大小為 64KB = 2 ^16
  • sdshdr32:存儲大小為 4GB = 2^ 32;
  • sdshdr64:存儲大小為 2^ 64;

5 種數據結構存儲不同長度的內容,Redis 會根據 SDS 存儲的內容長度來選擇不同的結構,源碼實現對應 sds.c/sdsReqType,截圖如下:

為了對 SDS 有一個更好的體感,這里以 sdshdr8 為例,執行指令:SET name Redis

執行上述 set 指令后,值對象對應的 SDS 結構如下圖:

SDS 各個屬性說明:

  • len:表示 buf 已用空間的長度,占 4 個字節,不包括 \0;
  • alloc:表示 buf 的實際分配長度,占 4 個字節,不包括 \0;
  • flags:標記當前字節數組是 sdshdr8/16/32/64 中的哪一種,占 1 個字節;
  • buf:表示字節數組,保存實際數據。為了表示字節數組的結束,Redis 會自動在數組最后加一個\0,需要額外占用 1 個字節的開銷;

從上面 SDS 的結構可以看出,SDS 依然遵循了 C語言中字符串以 \0 結尾的規則, 但是,\0占用的1 個字節空間并沒有計算在 SDS 的 len 屬性里面。

分析完 SDS 的結構,我們會問,SDS 在 Redis 中是如何存放的呢?

因為 Redis 的數據類型有很多(String、List、Set、Hash等等),不同數據類型會包含相同的元數據,所以值對象并不是直接存儲,而是被包裝成 redisObject 對象(源碼位于 server.h中),其定義如下圖:

所以,SDS 在 Redis Server 端的存儲如下圖:

另外,為了節省內存空間,Redis 還做了如下優化:

  • 當保存 Long 類型整數,RedisObject 中的指針直接賦值為整數數據,這樣就不用額外的指針指向整數。這種方式稱為 int 編碼方式。
  • 當保存字符串數據,且字符串小于等于 44 字節時,RedisObject 中的元數據、指針和 SDS 是一塊連續的內存區域,這樣可以避免內存碎片。這種方式稱為 embstr 編碼方式。
  • 當保存字符串數據,且字符串大于 44 字節時,Redis 不再把 SDS 和 RedisObject 放在一起,而是給 SDS 分配獨立的空間,并用指針指向 SDS 結構。這種方式稱為 raw 編碼模式。

下圖為 int、embstr 和 raw 這三種編碼模式的對比:

如果想查看一個值對象是采用哪種編碼模式,可以使用 OBJECT ENCODING((大小寫不敏感)命令,下面給了幾個示例截圖:

到此,SDS 的實現原理分析完成,需要補充的是:Redis 官方為了保證 String 的性能,在 SDS 設計上采用了兩個非常優秀的設計:空間預分配 和 惰性空間釋放。

2. 空間預分配

在對 SDS 進行修改操作時(追加字符串,拷貝字符串等),通常會調用 sds.c/sdsMakeRoomFor 方法對 SDS 的剩余容量進行檢查,如有必要會對 SDS 進行擴容,當計算修改之后字符串(用target_string表示)的目標長度之后分以下幾種情況:

(1)剩余的 freespace 足夠容納 target_string 和末尾\0字符,則不作任何操作

(2)剩余的 freespace 不夠容納 target_string 和末尾的\0字符

  • 當target_string_size < 1MB,則會直接分配2 * target_string_size 的空間用于存儲字符串
  • 當target_string_size >= 1MB,則會再額外多分配1MB的空間用于存儲字符串(target_string_size + 1024*1024)

3. 惰性空間釋放

當 SDS 字符串縮短時, 空余出來的空間并不會直接釋放,而是會被保留,等待下次再次使用,字符串縮短操作需要更新 sdshdr 頭中的 Len 字段以及alloced buffer中的\0字符的位置,如下源碼截圖,在更新字符串長度的過程中并沒有涉及到內存的重分配策略,只是簡單的修改sdshdr 頭中的 Len 字段。

四、SDS 的缺點 

從上面 SDS 的結構可以看出,SDS 除了存儲 String 的內容外,還需要額外的內存空間記錄數據長度、空間使用等信息,這個就導致了 SDS 的一個比較大的缺點:占內存。那么有什么更好的數據結構呢?我們下篇文章會進行分析。

不過,計算機領域很多時候都在空間和時間上的一種權衡。而Redis String 這種浪費內存換取讀寫速度就是一個很好的體現。

五、SDS 與 C字符串比較 

1. 獲取字符串長度復雜度

C字符串不記錄長度,獲取長度必須遍歷整個字符串,復雜度為O(N),SDS 在 len 屬性中記錄了 SDS 本身的長度, 獲取 SDS 長度的復雜度為 O(1) ;

2. 緩沖區溢出

C字符串不記錄自身的長度,每次增長或縮短一個字符串,都要對底層的字符數組進行一次內存重分配操作。如果在 append 操作之前沒有通過內存重分配來擴展底層數據的空間大小,就會產生緩存區溢出;如果進行 trim 操作之后沒有通過內存重分配來釋放不再使用的空間,就會產生內存泄漏;

SDS 通過未使用空間解除了字符串長度和底層數據長度的關聯,3.0版本用 free屬性記錄未使用空間,3.2版本用 alloc屬性記錄總的分配字節數量。通過未使用空間,SDS實現了空間預分配和惰性空間釋放兩種優化的空間分配策略,解決了字符串拼接和截取的空間問題;

3. 二進制安全

C 字符串以 \0結尾(即 以 \0判斷字符串結束),所以在 C字符串的內容里面不能包含 \0,否則會被認為是字符串結尾,因此,C字符串只能保存文本數據,不能保存像圖片這樣的二進制數據;

而 SDS 的 API 會以處理二進制的方式來處理存放在 bu f數組里的數據,不會對里面的數據做任何的限制。SDS 使用 len 屬性來判斷字符串是否結束,而不是空字符。

兩者比較歸納如下表:

C字符串

SDS

獲取字符串長度復雜度為O(N)

獲取字符串長度復雜度為O(1)

API是不安全的,可能會造成緩沖區溢出

API是安全的,不會造成緩沖區溢出

修改字符串長度必然需要內存重分配

修改字符串長度 N次最多需要執行 N次內存重分配

只能保存文本數據

可以保存文本或二進制數據

可以使用所有<string.h>庫中的函數

可以使用一部分<string.h>庫中的函數

六、總結

本文從 Redis的底層 SDS 實現分析了 String 的實現原理,可以說 SDS 是一種很優秀的設計,它即遵循了C語言的部分功能,又規避了 C語言 字符串常見的一些問題,這或許就是 Redis 優秀的一個原因。

另外,SDS 為了保證讀寫速度,盡管做了很多節省內存的操作(比如:sdshdr8/16/32/64,int/embstr/raw),但是,還在是一定程度上采用空間換時間。

通過 SDS 的設計,我們可以看出:在程序的世界里沒有“銀彈”,每種數據結構似乎總有其擅長的場景以及不足之處,這也正是各種數據結構百花齊放的原因。

最后,回答文章開頭的問題,為什么Redis String可以存放圖片,視頻?

我們把 SDS的結構抽象如下圖,盡管 String也是以 \0結尾,但是,因為 SDS 有 len 屬性來記錄 String 值的內容長度(used space),所以在獲取數據時只需要按照 len 獲取內容,而無需遍歷 String內容,所以也就不用擔心內容中有\0 異常結束String,所以可以存放圖片,視頻等二進制數據。

責任編輯:趙寧寧 來源: 猿java
相關推薦

2023-03-21 15:27:00

RedisC語言字符串

2024-02-20 20:12:09

C語言字符串Redis

2020-10-26 14:35:18

NLP自然語言人工智能

2020-05-13 12:17:33

RedisC字符C語言

2021-08-04 17:20:30

阿里巴巴AsyncJava

2014-11-21 10:50:26

JavaString

2015-05-25 15:31:56

C語言學習和使用 C 語言

2019-09-09 10:36:21

C語言編程語言程序員

2025-09-28 08:13:49

2020-09-22 15:29:03

UnixC++C

2016-09-27 21:25:08

Go語言Ken Thompso

2020-09-04 15:34:07

C編程語言開發

2012-06-12 09:47:17

C語言

2020-02-21 16:43:00

C語言編程語言程序員

2021-06-09 09:19:39

SSL證書數據安全公鑰

2025-01-10 11:42:13

2024-03-11 11:02:03

Date類JavaAPI

2024-11-29 08:20:22

Autowired場景項目

2020-11-17 10:20:53

Redis多線程單線程

2025-06-26 02:29:00

C語言void*機制
點贊
收藏

51CTO技術棧公眾號

av手机在线观看| 怡红院成永久免费人全部视频| 97视频一区| 黄色一区二区三区| 蜜桃91精品入口| 91av国产精品| 在线欧美日韩| 国产亚洲综合久久| 伦伦影院午夜理论片| 精精国产xxx在线视频app| 国产三级一区二区| 99re在线观看视频| 看黄色一级大片| 午夜久久福利| 亚洲天堂av在线播放| 无套白嫩进入乌克兰美女| 少妇视频一区| 亚洲精品一二三| 日韩一区二区三区高清| 亚洲av无码乱码在线观看性色| 老妇喷水一区二区三区| 欧美成人手机在线| 亚洲av毛片基地| 成人三级av在线| 91精品国产入口| 无码无遮挡又大又爽又黄的视频| 国产cdts系列另类在线观看| 国产亚洲一区二区三区在线观看 | 亚洲承认视频| 亚洲综合色噜噜狠狠| 天堂资源在线亚洲视频| 亚洲欧美日韩免费| 国产盗摄女厕一区二区三区| 国产精品人成电影| 免费av网站在线| 91久久久久| 久久99精品久久久久久青青91| 国产极品视频在线观看| 日韩伦理一区二区三区| 日韩欧美一级二级| 色呦色呦色精品| 国产一区二区三区朝在线观看| 午夜久久久影院| 成人国产一区二区三区| 黄色成人影院| 18欧美乱大交hd1984| 色视频一区二区三区| 欧美伦理影视网| 99久久99久久精品免费看蜜桃| av免费精品一区二区三区| 国产女人18毛片水18精| 久草在线在线精品观看| 国产欧美精品一区二区三区-老狼 国产欧美精品一区二区三区介绍 国产欧美精品一区二区 | 精品欧美日韩在线| 成人精品在线播放| 国产69精品一区二区亚洲孕妇| 亚洲free性xxxx护士白浆| 国产又粗又长视频| 精品一区二区三区香蕉蜜桃| 国产精品女人久久久久久| 无码人妻熟妇av又粗又大| 久久精品日产第一区二区| 欧洲成人在线观看| 无码免费一区二区三区| 日本成人在线一区| 国产精品自拍小视频| 中文字幕乱码视频| 精品一区二区三区欧美| 3d动漫精品啪啪一区二区三区免费| 国产伦精品一区二区三区视频痴汉| 久久99精品国产麻豆婷婷洗澡| 成人免费大片黄在线播放| 国产美女精品视频国产| 国产成人超碰人人澡人人澡| 国产欧美一区二区三区另类精品| 五月天激情开心网| 国产午夜精品在线观看| 亚洲资源视频| 午夜伦理在线视频| 亚洲va韩国va欧美va| www.日日操| 亚洲男男av| 精品国产不卡一区二区三区| 素人fc2av清纯18岁| 欧美理论电影大全| 蜜臀久久99精品久久久久久宅男| 久久久久99精品| 午夜宅男久久久| 国产99视频在线观看| 真实的国产乱xxxx在线91| 国产自产高清不卡| 国产高清在线精品一区二区三区| 日本wwwxxxx| 久久色.com| 亚洲欧美久久234| 最新av在线播放| 91黄色免费看| 91精品999| 成人免费直播在线| 亚洲网在线观看| 国产精品夜夜夜爽阿娇| 欧美精品一线| 日本一区二区三区在线播放| 亚洲欧美偷拍视频| 国产成人午夜高潮毛片| 欧美aaaaa喷水| 日本在线看片免费人成视1000| 一区二区三区影院| 国产成人无码一二三区视频| 日日夜夜亚洲精品| 91av久久久| 99精品视频一区| 亚洲一区bb| 爱啪啪综合导航| 91精品婷婷国产综合久久竹菊| 一级欧美一级日韩片| 波多野结衣在线观看一区二区三区 | 深爱五月综合网| 久久综合社区| 久久精品国产一区二区电影| 亚洲精品国产精品乱码| 另类综合日韩欧美亚洲| 91在线看网站| 国产三区在线观看| 色播五月激情综合网| www.欧美com| 日本久久综合| 欧美有码在线视频| av高清一区二区| 国产色婷婷亚洲99精品小说| 影音先锋亚洲视频| 9765激情中文在线| 91精品欧美综合在线观看最新| 欧美熟妇一区二区| 欧美激情综合| 国产在线a不卡| 国外av在线| 欧美日韩国产精品一区| 图片区乱熟图片区亚洲| 日韩精品二区| 国产成人免费av| 日韩精品视频无播放器在线看| 亚洲综合色噜噜狠狠| 天天综合网久久| 精品国产中文字幕第一页| 国模吧一区二区| 伊人网免费视频| 中文字幕亚洲精品在线观看 | 中文字幕美女视频| 日本欧美韩国一区三区| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 久九九久频精品短视频| 亚洲男人天堂网| 在线观看亚洲天堂| 成人avav影音| 国产欧美123| 视频一区国产| 久久99精品国产99久久6尤物| 国产精品美女一区| 欧美韩日一区二区三区| 天天干在线影院| 欧美精选视频在线观看| 国产成人精品av| 国产二区在线播放| 在线免费观看成人短视频| 成年人网站免费看| 天堂影院一区二区| 久久久久久国产精品免费免费| 91精品产国品一二三产区| 日韩成人xxxx| 欧美a视频在线观看| 国产亚洲精品aa| wwwwxxxx日韩| 香港欧美日韩三级黄色一级电影网站| 国产精品自产拍在线观看中文| 第九色区av在线| 91麻豆精品91久久久久同性| 国产67194| 粉嫩aⅴ一区二区三区四区五区| 青青草视频国产| 色天天色综合| 国产精品爱久久久久久久| av在线第一页| 欧美丰满美乳xxx高潮www| 手机在线免费看毛片| 丁香婷婷综合五月| 浮妇高潮喷白浆视频| 香蕉久久精品日日躁夜夜躁| 国产精品1234| 黄色网在线看| 日韩三级在线观看| 亚洲天堂男人av| 国产精品久久久久一区| 精品国产午夜福利在线观看| 影音先锋中文字幕一区二区| 久久国产欧美精品| 成人在线观看免费播放| 欧美精品情趣视频| 久久视频www| 51久久夜色精品国产麻豆| 九九视频在线免费观看| 99视频精品全部免费在线| caopor在线视频| 欧美 亚欧 日韩视频在线 | 国产va免费精品观看精品视频| 国产日韩欧美视频| 国产美女一区视频| 亚洲免费人成在线视频观看| 国产乱淫a∨片免费观看| 午夜伦欧美伦电影理论片| 日韩一级片在线免费观看| 丁香五精品蜜臀久久久久99网站| 成人羞羞国产免费网站| 欧美三级黄美女| 偷拍视频一区二区| 免费福利视频一区| 成人免费网视频| 日韩激情电影免费看| 久久久国产精彩视频美女艺术照福利| 天天色棕合合合合合合合| 欧美日韩激情一区| www.中文字幕在线观看| 亚洲资源中文字幕| 一级片久久久久| 99久久精品费精品国产一区二区| 中日韩av在线播放| 久久精选视频| av在线播放天堂| 99精品在线| 亚洲欧美国产一区二区| 夜夜躁狠狠躁日日躁2021日韩| 99久久99久久精品国产片| 成人四虎影院| 国产97色在线| 五月天国产在线| 精品国产一区二区三区四区在线观看| 国产一二在线观看| 亚洲国产欧美精品| 精品久久国产视频| 欧美日本视频在线| 午夜一级黄色片| 欧美性猛交xxxx乱大交| 国产精品19乱码一区二区三区| 亚洲啪啪综合av一区二区三区| 国产精品国产三级国产专业不 | 欧美精品三级日韩久久| 伊人久久久久久久久久久久| 午夜精品免费在线| 黄页网站免费观看| 一二三区精品福利视频| 精品一区在线观看视频| 国产精品国产三级国产普通话蜜臀 | 长河落日免费高清观看| 久久理论电影网| 亚洲色图14p| 97精品电影院| 国产中文字幕一区二区| 成人午夜免费电影| 中文字幕影片免费在线观看| av在线播放不卡| 国产又黄又粗又猛又爽的视频| av中文字幕亚洲| free性中国hd国语露脸| 北岛玲一区二区三区四区 | 久久免费的精品国产v∧| 中文精品在线观看| 久久亚洲一级片| 欧美做受xxxxxⅹ性视频| 欧美人体大胆444www| 亚洲欧洲国产专区| www..com.cn蕾丝视频在线观看免费版| 国产精品综合视频| 亚洲一区二区中文字幕在线观看| 精品无码三级在线观看视频| 天天看片天天操| 国产精品资源网| 无码人妻一区二区三区一| 成人晚上爱看视频| 99re久久精品国产| 国产人久久人人人人爽| 亚洲激情图片网| 亚洲色图一区二区三区| 91在线播放观看| 香蕉影视欧美成人| 欧美亚洲精品天堂| 天天影视网天天综合色在线播放| 日日夜夜操视频| 欧美日韩不卡一区二区| 国产高清免费av| 亚洲国产成人爱av在线播放| 撸视在线观看免费视频| 最新国产成人av网站网址麻豆| 欧美人体视频xxxxx| 1769国产精品| av成人在线看| 亚洲直播在线一区| 青青一区二区| 亚洲免费在线精品一区| 99综合视频| 男女污污的视频| 国产综合色在线视频区| 999精品免费视频| 国产欧美日韩激情| 天天干天天舔天天操| 午夜欧美大尺度福利影院在线看| 波多野结衣午夜| 精品欧美一区二区在线观看| 你懂的在线视频| 欧美成人免费播放| 亚洲男人av| 99视频免费观看蜜桃视频| 蜜臀av免费一区二区三区| 一区二区三区四区不卡| 亚洲激情综合| 色综合色综合色综合色综合| 久久综合精品国产一区二区三区| 免费黄色国产视频| 黄色一区二区在线| 97人妻一区二区精品免费视频| 精品第一国产综合精品aⅴ| 欧美视频综合| 97在线看福利| 精品中文字幕一区二区三区| 欧美精品一区在线发布| 欧美特黄视频| 九九热精品在线播放| 久久久综合网站| 一区二区三区免费高清视频| 欧美日韩一区中文字幕| 青青草免费在线| 久久久久久久电影一区| av高清一区| 欧美日韩高清在线一区| 国内精品99| 日本一二三四区视频| 国产精品久久久久一区二区三区共 | 极品美女扒开粉嫩小泬| 国产美女一区二区| 永久av免费网站| 在线观看欧美精品| 亚洲 欧美 精品| 欧美激情网友自拍| 粉嫩一区二区三区在线观看| 日本精品一区二区三区视频| 亚洲人成高清| 日本泡妞xxxx免费视频软件| 18成人在线视频| 亚洲在线免费观看视频| 亚洲精品美女免费| 高清视频在线观看三级| 成人激情av| 国内揄拍国内精品久久| 国产chinesehd精品露脸| 亚洲激情中文1区| www.com欧美| 色综合久久88色综合天天看泰| 天天干视频在线| 色婷婷av一区二区三区在线观看| 高清成人在线| 视频三区二区一区| 日本欧美一区二区在线观看| 午夜国产福利视频| 欧美日韩精品欧美日韩精品一综合| 国产黄在线看| 国产精品爽爽爽爽爽爽在线观看| 免费看日本一区二区| 日韩在线一级片| 91首页免费视频| www.毛片.com| 亚洲人高潮女人毛茸茸| 天天免费亚洲黑人免费| 欧美日韩精品免费观看| 首页亚洲欧美制服丝腿| 丰满的亚洲女人毛茸茸| 欧美午夜影院一区| 色开心亚洲综合| 国产精品污www一区二区三区| 一本色道久久综合亚洲精品高清 | 亚洲精品综合| 搡老熟女老女人一区二区| 疯狂欧美牲乱大交777| 欧美在线 | 亚洲| 国产成人91久久精品| 欧美成人激情| 亚洲av综合色区无码另类小说| 亚洲国产欧美另类丝袜| 韩国三级av在线免费观看| 成人黄色免费网站在线观看| 亚洲欧美亚洲| 亚洲中文字幕无码一区| 欧美性生活影院| 污视频网站免费在线观看| 国产欧美丝袜| 日本aⅴ亚洲精品中文乱码| 少妇久久久久久被弄高潮| 亚洲精品久久久久久久久久久久久| 吞精囗交69激情欧美| 国产人妻互换一区二区| 成人久久视频在线观看| 国产无遮挡又黄又爽又色视频|