《數(shù)據(jù)密集型應(yīng)用設(shè)計(jì)》閱讀筆記 第三章

注:書本鏈接:GitHub - Vonng/ddia: 《Designing Data-Intensive Application》DDIA中文翻譯
注:譯者文本網(wǎng)站:簡(jiǎn)介 · ddia-cn
注:如有侵權(quán)俩莽,請(qǐng)聯(lián)系刪除

第三章:存儲(chǔ)與檢索

第二章 中幻妓,我們討論了數(shù)據(jù)模型和查詢語(yǔ)言巧号,即程序員將數(shù)據(jù)錄入數(shù)據(jù)庫(kù)的格式,以及再次要回?cái)?shù)據(jù)的機(jī)制混驰。在本章中我們會(huì)從數(shù)據(jù)庫(kù)的視角來(lái)討論同樣的問(wèn)題:數(shù)據(jù)庫(kù)如何存儲(chǔ)我們提供的數(shù)據(jù),以及如何在我們需要時(shí)重新找到數(shù)據(jù)。

針對(duì) 事務(wù)性 負(fù)載優(yōu)化的和針對(duì) 分析性 負(fù)載優(yōu)化的存儲(chǔ)引擎之間存在巨大差異渊季。

注:我覺(jué)得這兩個(gè)概念與OLAP(在線分析處理)、OLTP(在線事務(wù)處理)是一致的审残。

日志結(jié)構(gòu)(log-structured) 的存儲(chǔ)引擎梭域,以及 面向頁(yè)面(page-oriented) 的存儲(chǔ)引擎(例如 B 樹)。

1搅轿、驅(qū)動(dòng)數(shù)據(jù)庫(kù)的數(shù)據(jù)結(jié)構(gòu)

許多數(shù)據(jù)庫(kù)在內(nèi)部使用了 日志(log)病涨,也就是一個(gè) 僅追加(append-only) 的數(shù)據(jù)文件。

(1)散列索引
  • 鍵值數(shù)據(jù)(key-value Data)

  • 散列映射(hash map)散列表(hash table)

  • 段(segment)

  • 壓縮(compaction)

(2)SSTables和LSM樹
  • 排序字符串表(Sorted String Table)

現(xiàn)在我們可以讓我們的存儲(chǔ)引擎以如下方式工作:

  • 有新寫入時(shí)璧坟,將其添加到內(nèi)存中的平衡樹數(shù)據(jù)結(jié)構(gòu)(例如紅黑樹)既穆。這個(gè)內(nèi)存樹有時(shí)被稱為 內(nèi)存表(memtable)

  • 當(dāng) 內(nèi)存表 大于某個(gè)閾值(通常為幾兆字節(jié))時(shí)雀鹃,將其作為 SSTable 文件寫入硬盤幻工。這可以高效地完成,因?yàn)闃湟呀?jīng)維護(hù)了按鍵排序的鍵值對(duì)黎茎。新的 SSTable 文件將成為數(shù)據(jù)庫(kù)中最新的段囊颅。當(dāng)該 SSTable 被寫入硬盤時(shí),新的寫入可以在一個(gè)新的內(nèi)存表實(shí)例上繼續(xù)進(jìn)行。

  • 收到讀取請(qǐng)求時(shí)踢代,首先嘗試在內(nèi)存表中找到對(duì)應(yīng)的鍵盲憎,如果沒(méi)有就在最近的硬盤段中尋找,如果還沒(méi)有就在下一個(gè)較舊的段中繼續(xù)尋找胳挎,以此類推饼疙。

  • 時(shí)不時(shí)地,在后臺(tái)運(yùn)行一個(gè)合并和壓縮過(guò)程慕爬,以合并段文件并將已覆蓋或已刪除的值丟棄掉窑眯。

日志結(jié)構(gòu)合并樹(或 LSM 樹)

基于這種合并和壓縮排序文件原理的存儲(chǔ)引擎通常被稱為 LSM 存儲(chǔ)引擎。

Lucene医窿,是一種全文搜索的索引引擎磅甩,在 Elasticsearch 和 Solr 被使用,它使用類似的方法來(lái)存儲(chǔ)它的關(guān)鍵詞詞典【12,13】留搔。全文索引比鍵值索引復(fù)雜得多更胖,但是基于類似的想法:在搜索查詢中,由一個(gè)給定的單詞隔显,找到提及單詞的所有文檔(網(wǎng)頁(yè)却妨、產(chǎn)品描述等)。這也是通過(guò)鍵值結(jié)構(gòu)實(shí)現(xiàn)的:其中鍵是 單詞(term)括眠,值是所有包含該單詞的文檔的 ID 列表(postings list)彪标。在 Lucene 中,從詞語(yǔ)到記錄列表的這種映射保存在類似于 SSTable 的有序文件中掷豺,并根據(jù)需要在后臺(tái)執(zhí)行合并【14】捞烟。

(3)B樹

我們前面看到的日志結(jié)構(gòu)索引將數(shù)據(jù)庫(kù)分解為可變大小的段,通常是幾兆字節(jié)或更大的大小当船,并且總是按順序?qū)懭攵翁饣O啾戎拢珺 樹將數(shù)據(jù)庫(kù)分解成固定大小的 塊(block)分頁(yè)(page)德频,傳統(tǒng)上大小為 4KB(有時(shí)會(huì)更大)苍息,并且一次只能讀取或?qū)懭胍粋€(gè)頁(yè)面。這種設(shè)計(jì)更接近于底層硬件壹置,因?yàn)橛脖P空間也是按固定大小的塊來(lái)組織的竞思。

  • 分支因子(branching factor)

  • 預(yù)寫式日志(WAL,即 write-ahead log钞护,也稱為 重做日志盖喷,即 redo log)

  • 鎖存器(latches,輕量級(jí)鎖)

(4)比較B樹和LSM樹
  • 寫入放大(write amplification):在數(shù)據(jù)庫(kù)的生命周期中每筆數(shù)據(jù)導(dǎo)致對(duì)硬盤的多次寫入

2难咕、其他索引結(jié)構(gòu)

(1)將值存儲(chǔ)在索引中
  • 堆文件(heap file)

聚集索引(在索引中存儲(chǔ)所有的行數(shù)據(jù))和 非聚集索引(僅在索引中存儲(chǔ)對(duì)數(shù)據(jù)的引用)之間的折衷被稱為 覆蓋索引(covering index)包含列的索引(index with included columns)课梳,其在索引內(nèi)存儲(chǔ)表的一部分列【33】距辆。這允許通過(guò)單獨(dú)使用索引來(lái)處理一些查詢(這種情況下,可以說(shuō)索引 覆蓋(cover) 了查詢)【32】惦界。

(2)多列索引
  • 最常見(jiàn)的多列索引被稱為 連接索引(concatenated index)

注:這個(gè)就是Mysql Innodb中的復(fù)合索引

  • 多維索引(multi-dimensional index) 是一種查詢多個(gè)列的更一般的方法挑格,這對(duì)于地理空間數(shù)據(jù)尤為重要。

  • 空間填充曲線(space-filling curve) 將二維位置轉(zhuǎn)換為單個(gè)數(shù)字沾歪,然后使用常規(guī) B 樹索引。

(3)全文搜索和模糊索引
(4)在內(nèi)存中存儲(chǔ)一切
  • 反緩存(anti-caching):通過(guò)在內(nèi)存不足的情況下將最近最少使用的數(shù)據(jù)從內(nèi)存轉(zhuǎn)移到硬盤雾消,并在將來(lái)再次訪問(wèn)時(shí)將其重新加載到內(nèi)存中灾搏。

注:例如redis的內(nèi)存淘汰策略

  • 非易失性存儲(chǔ)器(non-volatile memory, NVM)

3、事務(wù)處理還是分析立润?

數(shù)據(jù)倉(cāng)庫(kù)(data warehouse)

(1)數(shù)據(jù)倉(cāng)庫(kù)
  • 將數(shù)據(jù)存入倉(cāng)庫(kù)的過(guò)程稱為 “抽取 - 轉(zhuǎn)換 - 加載(ETL)
(2)星型和雪花型:分析的模式

4狂窑、列式存儲(chǔ)

(1)列壓縮
(2)內(nèi)存帶寬和矢量化處理
(3)列式存儲(chǔ)中的排序順序
  • 幾個(gè)不同的排序順序
(4)寫入列式存儲(chǔ)
(5)聚合:數(shù)據(jù)立方體和物化視圖
  • 物化視圖(Materialized View)

本章小結(jié)

在本章中,我們?cè)噲D深入了解數(shù)據(jù)庫(kù)是如何處理存儲(chǔ)和檢索的桑腮。將數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中會(huì)發(fā)生什么泉哈?稍后再次查詢數(shù)據(jù)時(shí)數(shù)據(jù)庫(kù)會(huì)做什么?

在高層次上破讨,我們看到存儲(chǔ)引擎分為兩大類:針對(duì) 事務(wù)處理(OLTP) 優(yōu)化的存儲(chǔ)引擎和針對(duì) 在線分析(OLAP) 優(yōu)化的存儲(chǔ)引擎丛晦。這兩類使用場(chǎng)景的訪問(wèn)模式之間有很大的區(qū)別:

  • OLTP 系統(tǒng)通常面向最終用戶,這意味著系統(tǒng)可能會(huì)收到大量的請(qǐng)求提陶。為了處理負(fù)載烫沙,應(yīng)用程序在每個(gè)查詢中通常只訪問(wèn)少量的記錄。應(yīng)用程序使用某種鍵來(lái)請(qǐng)求記錄隙笆,存儲(chǔ)引擎使用索引來(lái)查找所請(qǐng)求的鍵的數(shù)據(jù)锌蓄。硬盤查找時(shí)間往往是這里的瓶頸。

  • 數(shù)據(jù)倉(cāng)庫(kù)和類似的分析系統(tǒng)會(huì)少見(jiàn)一些撑柔,因?yàn)樗鼈冎饕蓸I(yè)務(wù)分析人員使用瘸爽,而不是最終用戶。它們的查詢量要比 OLTP 系統(tǒng)少得多铅忿,但通常每個(gè)查詢開(kāi)銷高昂剪决,需要在短時(shí)間內(nèi)掃描數(shù)百萬(wàn)條記錄。硬盤帶寬(而不是查找時(shí)間)往往是瓶頸辆沦,列式存儲(chǔ)是針對(duì)這種工作負(fù)載的日益流行的解決方案昼捍。

在 OLTP 這一邊,我們能看到兩派主流的存儲(chǔ)引擎:

  • 日志結(jié)構(gòu)學(xué)派:只允許追加到文件和刪除過(guò)時(shí)的文件肢扯,但不會(huì)更新已經(jīng)寫入的文件妒茬。Bitcask、SSTables蔚晨、LSM 樹乍钻、LevelDB肛循、Cassandra、HBase银择、Lucene 等都屬于這個(gè)類別多糠。

  • 就地更新學(xué)派:將硬盤視為一組可以覆寫的固定大小的頁(yè)面。B 樹是這種理念的典范浩考,用在所有主要的關(guān)系數(shù)據(jù)庫(kù)和許多非關(guān)系型數(shù)據(jù)庫(kù)中夹孔。

日志結(jié)構(gòu)的存儲(chǔ)引擎是相對(duì)較新的技術(shù)。他們的主要想法是析孽,通過(guò)系統(tǒng)性地將隨機(jī)訪問(wèn)寫入轉(zhuǎn)換為硬盤上的順序?qū)懭氪钌耍捎谟脖P驅(qū)動(dòng)器和固態(tài)硬盤的性能特點(diǎn),可以實(shí)現(xiàn)更高的寫入吞吐量袜瞬。

關(guān)于 OLTP怜俐,我們最后還介紹了一些更復(fù)雜的索引結(jié)構(gòu),以及針對(duì)所有數(shù)據(jù)都放在內(nèi)存里而優(yōu)化的數(shù)據(jù)庫(kù)邓尤。

然后拍鲤,我們暫時(shí)放下了存儲(chǔ)引擎的內(nèi)部細(xì)節(jié),查看了典型數(shù)據(jù)倉(cāng)庫(kù)的高級(jí)架構(gòu)汞扎,并說(shuō)明了為什么分析工作負(fù)載與 OLTP 差別很大:當(dāng)你的查詢需要在大量行中順序掃描時(shí)季稳,索引的重要性就會(huì)降低很多。相反佩捞,非常緊湊地編碼數(shù)據(jù)變得非常重要绞幌,以最大限度地減少查詢需要從硬盤讀取的數(shù)據(jù)量。我們討論了列式存儲(chǔ)如何幫助實(shí)現(xiàn)這一目標(biāo)一忱。

作為一名應(yīng)用程序開(kāi)發(fā)人員莲蜘,如果你掌握了有關(guān)存儲(chǔ)引擎內(nèi)部的知識(shí),那么你就能更好地了解哪種工具最適合你的特定應(yīng)用程序帘营。當(dāng)你調(diào)整數(shù)據(jù)庫(kù)的優(yōu)化參數(shù)時(shí)票渠,這種理解讓你能夠設(shè)想增減某個(gè)值會(huì)產(chǎn)生怎樣的效果。

盡管本章不能讓你成為一個(gè)特定存儲(chǔ)引擎的調(diào)參專家芬迄,但它至少大概率使你有了足夠的概念與詞匯儲(chǔ)備去讀懂你所選擇的數(shù)據(jù)庫(kù)的文檔问顷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市禀梳,隨后出現(xiàn)的幾起案子杜窄,更是在濱河造成了極大的恐慌,老刑警劉巖算途,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塞耕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嘴瓤,警方通過(guò)查閱死者的電腦和手機(jī)扫外,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門莉钙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人筛谚,你說(shuō)我怎么就攤上這事磁玉。” “怎么了驾讲?”我有些...
    開(kāi)封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵蚊伞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蝎毡,道長(zhǎng)厚柳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任沐兵,我火速辦了婚禮,結(jié)果婚禮上便监,老公的妹妹穿的比我還像新娘扎谎。我一直安慰自己,他們只是感情好烧董,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布毁靶。 她就那樣靜靜地躺著,像睡著了一般逊移。 火紅的嫁衣襯著肌膚如雪预吆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天胳泉,我揣著相機(jī)與錄音拐叉,去河邊找鬼。 笑死扇商,一個(gè)胖子當(dāng)著我的面吹牛凤瘦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播案铺,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蔬芥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了控汉?” 一聲冷哼從身側(cè)響起笔诵,我...
    開(kāi)封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姑子,沒(méi)想到半個(gè)月后乎婿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壁酬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年次酌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恨课。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岳服,死狀恐怖剂公,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吊宋,我是刑警寧澤纲辽,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站璃搜,受9級(jí)特大地震影響拖吼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜这吻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一吊档、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唾糯,春花似錦怠硼、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至舟误,卻和暖如春葡秒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嵌溢。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工凿歼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留改基,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像贺待,于是被迫代替她去往敵國(guó)和親抄沮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壮池,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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