谷歌技术三宝之BigTable
http://blog.csdn.net/opennaive/article/details/7532589
2006年的OSDI有兩篇google的論文,分別是BigTable和Chubby。Chubby是一個(gè)分布式鎖服務(wù),基于Paxos算法;BigTable是一個(gè)用于管理結(jié)構(gòu)化數(shù)據(jù)的分布式存儲(chǔ)系統(tǒng),構(gòu)建在GFS、Chubby、SSTable等google技術(shù)之上。相當(dāng)多的google應(yīng)用使用了BigTable,比如Google Earth和Google Analytics,因此它和GFS、MapReduce并稱為谷歌技術(shù)"三寶"。
與GFS和MapReduce的論文相比,我覺得BigTable的論文難懂一些。一方面是因?yàn)樽约簩?duì)數(shù)據(jù)庫不太了解,另一方面又是因?yàn)閷?duì)數(shù)據(jù)庫的理解局限于關(guān)系型數(shù)據(jù)庫。嘗試用關(guān)系型數(shù)據(jù)模型去理解BigTable就容易"走火入魔"。在這里推薦一篇文章(需要翻墻):Understanding HBase and BigTable,相信這篇文章對(duì)理解BigTable/HBase的數(shù)據(jù)模型有很大幫助。
1 什么是BigTable
Bigtable是一個(gè)為管理大規(guī)模結(jié)構(gòu)化數(shù)據(jù)而設(shè)計(jì)的分布式存儲(chǔ)系統(tǒng),可以擴(kuò)展到PB級(jí)數(shù)據(jù)和上千臺(tái)服務(wù)器。很多google的項(xiàng)目使用Bigtable存儲(chǔ)數(shù)據(jù),這些應(yīng)用對(duì)Bigtable提出了不同的挑戰(zhàn),比如數(shù)據(jù)規(guī)模的要求、延遲的要求。Bigtable能滿足這些多變的要求,為這些產(chǎn)品成功地提供了靈活、高性能的存儲(chǔ)解決方案。
Bigtable看起來像一個(gè)數(shù)據(jù)庫,采用了很多數(shù)據(jù)庫的實(shí)現(xiàn)策略。但是Bigtable并不支持完整的關(guān)系型數(shù)據(jù)模型;而是為客戶端提供了一種簡(jiǎn)單的數(shù)據(jù)模型,客戶端可以動(dòng)態(tài)地控制數(shù)據(jù)的布局和格式,并且利用底層數(shù)據(jù)存儲(chǔ)的局部性特征。Bigtable將數(shù)據(jù)統(tǒng)統(tǒng)看成無意義的字節(jié)串,客戶端需要將結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)串行化再存入Bigtable。
下文對(duì)BigTable的數(shù)據(jù)模型和基本工作原理進(jìn)行介紹,而各種優(yōu)化技術(shù)(如壓縮、Bloom Filter等)不在討論范圍。
2 BigTable的數(shù)據(jù)模型
Bigtable不是關(guān)系型數(shù)據(jù)庫,但是卻沿用了很多關(guān)系型數(shù)據(jù)庫的術(shù)語,像table(表)、row(行)、column(列)等。這容易讓讀者誤入歧途,將其與關(guān)系型數(shù)據(jù)庫的概念對(duì)應(yīng)起來,從而難以理解論文。Understanding HBase and BigTable是篇很優(yōu)秀的文章,可以幫助讀者從關(guān)系型數(shù)據(jù)模型的思維定勢(shì)中走出來。
本質(zhì)上說,Bigtable是一個(gè)鍵值(key-value)映射。按作者的說法,Bigtable是一個(gè)稀疏的,分布式的,持久化的,多維的排序映射。
先來看看多維、排序、映射。Bigtable的鍵有三維,分別是行鍵(row key)、列鍵(column key)和時(shí)間戳(timestamp),行鍵和列鍵都是字節(jié)串,時(shí)間戳是64位整型;而值是一個(gè)字節(jié)串。可以用?(row:string, column:string, time:int64)→string?來表示一條鍵值對(duì)記錄。
行鍵可以是任意字節(jié)串,通常有10-100字節(jié)。行的讀寫都是原子性的。Bigtable按照行鍵的字典序存儲(chǔ)數(shù)據(jù)。Bigtable的表會(huì)根據(jù)行鍵自動(dòng)劃分為片(tablet),片是負(fù)載均衡的單元。最初表都只有一個(gè)片,但隨著表不斷增大,片會(huì)自動(dòng)分裂,片的大小控制在100-200MB。行是表的第一級(jí)索引,我們可以把該行的列、時(shí)間和值看成一個(gè)整體,簡(jiǎn)化為一維鍵值映射,類似于:
[javascript] view plaincopyprint?
列是第二級(jí)索引,每行擁有的列是不受限制的,可以隨時(shí)增加減少。為了方便管理,列被分為多個(gè)列族(column family,是訪問控制的單元),一個(gè)列族里的列一般存儲(chǔ)相同類型的數(shù)據(jù)。一行的列族很少變化,但是列族里的列可以隨意添加刪除。列鍵按照family:qualifier格式命名的。這次我們將列拿出來,將時(shí)間和值看成一個(gè)整體,簡(jiǎn)化為二維鍵值映射,類似于:
[javascript] view plaincopyprint?
或者可以將列族當(dāng)作一層新的索引,類似于:
[javascript] view plaincopyprint?
時(shí)間戳是第三級(jí)索引。Bigtable允許保存數(shù)據(jù)的多個(gè)版本,版本區(qū)分的依據(jù)就是時(shí)間戳。時(shí)間戳可以由Bigtable賦值,代表數(shù)據(jù)進(jìn)入Bigtable的準(zhǔn)確時(shí)間,也可以由客戶端賦值。數(shù)據(jù)的不同版本按照時(shí)間戳降序存儲(chǔ),因此先讀到的是最新版本的數(shù)據(jù)。我們加入時(shí)間戳后,就得到了Bigtable的完整數(shù)據(jù)模型,類似于:
[javascript] view plaincopyprint?
圖1是Bigtable論文里給出的例子,Webtable表存儲(chǔ)了大量的網(wǎng)頁和相關(guān)信息。在Webtable,每一行存儲(chǔ)一個(gè)網(wǎng)頁,其反轉(zhuǎn)的url作為行鍵,比如maps.google.com/index.html的數(shù)據(jù)存儲(chǔ)在鍵為com.google.maps/index.html的行里,反轉(zhuǎn)的原因是為了讓同一個(gè)域名下的子域名網(wǎng)頁能聚集在一起。圖1中的列族"anchor"保存了該網(wǎng)頁的引用站點(diǎn)(比如引用了CNN主頁的站點(diǎn)),qualifier是引用站點(diǎn)的名稱,而數(shù)據(jù)是鏈接文本;列族"contents"保存的是網(wǎng)頁的內(nèi)容,這個(gè)列族只有一個(gè)空列"contents:"。圖1中"contents:"列下保存了網(wǎng)頁的三個(gè)版本,我們可以用("com.cnn.www", "contents:", t5)來找到CNN主頁在t5時(shí)刻的內(nèi)容。
再來看看作者說的其它特征:稀疏,分布式,持久化。持久化的意思很簡(jiǎn)單,Bigtable的數(shù)據(jù)最終會(huì)以文件的形式放到GFS去。Bigtable建立在GFS之上本身就意味著分布式,當(dāng)然分布式的意義還不僅限于此。稀疏的意思是,一個(gè)表里不同的行,列可能完完全全不一樣。
3 支撐技術(shù)
Bigtable依賴于google的幾項(xiàng)技術(shù)。用GFS來存儲(chǔ)日志和數(shù)據(jù)文件;按SSTable文件格式存儲(chǔ)數(shù)據(jù);用Chubby管理元數(shù)據(jù)。
GFS參見谷歌技術(shù)"三寶"之谷歌文件系統(tǒng)。BigTable的數(shù)據(jù)和日志都是寫入GFS的。
SSTable的全稱是Sorted Strings Table,是一種不可修改的有序的鍵值映射,提供了查詢、遍歷等功能。每個(gè)SSTable由一系列的塊(block)組成,Bigtable將塊默認(rèn)設(shè)為64KB。在SSTable的尾部存儲(chǔ)著塊索引,在訪問SSTable時(shí),整個(gè)索引會(huì)被讀入內(nèi)存。BigTable論文沒有提到SSTable的具體結(jié)構(gòu),LevelDb日知錄之四: SSTable文件這篇文章對(duì)LevelDb的SSTable格式進(jìn)行了介紹,因?yàn)長(zhǎng)evelDB的作者JeffreyDean正是BigTable的設(shè)計(jì)師,所以極具參考價(jià)值。每一個(gè)片(tablet)在GFS里都是按照SSTable的格式存儲(chǔ)的,每個(gè)片可能對(duì)應(yīng)多個(gè)SSTable。
Chubby是一種高可用的分布式鎖服務(wù),Chubby有五個(gè)活躍副本,同時(shí)只有一個(gè)主副本提供服務(wù),副本之間用Paxos算法維持一致性,Chubby提供了一個(gè)命名空間(包括一些目錄和文件),每個(gè)目錄和文件就是一個(gè)鎖,Chubby的客戶端必須和Chubby保持會(huì)話,客戶端的會(huì)話若過期則會(huì)丟失所有的鎖。關(guān)于Chubby的詳細(xì)信息可以看google的另一篇論文:The Chubby lock service for loosely-coupled distributed systems。Chubby用于片定位,片服務(wù)器的狀態(tài)監(jiān)控,訪問控制列表存儲(chǔ)等任務(wù)。
4 Bigtable集群
Bigtable集群包括三個(gè)主要部分:一個(gè)供客戶端使用的庫,一個(gè)主服務(wù)器(master server),許多片服務(wù)器(tablet server)。
正如數(shù)據(jù)模型小節(jié)所說,Bigtable會(huì)將表(table)進(jìn)行分片,片(tablet)的大小維持在100-200MB范圍,一旦超出范圍就將分裂成更小的片,或者合并成更大的片。每個(gè)片服務(wù)器負(fù)責(zé)一定量的片,處理對(duì)其片的讀寫請(qǐng)求,以及片的分裂或合并。片服務(wù)器可以根據(jù)負(fù)載隨時(shí)添加和刪除。這里片服務(wù)器并不真實(shí)存儲(chǔ)數(shù)據(jù),而相當(dāng)于一個(gè)連接Bigtable和GFS的代理,客戶端的一些數(shù)據(jù)操作都通過片服務(wù)器代理間接訪問GFS。
主服務(wù)器負(fù)責(zé)將片分配給片服務(wù)器,監(jiān)控片服務(wù)器的添加和刪除,平衡片服務(wù)器的負(fù)載,處理表和列族的創(chuàng)建等。注意,主服務(wù)器不存儲(chǔ)任何片,不提供任何數(shù)據(jù)服務(wù),也不提供片的定位信息。
客戶端需要讀寫數(shù)據(jù)時(shí),直接與片服務(wù)器聯(lián)系。因?yàn)榭蛻舳瞬⒉恍枰獜闹鞣?wù)器獲取片的位置信息,所以大多數(shù)客戶端從來不需要訪問主服務(wù)器,主服務(wù)器的負(fù)載一般很輕。
5 片的定位
前面提到主服務(wù)器不提供片的位置信息,那么客戶端是如何訪問片的呢?來看看論文給的示意圖,Bigtable使用一個(gè)類似B+樹的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)片的位置信息。
首先是第一層,Chubby file。這一層是一個(gè)Chubby文件,它保存著root tablet的位置。這個(gè)Chubby文件屬于Chubby服務(wù)的一部分,一旦Chubby不可用,就意味著丟失了root tablet的位置,整個(gè)Bigtable也就不可用了。
第二層是root tablet。root tablet其實(shí)是元數(shù)據(jù)表(METADATA table)的第一個(gè)分片,它保存著元數(shù)據(jù)表其它片的位置。root tablet很特別,為了保證樹的深度不變,root tablet從不分裂。
第三層是其它的元數(shù)據(jù)片,它們和root tablet一起組成完整的元數(shù)據(jù)表。每個(gè)元數(shù)據(jù)片都包含了許多用戶片的位置信息。
可以看出整個(gè)定位系統(tǒng)其實(shí)只是兩部分,一個(gè)Chubby文件,一個(gè)元數(shù)據(jù)表。注意元數(shù)據(jù)表雖然特殊,但也仍然服從前文的數(shù)據(jù)模型,每個(gè)分片也都是由專門的片服務(wù)器負(fù)責(zé),這就是不需要主服務(wù)器提供位置信息的原因。客戶端會(huì)緩存片的位置信息,如果在緩存里找不到一個(gè)片的位置信息,就需要查找這個(gè)三層結(jié)構(gòu)了,包括訪問一次Chubby服務(wù),訪問兩次片服務(wù)器。
6 片的存儲(chǔ)和訪問
片的數(shù)據(jù)最終還是寫到GFS里的,片在GFS里的物理形態(tài)就是若干個(gè)SSTable文件。圖5展示了讀寫操作基本情況。當(dāng)片服務(wù)器收到一個(gè)寫請(qǐng)求,片服務(wù)器首先檢查請(qǐng)求是否合法。如果合法,先將寫請(qǐng)求提交到日志去,然后將數(shù)據(jù)寫入內(nèi)存中的memtable。memtable相當(dāng)于SSTable的緩存,當(dāng)memtable成長(zhǎng)到一定規(guī)模會(huì)被凍結(jié),Bigtable隨之創(chuàng)建一個(gè)新的memtable,并且將凍結(jié)的memtable轉(zhuǎn)換為SSTable格式寫入GFS,這個(gè)操作稱為minor compaction。
當(dāng)片服務(wù)器收到一個(gè)讀請(qǐng)求,同樣要檢查請(qǐng)求是否合法。如果合法,這個(gè)讀操作會(huì)查看所有SSTable文件和memtable的合并視圖,因?yàn)镾STable和memtable本身都是已排序的,所以合并相當(dāng)快。
每一次minor compaction都會(huì)產(chǎn)生一個(gè)新的SSTable文件,SSTable文件太多讀操作的效率就降低了,所以Bigtable定期執(zhí)行merging compaction操作,將幾個(gè)SSTable和memtable合并為一個(gè)新的SSTable。BigTable還有個(gè)更厲害的叫major compaction,它將所有SSTable合并為一個(gè)新的SSTable。
遺憾的是,BigTable作者沒有介紹memtable和SSTable的詳細(xì)數(shù)據(jù)結(jié)構(gòu)。
7 BigTable和GFS的關(guān)系
集群包括主服務(wù)器和片服務(wù)器,主服務(wù)器負(fù)責(zé)將片分配給片服務(wù)器,而具體的數(shù)據(jù)服務(wù)則全權(quán)由片服務(wù)器負(fù)責(zé)。但是不要誤以為片服務(wù)器真的存儲(chǔ)了數(shù)據(jù)(除了內(nèi)存中memtable的數(shù)據(jù)),數(shù)據(jù)的真實(shí)位置只有GFS才知道,主服務(wù)器將片分配給片服務(wù)器的意思應(yīng)該是,片服務(wù)器獲取了片的所有SSTable文件名,片服務(wù)器通過一些索引機(jī)制可以知道所需要的數(shù)據(jù)在哪個(gè)SSTable文件,然后從GFS中讀取SSTable文件的數(shù)據(jù),這個(gè)SSTable文件可能分布在好幾臺(tái)chunkserver上。
8 元數(shù)據(jù)表的結(jié)構(gòu)
元數(shù)據(jù)表(METADATA table)是一張?zhí)厥獾谋?#xff0c;它被用于數(shù)據(jù)的定位以及一些元數(shù)據(jù)服務(wù),不可謂不重要。但是Bigtable論文里只給出了少量線索,而對(duì)表的具體結(jié)構(gòu)沒有說明。這里我試圖根據(jù)論文的一些線索,猜測(cè)一下表的結(jié)構(gòu)。首先列出論文中的線索:
serving it).
第一條線索,元數(shù)據(jù)表的行鍵是由片所屬表名的id和片最后一行編碼而成,所以每個(gè)片在元數(shù)據(jù)表中占據(jù)一條記錄(一行),而且行鍵既包含了其所屬表的信息也包含了其所擁有的行的范圍。譬如采取最簡(jiǎn)單的編碼方式,元數(shù)據(jù)表的行鍵等于strcat(表名,片最后一行的行鍵)。
第二點(diǎn)線索,除了知道元數(shù)據(jù)表的地址部分是常駐內(nèi)存以外,還可以發(fā)現(xiàn)元數(shù)據(jù)表有一個(gè)列族稱為location,我們已經(jīng)知道元數(shù)據(jù)表每一行代表一個(gè)片,那么為什么需要一個(gè)列族來存儲(chǔ)地址呢?因?yàn)槊總€(gè)片都可能由多個(gè)SSTable文件組成,列族可以用來存儲(chǔ)任意多個(gè)SSTable文件的位置。一個(gè)合理的假設(shè)就是每個(gè)SSTable文件的位置信息占據(jù)一列,列名為location:filename。當(dāng)然不一定非得用列鍵存儲(chǔ)完整文件名,更大的可能性是把SSTable文件名存在值里。獲取了文件名就可以向GFS索要數(shù)據(jù)了。
第三個(gè)線索告訴我們?cè)獢?shù)據(jù)表不止存儲(chǔ)位置信息,也就是說列族不止location,這些數(shù)據(jù)暫時(shí)不是咱們關(guān)心的。
通過以上信息,我畫了一個(gè)簡(jiǎn)化的Bigtable結(jié)構(gòu)圖:
結(jié)構(gòu)圖以Webtable表為例,表中存儲(chǔ)了網(wǎng)易、百度和豆瓣的幾個(gè)網(wǎng)頁。當(dāng)我們想查找百度貼吧昨天的網(wǎng)頁內(nèi)容,可以向Bigtable發(fā)出查詢Webtable表的(com.baidu.tieba, contents:, yesterday)。
假設(shè)客戶端沒有該緩存,那么Bigtable訪問root tablet的片服務(wù)器,希望得到該網(wǎng)頁所屬的片的位置信息在哪個(gè)元數(shù)據(jù)片中。使用METADATA.Webtable.com.baidu.tieba為行鍵在root tablet中查找,定位到最后一個(gè)比它大的是METADATA.Webtable.com.baidu.www,于是確定需要的就是元數(shù)據(jù)表的片A。訪問片A的片服務(wù)器,繼續(xù)查找Webtable.com.baidu.tieba,定位到Webtable.com.baidu.www是比它大的,確定需要的是Webtable表的片B。訪問片B的片服務(wù)器,獲得數(shù)據(jù)。
這里需要注意的是,每個(gè)片實(shí)際都由若干SSTable文件和memtable組成,而且這些SSTable和memtable都是已排序的。這就導(dǎo)致查找片B時(shí),可能需要將所有SSTable和memtable都查找一遍;另外客戶端應(yīng)該不會(huì)直接從元數(shù)據(jù)表獲得SSTable的文件名,而只是獲得片屬于片服務(wù)器的信息,通過片服務(wù)器為代理訪問SSTable。參考文獻(xiàn)
[1]?Bigtable: A Distributed Storage System for Structured Data. In proceedings of OSDI'06.
[2]?Understanding HBase and BigTable.
?
總結(jié)
以上是生活随笔為你收集整理的谷歌技术三宝之BigTable的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据挖掘十大算法之—C4.5
- 下一篇: eoiioe linux下解压命令大全