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

淺談redis整數(shù)集為什么不能降級

 更新時間:2021年07月21日 14:46:56   作者:煙花散盡13141  
本文主要介紹了redis整數(shù)集為什么不能降級,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

整數(shù)集合相信有的同學沒有聽說過,因為redis對外提供的只有封裝的五大對象!而我們本系列主旨是學習redis內(nèi)部結(jié)構(gòu)。內(nèi)部結(jié)構(gòu)是redis五大結(jié)構(gòu)重要支撐!

前面我們分別從redis內(nèi)部結(jié)構(gòu)分析了redis的List、Hash、Zset三種數(shù)據(jù)結(jié)構(gòu)了。今天我們再來分析set數(shù)據(jù)結(jié)構(gòu)內(nèi)部是如何存儲的

基本結(jié)構(gòu)

在src/t_set.c中我們發(fā)現(xiàn)這樣一段代碼

由此我們可知在set中是由兩種數(shù)據(jù)結(jié)構(gòu)構(gòu)成的: hashtable+intset 。關(guān)于redis內(nèi)部其他的結(jié)構(gòu)我專門在【redis專欄中有介紹】。hashtable不是我們今天的主角,我們今天先分析intset俗稱整數(shù)集合。

從上圖中我們可以看出,我構(gòu)造了兩個set集合分別為【commonset】、【cs】。兩個集合前者存儲字符串、后者專門存儲數(shù)字。

我們在通過object encoding key 來查看下兩個集合的底層數(shù)據(jù)結(jié)構(gòu),發(fā)現(xiàn)一個是hashtable 一個是intset 。這也驗證了我們上面對set基本結(jié)構(gòu)的描述。

在redis中對外提供五大類型實際上都是redis的一個抽象對象叫做redisobject。在內(nèi)部映射了我們redis內(nèi)部的數(shù)據(jù)結(jié)構(gòu)

針對commonset和cs兩個集合在內(nèi)部數(shù)據(jù)結(jié)構(gòu)大概可以這么理解

何時使用intset

你可以單純的認為只要是數(shù)字就會使用intset結(jié)構(gòu)來存儲,我恐怕要給你當頭一棒了。實際上并不是這樣

需要同時滿足以下兩個條件:

intset

圖中表示的很清楚了,在intset中的encoding有三種取值分別代表contents保存數(shù)據(jù)類型。這里有人可能會有疑問了contents的類型不就是int8_t嗎?為什么還需要encoding呢?這里通過源碼跟蹤內(nèi)部的確跟int8_t沒啥關(guān)系。而且數(shù)據(jù)的默認類型就是int16_t 。關(guān)于length這里無需太多解釋,記住一點表示contents元素的個數(shù)并非表示contents數(shù)組的長度!

了解intset的同學都知道在encoding三種取值范圍中涉及了升級的操作!在講升級之前我們先來了解下C、C++中int的取值范圍是如何定義的

int8_t的取值范圍是【-128,127】 。 類似于java中byte占1個字節(jié)也就是8位。他的取值范圍是

添加元素

sadd juejin -123
sadd juejin -6
sadd juejin 12
sadd juejin 56
sadd juejin 321	

juejin這個key內(nèi)部就是intset 。

上面我們添加了5個元素且這五個元素的長度都在16之內(nèi)!所以當前的intset的encoding=INTSET_ENC_INT16。-123在contents中占前16位。

所以當前五個元素占contents的長度是16*5=80 ;

注意set在存儲int類型數(shù)據(jù)時,內(nèi)部是按照從小到大的順序存儲的。

類型變動

上面的問題不知道你有沒有考慮過,或者說有沒有遇到過!intset默認是int16位,正如我們上面添加的五個元素。加入此時我們添加第6個元素是65535(32位)。那么此時16位的長度就不夠存儲了這個時候intset會怎么做!

另外當我們添加第6個元素后又將65535刪除了之后,結(jié)構(gòu)和添加之前是否一樣!下面我們帶著這兩個問題來一探究竟!??!

升級

首先我們針對第一問題來看看。原來五個元素都是16位就可以滿足了,這個時候添加的65535是32位長度的。那么是不是可以直接追加32位分配給65535呢?

答案是肯定不行,首先直接追加無法保證數(shù)組元素的大小順序!其次如果前五個分別是16位,第6個是32位那么在intset結(jié)構(gòu)中沒有多余的字段來進行標記。也就是說在解析的時候就無法判斷應(yīng)該解析16位還是32位了.

redis為了方便解析所以在有高長度加入時會將整個contents進行升級。意思就是將整個contents先進行擴容,然后在重新填充數(shù)據(jù)

加入65535

首先根據(jù)length可以確定擴容后元素個數(shù)為6 , 每個占位32,所以contents長度為32*6=192 。 此時前80位內(nèi)容保持不變

舊數(shù)據(jù)移位

開辟了足夠的空間后,我們就可以對舊數(shù)據(jù)進行移位了這里我們從原數(shù)組的末尾開始移動,在移動之前需要明確在新數(shù)組中的排序位置。此時我們首先將321進行比對確定在新數(shù)組中他的排名是第五名,那么他將占用新contents中128~159區(qū)間。

最終前5 個元素就會被移動好 。

最后將新加入的元素填充進去。當發(fā)生升級時肯定是因為新元素的長度大于原有長度了。那么他的值一定會是在新數(shù)組的兩端。負數(shù)在最左側(cè),正數(shù)在最右側(cè)

降級

接下來就是第二個問題當新加入的65535又被刪除了redis該怎么辦,這個時候元素長度實際16位就可以滿足了,但是此時encoding卻是32位的。按照我的看法應(yīng)該在實現(xiàn)降級!

但是遺憾的是redis并沒有,那么請思考為什么沒有?如果讓你實現(xiàn)你將如何實現(xiàn)

為什么不實現(xiàn)降級

當加入元素超過當前長度我們很容易就知道此時需要進行升級操作,但是當我們刪除一個數(shù)據(jù)時我們?nèi)绾闻袛嗍欠裥枰导墔s很困難,我們需要重新遍歷一遍剩下的元素是否小于當前長度,實現(xiàn)復雜度O(N) 。這就是為什么不進行降級原因之一

你可能會說重新遍歷一遍很快的反正在內(nèi)存中,那么你有沒有想過如果降級之后又遇到升級情況,這樣來回的升級降級就降低了我們程序的性能了。我們知道升級是必須的所以這里降級redis采取的是忽略的策略

小結(jié)

參考資料:內(nèi)存升級優(yōu)化內(nèi)存降級

到此這篇關(guān)于淺談redis整數(shù)集為什么不能降級的文章就介紹到這了,更多相關(guān)redis整數(shù)集降級內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis6 主從復制及哨兵機制的實現(xiàn)

    Redis6 主從復制及哨兵機制的實現(xiàn)

    本文主要介紹了Redis6 主從復制及哨兵機制的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • redis-cli -p 6379 info命令詳解

    redis-cli -p 6379 info命令詳解

    這篇文章主要介紹了redis-cli -p 6379 info命令詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Redis RDB技術(shù)底層原理詳解

    Redis RDB技術(shù)底層原理詳解

    為了使Redis在重啟之后仍能保證數(shù)據(jù)不丟失,需要將數(shù)據(jù)從內(nèi)存中以某種形式同步到硬盤中,這一過程就是持久化,本文重點給大家介紹Redis RDB技術(shù)底層原理實現(xiàn)方法,一起看看吧
    2021-09-09
  • redis中數(shù)據(jù)類型命令整理

    redis中數(shù)據(jù)類型命令整理

    在本篇文章里小編給大家整理的是關(guān)于redis中5種數(shù)據(jù)類型基本命令介紹,需要的朋友們可以學習下。
    2020-03-03
  • Redis分布式鎖之紅鎖的實現(xiàn)

    Redis分布式鎖之紅鎖的實現(xiàn)

    本文主要介紹了Redis分布式鎖之紅鎖的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • redis.clients.jedis.exceptions.JedisDataException異常的錯誤解決

    redis.clients.jedis.exceptions.JedisDataException異常的錯誤解決

    本文主要介紹了redis.clients.jedis.exceptions.JedisDataException異常的錯誤解決,這個異常通常發(fā)生在嘗試連接到一個?Redis?服務(wù)器時,客戶端發(fā)送了一個?AUTH?命令來驗證密碼,但是沒有配置密碼驗證,下來就來解決一下
    2024-05-05
  • 詳解如何發(fā)現(xiàn)并解決Redis熱點Key問題

    詳解如何發(fā)現(xiàn)并解決Redis熱點Key問題

    Redis 熱點 Key 是指在某一時間段內(nèi),被大量的讀寫操作命中的 Key,這種情況可能會導致性能瓶頸,數(shù)據(jù)一致性問題,緩存擊穿等問題,所以本文給大家介紹了如何發(fā)現(xiàn)并解決Redis熱點Key問題,需要的朋友可以參考下
    2024-05-05
  • redis?for?windows?6.2.6安裝包最新步驟詳解

    redis?for?windows?6.2.6安裝包最新步驟詳解

    這篇文章主要介紹了redis?for?windows?6.2.6安裝包全網(wǎng)首發(fā),使用Windows計劃任務(wù)自動運行redis服務(wù),文章給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • redis 實現(xiàn)登陸次數(shù)限制的思路詳解

    redis 實現(xiàn)登陸次數(shù)限制的思路詳解

    這篇文章主要介紹了redis 實現(xiàn)登陸次數(shù)限制的思路詳解,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • 深入解析Redis中常見的應(yīng)用場景

    深入解析Redis中常見的應(yīng)用場景

    這篇文章主要給大家介紹了關(guān)于Redis中常見的應(yīng)用場景的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-09-09

最新評論