redis

Redis分布式鎖是可重入的嗎?

不可重入,可重入鎖可以使用Redisson

redis與memcache差別

  1. 存儲(chǔ)方式
    memcache 將數(shù)據(jù)全部放在內(nèi)存中,斷電后會(huì)掛掉,無法做到數(shù)據(jù)的持久化。
    Redis采用RDB 與 AOF結(jié)合的形式可以做到數(shù)據(jù)的持久化。
  2. 數(shù)據(jù)支持類型
    Memcache對數(shù)據(jù)類型支持相對簡單,只支持String類型的數(shù)據(jù)結(jié)構(gòu)
    Redis支持多種數(shù)據(jù)結(jié)構(gòu),包括String,List,Hash,Set,Zset
  3. Redis的存儲(chǔ)大小遠(yuǎn)大于Memcache

緩存數(shù)據(jù)一致性

先更新數(shù)據(jù)庫再刪除緩存
在此基礎(chǔ)上可以設(shè)置緩存過期時(shí)間,過期了再從數(shù)據(jù)庫中讀取
還可以建立刪除緩存重試機(jī)制。

  1. Redis緩存過期策略
  • 惰性刪除:當(dāng)訪問redis中鍵值對時(shí)會(huì)判斷這個(gè)鍵值對是否過期,如果過期的話就刪除這個(gè)鍵值對
  • 定期刪除:采用expire方法設(shè)置過期刪除時(shí)間,會(huì)對鍵值對進(jìn)行輪詢對過期鍵值對進(jìn)行釋放。

內(nèi)存淘汰機(jī)制

內(nèi)存淘汰機(jī)制.png

Redis基本數(shù)據(jù)類型底層

https://juejin.im/post/6844903863145742350

基本數(shù)據(jù)類型:String/ hash/ list/ set/ sorted set
每一種數(shù)據(jù)類型都有不同的內(nèi)部編碼

String

內(nèi)部編碼

  • int:8個(gè)字節(jié)的長整形
  • embstr:小于等于44個(gè)字節(jié)的字符串(redis3.2版本之前是39字節(jié),之后是44字節(jié))
  • raw:大于44個(gè)字節(jié)的字符串

底層結(jié)構(gòu) SDS簡單動(dòng)態(tài)字符串
有三個(gè)變量記錄著已經(jīng)使用字節(jié)的數(shù)量,剩余未使用的數(shù)量,字符數(shù)組

struct sdshdr{
     //記錄buf數(shù)組中已使用字節(jié)的數(shù)量
     //等于 SDS 保存字符串的長度
     int len;
     //記錄 buf 數(shù)組中未使用字節(jié)的數(shù)量
     int free;
     //字節(jié)數(shù)組,用于保存字符串
     char buf[];
}
image.png

raw類型和embstr類型對比

embstr編碼的結(jié)構(gòu):


image.png

raw編碼的結(jié)構(gòu):


image.png

embstr和raw都是由redisObject和sds組成的。不同的是:embstr的redisObject和sds是連續(xù)的,只需要使用malloc分配一次內(nèi)存;而raw需要為redisObject和sds分別分配內(nèi)存,即需要分配兩次內(nèi)存。

所有相比較而言,embstr少分配一次內(nèi)存,更方便。但embstr也有明顯的缺點(diǎn):如要增加長度,redisObject和sds都需要重新分配內(nèi)存。

list

內(nèi)部編碼

  • ziplist:當(dāng)元素個(gè)數(shù)小于默認(rèn)設(shè)置的512個(gè)并且每一個(gè)元素的大小都小于64字節(jié) 會(huì)使用一塊連續(xù)的內(nèi)存存儲(chǔ)
  • linkedlist
  • quicklist(redis 3.2實(shí)現(xiàn)) 當(dāng)數(shù)據(jù)量多的時(shí)候會(huì)改成quicklist存儲(chǔ),結(jié)合了ziplist和linkedlist功能,將多個(gè)ziplist使用雙向指針串起來使用。

ziplist結(jié)構(gòu)
在較少的情況下,會(huì)使用一塊連續(xù)的內(nèi)存存儲(chǔ),所有元素彼此緊挨著一塊存儲(chǔ),這個(gè)結(jié)構(gòu)是 ziplist(壓縮列表)。在ziplist中有對應(yīng)的字段表示ziplist的信息。比如ziplist的個(gè)數(shù),最后一個(gè)值的位置。

ziplist結(jié)構(gòu).png

quicklist結(jié)構(gòu)
將多個(gè)ziplist使用雙向鏈表進(jìn)行連接。

quicklist結(jié)構(gòu).png

hash

內(nèi)部編碼

  • ziplist:當(dāng)元素個(gè)數(shù)小于默認(rèn)設(shè)置的512個(gè)并且每一個(gè)元素的大小都小于64字節(jié)
  • 字典dict(也稱為hashtable)

redis中的dict 結(jié)構(gòu)內(nèi)部包含兩個(gè) hashtable,通常情況下只有一個(gè) hashtable 是有值的。但是在 dict 擴(kuò)容縮容時(shí),需要分配新的 hashtable,然后進(jìn)行漸進(jìn)式搬遷,這時(shí)兩個(gè) hashtable 存儲(chǔ)的分別是舊的 hashtable 和新的 hashtable。待搬遷結(jié)束后,舊的 hashtable 被刪除,新的 hashtable 取而代之。

set

  • intset:當(dāng)集合中的元素都為整數(shù)且元素個(gè)數(shù)小于512個(gè)時(shí)
  • hashtable

inset結(jié)構(gòu)

typedef struct intset {
    // 編碼方式
    uint32_t encoding;
    // 集合包含的元素?cái)?shù)量
    uint32_t length;
    // 保存元素的數(shù)組
    int8_t contents[];
} intset;

Sorted set

  • ziplist:元素?cái)?shù)量比較少的時(shí)候使用(元素?cái)?shù)量小于128個(gè),長度小于64個(gè)字節(jié))
  • skiplist

skiplist

skiplist結(jié)構(gòu).png

skiplist 跳躍表 查找、插入、刪除的時(shí)間復(fù)雜度與紅黑樹相似都為O(logN)
Skip List主要思想是將鏈表與二分查找相結(jié)合,它維護(hù)了一個(gè)多層級(jí)的鏈表結(jié)構(gòu)
(1) 由很多層結(jié)構(gòu)組成
(2) 每一層都是一個(gè)有序的鏈表
(3) 最底層(Level 1)的鏈表包含所有元素
(4) 如果一個(gè)元素出現(xiàn)在 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會(huì)出現(xiàn)。
(5) 每個(gè)節(jié)點(diǎn)包含兩個(gè)指針,一個(gè)指向同一鏈表中的下一個(gè)元素,一個(gè)指向下面一層的元素。

查找一個(gè)節(jié)點(diǎn)的過程如下:

  • 從頂層鏈表的頭部開始進(jìn)行遍歷,比較每一個(gè)節(jié)點(diǎn)的元素與目標(biāo)元素的大小。
  • 如果當(dāng)前元素小于目標(biāo)元素,則繼續(xù)遍歷。
  • 如果當(dāng)前元素等于目標(biāo)元素,返回該節(jié)點(diǎn)。
  • 如果當(dāng)前元素大于目標(biāo)元素,移動(dòng)到前一個(gè)節(jié)點(diǎn)(必須小于等于目標(biāo)元素),然后跳躍到下一層繼續(xù)遍歷。
  • 如果遍歷至鏈表尾部,跳躍到下一層繼續(xù)遍歷。

插入一個(gè)節(jié)點(diǎn):先確定該元素要占據(jù)的層數(shù) K,然后在接下來的每一層都插入該節(jié)點(diǎn)。
就插入一個(gè)節(jié)點(diǎn)是一個(gè)概率性的事件,該元素需要占據(jù)的層數(shù)完全是隨機(jī)性的概率事件。

對于刪除一個(gè)節(jié)點(diǎn),需要先找到節(jié)點(diǎn)所在的位置(位于最底層鏈表中的位置),之后再自底向上地刪除該節(jié)點(diǎn)在每一行中的冗余復(fù)制。

為什么不使用紅黑樹而使用skiplist?
因?yàn)閞edis是單線程的,選用跳躍表的原因僅僅是因?yàn)樘S表的實(shí)現(xiàn)相較于紅黑樹更加簡潔。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容