基於LSM-Tree 的分散式元件化 KV 儲存系統 | DB·洞見回顧

語言: CN / TW / HK

隨著雲服務基礎架構以及微服務技術的日益成熟,很多大型系統能夠分解為根據應用 workload 需求的多個子系統,再通過網路互動組裝在一起協同工作。

Nova-LSM,一個將基於LSM-Tree的分散式KV 儲存系統分解為使用RDMA進行通訊的元件的工作。這些元件將儲存與處理分開,使處理元件能夠共享儲存頻寬和空間。處理元件將檔案塊 (SSTable) 分散到任意數量的儲存元件中,並通過一定機制平衡它們之間的負載,在執行時動態構建範圍以並行化壓縮並提高效能。Nova-LSM 具有很好的可伸縮性,在一些場景下效能優於其單機版本(LevelDB 和 RocksDB)幾個數量級。

本期DB·洞見將由騰訊雲資料庫專家工程師唐彥,從前沿學術的角度深度解讀Nova-LSM,重點介紹Nova-LSM的特性、重要設計及帶來的啟發。以下為分享實錄:

直播回放完整版連結:http://www.bilibili.com/video/BV1tS4y1b7tR/

直播回放完整版+文字版搭配,效果更佳

影片內含課件獲取方式哦~

一、LSM-Tree基本概念

1.1 LSM-Tree儲存系統

LSM-Tree全稱為“Log Structured Merge-Tree”,它是一種基於磁碟儲存的資料結構。

在以前,資料庫的索引基本上採用B+樹方式來作為索引結構,在此情況下,隨機寫效能常被別人詬病。LSM-Tree則主打將離散的隨機寫請求轉換成批量的順序寫操作。而無論是在機械硬碟還是在固態硬碟,順序的讀寫效能永遠好於隨機讀寫。因此LSM-Tree作為一種高效的KV儲存結構,被許多業界的成熟系統所應用,比如騰訊雲資料庫TDSQL新敏態引擎也是基於LSM-Tree進行開發。 file

LSM-Tree結構有較多優點:寫效能強大、空間利用率高、較高的可調參特性、併發控制簡單、有完備的修復方案等。 file

1.2 LSM-Tree的歷史

在資料庫更新方面,LSM-Tree與B+樹的區別可以理解為:一個是in-place update,一個是out-place update。

基於B+樹的更新,我們稱之為in-place update。如下圖所示,k1本來的值是v1,隨後我們想在k1寫下新值v4,這時需要找到k1,再把v4寫進去。因此,在B+樹的索引結構裡對資料進行更新或者插入,會引起實時的I/O。在B+樹的場景下,寫效能會受到一定影響,但由於B+樹可以支援較好的檢索效能,因此讀效能會較好。

相比之下,在LSM-Tree結構裡,如果這時對k1進行v4的更新,我們不會馬上把k1改成v4,而是將它轉化成順序寫,把它寫到記憶體裡,追加在(k3,v3)後面,因為順序寫的效能遠比隨機寫高,但這種方式則會犧牲讀效能及導致空間放大。 file

下圖展示的是1996年LSM-Tree最原始的結構。C0代表的是在記憶體裡的狀態,每當有資料寫入,它就會逐漸往下merge。當第i層滿時,它會把底下的葉子精簡,從Ci到Ci+1去往下merge。層數越大則表明資料寫入越早。每一層最初的版本的頭部是B+樹,C0是在記憶體的節點,接受最新的資料更新,C1層到Ck層都存在於磁碟。 file

1.3 LSM-Tree基本結構

目前主流的LSM-Tree基本架構如圖所示。我們會在記憶體中保留memtable結構,用於接受最新的資料更新操作,memtable結構裡的資料查詢則通過跳錶skiplist或者B+樹實現。當memtable達到一定大小時,我們會進行flush操作,停止寫入,再把memtable刷到磁碟上,變成靜態檔案即SSTable。

SSTable L0層與memtable保持一致,從L0層到L1層則會進行歸併排序。排序意味著L1層到Lk層都處於有順序的狀態,因此在每一層往下沉時,內部的資料會在物理上保持有序。每個資料再往下沉時,會進一步根據不同的key range來轉化成一個個互相不重疊的SSTable。 file

1.4 LSM-Tree在RocksDB中的實現

下圖展示的是基於LSM-Tree資料結構進行二次開發的RocksDB。當遇到寫請求時,RocksDB會先寫一個log,即Write-Ahead Log (WAL)日誌。當memtable還沒有刷到磁碟上時,如果機器發生故障,Write-Ahead Log (WAL)日誌則可以用於故障恢復。這是非常重要的功能。對TDSQL等金融應用場景資料庫而言,可靠性永遠排在第一位,寫日誌必須成功,才能把最新的資料插入到記憶體(memtable)裡。 file

memtable還有閾值控制機制。在實際的生產環境中,一般將閾值設定為1G,到1G後則會凍結成immutable memtable。當活躍的memtable被凍結成 immutable memtable後,原來的memtable則可以清空記憶體,重新接受資料的寫入。immutable memtable則不會再接受寫入,會準備被flush到磁碟上。

隨著越來越多的immutable memtable被flush到L0層,L0層的檔案個數會逐漸達到一個閾值,這時會觸發系統的compaction。由於L0層的SST檔案之間呈現的是無序的狀態,它們包含的key範圍有可能重疊,這時需要把L0層的檔案從磁碟上重新讀取並進行歸類排序,進而往下生成L1層的檔案。從L1層到Ln層(生產環境中一般配置成7層),所有的檔案的 key range 已經互不重疊,且按照 key 的順序進行排放。

當我們要讀取一個比較舊的資料,如果該資料不在記憶體也不在L0層時,我們會從L1層到Ln層去讀取該SST檔案。因為SST檔案數量較多,在實際中我們會採用bloom filter來加快讀取。

1.5 LSM-Tree查詢

基於LSM-Tree的查詢可分為點查與範圍查詢兩大類,對應的執行方式如下:

●點查:從上往下進行查詢,先查memtable,再到L0層、L1層。因為上層的資料永遠比下層版本新,所以在第一次發生匹配後就會停止查詢。

●範圍查詢:每一層都會找到一個匹配資料項的範圍,再將該範圍進行多路歸併,歸併過程中同一key只會保留最新版本。 file

1.6 LSM-Tree之空間/讀/寫放大

LSM-Tree效能的衡量主要考慮三個因素:空間放大、讀放大和寫放大。

一是空間放大。LSM-Tree的所有寫操作都是順序追加寫,對資料的更新並不會立即反映到資料既有的值裡,而是通過分配新的空間來儲存新的值,即out-place update。因此冗餘的資料或資料的多版本,仍會在LSM-Tree系統裡存在一定時間。這種實際的佔用空間大於資料本身的現象我們稱之為空間放大。因為空間有限,為了減少空間放大,LSM-Tree會從L1往L2、L3、L4不斷做compaction,以此來清理過期的資料以及不同資料的舊版本,從而將空間釋放出來。

二是讀放大。假設資料本身的大小為1k,由於儲存結構的設計,它所讀到的值會觸發多次IO操作,一次IO意味著一條讀請求,這時它所讀取到的則是在後端所需要做大的磁碟讀的實際量,已經遠大於目標資料本身的大小,從而影響到了讀效能。這種現象我們稱之為讀放大。為了減輕讀放大,LSM-Tree採用布隆過濾器來避免讀取不包括查詢鍵值的SST檔案。

三是寫放大。在每層進行compaction時,我們會對多個SST檔案進行反覆讀取再進行歸併排序,在刪掉資料的舊版本後,再寫入新的SST檔案。從效果上看,每條key在儲存系統裡可能會被多次寫入,相當於一條key在每層都會寫入一次,由此帶來的IO效能損失即寫放大。 file

LSM-Tree最初的理念是用空間放大和讀放大來換取寫放大的降低,從而實現較好的寫效能,但也需要做好三者的平衡。以下是兩種假設的極端情況。

第一種極端情況是:如果完全不做compaction,LSM-Tree基本等同於log檔案,當memtable不斷刷下來時,由於不做compaction,只做L0層的檔案,這時如果要讀一條key,讀效能會非常差。因為如果在memtable裡找不到該條key,就要去掃描所有的SST檔案,但與此同時寫放大現象也將不存在。

第二種極端情況是:如果compaction操作做到極致,實現所有資料全域性有序,此時讀效能最優。因為只需要讀一個檔案且該檔案處於有序狀態,在讀取時可以很快找到對應的key。但要達到這種效果,需要做非常多的compaction操作,要不斷地把需要刪的SST檔案讀取合併再來寫入,這會導致非常嚴重的寫放大。 file

二、Nova-LSM的簡介與特性

2.1 Nova-LSM架構設計一覽

Nova-LSM是基於LSM-Tree結構的架構體系,其主要元件包括三部分:

第一部分是寫日誌的元件,將WAL寫成功後再往LSM-Tree的memtable中查詢新的資料。

第二部分是本身處理LSM-Tree寫入的執行緒,其縮寫為LTC(LSM-Tree Component),代表著將該執行緒單獨元件化。

第三部分則是底層的儲存,負責把接收到的上層LTC元件下發下來,並提供標準的檔案介面。 file

Nova-LSM是一個存算分離的架構。上面處理LSM-Tree的是計算節點,它們要寫磁碟時,需要用flush操作將memtable寫到磁碟,compaction時要先從儲存節點讀取上來,接著進行歸併排序並再次寫回,再寫下去時則由底下的分散式儲存節點來進行。

它的架構借用了當下較好的資料庫產品理念。在計算節點和儲存裡,儲存節點會按照彼此的功能去劃分獨立的執行緒池,每個執行緒池的執行緒數可以配置。這相當於在計算節點裡將執行緒的功能分為四種:第一種執行緒與client相關,負責收發客戶請求;第二種執行緒負責RDMA、網路IO的相關操作;第三種執行緒與compaction相關,會不斷掃描當前的SST是否符合compaction及推動compaction的進行;第四種執行緒與Drange相關,負責不斷整理當前Drange的重排、重組織。

該工作的主要亮點之一,是在於把原本LSM-Tree這樣的單機系統明確地劃分出計算層、儲存層,通過一定方式解決了在計算層本來會發生的停寫、緩寫現象。

2.2 Nova-LSM所解決的核心問題

Nova-LSM所解決的核心問題主要有兩個。

第一個核心問題是:基於LSM-Tree結構的儲存系統,例如LevelDB、RocksDB等,都會不可避免地遇到緩寫或者停寫的問題。比如記憶體裡的memtable,在配置時最多可以寫8個,因為寫入多,需要全部flush到磁碟上。與此同時,當前L0層的SST檔案非常多,L0層即將開始做compaction。但compaction會涉及到磁碟IO,在還沒做完時,就會阻塞記憶體中的memtable對L0層SST進行flush的過程。當flush無法進行時,就會發生緩寫,隨著閾值的推進,在實在寫不進時甚至會停寫,這種現象體現在客戶端就是請求掉零。

為了解決LSM-Tree結構儲存系統中的緩寫、停寫問題,該文章提出了兩個解決辦法:

第一種方法是設計了存算分離的架構體系,具體如上圖所示。該架構的重要作用之一,是把處理寫入和處理磁碟IO的兩大主力模組拆分,計算儲存分離,哪個部分慢就為哪個部分增加節點以此來提高該部分的能力,這是比較亮眼的突破。

第二種方法是引入了動態分割槽,即Drange機制。該機制的目的是為了讓業務的寫入壓力,在LTC即計算層的memtable上進行區間劃分,每個range都有自己的memtable,通過區間劃分,從而實現多個range之間進行並行compaction。以L0層為例,我們可以把L0層變成沒有互相重疊的狀態,這時我們就可以對L0層進行並行的compaction,可以加快L0層的檔案的消化,從而減輕對memtable flush到磁碟上的過程的影響。 file

第二個核心問題是:在這種方式下需要劃分很多不同的Drange,每個range都會增加一定的memtable數量,memtable數量的增加會影響scan和get的效能。假設有一個主請求,在原來所有資料都寫在一個memtable裡的情況下,在讀取時,索引只需要面向這個memtable,再根據跳錶進行get,如果get到則可以馬上返回。現在劃分成不同的Drange,memtable數量增加,因此需要查詢的memtable以及L0層的SST也會變多。解決辦法是:實現了一個索引,可以查詢到一個key在memtable或L0 SST中的最新值(若存在)。

2.3 Nova-LSM論文主要成果

這篇文章將原本獨立的單節點儲存系統做成了一個存算分離、可以任意擴充套件的分散式架構。這種存算分離的架構體系,在擴充套件時對總吞吐量、總的響應和請求的能力有顯著提升。下圖是對該效果的具體展示。

左下角採用了最原始的配置,只有1個儲存節點和1個計算節點,計算節點只配置了32M的記憶體,這也意味著memtable相對較少,在這種情況下它的總吞吐量只有9k,相對較低。然後我們從縱軸來看,把計算能力向上擴充套件,通過垂直擴容把記憶體從32M變成4G,這時總吞吐量已經從9k提高到50k。 file

但從圖中也可以看到,這時效能曲線中間有空隙的地方越來越多,這些就是前面所提到的請求掉零。計算能力的加強意味著可以進行更多的寫入,記憶體變大意味著memtable的數量變多,L0層的SST檔案生成速度也會加快。當L0層的生成檔案速度加快後,就會對儲存層compaction的能力造成壓力,因為它在預設配置下只有1個節點。這時雖然它的峰值已經提高到了5k,但請求掉零的情況也更多了,即發生了停寫。因為L0 SST已經來不及compaction,這時只能等待,相當於計算節點在等儲存節點。

為了解決這個問題,我們需要對儲存節點進行擴容,比如將1個儲存節點擴到10個。這時可以明顯看到總吞吐量從5萬提高到了約250萬。雖然某些地方請求也會驟降,穩定性還有待提高,但從整體上看,幾乎已經沒有請求掉零現象出現了。

這也體現了傳統單機單節點LSM-Tree儲存系統與Nova-LSM之間的區別。在傳統單機單節點LSM-Tree儲存系統中,如果計算能力非常好但是磁碟能力不夠,這時很難在單節點上進行擴充套件。但在Nova-LSM中,如果發現哪部分能力不夠就可以進行擴充套件,計算能力不夠就擴計算節點,儲存能力不夠則擴儲存節點。這也遵循了當前分散式資料庫裡比較常見的存算分離、計算層和儲存層可以獨立擴容的理念。

三、Nova-LSM若干重要設計

3.1 LTC和StoCs之間的寫資料流程

第一個比較重要的設計是LTC和StoCs之間的寫資料流程。該流程展示的是:當在客戶端發起寫請求時,計算節點和儲存節點是以怎樣的方式將資料寫進去的過程。

首先是計算節點的客戶端發起一個新的寫請求操作。儲存節點在接收到該請求後,基於RDMA互動,它會在buffer區域分配一個記憶體區域,並且為這塊記憶體和偏移量(當前哪塊記憶體可以寫)分配一個id,告知StoC。客戶端接到響應後就會開始寫資料,完成後會通知儲存節點。儲存節點接收到訊號後,將資料持久化並且再告知客戶端。

上述流程是寫一個數據檔案即SSTable。寫完後,我們要以同樣的流程將元資料檔案更新。因為底層是分散式架構,需要知道哪些檔案寫在哪裡以及每個SST的範圍、版本號。 file

3.2 動態區間劃分

第二個比較重要的設計是動態區間劃分。假設業務的請求範圍為0-1萬,當前有10個計算節點,將這10個計算節點的區間劃分為10等份,比如第一個key的空間範圍為0-1000。在負責0-1000的計算節點裡,它會再進行劃分,這一層劃分業務無感知。這就叫動態區間劃分,簡稱Drange。其作用主要有以下幾點:

首先,每個range都是一棵LSM-Tree,按照資料區間,不同的Drange都有自己的memtables。比如0-1000區間又可以劃分為10個Drange,10個Drange之間的memtable相互獨立。這樣做的好處是這些Drange之間的key互不重疊,例如0-100、100-200、200-300。

其次,在Dranges下還有一層Tranges。如果發現Drange裡的部分range比如890-895存在熱點現象,而旁邊的range並非熱點,則可以用Tranges進行細粒度的複雜重均衡,實現動態均衡負載。

最後,在此基礎上,因為Drange的key範圍互不相交,當memtable變成immutable,不可再寫後,它們需要獨立地flush到磁碟上。這時,在L0層的SSTable來自不同的Drange,它們之間的key完全不相交,我們就可以進行並行的compaction。 file

3.3 Compactions

文章還將沒有Drange劃分和有Drange劃分兩種情況進行了對比。

在沒有Drange劃分的情況下,L0的compaction無法很好並行。在這種情況下,如果遇到最壞的情況,L0層的某一個SST有可能覆蓋了整個key空間,假設key範圍為0-600,L0層的SST檔案的範圍是0-1000,當發生compaction時,它必須要跟其他4個SST做歸併,這時不但要把L0層的其他SST全部讀取比較一遍,還要把L1層所有的SST都讀一遍再做歸併排序。這時寫放大會較為嚴重,意味著L0層到L1層的compaction會變慢,flush也會變慢,甚至flush不了時,前端就會出現緩寫、停寫現象。

有Drange劃分後,相當於compaction可以分開區間,如下方的示意圖所示。在0-100區間,L0到L1可以獨立去compaction,100-200區間也可以獨立去compaction,可以較好地實現並行compaction。而在原生的RocksDB裡,只有從L1開始compaction,才能進行並行compaction操作。 file

如果協調者發現當前儲存層的節點資源非常充足,compaction操作可以由儲存層主動發起,不需要計算層去發現當前有哪些可以做compaction,這是這篇文章中提到的另一個想法。

至於考慮下沉的原因,因為文章並未深入展開,個人猜測主要是考慮到在這種架構體系裡,儲存層比較容易擴充套件,而計算層較難擴充套件。因為計算層相當於分庫分表,如果擴充套件則會涉及到一定的路由重分佈,需要告訴前端請求路由的變化。但儲存層則非常容易擴充套件,如果能將這些非常耗時的操作放到儲存層,可以極大地減少在計算節點跟儲存節點之間資料的開銷。儲存層做完後,可以直接把更新後的元資料告訴計算層。

3.4 索引查詢以及Scan操作

因為劃分了很多不同的動態區間,memtable的數量也會增加,意味著查詢操作的耗時也會增加。所以要如何在原來的基礎上維護好讀效能?這篇文章提出了以下解決思路:

每個LTC維護了一個lookup index。如果這些資料存在於memtable和L0層的SST上,通過lookup index我們就可以快速查詢到想要的資料。當某一個L0層SST被compaction到L1層時,索引上就會移除掉對應的key。

LTC同時還維護了一個範圍索引即range index。因為知道每個Drange的範圍,所以當一個scan請求所涉及到的key,都可以在memtable和L0層SST中找到時,該範圍索引就能快速響應scan操作。 file

3.5 SSTable的分佈

最後一個比較重要的設計涉及到儲存層。當某個SST檔案要寫到儲存節點時,分散式系統首先要保證負載均衡,要保證資料避免單點故障不可恢復的場景。

該文章提出根據一定策略,將資料檔案即SST打散寫入到多個儲存節點裡。考慮到儲存成本,每個SSTable採用糾刪碼(Erasure Coding)的方式進行編碼然後分散式存放。預設情況下對每個 SSTable 採用 “3+1”的 EC 配置,將一個SSTable切分為3個數據塊,根據一定演算法,在這3個數據塊裡去計算出一個校驗塊,變成了“3+1”的形式。這種方式比傳統的多副本可以節省更多空間。假設一個SSTable是3M,這種“3+1”的方式最終所佔空間為4M,並且能容忍一個節點的丟失,與佔用6M空間的雙副本方案擁有同樣的故障容忍等級。而元資料檔案因為體積比較小,所以直接採用多副本儲存的方式,比如1個元資料檔案可以寫3個副本。 file

四、Nova-LSM效能效果展示

在本篇論文中,Nova- LSM具有較好的效能資料表現。以自身調參測試為例,資料表明,Nova- LSM可以通過調整不同的引數達到較好的擴充套件效果。文中分別使用Uniform均勻分佈和Zipf分佈來打散資料,存在熱點(比如80%的訪問概率都集中在20%的資料上)的情況下,實驗結果資料表明,在讀寫比例、資料訪問概率不一樣的各種場景下,Nova- LSM都能取得較好的效能結果。

下圖所示為Nova-LSM在自身調參下幾組不同引數的比較: file

下圖展示了Nova-LSM自身擴充套件性的效果: file

下圖所示為Nova-LSM吞吐量擴充套件性測試: file

以上測試是Nova- LSM自身不同引數下的對比。除此之外,該文章還將Nova- LSM與LevelDB以及RocksDB進行效能對比。 file

在小資料場景下,Nova- LSM的效能表現比RocksDB要更優異,特別在Zipf分佈且熱點資料存在、讀寫各佔一半的情況下,測試出來的效能資料要比RocksDB高4倍。但隨著資料量的擴大,在某些workload下 Nova-LSM 的優勢逐漸變得不明顯。比如在上圖中的(d)情況,一個10節點、2T的資料庫,RocksDB將其分為10份,在這種寫較多的場景下,Nova- LSM與原生的RocksDB差距不明顯。

另外,上圖中的藍色資料項RocksDB-tuned,它是RocksDB進行調優後產生的資料項,紅色資料項則沒有經過RocksDB調優,而紅色項卻取得了比藍色項更好的效能資料。

經過較多場景的驗證,像Nova-LSM這種基於LSM-Tree結構的儲存系統,實際上並不存在某一組引數能夠讓它在所有不同性質的workload下都取得較好效能。如上圖(d)組,即中間100%寫、均勻分佈的測試組,RocksDB經過調優後比沒經過調優、用原始引數的對照組的吞吐量更低。因為Nova-LSM本身需要有非常多的調優引數,因此很難存在一套引數在所有的場景裡都為最優。

五、Nova-LSM帶來的啟發和討論

一般情況下,基於LSM-Tree結構去進行優化的工作都面臨以下問題——讀放大、寫放大及空間放大。

如果完全不做compaction,LSM-Tree將會退化為Log檔案,此時讀效能最差,需要掃描所有SSTable檔案,但不存在寫放大。如果通過compaction操作將所有SSTable檔案維持為一個sorted run,即始終保持所有kv資料的全域性有序,則退化為sorted array,此時讀效能最優,查詢時只需讀取一個SSTable中的一個數據塊,但頻繁的compaction操作會導致嚴重的寫放大。所以我們不能走極端,需要在兩者之間提出新的改進方法,在讀放大、寫放大及空間放大之間做好平衡。

Nova-LSM就是在這三個因素之間做取捨,它的設計原理之一是將原本單機單節點的系統用分散式元件化的方式,將原本一份程式碼裡面的不同模組拆分出來,從而令每一個模組具有可擴充套件性,打破原先單機資源的限制。此外,該文章還創新性地提出,將不定期的compaction對磁碟IO造成的短期衝擊剝離出去。 file

與此同時,該篇文章在實驗驗證及工程實踐上仍有許多地方需要完善和優化。

第一,實驗使用的每個KV的預設大小是1KB。根據原理判斷,Drange這種設計在該場景下比較佔優勢。在具體實現中,當一個memtable包含的unique key 小於一定閾值時,不同的Drange之間會將memtable進行合併,其目的都是為了減少磁碟的寫入。因此使用1KB這種不算小的測試資料,對它而言是佔據優勢的。而其他原生的RocksDB則需要不斷地寫磁碟,由於每一條key的體積都不小,1000條可達到1兆,100萬條就能達到1G,這時Drange機制所帶來的減少磁碟寫入的優勢就會被放大了。

第二,Drange和Tranges機制的設立,可以保證一個計算節點在不同的memtable寫入之間存在動態均衡。從工業界落地的角度出發,這會涉及到較多的資料一致性保證。但文章並沒有進一步論述資料的移動是否會造成沒寫或者雙寫。

第三,工程實踐上仍存在不少流程細節有待深入推敲,比如在LTC和StoC的寫入流程互動中,文中提到先更新資料檔案block再更新元資料檔案block的流程,但如果在這兩次寫入中間發生了故障,如何處理?StoC使用erasure code方式保證資料可靠性時,如何保證n+1個數據塊和校驗塊寫入同時成功?故障時如何回滾?單個數據塊發生丟失時如何發現以及重新生成?這些問題都值得我們進行推敲。 file

第四,N個LTC會負責N個區域資料的寫入。比較傳統的基於中介軟體的分散式資料庫,會存在一箇中間件,中介軟體知道其下的儲存節點以及負責寫入的節點分別負責哪一部分資料,此時路由變更的靈活性會存在一定限制。

第五,所有的效能測試中基本只描述效能的最大值。最大值、最大吞吐量這些指標很重要,它代表著一個系統的能力上限。但在真實的業務場景中,除了能力的最大值,另一個非常重要的考察指標是穩定性。而Nova-LSM基於分散式架構,它所有的讀寫資料一直在進行網路互動。compaction本身因為磁碟的IO,給總體效能帶來了不穩定性,現在又加入了網路之間的開銷,網路抖動就更加頻繁,效能的抖動也是我們必須考慮的因素。 file

Nova- LSM並非只有理論,它在LevelDB的原始碼基礎上新增了2萬多行程式碼,實現了一套核心的設計,上圖所示為其原始碼地址,感興趣的同學可以嘗試進行二次開發。

關於講師

唐彥,騰訊雲資料庫專家工程師、浙江大學博士。研究領域主要關注分散式儲存、大規模資料密集型系統相關的關鍵技術,曾以第一作者身份在領域Top類期刊和會議上發表多篇論文。博士畢業後來到騰訊從事基礎研究與技術工程化工作,目前主要負責分散式資料庫 TDSQL 的元資料管理與叢集管控排程相關工作。