Redis 源碼硬核解析系列專題 - 第二篇:核心數據結構之SDS(Simple Dynamic String)

1. 引言

Redis沒有直接使用C語言的標準字符串(以\0結尾的字符數組),而是自定義了SDS(Simple Dynamic String)。SDS是Redis的基礎數據結構之一,廣泛用于鍵值存儲、命令參數等場景。本篇將深入剖析SDS的實現原理、優勢以及源碼細節。


2. 為什么不用C標準字符串?

C字符串存在以下問題:

  • 緩沖區溢出strcat等操作可能越界。
  • 長度計算:需要遍歷到\0,時間復雜度O(n)。
  • 內存管理:頻繁的拼接和釋放效率低下。

SDS通過額外的元數據和優化策略,解決了這些問題,成為Redis高性能的基石。


3. SDS的結構體定義

SDS的定義在src/sds.hsrc/sds.c中。Redis 3.2之后引入了多種SDS類型以節省內存,但核心思想一致。我們以最基本的SDS結構為例:

代碼片段sds.h):

typedef char *sds;struct sdshdr {unsigned int len;    // 已使用長度unsigned int free;   // 未使用長度char buf[];          // 實際存儲數據的柔性數組
};
  • len:記錄字符串的實際長度,避免遍歷。
  • free:記錄剩余可用空間,支持動態擴展。
  • buf:存儲字符串內容,緊跟結構體。

硬核點:SDS的內存布局是連續的,sds指針直接指向buf,而通過指針偏移可以訪問sdshdr

Mermaid內存布局圖

classDiagramclass SDS {-len: uint-free: uint-buf: char[]}note for SDS "sds指針指向buf起始地址"

4. SDS的核心操作解析
4.1 創建SDS(sdsnew()

代碼片段sds.c):

sds sdsnew(const char *init) {size_t initlen = (init == NULL) ? 0 : strlen(init);return sdsnewlen(init, initlen);
}sds sdsnewlen(const void *init, size_t initlen) {struct sdshdr *sh;size_t alloc = initlen;sh = zmalloc(sizeof(struct sdshdr) + alloc + 1); // +1 為\0sh->len = initlen;sh->free = 0;if (init) memcpy(sh->buf, init, initlen);sh->buf[initlen] = '\0';return (char*)sh->buf;
}

硬核解析

  • zmalloc():Redis自定義的內存分配器。
  • 內存分配包括sdshdr頭部和buf(加1字節存放\0以兼容C函數)。
  • 返回值是buf的地址,隱藏了頭部信息。
4.2 拼接SDS(sdscat()

代碼片段sds.c):

sds sdscat(sds s, const char *t) {return sdscatlen(s, t, strlen(t));
}sds sdscatlen

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76078.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76078.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76078.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python-59-基于python內置庫解析html獲取標簽關鍵信息

文章目錄 1 html.parser1.1 初始化和基礎使用1.1.1 handle_starttag(self, tag, attrs)1.1.2 handle_endtag(self, tag)1.1.3 handle_startendtag(self, tag, attrs)1.1.4 handle_data(self, data)1.1.5 handle_comment(self, data)1.2 解析HTML文檔的流程2 百度搜索關鍵詞鏈接…

Java的string默認值

在Java中,String類型的默認值取決于其定義和實例化的方式。 以下是關于String默認值的詳細說明 未實例化的String變量? 如果定義一個String變量但未對其進行實例化(即未使用new關鍵字或直接賦值),其默認值為:ml-search[null]。這…

高并發系統下的訂單號生成服務設計與實現

目錄 引言 訂單號設計的關鍵考量因素 基礎需求分析 唯一性保障 數據量預估 可讀性設計 系統架構考量 分庫分表兼容 可擴展性設計 技術選型與比較 性能優化 高可用性保障 實踐案例:高并發系統訂單號結構設計 結構詳解 業務類型標識(2位) 唯一標識部分…

使用LLaMAFactory微調Qwen大模型

一、環境配置與工具安裝 1. 硬件要求 GPU:至少1塊NVIDIA GPU(推薦RTX 4090/A100/H100,顯存≥16GB)。內存:≥64GB系統內存。存儲:≥100GB硬盤空間用于模型與數據集存儲。2. 軟件依賴 Python 3.8+:需安裝CUDA支持的PyTorch版本(如torch==2.0.1+cu117)。 依賴庫:通過以…

2025-3-29算法打卡

一,回文判定 1.題目描述: 題目描述 給定一個長度為 nn 的字符串 SS。請你判斷字符串 SS 是否回文。 輸入描述 輸入僅 11 行包含一個字符串 SS。 1≤∣S∣≤1061≤∣S∣≤106,保證 SS 只包含大小寫、字母。 輸出描述 若字符串 SS 為回…

Android 接 Twitter Share ,常見問題及解決方案

1. 應用未授權或授權失敗 問題描述:當嘗試分享內容到 Twitter 時,應用提示未授權,或者在授權過程中出現錯誤,無法獲取授權碼或訪問令牌。解決方案 檢查 Twitter API 密鑰和密鑰密碼:確保在 Twitter 開發者平臺創建應用后,獲取的 API 密鑰(Consumer Key)和 API 密鑰密碼…

【數據結構】樹與森林

目錄 樹的存儲方法 雙親表示法 孩子表示法 孩子兄弟表示法 樹、森林與二叉樹的轉換 樹轉換成二叉樹 森林轉換成二叉樹 二叉樹轉換成森林 樹與森林的遍歷 樹的遍歷 森林的遍歷 樹的存儲方法 雙親表示法 這種存儲結構采用一組連續空間來存儲每個結點,同時…

html5基于Canvas的動態時鐘實現詳解

基于Canvas的動態時鐘實現詳解 這里寫目錄標題 基于Canvas的動態時鐘實現詳解項目介紹技術棧項目架構HTML結構核心樣式設計 核心功能實現1. 時鐘表盤繪制2. 時鐘指針動畫3. 主題切換實現4. 時間格式切換 技術要點總結項目亮點總結參考資料 項目介紹 在這篇文章中,我…

Deepseek API+Python 測試用例一鍵生成與導出 V1.0.3

** 功能詳解** 隨著軟件測試復雜度的不斷提升,測試工程師需要更高效的方法來設計高覆蓋率的測試用例。Deepseek API+Python 測試用例生成工具在 V1.0.3 版本中,新增了多個功能點,優化了提示詞模板,并增強了對文檔和接口測試用例的支持,極大提升了測試用例設計的智能化和易…

react如何引用(按需加載)百度地圖,并結合and組件化封裝

1.技術選項: vitereactantdesign load-script 2.實現思路: 1.按需加載如何實現? 要實現按需加載就不能直接在項目的入口文件這種地方去通過script標簽引入,這里使用load-script封裝了一個加載百度地圖的Bmap.js方法,實現動態的插入script腳本。 根…

LeetCode 第31~33題

目錄 LeetCode 第31題:下一個排列 LeetCode 第32題:最長有效括號 LeetCode 第33題:搜索旋轉排序數組 LeetCode 第31題:下一個排列 題目描述 整數數組的一個排列就是將所有成員以序列或線性順序排列。例如arr[1,2,3],以…

虛擬現實--->unity學習

前言:這學期勞動課選了虛擬現實,其中老師算挺認真的,當然對一些不感興趣的同學來說是一種折磨,我對這個unity的學習以及后續的虛幻引擎剛開始連基礎的概念都沒有,后面漸漸也是滋生了一些興趣,用這篇博客記錄…

在Trae中設置Python解釋器版本

Python 是一種廣泛使用的高級編程語言,因其簡潔易讀的語法和強大的功能而備受歡迎。隨著 Python 的不斷發展,多個版本相繼發布,每個版本都帶來了新特性和改進。然而,這也帶來了一些問題,比如不同的工程,需要…

鴻蒙原生開發之狀態管理V2

一、ArkTS狀態變量的定義: State:狀態,指驅動UI更新的數據。用戶通過觸發組件的事件方法,改變狀態數據。狀態數據的改變,引起UI的重新渲染。 在鴻蒙原生開發中,使用ArkTS開發UI的時候,我們可以…

nginx配置跳轉設置Host有誤導致報404問題

我們有個項目,前端調用了第三方接口。為了避免跨域,所以使用nginx進行轉發。一直正常工作,相安無事。近日第三方調整了安全策略,http轉換成https,原本使用ip,現在也改成使用域名,所以nginx這里我…

深度學習 Deep Learning 第12章 深度學習的主流應用

深度學習 Deep Learning 第12章 深度學習的主流應用 內容概要 本周深入探討了深度學習在多個領域的應用,包括計算機視覺、語音識別、自然語言處理以及其他領域如推薦系統和知識表示。本章強調了硬件和軟件基礎設施的重要性,特別是GPU在加速神經網絡訓練…

【Qt】三種操作sqlite3的方式及其三種多表連接

一、sqlite3與MySQL數據庫區別: 1. 數據庫類型 SQLite3:是嵌入式數據庫,它將整個數據庫存儲在單個文件中,不需要獨立的服務器進程。這意味著它可以很方便地集成到各種應用程序中,如移動應用、桌面應用等。MySQL&…

mysqlworkbench導入.sql文件

1、MySQL Workbench 新建數據庫 或者 在左側導航欄的 ?Schemas 區域右鍵選擇 ?Create Schema...輸入數據庫名稱(例如 mydatabase),點擊 ?Apply確認創建,點擊 ?Finish 2、選擇目標數據庫 在左側導航欄的 ?Schemas 列表中&a…

《Spring Cloud Eureka 高可用集群實戰:從零構建高可靠性的微服務注冊中心》

從零構建高可用 Eureka 集群 | Spring Cloud 微服務架構深度實踐指南 本文核心內容基于《Spring Cloud 微服務架構開發》第1版整理,結合生產級實踐經驗優化 實驗環境:IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich…

實變函數:集合與子集合一例(20250329)

題目 設 r , s , t r, s, t r,s,t 是三個互不相同的數,且 A { r , s , t } A \{r, s, t\} A{r,s,t}, B { r 2 , s 2 , t 2 } B \{r^2, s^2, t^2\} B{r2,s2,t2}, C { r s , s t , r t } C \{rs, st, rt\} C{rs,st,rt} 若 A B C A B C ABC 則 { r , s…