redis篇(一):redis基本數(shù)據(jù)結(jié)構(gòu)

redis

后續(xù)源碼文件名稱統(tǒng)一通過()表示,redis底層是C語言,因此.h、.c文件可認(rèn)為是源碼文件

源碼版本 redis-6.0.5

redis全稱:REmote DIctionary Service 譯為遠(yuǎn)程字典服務(wù)

每個KV鍵值對都存儲在dictEntry(dict.h)里面,redis底層是哈希表(hashTable),結(jié)構(gòu)體現(xiàn)在dictEntry是數(shù)組,*next指針維護(hù)鏈表。

dictEntry

key是字符串結(jié)構(gòu),redis采用sds結(jié)構(gòu)(sds.h)存儲,由于底層是C語言編寫,C語言沒有String結(jié)構(gòu)。

image-20200618140600747

sds與char[]的區(qū)別

image-20200618141005606
  1. sds長度存儲在len屬性當(dāng)中,無需再計(jì)算
  2. 內(nèi)存分配不足導(dǎo)致溢出,sds會提前檢查空間剩余量并進(jìn)行分配
  3. 減少內(nèi)存分配次數(shù),sds修改后len變?yōu)?0字節(jié),而buf數(shù)組實(shí)際長度為21,10字節(jié)空余,1字節(jié)用于存儲空字符串
  4. 二進(jìn)制安全問題:C語言通過空字符串識別結(jié)束,像視頻、圖片、音頻等中間內(nèi)容包括了空字符,會導(dǎo)致解析失敗

value存儲在redisObject當(dāng)中(server.h)

image-20200618134749915

對象類型可以根據(jù)命令:type key查看

基本數(shù)據(jù)結(jié)構(gòu)

String

基本介紹

字符串類型的內(nèi)部編碼(對應(yīng)redisObject中encoding存儲的值)

可通過命令object encoding key查詢編碼

  1. int:(8字節(jié) 64位)
  2. embstr:sds的一種格式,存儲小于44字節(jié)的字符串 ,redisObject和sds連續(xù)分配,修改時需要重新全部分配,因此設(shè)置為只讀
  3. raw:存儲大于44字節(jié)的字符串,redisObject和sds分別分配。

embstr以及raw的臨界值可通過配置#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44實(shí)現(xiàn)(object.h)超過范圍則自動轉(zhuǎn)換類型,修改數(shù)據(jù)會轉(zhuǎn)換成raw類型,大內(nèi)存編碼無法退化為小內(nèi)存編碼。

應(yīng)用場景

  1. 熱點(diǎn)內(nèi)容緩存
  2. 分布式session
  3. 分布式鎖:setnx
  4. 全局id:incrby 項(xiàng)目上應(yīng)用:全局msgId
  5. 原子性操作可應(yīng)用的場景:限流、計(jì)數(shù)

Hash

value只能是字符串類型

基本介紹

  1. 優(yōu)點(diǎn):減少內(nèi)存空間、減少key沖突、批量獲取減少IO
  2. 缺點(diǎn):field無法單獨(dú)設(shè)置過期時間、無bit操作、數(shù)據(jù)量分布問題(都分布在key所在節(jié)點(diǎn))
  3. 基本操作指令:hset、hmset、hscan
image-20200609133918596

實(shí)現(xiàn)原理:(底層由兩種數(shù)據(jù)結(jié)構(gòu)組成)

hash的底層由兩種結(jié)構(gòu)組成:ziplist和hashtable

  1. ziplist壓縮列表(ziplist.c):

    image-20200618174939538
    image-20200618175323429

    通過當(dāng)前節(jié)點(diǎn)的長度和上一個節(jié)點(diǎn)的長度計(jì)算出上一個節(jié)點(diǎn)的地址

    使用場景:hash鍵值都小于64byte、鍵值對數(shù)量小于512個

    可通過redis.conf配置轉(zhuǎn)成哈希表的臨界值:hash-max-ziplist-value、hash-max-ziplist-entries

    當(dāng)超過這兩個閾值的時候轉(zhuǎn)換為hashtable(哈希表)

    編碼格式:根據(jù)字節(jié)區(qū)分

    image-20200618175446701
  2. hashtable哈希表(dict.h):redis底層哈希表可參照此結(jié)構(gòu)

    image-20200609155406544
    image-20200618175859237
    image-20200618180044562

    根據(jù)負(fù)載因子就是鏈表的長度(dict_force_resize_ratio=5),若大于,則觸發(fā)rehash,擴(kuò)容大小為當(dāng)前庫大小*2

    rehash過程: redis-rehash過程是采用漸進(jìn)式rehash即分多次、漸進(jìn)式完成的

    1. 擴(kuò)容大小h[1]為h[0]使用的數(shù)量*2,講rehashidex索引計(jì)數(shù)器置0,開始rehash
    2. 程序進(jìn)行crud的過程中外,還遷移rehashidex上的節(jié)點(diǎn),重新計(jì)算hash值,遷移h[0]節(jié)點(diǎn)到h[1]當(dāng)中,rehashidx+1
    3. rud操作(即除了新增操作)會兩個哈希表同時操作,新增操作只操作h[1]表,保證h[0]中的數(shù)據(jù)只減不增,最后變成空表釋放空間

    應(yīng)用場景

    1. 用戶的任務(wù)進(jìn)度:key-用戶id field:任務(wù)名稱 value:任務(wù)進(jìn)度
    2. 用戶的購物車:key-用戶id field:商品 value:商品數(shù)量

List

左右都可取出數(shù)據(jù)

實(shí)現(xiàn)原理

3.2版本之后采用quicklist來存儲

image-20200618190010964
image-20200609183912407
image-20200609183927880

應(yīng)用場景

  1. 由于list是有序排列,因此可以作為時間線
  2. 消息隊(duì)列:BLPOP/BRPOP指令,阻塞等待,有數(shù)據(jù)才彈出

Set

基本介紹:無序集合(最大存儲40億數(shù)據(jù))

實(shí)現(xiàn)原理:根據(jù)數(shù)據(jù)類型用不同的數(shù)據(jù)結(jié)構(gòu)

  1. 整數(shù)類型:inset存儲
  2. 非整數(shù)類型:hashtable

應(yīng)用場景

  1. 漂流瓶等從集合隨機(jī)抽取的活動
  2. 點(diǎn)贊、簽到、喜歡的用戶等:key-like+uid value-對象id
  3. 商品標(biāo)簽:通過交集并集

Zset

基本介紹:有序集合

實(shí)現(xiàn)原理:源碼結(jié)構(gòu)(server.h)

zskiplistNode
image-20200618190932407
  1. 元素?cái)?shù)量小于128,長度小于64字節(jié)用ziplist
  2. 超過閾值后,用skiplist+dict存儲(跳躍表):跳躍表就是維護(hù)了多層數(shù)據(jù),根據(jù)當(dāng)前層判斷是否需要到下層查找

應(yīng)用場景:key score field

  1. score為時間戳,可以統(tǒng)計(jì)指定時間段內(nèi)的數(shù)據(jù)
  2. zrevrange:獲取排名

Bitmaps

基本介紹:位運(yùn)算,8位2進(jìn)制組成

常用指令:bitcount k1 統(tǒng)計(jì)二進(jìn)制位中1的個數(shù)

應(yīng)用場景

  1. 用戶訪問統(tǒng)計(jì):位運(yùn)算
  2. 在線用戶統(tǒng)計(jì):維護(hù)串很長的二進(jìn)制,用戶根據(jù)id,在線就修改指定位置為1,統(tǒng)計(jì)可通過bitcount

Hyperloglogs

基本介紹:位運(yùn)算,8位2進(jìn)制組成

基本原理:與布隆過濾器有類似作用

應(yīng)用場景:海量數(shù)據(jù)統(tǒng)計(jì)問題

Streams

基本介紹:原理類似kafka

應(yīng)用場景:可實(shí)現(xiàn)發(fā)布訂閱功能

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

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