Bigtable分析1——讀Bigtable論文

BigTable關鍵詞:可伸縮、結構化數據、PB級、幾千臺服務器。

超過60個Google產品使用BigTable(包括Web Indexing、Google Earth、Google Finance、Google Analytics, Google Finance, Orkut, Personalized Search, Writely, and Google Earth),這些應用的需求不盡相同:

1、 數據大小:從URL到Web頁面到衛星圖象。

2、 延遲:從後臺批處理應用(要求吞吐量大)到實時數據服務(要求數據延遲小)。

3、 集羣規模:從個位數到幾千臺,存儲幾百TB的數據。


1 簡介:(chapter 1 Introduction)


Bigtable實現了幾個目標:

1、廣泛的適應性;2、伸縮性;3、高性能;4、高可用性。

數據模型:

不完全支持關係模型、提供一個簡單的數據模型,允許用戶動態控制數據分佈和格式,允許用戶考慮數據的locality。數據通過row和column name(可以是任意字符串)索引,BigTable不識別數據的格式。通過選擇schema用戶可以控制數據的locality。通過schema parameter用戶可以動態的控制從內存去數據還是從disk取數據。


2 數據模型:(chapter 2 Data Model)


是一個sparse, distributed, persistent multi-dimensional sorted map。數據通過行關鍵字(row key)、列關鍵字(column key)、時間戳(timestamp)定位,BigTable不識別數據格式:

(row:string, column:string, time:int64) -> string


上圖是存儲Web頁面的一個例子:row name是一個反轉URL,column family “contents:”存儲頁面內容,column family “anchor:”存儲指向該頁面的錨文字,列名”anchor:xxx”中的xxx反映了指向包含該頁面連接的頁面URL。數據可以有多個版本,通過時間戳來區別。

行:(Row)

行關鍵字可以是任意字符串,最大支持64KB(實際應用中典型大小是10-100字節)。對行的讀寫是原子的,不管讀寫行中的多少個列,在應用需要併發讀寫一個行時簡化了應用的設計。

行通過行關鍵字的字典序排序,row range稱做tablet,是動態劃分的,是分佈和負載均衡的單位。用戶通過選擇合適的row關鍵字可以實現locality(這裏想表達的意思其實是把相關的數據連續分佈,可以提高讀寫性能)。

列簇:(column family)

列關鍵字可以分組成column family,這是訪問控制的基本單元。列簇中存儲的數據往往是同類型的,我們把列簇中的數據壓縮在一起。我們的設計原意是控制列簇的個數,並且列簇在使用中很少變化,而列的個數則是無限的。

列關鍵字格式如下:family:qualifier,列簇名必須是可打印的,qualifier可以是任意字符串。

訪問控制以及磁盤、內存統計都是基於列簇的。

時間戳:(timestamp)

每個數據項可以有多個版本,通過時間戳區分。時間戳是一個64位整數,代表真實時間(毫秒級),可以由bigtable賦值也可以由應用指定,如果應用指定,需要保證時間戳不要衝突。多個版本的數據按時間戳降序排列,保證能夠優先讀取到最新版本的數據。

可以針對列簇設定GC策略:保留最近n個版本,或最近某段時間的版本。


3 API:(chapter 3 API)


創建刪除table、創建刪除column family、修改集羣/表/列簇的元數據(例如訪問權限)。應用可以寫數據、刪除數據、查找單獨行的數據、或遍歷一組數據。


在”com.cnn.www”行中增加一個anchor,刪除另一個anchor。


遍歷”com.cnn.www”行的所有anchor列。


BigTable支持:

1、 單行事務。

2、 允許數據項用作整數記數器(沒明白什麼意思?)

3、 支持在服務器側運行client提供的腳本(類似存儲過程,通過sawzall語言編寫)。

可以和mapreduce一起使用,做爲mapreduce的輸入或輸出。


4 Building Block(chapter 4)


l GFS:用來存儲log和data file。

l Cluster Management System:用來執行job調度、管理共享機器的資源(BigTable和其他應用進程共享機器)、處理機器故障、監控機器狀態。

l Google SSTable:用來存儲Bigtable數據,SSTable提供一個持久化的、排序的、不變的Key-Value Map(persistent ordered immutable map from keys to values),key和value可以是任意字節串。支持通過key查找value,遍歷一個key的範圍。SSTable內部建立有索引,運行時把索引載入內存,也支持把所有數據載入內存。

l Chubby:分佈式鎖服務。BigTable通過chubby來保證任何時候最多隻有一個activer的master;記錄Table的根目錄;發現tablet服務器的active狀態;存儲元數據信息(每個表的column family信息);存儲ACL(access control list)。如果chubby不可用超過一段時間,則bigtable也就不可用了。根據我們的測試(14個bigtable集羣、基於11個chubby實例),因爲chubby不可用(因爲chubby故障或網絡問題)而導致bigtable不可用的概率爲0.0047%。(The percentage for the single cluster that was most affected by Chubby unavailability was 0.0326%.這句怎麼理解?)


5 實現(chapter 5 Implementation)


實現分爲三個組件:

1、 客戶端庫:連接到Client應用中;

2、 一個Master Server:負責把tablet分配給tablet server,檢測tablet server的加入和退出,平衡tablet server負載,GFS中文件的垃圾回收,處理元數據變化(像表、Column Family的創建)。數據讀寫過程並不經過master server,所以master server的負載通常很輕。

3、 多個Tablet Server:可以根據負載變化動態添加或刪除。管理一組tablet(典型的從10幾個到幾千個),負責對他管理的tablet的讀寫請求,在tablet太大時進行切分。

一個Bigtable集羣存儲一組table,每一張table由一組tablet組成,每個tablet包含一個row range的所有數據。表剛剛創建時,只有一個tablet,隨着表的增長,被自動切分成多個tablet,典型的每個tablet有100-200MB大小。


如何定位Tablet(Tablet Location)


使用一個類似B+樹的三層目錄結構保存tablet的定位信息。

一般來說,METADATA表項大概1KB,那麼按照每個METADATA表128MB算,三層目錄總共能索引2^34個數據Tablet,假設每個數據Tablet也是128MB,則總共能存儲2^61字節數據(2EB)。

Client側庫會緩存元數據信息,並且會預取元數據信息;在tablet server側,元數據信息是存儲在內存中的。通過上述手段,我們能夠加快tablet的定位過程。

元數據中也會存儲一些其他信息,包括 a log of all events pertaining to each tablet。

Tablet分配(Tablet assignment)

每個tablet都會被指定一個tablet服務器。該工作是由master服務器完成的。

每個Tablet服務器會在Chubby中獲取一個文件鎖,Master服務器通過掃描chubby文件來發現Tablet服務器。Master服務器通過心跳來發現Tablet服務器故障,當tablet服務器心跳丟失時,Master服務器嘗試去獲取tablet服務器的文件鎖,如果獲取成功,就說明tablet服務器發生了故障,Master就重新故障Tablet服務器上的所有tablet。


當Master被CMS啓動時,它通過如下步驟進行Tablet分配:

1、 從Chubby服務中獲取Master鎖,避免Master的多主現象。

2、 通過掃描Chubby中的文件發現所有Tablet Server。

3、 和所有Tablet服務器通信,發現已經分配的Tablet。

4、 (如果Root Metadata表還未分配則先分配Root Metadata)掃描元數據發現所有的Tablet,發現未分配的Tablet並進行分配。


在實際運行過程中,Tablet可能發生變化,Master通過如下方式跟蹤Tablet的變化,並進行分配。在如下場景會發生Tablet的變化:

1、 創建、刪除Tablet。

2、 合併Tablet。

3、 切分Tablet。

其中第1、2兩種情況都是由Master發起的,Master自然知道這個變化信息。第三種情況是Tablet服務器發起的,需要由Tablet服務器通知Master服務器;如果該通知丟失,則在下一次Master通知Tablet服務器加載Tablet時會發現。


數據操作和合並(Tablet Servering & Compactions)

寫操作:用戶更新數據時,被寫入memtable,同時記錄在commit log中;當memtable大小增長到一定程度時,寫入到磁盤的sstable中;當SSTable個數太多時,會進行多個SSTable的合併。

讀操作:讀取所有的SSTable和memtable,把數據合併之後給用戶返回。

系統啓動時:把SSTable的索引信息讀入內存;並且根據commit log重建memtable。


6 細化設計(Refinements)


Locality Group

用戶可以把多個列簇組成一個locality group,BigTable爲每個Tablet每個locality group保存一個SSTable文件。

一般locality group的劃分原則爲,把不會一起讀取的列簇劃分到不同的locality group中,有利於提高讀取效率。

還可以針對locality group指定一些優化參數,例如是否緩存到內存。


壓縮(Compression)

用戶可以控制SSTable是否壓縮,以及壓縮格式。壓縮應用在一個SSTable Block上,SSTable Block的大小用戶可以指定,之所以不對整個SSTable進行壓縮,是爲了在讀取時避免解壓整個SSTable,提高讀取效率。

常用的是兩遍壓縮法,第一遍採用“Bentley and McIlroy’s scheme”在一個大窗口中發現公共子串,第二遍採用一個快速壓縮算法在16k的窗口中發現重複子串。這樣速度很快,壓縮100-200MB/s,解壓400-1000MB/s。

文中舉了個例子,它們對WebTable的壓縮比達到了10:1,而Gzip的典型的壓縮率爲3:1-4:1。爲什麼能夠達到這麼高的壓縮率呢?這個跟Row的排序很相關,儘量選擇一種合適的Row的編碼格式,以便能夠把相似的內容排到一起。


通過緩存提高讀取性能(Caching for read performance)

使用兩級緩存,Scan Cache和Block Cache。

l Scan Cache用於緩存BigTable接口返回的Key-Value對。這對於頻繁讀取的內容非常有用。

l Block Cache用於緩存讀取GFS時返回的SSTable Block。這對於讀取內容和最近讀取內容很近的場景效果很好。


布隆過濾器(Bloom Filter)

布隆過濾器可以針對一個locality group指定是否創建,通過布隆過濾器可以發現一個row/column上是否有值,減少訪問磁盤的個數。


Commit-log實現(Commit-log implementation)

如果爲每個tablet記錄一個Commit log,則Commit log的個數會太多,所以BigTable採用的方案是爲每個Tablet Server記錄一個Commit log。這帶來了一個問題,不同的Tablet的commit log共存於一個物理文件,在Tablet Server故障恢復時,接替工作的多個Tablet Server都要讀取commit log進行數據恢復,效率很低。所以在恢復時,先對commit log進行排序,把單個Tablet的commit log聚合成連續的塊,然後在進行恢復。使用類似於map-reduce的方式加速排序過程。

日誌文件有兩個,每個通過一個線程寫,發現寫性能下降時,進行切換。


加速Tablet恢復(Speeding up tablet recovery)

當把Tablet從一個Tablet Server遷移到另一個Server時,如果通過commit log進行數據恢復,則效率過低。所以在遷移之前,先把數據全部保存到SSTable中,便於快速恢復。保存到SSTable中採用兩遍寫入磁盤法,第一遍寫SSTable時同時提供BigTable服務,第二遍寫SSTable時不提供BigTable服務,減少寫SSTable過程中對業務的衝擊。


採用只讀SSTable(Exploiting immutability)

SSTable是隻讀的,一旦寫入磁盤就不再變化,這簡化了很多方面的設計:

l 簡化了併發控制,變化的只有memtable,採用寫時複製(copy-on-write)策略降低併發衝突。

l SSTable垃圾回收採用mark¬-and-sweep方式。

l Tablet拆分很容易,讓拆分後的child tablet的SSTable共享parent tablet的SSTable

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章