淺談Redis一-數(shù)據(jù)結(jié)構(gòu)

Redis“快”的重要表現(xiàn):它接收到一個鍵值對操作后柬焕,能以微秒級別的速度找到數(shù)據(jù)沃饶,并快速完成操作。能夠這么優(yōu)秀的原因一方面石抡,這是因為它是內(nèi)存數(shù)據(jù)庫檐嚣,所有操作都在內(nèi)存上完成,內(nèi)存的訪問速度本身就很快啰扛。另一方面嚎京,這要歸功于它的數(shù)據(jù)結(jié)構(gòu)。

底層數(shù)據(jù)結(jié)構(gòu)一共有 6 種隐解,分別是簡單動態(tài)字符串鞍帝、雙向鏈表、壓縮列表煞茫、哈希表帕涌、跳表和整數(shù)數(shù)組。

數(shù)據(jù)結(jié)構(gòu)對應關系

String 類型的底層實現(xiàn)只有一種數(shù)據(jù)結(jié)構(gòu)续徽,也就是簡單動態(tài)字符串宵膨。而 List、Hash炸宵、Set 和 Sorted Set 這四種數(shù)據(jù)類型辟躏,都有兩種底層實現(xiàn)結(jié)構(gòu)。通常情況下土全,我們會把這四種類型稱為集合類型捎琐,它們的特點是一個鍵對應了一個集合的數(shù)據(jù)。

鍵和值用什么結(jié)構(gòu)組織裹匙?

為了實現(xiàn)從鍵到值的快速訪問瑞凑,Redis 使用了一個哈希表來保存所有鍵值對。

一個哈希表概页,其實就是一個數(shù)組籽御,數(shù)組的每個元素稱為一個哈希桶。所以惰匙,我們常說技掏,一個哈希表是由多個哈希桶組成的,每個哈希桶中保存了鍵值對數(shù)據(jù)项鬼。哈希桶中的元素保存的并不是值本身哑梳,而是指向具體值的指針。

這個哈希表保存了所有的鍵值對绘盟,所以鸠真,我也把它稱為全局哈希表悯仙。

全局哈希

注意: Redis 中寫入大量數(shù)據(jù)后,可能發(fā)現(xiàn)操作有時候會突然變慢了吠卷。哈希表的沖突問題和 rehash 可能帶來的操作阻塞锡垄。

為什么哈希表操作變慢了?

哈希沖突是不可避免的問題祭隔。這里的哈希沖突偎捎,也就是指,兩個 key 的哈希值和哈希桶計算對應關系時序攘,正好落在了同一個哈希桶中茴她。

Redis 解決哈希沖突的方式,就是鏈式哈希程奠。鏈式哈希也很容易理解丈牢,就是指同一個哈希桶中的多個元素用一個鏈表來保存,它們之間依次用指針連接瞄沙。如圖所示

哈希沖突

但是己沛,這樣的話,哈希沖突鏈上的元素只能通過指針逐一查找再操作距境,隨著數(shù)量越來越多申尼,性能將會越來越差,為了解決這個問題垫桂,Redis 會對哈希表做 rehash 操作师幕。

為了使 rehash 操作更高效,Redis 默認使用了兩個全局哈希表:哈希表 1 和哈希表 2诬滩。一開始霹粥,當你剛插入數(shù)據(jù)時,默認使用哈希表 1疼鸟,此時的哈希表 2 并沒有被分配空間后控。隨著數(shù)據(jù)逐步增多,Redis 開始執(zhí)行 rehash空镜,這個過程分為三步:

  • 給哈希表 2 分配更大的空間浩淘,例如是當前哈希表 1 大小的兩倍;

  • 把哈希表 1 中的數(shù)據(jù)重新映射并拷貝到哈希表 2 中吴攒;

  • 釋放哈希表 1 的空間张抄。

但是這個過程設計了大量的數(shù)據(jù)拷貝,如果一次性把哈希表 1 中的數(shù)據(jù)都遷移完舶斧,會造成 Redis 線程阻塞欣鳖。為了避免這個問題,Redis 采用了漸進式 rehash茴厉。主要是將上述第二步的步驟修改為:

  • Redis 仍然正常處理客戶端請求泽台,每處理一個請求時,從哈希表 1 中的第一個索引位置開始矾缓,順帶著將這個索引位置上的所有 entries 拷貝到哈希表 2 中怀酷;等處理下一個請求時,再順帶拷貝哈希表 1 中的下一個索引位置的 entries嗜闻。
rehash

不同操作的復雜度

  • 單元素操作是基礎蜕依;

  • 范圍操作非常耗時;

  • 統(tǒng)計操作通常高效琉雳;

  • 例外情況只有幾個样眠。

第一,單元素操作翠肘,是指每一種集合類型對單個數(shù)據(jù)實現(xiàn)的增刪改查操作檐束。這些操作的復雜度由集合采用的數(shù)據(jù)結(jié)構(gòu)決定,例如束倍,HGET被丧、HSET 和 HDEL 是對哈希表做操作,所以它們的復雜度都是 O(1)绪妹;Set 類型用哈希表作為底層數(shù)據(jù)結(jié)構(gòu)時甥桂,它的 SADD、SREM邮旷、SRANDMEMBER 復雜度也是 O(1)黄选。

第二,范圍操作婶肩,是指集合類型中的遍歷操作糕簿,可以返回集合中的所有數(shù)據(jù),比如 Hash 類型的 HGETALL 和 Set 類型的 SMEMBERS狡孔,或者返回一個范圍內(nèi)的部分數(shù)據(jù)懂诗,比如 List 類型的 LRANGE 和 ZSet 類型的 ZRANGE。這類操作的復雜度一般是 O(N)苗膝,比較耗時殃恒,我們應該盡量避免

第三辱揭,統(tǒng)計操作离唐,是指集合類型對集合中所有元素個數(shù)的記錄,例如 LLEN 和 SCARD问窃。這類操作復雜度只有 O(1)亥鬓,這是因為當集合類型采用壓縮列表、雙向鏈表域庇、整數(shù)數(shù)組這些數(shù)據(jù)結(jié)構(gòu)時嵌戈,這些結(jié)構(gòu)中專門記錄了元素的個數(shù)統(tǒng)計覆积,因此可以高效地完成相關操作。

第四熟呛,例外情況宽档,是指某些數(shù)據(jù)結(jié)構(gòu)的特殊記錄,例如壓縮列表和雙向鏈表都會記錄表頭和表尾的偏移量庵朝。這樣一來吗冤,對于 List 類型的 LPOP、RPOP九府、LPUSH椎瘟、RPUSH 這四個操作來說,它們是在列表的頭尾增刪元素侄旬,這就可以通過偏移量直接定位肺蔚,所以它們的復雜度也只有 O(1),可以實現(xiàn)快速操作勾怒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婆排,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子笔链,更是在濱河造成了極大的恐慌段只,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鉴扫,死亡現(xiàn)場離奇詭異赞枕,居然都是意外死亡,警方通過查閱死者的電腦和手機坪创,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門炕婶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莱预,你說我怎么就攤上這事柠掂。” “怎么了依沮?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵涯贞,是天一觀的道長。 經(jīng)常有香客問我危喉,道長宋渔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任辜限,我火速辦了婚禮皇拣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘薄嫡。我一直安慰自己氧急,他們只是感情好颗胡,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著态蒂,像睡著了一般杭措。 火紅的嫁衣襯著肌膚如雪费什。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音窘拯,去河邊找鬼就乓。 笑死,一個胖子當著我的面吹牛稿黍,可吹牛的內(nèi)容都是我干的疹瘦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼巡球,長吁一口氣:“原來是場噩夢啊……” “哼言沐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酣栈,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤险胰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后矿筝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體起便,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年窖维,在試婚紗的時候發(fā)現(xiàn)自己被綠了榆综。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡铸史,死狀恐怖鼻疮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琳轿,我是刑警寧澤判沟,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站利赋,受9級特大地震影響水评,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜媚送,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一中燥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塘偎,春花似錦疗涉、人聲如沸拿霉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绽淘。三九已至,卻和暖如春闹伪,著一層夾襖步出監(jiān)牢的瞬間沪铭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工偏瓤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杀怠,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓厅克,卻偏偏與公主長得像赔退,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子证舟,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容