Bigtable:結構化數據的分佈式存儲系統(一)

譯自Bigtable_A Distributed Storage System for Structured Datahtml

做者:Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes, Robert E.Gruber正則表達式

摘要算法

Bigtable是海量結構化數據的分佈式存儲系統,用於處理分佈在幾千臺普通服務器上的PB級的數據。數據庫

Google的不少項目都使用Bigtable存儲數據,包括Web索引、Google Earth以及GoogleFinance。不論是從數據量層面(從URL到網頁到衛星圖像)仍是從響應速度層面(從後端的批量處理到實時數據服務),這些應用都對Bigtable提出了各類各樣的要求。針對千差萬別的需求,Bigtable成功提供了靈活的高性能解決方案。後端

本文介紹了Bigtable的簡單數據模型。利用該模型,客戶端能夠動態地控制數據的分佈和格式。本文還介紹了Bigtable的設計和實現。數組

1 引言緩存

過去兩年,咱們設計、實現並部署告終構化數據的分佈式存儲系統Bigtable,用於處理分佈在幾千臺機器上的PB級的數據。Bigtable具備適用性廣、可擴展性強、高性能和高可用性的優勢。服務器

Bigtable已經用於Google的60多個產品和項目,包括GoogleAnalytics、Google Finance、Orkut、Personalized Search、Writely以及Google Earth。這些產品對Bigtable的要求各不相同:有的須要高吞吐量的批處理;有的則須要及時響應,快速將數據返回給終端用戶。這些產品使用Bigtable 集羣時的配置方式也有很大差別:有的集羣只有幾臺服務器,而有的則須要上千臺服務器,存儲幾百TB的數據。網絡

Bigtable的不少實現策略都與數據庫相似。並行數據庫和內存數據庫已經具有可擴展性和高性能,但Bigtable提供的接口與這些系統徹底不一樣。Bigtable不支持完整的關係數據模型;相反,它提供了簡單的數據模型。客戶端可利用這個模型動態控制數據的分佈和格式,也能夠本身推測底層存儲數據的位置。數據的下標是行和列的名稱,名稱能夠是任意字符串。雖然客戶端程序通常會對各類結構化或者半結構化的數據進行串行化處理,但Bigtable依然會將這些數據視爲未解析的字符串。經過仔細選擇數據模式,客戶端能夠控制數據的位置;而後經過BigTable的模式參數來決定將數據存放在內存中仍是硬盤上。數據結構

第2節詳細介紹了數據模型,第3節概述了客戶端API。第4節簡要介紹了Bigtable所依賴的底層Google基礎框架。第5節介紹了Bigtable實現的關鍵部分,第6節介紹了改善Bigtable性能的調優方法。第7節介紹了Bigtable的性能。第8節介紹了Bigtable在Google的應用狀況,第9節介紹了在Bigtable的設計和後期支持過程當中得出的經驗和教訓。第10節介紹了相關研究工做,第11節爲本文結論。

2 數據模型

Bigtable是一個稀疏的分佈式持久化存儲的多維度排序Map。Map的索引是行關鍵字、列關鍵字以及時間戳;Map中的每一個value都是一個未經解析的byte數組。

(row:string,column:string, time:int64) → string

認真分析了一個相似於Bigtable系統的各類潛在功能後,咱們決定使用這個數據模型。舉個例子:假設咱們須要存儲海量網頁及相關信息,這些數據能夠用於不少不一樣的項目。咱們暫且稱該表爲Webtable。在Webtable中,咱們以URL爲行關鍵字,以網頁的某些屬性爲列名,網頁內容放在「contents:」列中,並以時間戳標記該網頁的獲取時間,如圖1所示。

圖1:存儲Web頁面的樣表的片斷行名爲反向URL contents列族爲網頁內容,anchor列族爲引用該網頁的錨連接文本。CNN的主頁被SportsIllustrator和MY-look的主頁引用,所以該行包含了名爲「 anchor:cnnsi.com」和 「anchhor:my.look.ca」的列。每一個錨連接只有一個版本;而contents 列則有三個版本,分別由時間戳t三、t5和t6標識。

表中的行關鍵字是任意字符串(目前支持最大64KB的字符串,可是大多數用戶僅須要10-100個字節)。對同一個行關鍵字的讀或者寫操做都是原子的(不受讀或者寫這一行中的列數影響),這種設計便於用戶理解程序在對同一個行進行併發更新操做時的行爲。

Bigtable經過行關鍵字的字母順序組織數據。表中的每一個行均可以動態分區。每一個分區叫作一個」Tablet」,Tablet是數據分佈和負載均衡調整的最小單位。當操做只讀取行中不多幾列的數據時,效率很高,一般只須要機器間的少數幾回通訊便可完成。用戶能夠利用該特色,選擇合適的行關鍵字,更加合理地安排數據位置。舉例來講,在Webtable中,經過反轉URL中主機名,能夠把同一個域名下的網頁彙集起來組織成連續的行。例如,咱們能夠把maps.google.com/index.html的數據存放在關鍵字com.google.maps/index.html下。把相同域中的網頁存儲在連續的區域可以提升基於主機和域名的分析效率。

列族

列關鍵字組成的集合叫作「列族「,列族是訪問控制的基本單位。存放在同一列族下的全部數據一般屬於同一類型(能夠把同一列族下的數據壓縮在一塊兒)。必須先建立列族,而後才能在列族中的任何列關鍵字下存放數據;列族建立後,其中的任何一個列關鍵字下均可以存放數據。一張表中的列族不能太多(最多幾百個),且列族在運行期間幾乎不發生改變;但一張表中能夠有無限多個列。

列關鍵字的命名語法爲列族:限定詞。列族的名稱必須是可打印的字符串,而限定詞的名字則能夠是任意字符串。例如,Webtable中有個列族language,該列族用來存放撰寫網頁的語言。咱們在language 列族中只使用一個列關鍵字,用來存放每一個網頁的語言標識 ID。在Webtable中,另外一個有用的列族是anchor;該列族的每個列關鍵字表明一個錨連接,如圖1所示。Anchor列族的限定詞爲引用該網頁的站點名,每列的數據項存放的是連接文本。

訪問控制、磁盤和內存的使用統計都是在列族層面進行的。在Webtable中,控制權限可以實現對不一樣類型應用的管理:有些應用能夠添加新的基本數據,有些應用能夠讀取基本數據並建立繼承的列族,有些應用則只容許瀏覽數據(甚至可能由於隱私的緣由不能瀏覽全部數據)。

時間戳

在Bigtable中,表的每個數據項均可以包含同一份數據的不一樣版本;不一樣版本的數據經過時間戳來索引。Bigtable時間戳的類型是64位整型。Bigtable能夠給時間戳賦值,時間能夠精確到毫秒;用戶程序也能夠給時間戳賦值。若是應用程序須要避免數據版本衝突,則必須生成惟一的時間戳。在數據項中,不一樣版本的數據按照時間戳倒序排序,即最新的數據排在最前面。

爲了便於管理不一樣版本的數據,咱們對每個列族配置了兩個設置參數,Bigtable能夠經過這兩個參數自動對廢棄版本的數據進行垃圾收集。客戶端程序能夠指定只保存最後n個版本的數據,也能夠指定只保存最近版本的數據(好比,只保存最近7天寫入的數據)。

在Webtable中,contents:列存儲的時間戳信息是網絡爬蟲實際抓取頁面的時間。前文說起的垃圾收集機制支持僅保留最新三個版本的網頁數據。

3 API

Bigtable API提供了建立和刪除表以及列族的函數。Bigtable還提供了修改集羣、表和列族元數據(例如訪問權限)的函數。

客戶端程序能夠對Bigtable進行以下的操做:寫入或刪除Bigtable中的值、從每一個行中查找值、或者遍 歷表中的一個數據子集。圖2中,C++代碼使用RowMutation抽象對象進行了一系列的更新操做。(爲了保證示例代碼簡潔,咱們省略了一些細節相關代碼。)調用Apply函數對Webtable 進行了一次原子修改操做:爲www.cnn.com增長了一個錨點,同時刪除了另一個錨點。

圖2:向Bigtable寫入值

圖3中的C++代碼使用Scanner抽象對象遍歷一個行內的全部錨點。客戶端程序能夠遍歷多個列族,能夠經過多種方法對掃描輸出的行、列和時間戳進行限制。例如,咱們能夠限制上述掃描只輸出匹配正則表達式*.cnn.com的錨點,或者時間戳在當前時間10天內的錨點。

圖3:從Bigtable中讀值

Bigtable還支持更加複雜的數據處理。首先,Bigtable支持單行上的事務處理。利用這個功能,用戶能夠對存儲在一個行關鍵字下的數據進行原子讀-更新-寫操做。Bigtable雖然提供了跨行批量寫入數據的接口,但目前還不支持通用的跨行事務處理。其次,Bigtable容許把數據項用作整數計數器。最後,Bigtable容許在服務器的地址空間內執行客戶端腳本程序。腳本程序使用Google開發的Sawzall數據處理語言。雖然基於Sawzall語言的API目前不支持客戶端腳本程序向Bigtable寫入數據,但它支持多種形式的數據轉換、基於任意表達式的數據過濾以及基於多種操做符的數據彙總。

Bigtable能夠和MapReduce一塊兒使用。MapReduce是Google開發的大規模並行計算框架。咱們已經開發了一些Wrapper類。經過這些類,Bigtable能夠做爲MapReduce框架的輸入和輸出。

4 構件

Bigtable基於Google的其餘幾個基礎構件。Bigtable使用Google的分佈式文件系統(GFS)存儲日誌文件和數據文件。Bigtable集羣通常運行在共享的機器池中,池中的機器還會運行其它各類分佈式應用程序。Bigtable的進程每每須要和其它應用的進程共享機器。Bigtable 依賴集羣管理系統調度任務、管理共享的機器上的資源、處理機器故障、監視機器狀態。

Bigtable內部存儲數據文件是Google SSTable格式的。SSTable是有序的持久化Map結構,不可更改;Map是key-value映射的數據結構,key和value的值都是任意的Byte串。SSTable支持查詢與key值相關的value,或遍歷某個key值範圍內的全部key-value對。

從內部結構來看,SSTable是一系列的數據塊(每一個塊的大小能夠自由配置,通常是64KB)。SSTable使用塊索引(存儲在SSTable的最後)來定位數據塊;打開SSTable時,索引被加載到內存。每次查找均可以經過一次磁盤搜索完成:首先使用二分查找法在內存中的索引裏找到數據塊的位置,而後再從硬盤讀取相應的數據塊;也能夠把整個SSTable都放在內存中,這樣就沒必要訪問硬盤了。

Bigtable還依賴高可用的持久化分佈式鎖服務組件Chubby。一個Chubby服務包含5個活動副本,其中一個副本爲Master,負責處理請求。只有當大多數副本處於正常運行狀態且彼此之間可以互相通訊時,Chubby服務纔是可用的。出現副本失效的狀況時,Chubby使用Paxos算法來保證副本的一致性。Chubby的命名空間包括目錄和小文件。每一個目錄或者文件能夠當作一個鎖,讀寫文件的操做都是原子的。Chubby客戶端程序庫提供Chubby文件的一致性緩存。每一個Chubby客戶端程序都維護一個與Chubby服務的會話。若是客戶端程序不能在租約到期時從新簽定會話租約,會話便會過時失效。會話失效後,其鎖和打開的文件句柄都會失效。Chubby客戶端程序能夠在文件和目錄上註冊回調函數,當文件或目錄改變、或者會話過時時,回調函數會通知客戶端程序。

Bigtable使用Chubby處理如下幾類任務:

  • 確保最多隻有一個活動的Master副本;
  • 存儲Bigtable數據的自引導指令的位置(見第5.1節);
  • 查找Tablet服務器,負責處理失效的Tablet服務器(見第5.2節);
  • 存儲Bigtable的模式信息(每張表的列族信息);
  • 存儲訪問控制列表。

若是Chubby長時間沒法訪問,Bigtable就會失效。最近咱們在使用了11個Chubby服務實例的14個BigTable集羣上測量了這種影響。因爲Chubby不可用致使BigTable中的部分數據不能訪問的平均概率是0.0047%。(不能訪問的緣由多是Chubby自己失效或者網絡問題)。單個集羣受Chubby失效影響的最大概率是0.0326%。

參考資料

  1. Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes and Robert E.Gruber. Bigtable_A Distributed Storage System for Structured Data

  2. Yan Wei. Google Bigtable中文版

相關文章
相關標籤/搜索