Redis 存儲原理與數據模型(三)

目錄

存儲結構

?存儲轉換

數據組織

hash 沖突

?負載因子

擴容

?縮容

?漸進式rehash

?Redis 線程模型

單線程命令處理機制

為什么Redis 命令的單線程快

機制

優化

柔性數組

?Redis reactor_io 多線程網絡模型


存儲結構

  • key-value鍵值對通過 hash 的方式存儲到數組中
  • value 主要的數據結構有string,list,hash,set,zset
  • value 的數據不是單一類型,可以嵌入 key - value 鍵值對

?

?存儲轉換

? ? ? ? redis 在進行編碼存儲的時候,同一類型不同的數據量會導致編碼的方式不同

  • 數據量少的時候,以存儲效率高為主
  • 數據量多的時候,以運行查詢快為主

數據組織

????????redis 的 KV 數據組織方式是字典,通過 hashtable 來實現。hashtable 就是通過 hash 運算的方式來決定字符串放到數組的哪一個槽位,數組的大小根據數據量來進行調整,所以就會涉及到擴容和縮容。

  • 字符串經過 hash 函數運算得到 64 位整數
  • 64 位整數%表長size得到余數,即是字符串在數組中的槽位
  • 將數組存入對應的槽位中

hash 沖突

? ? ? ? ?當存儲的數據個數大于數組的長度時,必將發生沖突,就是在一個槽內存了兩個或多個數據。

抽屜原理: n+1個蘋果放在 n 個抽屜中,蘋果最多的那個抽屜至少有 2 個蘋果;64位整數遠大 于數組的長度,比如數組長度為 4,那么 1、5、9、1+4n 都是映射到1號位數組;所以大概 率會發生沖突;

?負載因子

負載因子 = used / size ,?used 是數組存儲元素的個數,size 是數組的長度;

負載因子越小,沖突越小;

負載因子越大,沖突越大;

redis 的負載因子是 1

擴容

?如果負載因子 > 1,則會發生擴容,擴容的規則是翻倍擴容;

如果正在 fork (在 rdb、aof 復寫以及 rdb-aof 混用情況下)時,會阻止擴容,但是此時若負載 因子 > 5,索引效率大大降低, 則馬上擴容;

?擴容的時候,會發生rehash,擴容后每個元素可能會有兩個位置出現。

?縮容

如果負載因子 < 0.1 ,則會發生縮容,縮容的規則是恰好包含 used 的 2的n次方;

理解如下:假如此時數組存儲元素個數為 9,恰好包含該元素的就是 2的4次方,也就是 16;

縮容也會發生rehash,位置的調整與擴容相反。

?

?漸進式rehash

當 hashtable 中的元素過多的時候,不能一次性 rehash 到 ht[1] ,這樣會長期占用 redis,其他 命令得不到響應,所以需要使用漸進式 rehash;

rehash步驟:

? ? ? ? 將 ht[0] 中的元素重新經過 hash 函數生成 64 位整數,再對ht[1] 長度進行取余,從而映射到 ht[1]。

漸進式 rehash 規則:

? ? ? ? 1. 分治的思想,將 rehash 分到之后的每步增刪改查的操作當中;

? ? ? ? 2. 在定時器中,閑時最大執行一毫秒 rehash ,每次步長 100 個數組槽位。

處于漸進式 rehash 階段時,是否會發生擴容縮容?不會!

?Redis 線程模型

????????Redis采用"單線程處理命令+多線程處理后臺任務"的混合模型。核心命令執行保持單線程特性,通過多線程處理網絡I/O、持久化等輔助操作。

單線程命令處理機制

前提:單線程不能有耗時操作

1.避免加鎖復雜度

  • 多線程會引入并發沖突,需要加鎖控制:
  • 加鎖粒度難把控,鎖得多了性能下降,鎖得少了數據錯亂
  • 容易出現死鎖、競態等問題
  • 代碼復雜度和維護成本上升

2.避免線程切換開銷

  • 多線程會發生頻繁的 CPU 上下文切換:
  • 線程切換需要保存/恢復寄存器等上下文信息
  • 如果 Redis 每條命令都切換線程,反而會拉低整體性能

3.數據結構無需加鎖

  • 單線程訪問所有核心數據結構(如字典、跳表等),天然線程安全
  • 操作原子性強,不會出現“半更新”的問題
  • 命令順序可控,執行邏輯簡單可靠
為什么Redis 命令的單線程快
機制
特點說明
內存數據庫所有數據存儲在內存中,讀取/寫入速度極快
高效數據結構字典,跳表,壓縮列表,整數集合,quicklist,按需切換,空間與效率均衡
數據組織機制優化漸進式 Rehash,按需擴容,避免一次性耗時操作
Reactor 網絡模型使用多路復用(epoll/select/poll),IO 高效
單線程無鎖設計所有命令串行執行,避免加鎖帶來的性能損耗和線程切換開銷
優化

1.分治

  • ? ?將rehash分布在每次操作中
  • ? ?定時器 + 空閑時間處理機制

2. 耗時阻塞操作在其他線程中處理

操作線程方式
Lazy Free創建后臺線程異步刪除大 Key
AOF Rewrite在子進程中異步執行
RDB Save在子進程中快照,不阻塞主線程
Redis 6.0 I/O 多線程網絡I/O在多線程中完成,提高并發性能

3.對象類型采用不同的數據結構實現

柔性數組

C99 引入的一種結構體末尾的數組字段,用于實現可變長度數組

  • 柔性數組的大小是在 運行時動態決定的
  • 它不占結構體靜態大小,而是結構體分配內存時追加在后面的一段連續空間
struct MyStruct {int id;char name[20];int data[];  // 柔性數組成員,必須是結構體的最后一個字段
};

?Redis reactor_io 多線程網絡模型

  • IO密集型程序:主要等待外部資源
  • CPU密集型程序:主要占用CPU計算資源

Redis 主線程管理調度 + 執行命令,IO 線程專職網絡通信,讓系統性能和單線程一致性兩者兼得?

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

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

相關文章

langchain4j中使用milvus向量數據庫做RAG增加索引

安裝milvus向量數據庫 官方網址 https://milvus.io/zh 使用docker安裝milvus mkdir -p /data/docker/milvus cd /data/docker/milvus wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh#在docker中啟動milvus sh standalone_emb…

UE5.3 C++ 房屋管理系統(一)

一.框架思路 1.如何加載。房屋管理&#xff0c;既然管理。就存在動態加載&#xff0c;和靜態加載的考慮。如果是靜態加載&#xff0c;就是在編輯器情況下放置&#xff0c;但這樣方便了擺放&#xff0c;但管理就需要在開始是將所有的房屋找到加到管理者里。你無法決定拖入場景的…

4.1【LLaMA-Factory 實戰】醫療領域大模型:從數據到部署的全流程實踐

【LLaMA-Factory實戰】醫療領域大模型&#xff1a;從數據到部署的全流程實踐 一、引言 在醫療AI領域&#xff0c;構建專業的疾病診斷助手需要解決數據稀缺、知識專業性強、安全合規等多重挑戰。本文基于LLaMA-Factory框架&#xff0c;詳細介紹如何從0到1打造一個垂直領域的醫…

解決LangChain4j報錯HTTP/1.1 header parser received no bytes

問題描述 當使用langchain4j-open-ai調用自己部署的大模型服務時報錯&#xff1a; public static void main(String[] args) {OpenAiChatModel model OpenAiChatModel.builder().apiKey("none").modelName("qwen2.5-instruct").baseUrl("http://19…

阿里云codeup以及本地gitclone+http

cmd命令行亂碼問題、解決 chcp 65001 git代碼提交 git add . git commit -m init git push origin master

2025.05.07-淘天算法崗-第二題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 02. 完美拼圖挑戰 問題描述 A先生是一位拼圖愛好者,他有兩種形狀的拼圖塊: a a a

Spring Boot中Redis序列化配置詳解

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 引言 在使用Spring Boot集成Redis時&#xff0c;序列化方式的選擇直接影響數據存儲的效率和系統兼容性。默認的JDK序列化存在可讀性差、存儲空間大等問題&am…

紫禁城多語言海外投資理財返利源碼帶前端uniapp純工程文件

測試環境&#xff1a;Linux系統CentOS7.6、寶塔、PHP7.2、MySQL5.6&#xff0c;根目錄public&#xff0c;偽靜態thinkphp&#xff0c;開啟ssl證書 語言&#xff1a;中文簡體、英文、越南語、馬來語、日語、巴西語、印尼語、泰語 前端是uniapp的源碼&#xff0c;我已經把nmp給你…

搭建大數據學習的平臺

一、基礎環境準備 1. 硬件配置 物理機&#xff1a;建議 16GB 內存以上&#xff0c;500GB 硬盤&#xff0c;多核 CPU虛擬機&#xff1a;至少 3 臺&#xff08;1 主 2 從&#xff09;&#xff0c;每臺 4GB 內存&#xff0c;50GB 硬盤 2. 操作系統 Ubuntu 20.04 LTS 或 CentOS…

Linux 軟硬連接詳解

目錄 一、軟鏈接&#xff08;Symbolic Link&#xff09; ?定義與特性 ?實現方法?使用 ln -s 命令&#xff1a; 二、硬鏈接&#xff08;Hard Link&#xff09; 1、是什么 2、工作機制 3、實現方式 一、軟鏈接&#xff08;Symbolic Link&#xff09; ?定義與特性 定義…

每日c/c++題 備戰藍橋杯(洛谷P1115 最大子段和)

洛谷P1115 最大子段和 題解 題目描述 最大子段和是一道經典的動態規劃問題。題目要求&#xff1a;給定一個包含n個整數的序列&#xff0c;找出其中和最大的連續子序列&#xff0c;并輸出該最大和。若所有數均為負數&#xff0c;則取最大的那個數。 輸入格式&#xff1a; 第…

前端取經路——框架修行:React與Vue的雙修之路

大家好,我是老十三,一名前端開發工程師。在前端的江湖中,React與Vue如同兩大武林門派,各有千秋。今天,我將帶你進入這兩大框架的奧秘世界,共同探索組件生命周期、狀態管理、性能優化等核心難題的解決之道。無論你是哪派弟子,掌握雙修之術,才能在前端之路上游刃有余。準…

PyTorch API 1 - 概述、數學運算、nn、實用工具、函數、張量

文章目錄 torch張量創建操作索引、切片、連接與變異操作 加速器生成器隨機采樣原地隨機采樣準隨機采樣 序列化并行計算局部禁用梯度計算數學運算常量逐點運算歸約操作比較運算頻譜操作其他操作BLAS 和 LAPACK 運算遍歷操作遍歷操作遍歷操作遍歷操作遍歷操作遍歷操作遍歷操作遍歷…

java命令行打包class為jar并運行

1.創建無包名類: 2.添加依賴jackson 3.引用依賴包 4.命令編譯class文件 生成命令: javac -d out -classpath lib/jackson-core-2.13.3.jar:lib/jackson-annotations-2.13.3.jar:lib/jackson-databind-2.13.3.jar src/UdpServer.java 編譯生成class文件如下 <

ABC 轉 STL 全攻略:格式解析、方法實操與問題解決

在 3D 建模與設計領域&#xff0c;不同格式文件間的轉換是一項基礎且重要的操作。ABC&#xff08;Alembic&#xff09;和 STL&#xff08;Standard Triangle Language&#xff09;是其中常見的兩種格式。ABC 格式因其高效存儲和傳輸 3D 數據的特性&#xff0c;常被用于影視特效…

編寫一個處理txt的loader插件,適用于wbepack

處理txt的webpack的loader插件 編寫一個處理txt的loader插件&#xff0c;適用于wbepack 編寫一個處理txt的loader插件&#xff0c;適用于wbepack 實現一個處理txt的插件&#xff0c;給文本每行前后添加**** module.exports function txtLoader(content) {// 確保 Loader 是異…

DeepSeek的100個應用場景

在春節前夕&#xff0c;浙江杭州的AI企業DeepSeek推出了其開源模型DeepSeek-R1&#xff0c;以僅相當于Open AI最新模型1/30的訓練成本&#xff0c;在數學、編程等關鍵領域展現出媲美GPT-o1的出色性能。發布僅數日&#xff0c;DeepSeek-R1便迅速攀升至中美兩國蘋果應用商店免費榜…

ev_loop_fork函數

libev監視器介紹&#xff1a;libev監視器用法-CSDN博客 libev loop對象介紹&#xff1a;loop對象-CSDN博客 libev ev_loop_fork函數介紹:ev_loop_fork函數-CSDN博客 libev API吐血整理&#xff1a;https://download.csdn.net/download/qq_39466755/90794251?spm1001.2014.3…

【PostgreSQL數據分析實戰:從數據清洗到可視化全流程】金融風控分析案例-10.1 風險數據清洗與特征工程

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 PostgreSQL金融風控分析案例&#xff1a;風險數據清洗與特征工程實戰一、案例背景&#xff1a;金融風控數據處理需求二、風險數據清洗實戰&#xff08;一&#xff09;缺失值…

OpenCV 的 CUDA 模塊中用于將一個多通道 GpuMat 圖像拆分成多個單通道圖像的函數split()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::cuda::split 是 OpenCV CUDA 模塊中的一個函數&#xff0c;用于將一個多通道的 GpuMat 圖像拆分成多個單通道的 GpuMat 圖像。這個函數是 CP…