BigTable
BigTable
BigTable是Google設計的分散式數據存儲系統,用來處理海量的數據的一種非關係型的資料庫
BigTable是非關係的資料庫,是一個稀疏的、分散式的、持久化存儲的多維度排序Map。Bigtable的設計目的是可靠的處理PB級別的數據,並且能夠部署到上千台機器上。Bigtable已經實現了下面的幾個目標:適用性廣泛、可擴展、高性能和高可用性。Bigtable已經在超過60個Google的產品和項目上得到了應用,包括 Google Analytics、GoogleFinance、Orkut、Personalized Search、Writely和GoogleEarth。這些產品對Bigtable提出了迥異的需求,有的需要高吞吐量的批處理,有的則需要及時響應,快速返回數據給最終用戶。它們使用的Bigtable集群的配置也有很大的差異,有的集群只有幾台伺服器,而有的則需要上千台伺服器、存儲幾百TB的數據。
在很多方面,Bigtable和資料庫很類似:它使用了很多資料庫的實現策略。并行資料庫【14】和內存資料庫【13】已經具備可擴展性和高性能,但是Bigtable提供了一個和這些系統完全不同的介面。Bigtable不支持完整的關係數據模型;與之相反,Bigtable為客戶提供了簡單的數據模型,利用這個模型,客戶可以動態控制數據的分佈和格式(alex註:也就是對BigTable而言,數據是沒有格式的,用資料庫領域的術語說,就是數據沒有Schema,用戶自己去定義Schema),用戶也可以自己推測(alex註:reasonabout)底層存儲數據的位置相關性(alex註:位置相關性可以這樣理解,比如樹狀結構,具有相同前綴的數據的存放位置接近。在讀取的時候,可以把這些數據一次讀取出來)。數據的下標是行和列的名字,名字可以是任意的字元串。Bigtable將存儲的數據都視為字元串,但是Bigtable本身不去解析這些字元串,客戶程序通常會在把各種結構化或者半結構化的數據串列化到這些字元串里。通過仔細選擇數據的模式,客戶可以控制數據的位置相關性。最後,可以通過BigTable的模式參數來控制數據是存放在內存中、還是硬碟上。
特點:
1、適合大規模海量數據,PB級數據;
2、分散式、併發數據處理,效率極高;
3、易於擴展,支持動態伸縮;
4、適用於廉價設備;
5、適合於讀操作,不適合寫操作。
6、不適用於傳統關係資料庫;
應用:
2010年9月,Google宣布將放棄MapReduce新索引系統將遷移至BigTable平台。新平台基於Colossus,也被稱為GFS2。
本質上說,Bigtable是一個鍵值(key-value)映射。按作者的說法,Bigtable是一個稀疏的,分散式的,持久化的,多維的排序映射。
先來看看多維、排序、映射。Bigtable的鍵有三維,分別是行鍵(row key)、列鍵(column key)和時間戳(timestamp),行鍵和列鍵都是位元組串,時間戳是64位整型;而值是一個位元組串。可以用 (row:string, column:string, time:int64)→string 來表示一條鍵值對記錄。
行鍵可以是任意位元組串,通常有10-100位元組。行的讀寫都是原子性的。Bigtable按照行鍵的字典序存儲數據。Bigtable的表會根據行鍵自動劃分為片(tablet),片是負載均衡的單元。最初表都只有一個片,但隨著表不斷增大,片會自動分裂,片的大小控制在100-200MB。行是表的第一級索引,我們可以把該行的列、時間和值看成一個整體,簡化為一維鍵值映射,類似於:
table{
"1" : {sth.},//一行
"aaaaa" : {sth.},
"aaaab" : {sth.},
"xyz" : {sth.},
"zzzzz" : {sth.}
}
列是第二級索引,每行擁有的列是不受限制的,可以隨時增加減少。為了方便管理,列被分為多個列族(column family,是訪問控制的單元),一個列族裡的列一般存儲相同類型的數據。一行的列族很少變化,但是列族裡的列可以隨意添加刪除。列鍵按照family:qualifier格式命名的。這次我們將列拿出來,將時間和值看成一個整體,簡化為二維鍵值映射,類似於:
table{
// ...
"aaaaa" : { //一行
"A:foo" : {sth.},//一列
"A:bar" : {sth.},//一列
"B:" : {sth.} //一列,列族名為B,但是列名是空字串
},
"aaaab" : { //一行
"A:foo" : {sth.},
"B:" : {sth.}
},
// ...
}
或者可以將列族當作一層新的索引,類似於:
table{
// ...
"aaaaa" : { //一行
"A" : { //列族A
"foo" : {sth.}, //一列
"bar" : {sth.}
},
"B" : { //列族B
"" : {sth.}
}
},
"aaaab" : { //一行
"A" : {
"foo" : {sth.},
},
"B" : {
"" : "ocean"
}
},
// ...
}
時間戳是第三級索引。Bigtable允許保存數據的多個版本,版本區分的依據就是時間戳。時間戳可以由Bigtable賦值,代表數據進入Bigtable的準確時間,也可以由客戶端賦值。數據的不同版本按照時間戳降序存儲,因此先讀到的是最新版本的數據。我們加入時間戳后,就得到了Bigtable的完整數據模型,類似於:
table{
// ...
"aaaaa" : { //一行
"A:foo" : { //一列
15 : "y", //一個版本
4 : "m"
},
"A:bar" : { //一列
15 : "d",
},
"B:" : { //一列
6 : "w"
3 : "o"
1 : "w"
}
},
// ...
}
查詢時,如果只給出行列,那麼返回的是最新版本的數據;如果給出了行列時間戳,那麼返回的是時間小於或等於時間戳的數據。比如,我們查詢"aaaaa"/"A:foo",返回的值是"y";查詢"aaaaa"/"A:foo"/10,返回的結果就是"m";查詢"aaaaa"/"A:foo"/2,返回的結果是空。
Figure 1是Bigtable論文里給出的例子,Webtable表存儲了大量的網頁和相關信息。在Webtable,每一行存儲一個網頁,其反轉的url作為行鍵,比如”com.google.maps“,反轉的原因是為了讓同一個域名下的子域名網頁能聚集在一起。圖1中的列族"anchor"保存了該網頁的引用站點(比如引用了CNN主頁的站點),qualifier是引用站點的名稱,而數據是鏈接文本;列族"contents"保存的是網頁的內容,這個列族只有一個空列"contents:"。圖1中"contents:"列下保存了網頁的三個版本,我們可以用("com.cnn.www", "contents:", t5)來找到CNN主頁在t5時刻的內容。