本節主要記錄SSTable的結構 爲下一步代碼閱讀打好基礎,考慮到已經有大量優秀博客解析透徹 就再也不編寫了 算法
這裏推薦 https://blog.csdn.net/tankles/article/details/7663905app
SSTable是Bigtable中相當重要的一塊,對於LevelDB來講也是如此,對LevelDB的SSTable實現細節的瞭解也有助於瞭解Bigtable中一些實現細節。
本節內容主要講述SSTable的靜態佈局結構,SSTable文件造成了不一樣Level的層級結構,至於這個層級結構是如何造成的咱們放在後面Compaction一節細說。本節主要介紹SSTable某個文件的物理佈局和邏輯佈局結構,這對了解LevelDB的運行過程頗有幫助。
LevelDB不一樣層級都有一個或多個SSTable文件(之後綴.sst爲特徵),全部.sst文件內部佈局都是同樣的。上節介紹Log文件是物理分塊的,SSTable也同樣會將文件劃分爲固定大小的物理存儲塊Block,可是二者邏輯佈局大不相同,根本緣由是:Log文件中的記錄是Key無序的,即前後記錄的key大小沒有明確大小關係,而.sst文件內部則是根據記錄的Key由小到大排列的,從下面介紹的SSTable佈局能夠體會到Key有序是爲什麼如此設計.sst文件結構的關鍵。
佈局
圖1 .sst文件的分塊結構
圖1展現了一個.sst文件的物理劃分結構,同Log文件同樣,也是劃分爲固定大小的存儲塊,每一個Block分爲三個部分,包括Block、Type和CRC。Block爲數據存儲區,Type區用於標識Block中數據是否採用了數據壓縮算法(Snappy壓縮或者無壓縮兩種),CRC部分則是Block數據校驗碼,用於判別數據是否在生成和傳輸中出錯。
以上是.sst的物理佈局,下面介紹.sst文件的邏輯佈局,所謂邏輯佈局,就是說盡管你們都是物理塊,可是每一塊存儲什麼內容,內部又有什麼結構等。圖2展現了.sst文件的內部邏輯解釋。
.net
圖2 邏輯佈局
從圖2能夠看出,從大的方面,能夠將.sst文件劃分爲數據存儲區和數據管理區,數據存儲區存放實際的Key:Value數據,數據管理區則提供一些索引指針等管理數據,目的是更快速便捷的查找相應的記錄。兩個區域都是在上述的分塊基礎上的,就是說文件的前面若干塊實際存儲KV數據,後面數據管理區存儲管理數據。管理數據又分爲四種不一樣類型:紫色的Meta Block,紅色的MetaBlock Index和藍色的Index block以及一個文件尾部塊Footer。
LevelDB 1.2版對於Meta Block尚無實際使用,只是保留了一個接口,估計會在後續版本中加入內容,下面咱們看看Index block和文件尾部Footer的內部結構。
設計
圖3 Index block結構
圖3是Index block的內部結構示意圖。再次強調一下,Data Block內的KV記錄是按照Key由小到大排列的,Index block的每條記錄是對某個Data Block創建的索引信息,每條索引信息包含三個內容:Data Block中key上限值(不必定是最大key)、Data Block在.sst文件的偏移和大小,以圖3所示的數據塊i的索引Index i來講:紅色部分的第一個字段記載大於等於數據塊i中最大的Key值的那個Key,第二個字段指出數據塊i在.sst文件中的起始位置,第三個字段指出Data Block i的大小(有時候是有數據壓縮的)。後面兩個字段好理解,是用於定位數據塊在文件中的位置的,第一個字段須要詳細解釋一下,在索引裏保存的這個Key值未必必定是某條記錄的Key,以圖3的例子來講,假設數據塊i 的最小Key=「samecity」,最大Key=「the best」;數據塊i+1的最小Key=「the fox」,最大Key=「zoo」,那麼對於數據塊i的索引Index i來講,其第一個字段記載大於等於數據塊i的最大Key(「the best」),同時要小於數據塊i+1的最小Key(「the fox」),因此例子中Index i的第一個字段是:「the c」,這個是知足要求的;而Index i+1的第一個字段則是「zoo」,即數據塊i+1的最大Key。
文件末尾Footer塊的內部結構見圖4,metaindex_handle指出了metaindex block的起始位置和大小;inex_handle指出了index Block的起始地址和大小;這兩個字段能夠理解爲索引的索引,是爲了正確讀出索引值而設立的,後面跟着一個填充區和魔數(0xdb4775248b80fb57)。
3d
圖4 Footer 指針
上面主要介紹的是數據管理區的內部結構,下面咱們看看數據區的一個Block的數據部份內部是如何佈局的,圖5是其內部佈局示意圖。 blog
圖5 Data Block內部結構
從圖中能夠看出,其內部也分爲兩個部分,前面是一個個KV記錄,其順序是根據Key值由小到大排列的,在Block尾部則是一些「重啓點」(Restart Point),實際上是一些指針,指出Block內容中的一些記錄位置。
「重啓點」是幹什麼的呢?簡單來講就是進行數據壓縮,減小存儲空間。咱們一再強調,Block內容裏的KV記錄是按照Key大小有序的,這樣的話,相鄰的兩條記錄極可能Key部分存在重疊,好比key i=「the car」,Key i+1=「the color」,那麼二者存在重疊部分「the c」,爲了減小Key的存儲量,Key i+1能夠只存儲和上一條Key不一樣的部分「olor」,二者的共同部分從Key i中能夠得到。記錄的Key在Block內容部分就是這麼存儲的,主要目的是減小存儲開銷。「重啓點」的意思是:在這條記錄開始,再也不採起只記載不一樣的Key部分,而是從新記錄全部的Key值,假設Key i+1是一個重啓點,那麼Key裏面會完整存儲「the color」,而不是採用簡略的「olor」方式。可是若是記錄條數比較多,隨機訪問一條記錄,須要從頭開始一直解析才行,這樣也產生很大的開銷,因此設置了多個重啓點,Block尾部就是指出哪些記錄是這些重啓點的。
索引
在Block內容區,每一個KV記錄的內部結構是怎樣的?圖6給出了其詳細結構,每一個記錄包含5個字段:key共享長度,key非共享長度,value長度,key非共享內容,value內容。好比上面的「the car」和「the color」記錄,key共享長度5;key非共享長度是4;而key非共享內容則實際存儲「olor」;value長度及內容分別指出Key:Value中Value的長度和存儲實際的Value值。
上面講的這些就是.sst文件的所有內部奧祕。
原文:https://blog.csdn.net/tankles/article/details/7663905?utm_source=copy