日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

BitCask 持久化hash存储引擎 原理介绍

發(fā)布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BitCask 持久化hash存储引擎 原理介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 前言
    • 引擎背景
    • 引擎原理
      • 1. 磁盤數(shù)據(jù)結(jié)構(gòu)
      • 2. 內(nèi)存數(shù)據(jù)結(jié)構(gòu)
      • 3. 讀流程
      • 4. 數(shù)據(jù)合并
    • 總結(jié)

前言

最近工作中部分項(xiàng)目中,對存儲引擎的需求希望高性能的寫、點(diǎn)查,并不需要Range。這里看到大家總會提到BitCask這個存儲引擎方案,并不是很了解,特此做一個總體的學(xué)習(xí)記錄。

引擎背景

BitCask 是分布式數(shù)據(jù)庫Riak有存儲引擎上的一些需求,但是當(dāng)時(2010年左右)業(yè)界并沒有一個能夠滿足需求的引擎,包括但不限于Berkeley DB, Tokyo Cabinet, Innostore等。所以BitCask便應(yīng)運(yùn)而生,主要為了解決以下一些需求:

  • 讀/寫 的低延時
  • 隨機(jī)寫場景下的高吞吐
  • 支持?jǐn)?shù)據(jù)量遠(yuǎn)大于內(nèi)存的持久化存儲
  • 異常恢復(fù)機(jī)制,能夠快速recovery且不丟數(shù)據(jù)
  • 便捷得數(shù)據(jù)備份機(jī)制
  • 支持易理解的數(shù)據(jù)結(jié)構(gòu)
  • 大并發(fā)/大數(shù)據(jù)量下的引擎穩(wěn)定性保障
  • 支持平滑遷移到Riak

除了最后一條定制化需求之外,對于今天我們的存儲引擎來說其實(shí)都是一些最基本的需求,因?yàn)闆]有強(qiáng)Range性能需求,所以這一些基本要求也是可以理解的,無非就是引擎的穩(wěn)定性和性能。然而,當(dāng)時業(yè)界并沒有這樣的一個存儲引擎,所以Riak的開發(fā)者們也就只能擼起袖子自己搞了。google的bigtable中提出的LSM-tree對讀性能并不友好,所以也不滿足。

因?yàn)闆]有Range,他們便從hash數(shù)據(jù)結(jié)構(gòu)入手來提供O(1)的點(diǎn)查,由借鑒了Log-Structure Merged 數(shù)據(jù)結(jié)構(gòu)中的log-merging思想,來提供強(qiáng)大的寫入性能。

引擎原理

1. 磁盤數(shù)據(jù)結(jié)構(gòu)

BitCask磁盤數(shù)據(jù)結(jié)構(gòu)非常簡單,一個BitCask實(shí)例就是一個文件系統(tǒng)目錄。需要保證同一時刻只有一個進(jìn)程會訪問這個目錄,進(jìn)程寫入的數(shù)據(jù)更新僅僅會落在一個Active data file中,當(dāng)這個文件達(dá)到了一個給定的閾值,會創(chuàng)建一個新的active data file,而之前的接受寫入的文件會被標(biāo)記為只讀。

進(jìn)程寫入key/value到active data file的過程時追加寫方式,也就是類似于一個文件writer,這個過程會轉(zhuǎn)化成磁盤上的順序?qū)?#xff0c;所以寫入性能肯定會很高。

每一個磁盤上的entry數(shù)據(jù)格式如下:

  • crc : 當(dāng)前entry的數(shù)據(jù)校驗(yàn)

  • tstamp: 時間戳

  • ksz: key size

  • value_sz : value size

  • key : key的內(nèi)容

  • value : value的內(nèi)容

如果想要刪除數(shù)據(jù),也是寫入一個deletion的 tombstone標(biāo)記,后續(xù)的log-merging會清理。

所以,每一個磁盤上的datafile 中的entry最后都追加成這樣的形態(tài):

2. 內(nèi)存數(shù)據(jù)結(jié)構(gòu)

之前說了,bitcask保證低延時的情況下也是為了提升讀寫吞吐的,他們?yōu)榱俗屪x性能遠(yuǎn)超LSM-tree的這樣的數(shù)據(jù)結(jié)構(gòu),采用了hash表作為內(nèi)存索引數(shù)據(jù)結(jié)構(gòu)。

內(nèi)存數(shù)據(jù)結(jié)構(gòu)叫做keydir,形態(tài)如下:

這個hash表映射的key都是定長的,這個key在hash表中的’value’ 存儲了幾個字段:

  • file_id : 這個key所屬的datafile id
  • value_sz : value size
  • value_pos: value在 data file中的偏移地址
  • tstamp: 時間戳

這個內(nèi)存數(shù)據(jù)結(jié)構(gòu)僅僅保存最新的key-value數(shù)據(jù)信息,同一個key的舊數(shù)據(jù)還會存儲在舊的data file中,在后續(xù)的log-merging過中會被清理。

3. 讀流程

如下圖:

總共分為四步:

  1. 從內(nèi)存的hash表中找到之前寫入的key,取出這個key數(shù)據(jù)所在的file_id
  2. 拿著file-id找到對應(yīng)的data file
  3. 根據(jù)value_pos 找到datafile上的指定entry
  4. 從entry的末尾向前讀取value_sz 的數(shù)據(jù),即為key的value數(shù)據(jù)

現(xiàn)在,從Get的流程中我們很明顯的能夠看到bitcask 設(shè)計(jì)上存在的一些問題:

  1. 內(nèi)存索引 中hash表中存放的是所有寫入的key,也就是一個機(jī)器能夠存放的總數(shù)據(jù)量是有限的
  2. 因?yàn)闆]有持久化索引,所以機(jī)器異常恢復(fù)的時候需要遍歷磁盤上所有的data file,來構(gòu)建內(nèi)存hash索引
  3. 沒有讀緩存,即讀的過程中value都需要從磁盤加載,這里bitcask的開發(fā)者說是考慮到成本太高,也就沒有做了。。。那個時候的內(nèi)存應(yīng)該還挺貴的,記得10年的能買得起的筆記本電腦內(nèi)存應(yīng)該還處于2G以下,那個時候筆記本架構(gòu)普遍在大幾千:)

但是這個并不影響bitcask在當(dāng)時的性能優(yōu)勢,第一個數(shù)據(jù)量問題其實(shí)能夠達(dá)到超過內(nèi)存10倍的持久化存儲能力就滿足 Riak的需求了這里他們也沒有再多說。第二個問題則就是時間上的問題,或者可以多線程recovery來重放,他們也能接受。。。

4. 數(shù)據(jù)合并

之前說了,為了提升寫吞吐,bitcask采用了追加寫方式,包括刪除操作也是一個追加的過程。因?yàn)槭亲芳訉?#xff0c;也就有了GC來清理過期數(shù)據(jù)。

數(shù)據(jù)合并的過程大體如下,也很簡單:

就是根據(jù)內(nèi)存中的lastest hash表中的key數(shù)據(jù),遍歷所有older data files,只保留最新版本的key數(shù)據(jù),將entry寫入到一個新的merged data file中。因?yàn)檫@個文件可能會很大,所以會生成一個hint file來索引這個merged data file的內(nèi)容。當(dāng)然,hint file中的每一個entry也是對應(yīng)merged data file中的每一個entry,只是并沒有存儲value,而是存儲了value的偏移地址來加速讀取。

這個merged data file和hint file 除了能夠清理過期數(shù)據(jù),釋放空間之外還能夠在機(jī)器異常恢復(fù)之后加速內(nèi)存中hash 索引的重建(畢竟都是lastest version,也就不需要再重新遍歷所有的數(shù)據(jù)了)

總結(jié)

總的來說,bitcask就是一個簡單的持久化hash引擎。隨著硬件的飛速發(fā)展,DRAM的價格越來越便宜,磁盤的性能不斷飆升,且價格也在不斷降低。到現(xiàn)在,甚至操作系統(tǒng)的I/O棧和網(wǎng)絡(luò)協(xié)議棧都因?yàn)橛布臉O致性能而成為瓶頸,而bitcask在那個時候構(gòu)建在文件系統(tǒng)之上的持久化層相比于現(xiàn)在已經(jīng)遠(yuǎn)遠(yuǎn)達(dá)不到性能要求了。

現(xiàn)在來看,內(nèi)存數(shù)據(jù)結(jié)構(gòu)不會有太大的變化,還是hash表。但底層只能基于新硬件來構(gòu)建引擎,并且引擎層跳過操作系統(tǒng)I/O棧自己來管理硬件,在此基礎(chǔ)上的hash引擎在當(dāng)代才能夠被稱為高性能的hash引擎。

當(dāng)然,還需要有類似rocksdb開發(fā)者們的卓越編碼能力以及對操作系統(tǒng)細(xì)節(jié)的深刻理解和應(yīng)用才能讓引擎的性能在當(dāng)下的硬件上發(fā)揮到極致。

總結(jié)

以上是生活随笔為你收集整理的BitCask 持久化hash存储引擎 原理介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。