欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis的底層數(shù)據(jù)結(jié)構(gòu)詳解

 更新時間:2025年02月19日 11:23:47   作者:nodelaynow  
Redis性能高得益于其優(yōu)化的數(shù)據(jù)結(jié)構(gòu),Redis的數(shù)據(jù)結(jié)構(gòu)分為對外暴露的和內(nèi)部底層的兩種,對外暴露的數(shù)據(jù)結(jié)構(gòu)包括String、list、hash、set、zset等,而內(nèi)部底層的數(shù)據(jù)結(jié)構(gòu)則包括SDS、hashtable、ziplist、linkedlist、quicklist、intset、skiplist等

redis性能高的原因很大程度上是由于它的每一種數(shù)據(jù)結(jié)構(gòu)都經(jīng)過專門設計來應對不同場景

redis的數(shù)據(jù)結(jié)構(gòu)本質(zhì)上可以分為兩層,對外暴露的數(shù)據(jù)結(jié)構(gòu)以及內(nèi)部底層的數(shù)據(jù)結(jié)構(gòu)

1. redis數(shù)據(jù)結(jié)構(gòu)層次

1.1 外部數(shù)據(jù)結(jié)構(gòu)

對外暴露的數(shù)據(jù)結(jié)構(gòu)即我們所使用的String,list,hash,set,zset等

1.2 內(nèi)部數(shù)據(jù)結(jié)構(gòu)

redis內(nèi)部有更為精細的實現(xiàn),總的來說有以下幾種:

SDS,hashtable,ziplist,linkedlist,quicklist,intset,skiplist等

2. redis底層實現(xiàn)

2.1 String字符串類型的底層實現(xiàn)

字符串類型的底層實現(xiàn)主要依賴于SDS這種數(shù)據(jù)結(jié)構(gòu),相較于傳統(tǒng)的C語言所表達的字符串,SDS內(nèi)部作出改動,包含了len(字符串真實的長度),buf[](存放字符串數(shù)據(jù)的數(shù)組),alloc(buf數(shù)組所擁有的實際長度),flags。

不同字符串長度會使用相同結(jié)構(gòu)但不同長度的SDS數(shù)據(jù)結(jié)構(gòu)(內(nèi)部buf,alloc會不同),flags就是用來指定你用的是哪一種。

SDS除開長度所導致的結(jié)構(gòu)不同,具體的編碼模式也會隨著傳值不同而不同,總的來說分為三種:RAW,EMBSTR,INT(寫作int類型 但是實際上存儲的是long)。

當外部傳來一個值為字符串類型的value時,redis會首先使用RAW接收,然后出于節(jié)省內(nèi)存考慮,轉(zhuǎn)化為INT或者EMBSTR類型的編碼方式。

這樣的好處是,當我們試圖對字符串進行increment這種操作時,int類型會自動直接加1,而str會試圖轉(zhuǎn)化為int,然后再加1,而當我們進行append這類操作時,int類型會試圖轉(zhuǎn)化為str再執(zhí)行,而str會直接執(zhí)行,不然編碼方式不同,對于某些情況下的命令結(jié)果也會不同

2.2 Hash類型的底層實現(xiàn)

hash類型的底層實現(xiàn)主要分為兩種,ziplist和hashtable

ziplist是一塊存放于連續(xù)內(nèi)存的鏈表,基于內(nèi)存連續(xù),它的讀取效率很高,尋找元素時直接遍歷,內(nèi)部不存儲前后節(jié)點這類數(shù)據(jù),但是也正因為內(nèi)存連續(xù),它本身也會收到一些限制,實際上ziplist要滿足以下兩種條件才會被使用

  • 長度小于512
  • 單個value小于64字節(jié)

如不滿足,強行使用,會導致涉及插入修改等發(fā)生的內(nèi)存拷貝成本較大,影響性能。

而不滿足時,我們會使用hashtable來實現(xiàn),哈希表里面的hash搜索能保證時間復雜度接近O(1),以鏈表數(shù)組的方式解決hash沖突,而當哈希表需要進行擴容時,為了避免單次擴容所導致的響應時間劇烈增加,它將單次擴容所需要的重哈希分散到后續(xù)對哈希表的增刪改查操作里,一步步進行hash擴容。

2.3 list類型的底層實現(xiàn)

list類型在redis3.2之前使用ziplist或者linkedlist去實現(xiàn),而在3.2之后使用quicklist去實現(xiàn)。

quicklist是一種結(jié)合了ziplist和linkedlist兩者的鏈表數(shù)據(jù)結(jié)構(gòu),內(nèi)部每個節(jié)點即為一個ziplist,這樣的設計實際上是對空間和時間的這種。

對于一個雙向列表而言,不僅需要保存內(nèi)部數(shù)據(jù),還要維護前后指針,占用空間;當列表長度過長時,也會產(chǎn)生碎片化問題,因此我們將部分數(shù)據(jù)封裝在一個ziplist里,減少指針個數(shù),并且減少內(nèi)存脆片,當然ziplist本身也不宜設置過長,找不到足夠大的連續(xù)空間給ziplist的話,存儲效率也會下降。具體長度設置要取決于業(yè)務場景。

2.4 set類型的底層實現(xiàn)

set類型主要由hashtable和intset實現(xiàn)

當內(nèi)部數(shù)據(jù)全為整數(shù)并且內(nèi)部數(shù)據(jù)量小于512個時,就使用intset去實現(xiàn),intset本質(zhì)上是一個由整數(shù)實現(xiàn)的有序集合,內(nèi)部使用二分查找,和ziplist一樣,也是一塊連續(xù)的內(nèi)存空間,并且針對證書大小也進行了不同的編碼來實現(xiàn)對內(nèi)存的優(yōu)化。

當不滿足條件時,就會使用hashtable去實現(xiàn),key即為存儲數(shù)據(jù),因為我們不關(guān)心value的值,所以value一般存儲為null值。

2.5 zset類型的底層實現(xiàn)

zset類型由skiplist(跳表)來實現(xiàn),以 1 2 3 4 5 6 7 8 9 10中查找7為例,按照鏈表而言,要一個一個遍歷去查找,而對于跳表,每個節(jié)點內(nèi)部會隨機儲存下一個目標以及跳過的層數(shù),比如從1開始,跳到4,4<7,因此不需要關(guān)心1-4之間的數(shù)據(jù),4跳到8,8>7,因此回溯到4,4跳到6,然后6跳到8,發(fā)現(xiàn)8>7,因此回溯到6,6跳到7,這就是跳表的基礎(chǔ)原理,每個節(jié)點內(nèi)部會儲存下一個節(jié)點以及能夠跳躍的節(jié)點。

那么是怎么設定每個節(jié)點能夠跳躍到哪些節(jié)點的呢?

每個節(jié)點在初始化時,會隨機設置一個level數(shù)組來表明自身的層級(隨機概率p由開發(fā)者設定),最下面一層存儲下一個節(jié)點,第二層存儲下一個擁有二層數(shù)組的節(jié)點,第三層存儲下一個擁有三層數(shù)組的節(jié)點,最終打到尾節(jié)點上。

總結(jié)

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

相關(guān)文章

  • 使用Redis實現(xiàn)分布式鎖的方法

    使用Redis實現(xiàn)分布式鎖的方法

    為了保證我們線上服務的并發(fā)性和安全性,目前我們的服務一般拋棄了單體應用,采用的都是擴展性很強的分布式架構(gòu),這篇文章主要介紹了使用Redis實現(xiàn)分布式鎖的方法,需要的朋友可以參考下
    2022-06-06
  • Redis使用SETNX命令實現(xiàn)分布式鎖

    Redis使用SETNX命令實現(xiàn)分布式鎖

    分布式鎖是一種用于在分布式系統(tǒng)中控制多個節(jié)點對共享資源進行訪問的機制,本文主要為大家詳細介紹了Redis如何使用SETNX命令實現(xiàn)分布式鎖,需要的可以參考下
    2025-01-01
  • RedisTemplate常用操作方法總結(jié)(set、hash、list、string等)

    RedisTemplate常用操作方法總結(jié)(set、hash、list、string等)

    本文主要介紹了RedisTemplate常用操作方法總結(jié),主要包括了6種常用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • Caffeine實現(xiàn)類似redis的動態(tài)過期時間設置示例

    Caffeine實現(xiàn)類似redis的動態(tài)過期時間設置示例

    這篇文章主要為大家介紹了Caffeine實現(xiàn)類似redis的動態(tài)過期時間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Redis是單線程的嗎

    Redis是單線程的嗎

    Redis使用單線程的原因就是多線程并不能有效提升Redis的性能,相反可能還會降低性能,所以自然而然使用單線程,本文給大家詳細介紹了Redis為什么是單線程的,感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • 詳解使用Redis SETNX 命令實現(xiàn)分布式鎖

    詳解使用Redis SETNX 命令實現(xiàn)分布式鎖

    本篇文章主要介紹了詳解使用Redis SETNX 命令實現(xiàn)分布式鎖,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • 簡介Lua腳本與Redis數(shù)據(jù)庫的結(jié)合使用

    簡介Lua腳本與Redis數(shù)據(jù)庫的結(jié)合使用

    這篇文章主要介紹了簡介Lua腳本與Redis數(shù)據(jù)庫的結(jié)合使用,Redis是基于主存的高性能數(shù)據(jù)庫,需要的朋友可以參考下
    2015-06-06
  • Redis的Expire與Setex區(qū)別說明

    Redis的Expire與Setex區(qū)別說明

    這篇文章主要介紹了Redis的Expire與Setex區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Redis連接失?。嚎蛻舳薎P不在白名單中的問題分析與解決方案

    Redis連接失?。嚎蛻舳薎P不在白名單中的問題分析與解決方案

    在現(xiàn)代分布式系統(tǒng)中,Redis作為一種高性能的內(nèi)存數(shù)據(jù)庫,被廣泛應用于緩存、消息隊列、會話存儲等場景,然而,在實際使用過程中,我們可能會遇到各種連接問題,其中“客戶端IP不在白名單中”是一個常見的錯誤,本文將從錯誤分析、原因排查、解決方案等詳細探討如何解決這一問題
    2025-01-01
  • Redis主從復制與讀寫分離的實現(xiàn)

    Redis主從復制與讀寫分離的實現(xiàn)

    Redis在作為緩存的時候,隨著項目訪問量的增加,對Redis服務器的操作也越加頻繁,雖然Redis讀寫速度都很快,但是一定程度上也會造成一定的延時,本文主要介紹了Redis主從復制與讀寫分離的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12

最新評論