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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市第股,隨后出現(xiàn)的幾起案子应民,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瑞妇,死亡現(xiàn)場離奇詭異稿静,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辕狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門改备,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔓倍,你說我怎么就攤上這事悬钳。” “怎么了偶翅?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵默勾,是天一觀的道長。 經(jīng)常有香客問我聚谁,道長母剥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任形导,我火速辦了婚禮环疼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朵耕。我一直安慰自己炫隶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布阎曹。 她就那樣靜靜地躺著伪阶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪处嫌。 梳的紋絲不亂的頭發(fā)上栅贴,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機(jī)與錄音锰霜,去河邊找鬼筹误。 笑死,一個胖子當(dāng)著我的面吹牛癣缅,可吹牛的內(nèi)容都是我干的厨剪。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼友存,長吁一口氣:“原來是場噩夢啊……” “哼祷膳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屡立,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤直晨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勇皇,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罩句,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了敛摘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片门烂。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兄淫,靈堂內(nèi)的尸體忽然破棺而出屯远,到底是詐尸還是另有隱情,我是刑警寧澤捕虽,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布慨丐,位于F島的核電站,受9級特大地震影響泄私,放射性物質(zhì)發(fā)生泄漏房揭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一挖滤、第九天 我趴在偏房一處隱蔽的房頂上張望崩溪。 院中可真熱鬧,春花似錦斩松、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞪讼,卻和暖如春钧椰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背符欠。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工嫡霞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人希柿。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓诊沪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親曾撤。 傳聞我的和親對象是個殘疾皇子端姚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351