BigTable:結構化數據的分佈式存儲系統

摘要

Bigtable是一個用於管理結構化數據的分佈式存儲系統,旨在擴展到非常大的規模:數千個商用服務器上的數PB數據。Google的許多項目都在Bigtable中存儲數據,包括網絡索引,Google Earth和Google Finance。這些應用對Bigtable提出了非常不同的要求,包括數據大小(從URL到網頁到衛星圖像)和延遲要求(從後端批處理到實時數據服務)。儘管有這些不同的需求,但Bigtable已成功爲所有這些Google產品提供靈活、高性能的解決方案。在本文中,我們描述了Bigtable提供的簡單數據模型,它爲客戶提供了對數據佈局和格式的動態控制,並描述了Bigtable的設計和實現。

1. 簡介

在過去兩年半的時間裏,我們設計、實施並部署了一個叫Bigtable的分佈式存儲系統,用於管理Google的結構化數據。Bigtable旨在可靠地擴展到數PB的數據和數千臺計算機。Bigtable實現了多個目標:廣泛的適用性、可擴展性、高性能和高可用性。Bigtable被超過60個Google產品和項目使用,包括Google Analytics、Google Finance、Orkut、Personalized
Search、Writely和Google Earth。這些產品使用Bigtable來處理各種要求苛刻的工作,從面向吞吐量的批處理作業到對延遲敏感的數據服務,再到終端用戶。這些產品使用的Bigtable集羣涵蓋了從少量到數千臺服務器的各種配置,並可存儲高達數百TB的數據。

在很多方面,Bigtable類似於數據庫:它與數據庫共享許多實現策略。並行數據庫[14]和內存數據庫[13]已經實現了可擴展性和高性能,但Bigtable提供了與這些系統不同的接口。Bigtable不支持完整的關係數據模型; 相反,它爲客戶提供了一個簡單的數據模型,支持對數據佈局和格式的動態控制,並允許客戶端推斷數據在底層存儲中的位置屬性。使用可以是任意字符串的行名和列名來索引數據。Bigtable也將數據視爲未解釋的字符串,儘管客戶端經常將各種形式的結構化和半結構化數據序列化爲這些字符串。客戶端可以通過在模式中仔細選擇來控制數據的位置。最後,Bigtable模式參數允許客戶端動態控制是從內存還是從磁盤提供數據。

第2節更詳細地描述了數據模型,第3節提供了客戶端API的概述。第4節簡要介紹了Bigtable所依賴的底層Google基礎設施。第5節描述了Bigtable實現的基本原理,第6節描述了我們爲提高Bigtable性能所做的一些改進。第7節提供了Bigtable的性能測試。我們在第8節中描述了幾個關於如何在Google中使用Bigtable的示例,並在第9節中討論了我們設計和支持Bigtable時學到的一些經驗教訓。最後,第10節描述了相關工作,第11節介紹了我們的總結。

2. 數據模型

Bigtable是一個稀疏的、分佈式的、持久化的多維有序映射。映射由行鍵、列鍵和時間戳索引; 映射中的每個值都是未解釋的字節數組。

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

圖1:存儲Web頁面的示例表的一部分。行名稱是反轉的URL。內容列族包含頁面內容,錨列族包含引用頁面的任何錨點的文本。 CNN的主頁由Sports Illustrated和MY-look主頁引用,因此該行包含名爲anchor:cnnsi.com和anchor:my.look.ca的列。每個錨單元有一個版本; 內容列有三個版本,時間戳分別爲t3,t5和t6。
在研究了類Bigtable系統的各種潛在用途後,我們確定了這個數據模型。作爲推動我們的一些設計決策的一個具體例子:假設我們想要保留會被許多不同項目使用的大量網頁和相關信息的副本; 讓我們將這個特定的表稱爲Webtable。在Webtable中,我們將URL用作行鍵,將網頁的各個方面用作列名,並將網頁的內容存儲在contents列中:列在抓取網頁時的時間戳下,如圖1所示。

2.1 行

表中的行鍵是任意字符串(當前最大爲64KB,但對於大多數用戶來說,10-100字節是典型的大小)。單個行鍵下的每次數據讀取或寫入都是原子的(無論行中讀取或寫入的不同列的數量如何),這一設計決策使客戶端更容易在出現併發更新到同一行時推斷系統的行爲。

Bigtable維護按行鍵的字典順序排列的數據。表的行範圍是動態分區的。每個行範圍稱爲一個分片,它是分配和負載均衡的單位。結果,小的行範圍的讀取是高效的,並且通常只需要與少量機器通信。客戶端可以通過選擇行鍵來利用此特性,以便它們獲得數據訪問的好的定位。例如,在Webtable中,通過反轉的URL的主機名組成,將同一域名中的頁面分組在一起成爲連續的行。例如,我們會在鍵com.google.maps/index.html下存儲maps.google.com/index.html的數據。將來自同一域名的頁面存儲在彼此附近使得一些主機和域名分析更高效。

2.2 列族

列鍵被分組後的集合稱爲稱爲列族,這構成了訪問控制的基本單元。存儲在列族中的所有數據通常具有相同的類型(我們將同一列族中的數據壓縮在一起)。必須先創建列族,然後才能將數據存儲在該族中的任何列鍵下; 在創建列族之後,可以使用列族中的任何列鍵。我們的意圖是表中不同列族的數量很小(最多數百個),並且族在運行期間很少發生變化。相反,表可能具有無限數量的列。

使用以下語法命名列鍵:family:qualifier。列族名稱必須是可打印的,但限定符可以是任意字符串。Webtable的示例列族是language,它存儲編寫網頁的語言。我們在language列族中只使用一個列鍵,它存儲每個網頁的語言ID。該表的另一個有用的列族是anchor; 此列族中的每個列鍵代表一個錨點,如圖1所示。限定符是引用站點的名稱; 單元內容是鏈接文本。

訪問控制以及磁盤和內存統計都在列族級別執行。在我們的Webtable示例中,這些控制允許我們管理幾種不同類型的應用:一些用於添加新的基礎數據,一些用於讀取基礎數據並創建派生列族,還有一些僅允許查看現有數據(出於隱私原因甚至可能不會查看所有現有列族)。

2.3 時間戳

Bigtable中的每個單元都可以包含相同數據的多個版本; 這些版本由時間戳索引。Bigtable時間戳是64位整數。它們可以由Bigtable分配,在這種情況下,它們以微秒錶示“實時”,或由客戶端應用顯式分配。需要避免衝突的應用必須自己生成唯一的時間戳。以時間戳遞減的順序存儲單元的不同版本,以便可以首先讀取最新版本。

爲了方便版本化數據的管理,我們支持兩個列族設置,告訴Bigtable自動垃圾收集單元版本。客戶端可以指定僅保留單元的最後n個版本,或者僅保留足夠新的版本(例如,僅保留在過去七天中寫入的值)。

在我們的Webtable示例中,我們將存儲在contents列已爬取網頁的時間戳設置爲:實際爬取這些頁面版本的時間。上面描述的垃圾收集機制讓我們能只保留每個頁面的最新三個版本。

3. API

Bigtable API提供了創建和刪除表和列族的功能。它還提供用於更改集羣、表和列族元數據的功能,例如訪問控制權限。

客戶端應用程序可以在Bigtable中寫入或刪除值,從單個行中查找值,或迭代表中數據的子集。圖2顯示了使用RowMutation抽象來執行一系列更新的C ++代碼。(不相關的細節被省略以保持示例簡短。)調用Apply對Webtable執行原子變更:它向www.cnn.com添加一個錨並刪除一個不同的錨。

圖2:寫入Bigtable。
圖3顯示了使用Scanner抽象迭代特定行中所有錨點的C ++代碼。客戶端可以迭代多個列族,並且有幾種機制可以生成限制的掃描行、列和時間戳。例如,我們可以將上面的掃描限制爲僅生成其列與正則表達式錨點:*.cnn.com匹配的錨點,或者僅生成其時間戳落在當前時間的十天內的錨點。

圖3:從Bigtable讀取。
Bigtable支持其他一些功能,允許用戶以更復雜的方式操作數據。首先,Bigtable支持單行事務,可用於對存儲在單行鍵下的數據執行原子讀-修改-寫序列操作。Bigtable目前不支持跨行的常規事務,但它提供了一個接口,用於在客戶端上批量跨行寫入。其次,Bigtable允許將單元用作整數計數器。最後,Bigtable支持在服務器的地址空間中執行客戶端提供的腳本。這些腳本是用Google開發的一種語言編寫的,用於處理稱爲Sawzall的數據[28]。目前,我們基於Sawzall的API不允許客戶端腳本寫回Bigtable,但它允許各種形式的數據轉換,基於任意表達式的過濾以及通過各種運算符進行彙總。

Bigtable可以與MapReduce[12]一起使用,MapReduce是一個在Google中用於運行開發的大規模並行計算的框架。我們編寫了一組包裝器,允許Bigtable既可以用作輸入源,也可以用作MapReduce作業的輸出目標。

4. 構成模塊

Bigtable建立在其他幾個Google基礎設施上。Bigtable使用分佈式Google文件系統(GFS)[17]來存儲日誌和數據文件。Bigtable集羣通常在運行有各種其他分佈式應用的共享計算機池中運行,並且Bigtable進程通常與來自其他應用的進程共享相同的計算機。Bigtable依賴於集羣管理系統來調度作業、管理共享機器上的資源、處理機器故障以及監視機器狀態。

Google SSTable文件格式在內部用於存儲Bigtable數據。SSTable提供從鍵到值的持久的、有序不可變的映射,其中鍵和值都是任意字節串。提供了查找與指定鍵相關聯的值的操作,並迭代指定鍵範圍內的所有鍵/值對。在內部,每個SSTable都包含一系列塊(通常每個塊的大小爲64KB,但這是可配置的)。塊索引(存儲在SSTable的末尾)用於定位塊; 打開SSTable時,索引將加載到內存中。可以使用單個磁盤搜索執行查找:我們首先通過在內存索引中執行二分查找,然後從磁盤讀取相應的塊來找到適當的塊。可選地,SSTable可以完全映射到內存中,這允許我們在不接觸磁盤的情況下執行查找和掃描。

Bigtable依賴於一種名爲Chubby[8]的高可用和持久化的分佈式鎖服務。Chubby服務由五個活躍副本組成,其中一個被選爲主服務器並主動服務請求。當大多數副本正在運行並且可以相互通信時,該服務是活着的。Chubby使用Paxos算法[9,23]來保證其副本在失敗時保持一致。Chubby提供了一個由目錄和小文件組成的命名空間。每個目錄或文件都可以用作鎖,對文件的讀寫是原子的。Chubby客戶端庫提供了Chubby文件的一致緩存。每個Chubby客戶端都使用Chubby服務維護會話。如果客戶端會話無法在租約到期時間內續訂其會話租約,則會話過期。當客戶端的會話到期時,它會丟失所有的鎖和打開的句柄。Chubby客戶端還可以在Chubby文件和目錄上註冊回調,以通知更改或會話到期。

Bigtable在各種任務中使用Chubby:確保任何時候最多隻有一個活躍的主服務器; 存儲Bigtable數據的引導位置(參見5.1節); 發現片服務器並最終確定片服務器死亡(參見第5.2節); 存儲Bigtable元信息(每個表的列族信息); 並存儲訪問控制列表。如果Chubby長時間不可用,Bigtable將無法使用。我們最近在跨越11個Chubby實例的14個Bigtable集羣中測試了這種影響。由於Chubby不可用(由Chubby停機或網絡問題引起)導致Bigtable中存儲的某些數據無法使用的Bigtable服務小時數的平均百分比爲0.0047%。受Chubby不可用性影響最大的單個集羣的百分比爲0.0326%。

5. 實現

Bigtable實現有三個主要組成:鏈接到每個客戶端的庫,一個主服務器和許多片服務器。可以從集羣中動態添加(或刪除)片服務器,以適應工作負載的變化。

主服務器負責將分片分配給片服務器,檢測片服務器的添加和過期、均衡片服務器負載以及GFS中文件的垃圾收集。此外,它還處理模式更改,例如表和列族創建。

每個片服務器管理一組分片(通常我們每個片服務器有10到1000個分片)。片服務器處理對已加載的分片的讀寫請求,並且還會拆分已經過大的分片。與許多單主分佈式存儲系統[17,21]一樣,客戶端數據不會通過主服務器傳輸:客戶端直接與片服務器通信以進行讀寫。由於Bigtable客戶端不依賴主服務器來獲取分片位置信息,因此大多數客戶端從不與主服務器通信。因此,主服務器的負載實際很輕量。

Bigtable集羣存儲了許多表。每個表包含一組分片,每個分片包含與行範圍相關的所有數據。最初,每個表只包含一個分片。隨着表的增長,它會自動拆分爲多個分片,默認情況下每個大小約爲100-200 MB。

5.1 分片位置

我們使用類似於B+ tree [10]的三級層次結構來存儲分片位置信息(圖4)。

圖4:分片位置層次結構。
第一層是存儲在Chubby中的文件,其中包含根分片的位置。根分片中的特殊METADATA表包含所有分片的位置。每個METADATA分片都包含一組用戶分片的位置。根分片只是METADATA表中的第一個分片,但是經過特殊處理 - 它永遠不會拆分 - 以確保分片位置層次結構不超過三個層級。

METADATA表將分片的位置存儲在行鍵下,該行鍵是片的表標識符及其結束行的編碼。每個METADATA行在內存中的存儲大約爲1KB的數據。由於適度的128 MB METADATA分片的限制,我們的三級定位方案足以定位2^34個分片(或128 MB分片中2^61字節)。

客戶端庫緩存分片位置。如果客戶端不知道分片的位置,或者它發現緩存的位置信息不正確,則它會沿分片位置層次結構遞歸地向上移動。如果客戶端的緩存爲空,則位置算法需要三次網絡往返,包括從Chubby讀取一次。如果客戶端的緩存是陳舊的,則位置算法可能需要六次往返,因爲只有在未命中時纔會發現過時的緩存條目(假設METADATA分片不會頻繁移動)。由於分片位置存儲在內存中,因此不需要訪問GFS,但我們通過使用客戶端庫預拉取分片位置來進一步降低此成本:只要讀取METADATA表,它就會讀取多個分片的元數據。

我們還將輔助信息存儲在METADATA表中,包括與每個分片相關的所有事件的日誌(例如服務器開始提供服務時間)。此信息有助於調試和性能分析。

5.2 片分配

每個分片一次分配給一個片服務器。主服務器會跟蹤活着的片服務器的集合,以及當前的分片到片服務器的分配,包括哪些分片未分配。如果分片未分配,並且一個片服務器具有足夠的空間給該分片,則主服務器會通過向片服務器發送分片加載的請求來分配分片。

Bigtable使用Chubby來跟蹤片服務器。當片服務器啓動時,它會創建並獲取對特定Chubby目錄中唯一命名文件的獨佔鎖。主服務器監控此目錄(服務器目錄)以發現片服務器。如果一個片服務器失去其獨佔鎖,它將停止爲其分片提供服務:例如,由於網絡隔離導致服務器丟失其Chubby會話。(Chubby提供了一種有效的機制,允許片服務器檢查它是否仍然保持鎖而不會產生網絡流量。)只要文件仍然存在,片服務器就會嘗試重新獲取其文件的獨佔鎖。如果該文件不再存在,則片服務器將永遠無法再次服務,因此它會自行終止。每當片服務器終止時(例如,因爲集羣管理系統正在從集羣中移除片服務器的機器),它就會嘗試釋放其鎖定,以便主服務器更快地重新分配其分片。

主服務器負責檢測片服務器何時不再服務其分片,以及儘快重新分配這些分片。要檢測片服務器何時不再爲其分片提供服務,主服務器會定期向每個片服務器詢問其鎖狀態。如果片服務器報告它已失去鎖定,或者主服務器在最近幾次嘗試期間無法訪問服務器,則主服務器會嘗試獲取該服務器文件的獨佔鎖。如果主服務器能夠獲得鎖,則Chubby處於活躍狀態且片服務器已經死機或無法訪問Chubby,因此主服務器確保片服務器永遠不會通過刪除其服務器文件再次服務。一旦服務器文件被刪除後,主服務器可以將之前分配給該服務器的所有分片移動到未分配的分片集合中。爲了確保Bigtable集羣不容易受到主服務器和Chubby之間的網絡問題的影響,如果其Chubby會話到期,主服務器將自行終止。但是,如上所述,主服務器故障不會改變分片到片服務器的分配。

當主服務器被集羣管理系統啓動時,它需要先獲得當前的分片分配,然後才能更改它們。 主服務器在啓動時執行以下步驟。(1) 主服務器在Chubby中獲取一個唯一的主服務器鎖,這會阻止併發的主服務器實例化。(2) 主服務器掃描Chubby中的服務器目錄以查找活躍的服務器。(3) 主服務器與每個活躍片服務器通信,以發現已爲每個服務器分配了哪些分片。(4) 主服務器掃描METADATA表以獲知分片集合。每當此掃描遇到尚未分配的分片時,主服務器會將該分片添加到未分配分片的集合中,這使該分片有資格進行分片分配。

一個複雜的問題是,在分配METADATA分片之前,不能對METADATA表進行掃描。因此,在開始此掃描(步驟4)之前,如果在步驟3中未發現根分片的分配,則主服務器會將根分片添加到未分配的分片集合中。此添加確保將分配根分片。由於根分片包含所有METADATA分片的名稱,因此主服務器在掃描根分片後會知道所有分片。

表的現有分片的集合只有在創建或刪除表、將兩個現有分片合併爲一個更大的分片、或者將現有分片拆分爲兩個較小的分片時纔會更改。主服務器能夠跟蹤這些變化,因爲它會啓動除最後一項之外的所有變化。分片拆分是特殊處理的,因爲它們是由片服務器啓動的。片服務器通過在METADATA表中記錄新分片的信息來提交拆分。拆分提交後,它會通知主服務器。如果拆分通知丟失(由於片服務器或主服務器已經死亡),主服務器會在請求片服務器加載現在已拆分的分片時檢測新分片。片服務器將通知主服務器該拆分,因爲它在METADATA表中找到的分片條目將僅指定主機要求加載的一部分分片。

5.3 片服務器

分片的持久狀態存儲在GFS中,如圖5所示。更新被提交到存儲重做記錄的提交日誌中。在這些更新中,最近提交的更新存儲在稱爲memtable的排序緩衝區的內存中; 較舊的更新存儲在一系列SSTable中。要恢復分片,片服務器會從METADATA表中讀取其元數據。此元數據包含組成分片的SSTable列表和一組重做點,這些重做點是指向可能包含分片數據的任何提交日誌的指針。服務器將SSTable的索引讀入內存,並通過應用自重做點以來已提交的所有更新來重構memtable。

圖5:分片表示
當寫操作到達片服務器時,服務器檢查它是否格式正確,並且發送者是否有權執行變更。通過從Chubby文件中讀取允許的寫入器列表來執行授權(這幾乎總是命中Chubby客戶端緩存)。將有效的變更寫入提交日誌。分組提交用於提高許多小變更的吞吐量[13,16]。寫入提交後,其內容將插入到memtable中。

當讀取操作到達片服務器時,類似地會檢查其是否格式良好並有適當的授權。在SSTables的列表和memtable的合併視圖上執行有效的讀操作。由於SSTable和memtable是按字典序排序的數據結構,因此可以有效地形成合並視圖。

在拆分和合並分片的同時,可以繼續進行讀取和寫入操作。

5.4 壓縮

當寫操作執行時,memtable的大小增加。當memtable大小達到閾值時,memtable被凍結,並創建一個新的memtable,凍結的memtable轉換爲SSTable並寫入GFS。這個minor壓縮過程有兩個目標:它縮小了片服務器的內存使用量,並減少了如果此服務器死機時恢復期間必須從提交日誌中讀取的數據量。壓縮發生時,輸入的讀寫操作可以繼續。

每次minor壓縮都會創建一個新的SSTable。如果此行爲繼續未被遏制,則讀取操作可能需要合併來自任意數量的SSTable的更新。反之,我們通過在後臺定期執行合併壓縮來限制此類文件的數量。合併壓縮讀取一些SSTable和memtable的內容,並寫出一個新的SSTable。壓縮完成後,可以丟棄輸入的SSTable和memtable。

將所有SSTable重寫爲一個SSTable的合併壓縮稱爲major壓縮。非major壓縮生成的SSTable可以包含特殊刪除條目,這些條目可以抑制仍處於活躍狀態的舊SSTable中的已刪除數據。另一方面,major壓縮產生不包含刪除信息或刪除數據的SSTable。Bigtable在其所有分片中循環、並定期對其進行major壓縮。這些major壓縮允許Bigtable回收已刪除數據使用的資源,並允許它確保已刪除的數據及時從系統中消失,這對於存儲敏感數據的服務非常重要。

6. 改進

上一節中描述的實現需要進行一些改進,以實現用戶所需的高性能、可用性和可靠性。本節更詳細地描述了部分實現,以突出顯示這些改進。

6.1 位置分組

客戶端可以將多個列族組合到一個位置分組中。爲每個分片中的每個位置分組生成單獨的SSTable。將通常不一起訪問的列族隔離到不同的位置分組中可以實現更高效的讀取。例如,Webtable中的頁面元數據(例如語言和校驗和)可以位於一個位置分組中,並且頁面的內容可以位於不同的分組中:想要讀取元數據的應用不需要讀取所有頁面內容。

此外,可以基於每個位置分組指定一些有用的調整參數。例如,可以將位置分組聲明到內存中。內存中位置分組的SSTable可以延遲加載到片服務器的內存中。一旦加載後,可以在不訪問磁盤的情況下讀取屬於此位置分組的列族。此功能對於經常訪問的小塊數據非常有用:我們在內部將它用於METADATA表中的位置列族。

6.2 壓縮

客戶端可以控制SSTable是否壓縮一個位置分組,以及如果是,則使用哪種壓縮格式。用戶指定的壓縮格式應用於每個SSTable塊(其大小可通過位置分組的特定調整參數控制)。雖然我們通過單獨壓縮每個塊而損失了一些空間,但我們受益於可以在不解壓縮整個文件的情況下讀取SSTable的一小部分。許多客戶端使用兩遍自定義壓縮方案。 第一遍使用Bentley和McIlroy的方案[6],它在大窗口中壓縮長公共字符串。 第二遍使用快速壓縮算法,該算法在數據的小16 KB窗口中查找重複項。兩種壓縮算法都非常快 - 它們以100-200 MB/s的速度編碼,在現代機器上以400-1000 MB/s的速度進行解碼。

儘管我們在選擇壓縮算法時強調速度而不是空間縮減,但這種兩遍壓縮方案確實出奇的好。例如,在Webtable中,我們使用此壓縮方案來存儲網頁內容。在一個實驗中,我們將大量文檔存儲在壓縮的位置分組中。出於實驗目的,我們限定每個文檔只有一個版本,而不是存儲對我們可用的所有版本。該方案實現了空間減少到10:1。這比基於HTML頁面典型的Gzip壓縮減少到3:1或4:1要好得多,因爲Webtable行的佈局方式:來自同一個主機的所有頁面都彼此靠近存儲。這允許Bentley-McIlroy算法識別來自同一主機的頁面中的大量共享引用。許多應用(不僅僅是Webtable)選擇其行名稱,以便類似的數據最終聚集在一起,從而實現非常好的壓縮率。當我們在Bigtable中存儲相同值的多個版本時,壓縮率會更好。

6.3 爲讀取性能緩存

爲了提高讀取性能,片服務器使用兩級緩存。掃描緩存是一種更高級別的緩存,用於將SSTable接口返回的鍵值對緩存到片服務器代碼中。塊緩存是一個較低級別的緩存,用於緩存從GFS讀取的SSTables塊。掃描緩存對於傾向於重複讀取相同數據的應用最有用。塊緩存對於傾向於讀取與其最近讀取的數據接近的數據的應用(例如,順序讀取,或熱行內相同位置分組中的不同列的隨機讀取)非常有用。

6.4 布隆過濾器

如第5.3節所述,讀取操作必須從組成分片狀態的所有SSTable中讀取。如果這些SSTable不在內存中,我們最終可能會進行許多磁盤訪問。我們通過允許客戶端指定應該爲特定位置分組中的SSTable創建的Bloom過濾器[7]來減少訪問次數。Bloom過濾器允許我們詢問SSTable是否可能包含指定行/列對的任何數據。對於某些應用,用於存儲Bloom過濾器的少量片服務器內存大大減少了讀取操作所需的磁盤搜索次數。我們對Bloom過濾器的使用也意味着對不存在的行或列的大多數查找不需要接觸磁盤。

6.5 提交日誌實現

如果我們將每個分片的提交日誌保存在單獨的日誌文件中,則會在GFS中同時寫入大量文件。依賴於每個GFS服務器上的基礎文件系統實現,這些寫入可能導致大量磁盤搜索以寫入不同的物理日誌文件。此外,每個分片具有單獨的日誌文件也會降低分組提交優化的效果,因爲分組往往會更小。爲了解決這些問題,我們將變更添加到每個片服務器的單個提交日誌中,在同一物理日誌文件[18,20]中混合不同分片的變更。

在正常操作中使用單一日誌可提供顯著的性能優勢,但這會使恢復變得複雜。當片服務器死機時,它所服務的分片將被移動到許多其他片服務器:每臺服務器通常會加載少量原服務器的分片。要恢復分片的狀態,新的片服務器需要從原片服務器寫入的提交日誌中重新應用該分片的變更。但是,這些分片的變更混合在同一物理日誌文件中。一種方法是每個新的片服務器讀取這個完整的提交日誌文件,並僅應用它需要恢復的分片所需的條目。但是,在這樣的方案下,如果從故障片服務器給100臺計算機的每臺計算機分配一個分片,那麼日誌文件將被讀取100次(每個服務器一次)。

我們通過首先按照鍵<table,row name,log sequence number>的順序對提交日誌條目進行排序來避免重複日誌讀取。在排序的輸出中,特定分片的所有變更都是連續的,因此可以通過一次磁盤搜索然後順序讀取來高效讀取。爲了並行化排序,我們將日誌文件分區爲64 MB段,並在不同的片服務器上並行對每個段進行排序。此排序過程由主服務器協調,並在片服務器表示需要從某個提交日誌文件中恢復變更時啓動。

將提交日誌寫入GFS有時會由於各種原因導致性能問題(例如,GFS服務器計算機涉及寫入崩潰中,或者到達特定的三個GFS服務器集合的網絡路徑正在遭受網絡擁塞,或者負載過重)。爲了保護GFS延遲峯值變更,每個片服務器實際上有兩個日誌寫入線程,每個線程寫入自己的日誌文件; 這兩個線程同時只有一個在活躍使用中。如果對活躍日誌文件的寫入性能不佳,則將日誌文件寫入切換到另一個線程,並且提交日誌隊列中的變更由新激活的日誌寫入線程寫入。日誌條目包含序列號,以允許恢復過程忽略由此日誌切換過程產生的重複條目。

6.6 加快分片的恢復速度

如果主服務器將分片從一臺片服務器移動到另一臺,則源片服務器首先會對該分片進行minor壓縮。該壓縮減少了片服務器的提交日誌中未壓縮狀態的數量來縮短恢復時間。完成此壓縮後,片服務器將停止爲該分片提供服務。在實際卸載分片之前,片服務器會執行另一次(通常是非常快速的)minor壓縮,以消除在執行第一次minor壓縮時到達的片服務器日誌中的任何剩餘未壓縮狀態。在完成第二次minor壓縮之後,可以將該分片加載到另一臺片服務器上,而無需任何日誌條目的恢復。

6.7 利用不變性

除了SSTable緩存之外,Bigtable系統的其他各個部分都被簡化了,因爲我們生成的所有SSTable都是不可變的。例如,從SSTables讀取時,我們不需要對訪問文件系統同步。因此,可以非常有效地實現對行的併發控制。讀取和寫入都可訪問的唯一可變數據結構是memtable。爲了減少讀取memtable期間的競爭,我們將memtable的每個行寫入進行寫時複製並允許讀取和寫入並行進行。

由於SSTables是不可變的,因此永久刪除已刪除數據的問題將轉換爲垃圾收集過時的SSTables。每個分片的SSTable都在METADATA表中註冊。主服務器將過時的SSTable利用標記清除垃圾收集[25]從SSTable集合移除,其中METADATA表包含根集合。

最後,SSTables的不變性使我們能夠快速拆分分片。我們讓子分片共享父分片的SSTables,而不是爲每個子分片生成一組新的SSTable。

7. 性能評估

我們搭建了一個帶有N臺片服務器的Bigtable集羣,用於測量Bigtable的性能和可擴展性,因爲N是多變的。片服務器配置爲使用1 GB內存並寫入由1786臺機器組成的GFS單元,每臺機器具有兩個400 GB IDE硬盤驅動。N臺客戶機生成了用於這些測試的Bigtable負載。(我們使用與片服務器相同數量的客戶端來確保客戶端永遠不會成爲瓶頸。)每臺機器都有兩個雙核Opteron 2 GHz芯片,足夠的物理內存來容納所有正在運行的進程的工作集,以及一個千兆比特以太網鏈路。這些機器被安排在一個兩級樹形交換網絡中,根部有大約100-200 Gbps的總帶寬。所有機器都在同一個託管設施中,因此任何兩臺機器之間的往返時間不到一毫秒。

片服務器和主服務器,測試客戶端和GFS服務器都運行在同一組計算機上。每臺機器都運行一個GFS服務器。某些計算機還運行片服務器或客戶端進程,或者與這些實驗同時使用資源池的其他作業的進程。

R是測試中涉及的Bigtable不同行鍵的數量。選擇R以使每個基準測試從每個片服務器讀取或寫入大約1 GB的數據。

順序寫入基準測試使用名稱爲0到R-1的行鍵。行鍵的這個空間被劃分爲10N個相等大小的範圍。這些範圍由中央調度程序分配給N個客戶端,一旦客戶端處理完成分配給它的前一個範圍,就將下一個可用範圍分配給該客戶端。此動態分配有助於減輕由客戶端計算機上運行的其他進程引起的性能變化的影響。我們在每個行鍵下面寫了單個字符串。每個字符串都是隨機生成的,因此是不可壓縮的。另外,不同行鍵下的字符串是不同的,因此不可能進行跨行壓縮。隨機寫入基準測試是類似的,除了在寫入之前立即對行鍵進行模數R散列,以便在整個基準測試持續時間內將寫入負載大致均勻地分佈在整個行空間中。

圖6:每秒讀/寫的1000字節的數量。該表顯示了每臺片服務器的速率; 該圖顯示了總速率。
順序讀取基準測試以與順序寫入基準測試完全相同的方式生成行鍵,但不是在行鍵下寫入,而是讀取存儲在行鍵下的字符串(由早期的順序寫入基準測試調用寫入)。類似地,隨機讀取基準測試隱藏了隨機寫入基準測試的操作。

掃描基準測試與順序讀取基準測試類似,但使用Bigtable API提供的支持以掃描行範圍內的所有值。由於單個RPC從片服務器獲取大量值,因此使用掃描可減少基準測試執行的RPC數量。隨機讀取(mem)基準測試類似於隨機讀取基準測試,但包含有基準測試數據的位置分組被標記在內存中,因此從片服務器的內存中讀取數據,而不是需要GFS讀取。對於此基準測試,我們將每臺片服務器的數據量從1 GB減少到100 MB,以便它可以輕鬆被放入片服務器可用的內存中。

圖6顯示了在向Bigtable讀取和寫入1000字節值時基準測試性能的兩個視圖。該表顯示了每臺片服務器每秒的操作數; 該圖顯示了每秒的總操作數。

7.1 單個片服務器性能

讓我們首先考慮一臺片服務器的性能。隨機讀取比所有其他操作慢一個數量級或更多。每次隨機讀取都涉及通過網絡將64 KB SSTable塊從GFS傳輸到片服務器,其中只使用了1000字節的值。片服務器每秒執行大約1200次讀取,這轉換爲從GFS大約75 MB/s的數據讀取。由於我們的網絡堆棧、SSTable解析和Bigtable代碼的開銷,這個帶寬足以使片服務器CPU飽和,並且幾乎足以使我們系統中使用的網絡鏈路飽和。具有此類訪問模式的大多數Bigtable應用將塊大小減小到較小的值,通常爲8KB。

從內存中隨機讀取要快得多,因爲每1000字節的讀取從片服務器的本地內存中讀取而不從GFS獲取大的64 KB塊。

隨機和順序寫入比隨機讀取執行得更好,因爲每個片服務器將所有輸入的寫入附加到單個提交日誌中,並使用分組提交將這些寫入有效地流式傳輸到GFS。隨機寫入和順序寫入的性能沒有顯著差異; 在這兩種情況下,對片服務器的所有寫入都記錄在同一個提交日誌中。

順序讀取比隨機讀取執行得更好,因爲從GFS獲取的每個64 KB SSTable塊都存儲在我們的塊緩存中,用於爲接下來的64個讀取請求提供服務。

由於片服務器可以返回大量值以響應單個客戶端RPC,因此掃描速度更快,因此RPC開銷會在大量值上分攤。

7.2 擴展性

隨着我們將系統中的片服務器數量從1增加到500,總體吞吐量急劇增加了一百倍。例如,當片服務器增加500倍,內存中隨機讀取的性能增加了近300倍。出現這種情況是因爲此基準測試的性能瓶頸是單個片服務器CPU。

但是,性能沒有線性增加。對於大多數基準測試,從1臺到50臺片服務器時,每臺服務器吞吐量顯著下降。這種下降是由多個服務器配置中的負載不平衡引起的,通常是由於其他進程爭用CPU和網絡。我們的負載均衡算法試圖解決這種不平衡問題,但由於兩個主要原因無法完成工作:重新均衡會受限於減少分片的移動次數(分片短時間內不可用,當移動它時通常不到一秒鐘),隨着基準測試的前進,我們的基準測試產生的負載會隨之偏移。

隨機讀取基準測試顯示了最差的擴展(服務器數量增加了500倍,總吞吐量增加了100倍)。出現此問題的原因是(如上所述)我們通過網絡爲每1000字節讀取傳輸一個大的64KB塊。這種傳輸使我們網絡中各個共享的1千兆比特鏈路達到飽和,因此,隨着我們增加機器數量,每臺服務器吞吐量顯著下降。

8. 實際應用

截至2006年8月,共有388個非測試Bigtable集羣在各Google機器集羣中運行,總計約24500臺片服務器。表1顯示了每個集羣的片服務器的粗略分佈。許多這些集羣用於開發目的,因此在很長一段時間內處於閒置狀態。一組14個繁忙的集羣,總計8069個片服務器,每秒的請求總量超過120萬,輸入的RPC流量約爲741 MB/s,輸出的RPC流量約爲16 GB/s。

表1:Bigtable集羣中片服務器數量的分佈。
表2提供了有關當前使用的一些表的一些數據。有些表存儲提供給用戶服務的數據,而有些表存儲用於批處理的數據; 這些表在包括總大小、平均單元大小、從內存提供的數據百分比以及表模式的複雜性方面範圍很廣。在本節的其餘部分,我們將簡要介紹三個產品團隊如何使用Bigtable。

表2:生產用途中幾個表的特徵。表大小(壓縮前測量)和#Cells表示大致尺寸。對於已禁用壓縮的表,未給出壓縮率。

8.1 Google Analytics

Google Analytics(analytics.google.com)是一項服務,可幫助網站管理員分析其網站上的流量模式。它提供了彙總統計信息,例如每天唯一身份訪問者的數量和每個URL每天的網頁瀏覽量,以及網站跟蹤報告,例如進行購買的用戶百分比,因爲他們之前查看過特定網頁。

爲了啓用該服務,網站管理員在其網頁中嵌入了一個小型JavaScript程序。每當訪問頁面時都會調用此程序。它會在Google Analytics中記錄有關請求的各種信息,例如用戶標識符和有關正在獲取的頁面的信息。Google Analytics彙總了這些數據,並將其提供給網站管理員。

我們簡要介紹Google Analytics使用的兩個表。原始點擊表(~200 TB)爲每個終端用戶會話維護一行。行名稱是一個元組,包含網站的名稱和創建會話的時間。此模式可確保訪問同一網站的會話是連續的,並且它們按時間順序排序。此表壓縮到原始大小的14%。

摘要表(~20 TB)包含每個網站的各種預定義摘要。此表是通過定期調度的MapReduce作業從原始點擊表生成的。每個MapReduce作業都從原始點擊表中提取最近的會話數據。整個系統的吞吐量受到GFS吞吐量的限制。此表壓縮到原始大小的29%。

8.2 Google Earth

Google通過基於網絡的Google地圖界面(maps.google.com)和Google Earth(earth.google.com)顧客客戶端軟件運營一系列服務,爲用戶提供訪問世界範圍地面的高分辨率衛星圖像的權限。這些產品允許用戶在世界各地進行導航:他們可以在許多不同級別的分辨率下平移、查看和標註衛星圖像。該系統使用一個表來預處理數據,使用一組不同的表來提供客戶端數據。

預處理管道使用一個表來存儲原始圖像。在預處理期間,圖像被清理併合併到最終的服務數據中。該表包含大約70 TB的數據,因此從磁盤提供服務。圖像已經被有效壓縮,因此禁用Bigtable壓縮。

圖像表中的每一行對應一個地理段。命名行以確保相鄰的地理段彼此靠近存儲。該表包含一個列族,用於跟蹤每個段的數據源。此列族具有大量列:基本上每個原始數據一列。由於每個段僅由幾個圖像構成,因此該列族非常稀疏。

預處理管道在很大程度上依賴於Bigtable上的MapReduce來轉換數據。在某些MapReduce作業期間,整個系統的每個片服務器處理超過1 MB/s的數據。

服務系統使用一個表來索引存儲在GFS中的數據。此表相對較小(~500 GB),但每個數據中心每秒必須提供數萬個低延遲的查詢。因此,該表託管在數百臺片服務器上,並在內存中容納列族。

8.3 Personalized Search

Personalized Search(www.google.com/psearch)是一項選擇性服務,可記錄用戶在各種Google業務上的查詢和點擊,例如網絡搜索、圖片和新聞。用戶可以瀏覽他們的搜索歷史記錄以重新訪問他們的舊查詢和點擊,他們可以根據他們歷史的Google使用模式請求個性化搜索結果。

Personalized Search將每個用戶的數據存儲在Bigtable中。每個用戶都有一個唯一的userid,並被分配一個由該userid命名的行。所有用戶操作都存儲在表中。爲每種類型的操作保留單獨的列族(例如,存在存儲所有Web查詢的列族)。每個數據元素使用Bigtable時間戳作爲對應用戶操作發生的時間。Personalized Search使用Bigtable上的MapReduce生成用戶畫像。這些用戶畫像用於個性化實時搜索結果。

Personalized Search數據在多個Bigtable集羣中進行復制,以提高可用性並減少因與客戶端的距離而導致的延遲。Personalized Search團隊最初在Bigtable之上構建了一個客戶端複製機制,並確保了所有副本的最終一致性。當前系統現在使用內置於服務器中的複製子系統。

Personalized Search存儲系統的設計允許其他團隊在其自己的列中添加新的每個用戶的信息,並且該系統現在被許多其他需要存儲每個用戶的配置選項和設置的Google業務使用。在許多團隊之間共享一個表導致了非常多的列族。爲了幫助支持共享,我們爲Bigtable添加了一個簡單的配額機制,以限制共享表中任何特定客戶端的存儲消耗; 此機制在使用此係統的各個產品團隊之間爲每個用戶的信息存儲提供了一些隔離。

9. 教訓

在設計、實施、維護和支持Bigtable的過程中,我們獲得了有用的經驗,並學到了幾個有趣的教訓。

我們學到的一個教訓是,大型分佈式系統容易受到許多類型的故障的影響,而不僅僅是許多分佈式協議中假設的標準網絡分區和失敗停止故障。例如,我們看到了由於以下所有原因導致的問題:內存和網絡損壞、大的時鐘偏差、掛機、擴展和非對稱網絡分區、我們正在使用的其他系統中的錯誤(例如Chubby)、GFS配額溢出、計劃內和計劃外硬件維護。由於我們已經獲得了更多這些問題的經驗,我們通過改變各種協議來解決它們。例如,我們將校驗和添加到RPC機制中。我們還通過去除系統的一部分關於另一部分的假設來處理一些問題。例如,我們停止假設給定的Chubby操作只能返回一組固定的錯誤。

我們學到的另一個教訓是,在明確如何使用新功能之前,延遲添加新功能非常重要。例如,我們最初計劃在API中支持通用事務。但是,由於我們沒有立即使用它們,因此我們沒有實現它們。既然我們在Bigtable上運行了許多真正的應用,我們就能夠檢驗它們的實際需求,並發現大多數應用只需要單行事務。在人們要求分佈式事務的地方,最重要的用途是維護二級索引,我們計劃增加一種專門的機制來滿足這種需求。新機制不如分佈式事務通用,但效率更高(特別是對於跨越數百行或更多行的更新),並且還可以更好地與我們的樂觀的跨數據中心複製方案進行交互。

我們從支持Bigtable中學到的實用的經驗教訓是適當的系統級監控的重要性(即監控Bigtable本身以及使用Bigtable的客戶端進程)。例如,我們擴展了我們的RPC系統,以便對於RPC的樣本,它保留了代表該RPC重要操作完成的詳細跟蹤。此功能使我們能夠檢測並修復許多問題,例如分片數據結構上的鎖競爭、提交Bigtable變更時寫入GFS的速度慢、以及當METADATA分片不可用時對METADATA表的訪問卡頓。另一個有用的監控示例是每個Bigtable集羣都在Chubby中註冊。這使我們能夠追蹤所有集羣、發現它們有多大、查看它們運行的軟件版本、接收的流量、以及是否存在任何問題,例如意外的大延遲。

我們學到的最重要的教訓是簡單設計的價值。鑑於我們系統的大小(大約100000行非測試代碼),以及代碼以意想不到的方式隨時間演變的事實,我們發現代碼和設計的清晰度對代碼維護和調試有很大幫助。其中一個例子是我們的片服務器成員協議。我們的第一個協議很簡單:主服務器定期向片服務器發放租約,如果租約到期,片服務器會自行終止。遺憾的是,該協議在存在網絡問題時顯著降低了可用性,並且對主服務器恢復時間也很敏感。我們重新設計了協議幾次,直到我們有一個表現良好的協議。但是,生成的協議過於複雜,並且依賴於其他應用很少使用的Chubby功能的行爲。我們發現,我們花費了大量時間來調試模糊的角落情況,不僅在Bigtable代碼中,而且在Chubby代碼中。最終,我們取消了這個協議並轉而採用了一種更簡單的新協議,該協議完全取決於廣泛使用的Chubby功能。

10. 相關工作

Boxwood項目[24]的組件在某些方面與Chubby、GFS和Bigtable重疊,因爲它提供分佈式協議、鎖、分佈式塊存儲和分佈式B樹存儲。在存在重疊的每種情況下,看起來Boxwood的組件的目標水平低於相應的Google服務。Boxwood項目的目標是爲構建更高級別的服務(如文件系統或數據庫)提供基礎設施,而Bigtable的目標是直接支持希望存儲數據的客戶端應用。

許多最近的項目已經解決了通過廣域網(通常是“互聯網規模”)提供分佈式存儲或更高級別服務的問題。這包括以CAN[29]、Chord[32]、Tapestry[37]和Pastry[30]等項目開始的分佈式哈希表的工作。這些系統解決了Bigtable不會出現的問題,例如高度可變的帶寬、不可信的參與者或頻繁的重新配置; 分散控制和拜占庭容錯並不是Bigtable的目標。

就應用開發者可能提供的分佈式數據存儲模型而言,我們認爲分佈式B樹或分佈式哈希表提供的鍵值對模型過於侷限。鍵值對是一個有用的構建塊,但它們不應該是爲開發者提供的唯一構建塊。我們選擇的模型比簡單的鍵值對更豐富,並支持稀疏的半結構化數據。儘管如此,它仍然很簡單,它是一個非常有效的平面文件表示,並且它足夠透明(通過位置分組),以允許我們的用戶調整系統的重要行爲。

一些數據庫供應商開發了可以存儲大量數據的並行數據庫。Oracle的Real Application Cluster數據庫[27]使用共享磁盤來存儲數據(Bigtable使用GFS)和分佈式鎖管理器(Bigtable使用Chubby)。IBM的DB2 Parallel Edition[4]基於類似於Bigtable的非共享[33]架構。每個DB2服務器負責存儲在本地關係數據庫中表的行的子集。這兩種產品對其完整的關係模型都提供了事務。

Bigtable位置分組實現了類似的壓縮和磁盤讀取性能優勢,這些優勢來自於其他在磁盤上使用基於列的存儲而不是基於行的存儲組織數據的系統(包括C-Store[1,34]和商業產品,如Sybase IQ[15, 36]、SenSage[31]、KDB +[22]和MonetDB/X100中的ColumnBM存儲層[38])。另一個將垂直和水平數據分成平面文件並實現良好數據壓縮率的系統是AT&T的Daytona數據庫[19]。位置分組不支持CPU緩存級優化,例如Ailamaki[2]所描述的優化。

Bigtable使用memtables和SSTables將更新存儲到分片的方式類似於Log-Structured Merge Tree[26]存儲對索引數據的更新的方式。在兩個系統中,排序數據在寫入磁盤之前都在內存中緩存,讀取必須合併內存和磁盤中的數據。

C-Store和Bigtable共享許多特性:兩個系統都使用非共享體系結構,並且具有兩種不同的數據結構,一種用於最近的寫入,另一種用於存儲長期存在的數據,具有將數據從一種形式移動到另一種形式的機制。這些系統的API差別很大:C-Store的行爲類似於關係數據庫,而Bigtable提供較低級別的讀寫接口,旨在支持每臺服務器每秒數千次此類操作。C-Store也是“讀取優化的關係型DBMS”,而Bigtable在讀取密集型和寫入密集型應用上都提供了良好的性能。

Bigtable的負載均衡器必須解決非共享數據庫所面臨的一些相同類型的負載和內存平衡問題(例如,[11,35])。我們的問題稍微簡單一點:(1) 我們不考慮相同數據(可能是由於視圖或索引的替代形式)的多個副本的可能性; (2) 我們讓用戶告訴我們哪些數據屬於內存,哪些數據應保留在磁盤上,而不是試圖動態確定; (3) 我們沒有複雜的查詢來執行或優化。

11. 總結

我們已經描述了Bigtable,一種在Google中用於存儲結構化數據的分佈式系統。Bigtable集羣自2005年4月開始投入生產使用,在此之前我們在設計和實施上花費了大約7個人年。截至2006年8月,超過60個項目正在使用Bigtable。我們的用戶喜歡Bigtable實現提供的性能和高可用性,並且他們可以通過在系統資源需求隨時間變化時向系統添加更多計算機來擴展其集羣的容量。

鑑於Bigtable的不尋常的接口,一個有趣的問題是我們的用戶適應使用它有多困難。新用戶有時不確定如何最好地使用Bigtable接口,特別是如果他們習慣於使用支持通用事務的關係數據庫。儘管如此,許多Google產品成功使用Bigtable的事實表明我們的設計在實踐中運作良好。

我們正在實現其他幾個Bigtable功能,例如支持二級索引和構建跨數據中心複製的多主服務器副本的Bigtables的基礎設施。我們還開始將Bigtable作爲服務部署到產品團隊,以便各個團隊不需要維護自己的集羣。隨着我們服務集羣的擴展,我們需要在Bigtable內部處理更多的資源共享問題[3,5]。

最後,我們發現在Google內構建自己的存儲解決方案有很大的優勢。通過爲Bigtable設計我們自己的數據模型,我們獲得了很大的靈活性。此外,我們對Bigtable的實現以及Bigtable所依賴的其他Google基礎設施的控制意味着我們可以消除他們出現的瓶頸和低效率。

致謝

我們感謝匿名審稿人David Nagle和我們的上級Brad Calder對本文的反饋。Bigtable系統受益於Google內衆多用戶的反饋。此外,我們感謝以下人士對Bigtable的貢獻:Dan Aguayo,Sameer Ajmani,Zhifeng Chen,Bill Coughran,Mike Epstein,Healfdene Goguen,Robert Griesemer,Jeremy Hylton,Josh Hyman,Alex Khesin,Joanna Kulik,Alberto Lerner, Sherry Listgarten,Mike Maloney,Eduardo Pinheiro,Kathy Polizzi,Frank Yellin和Arthur Zwiegincew。

參考文獻

  1. ABADI, D. J., MADDEN, S. R., AND FERREIRA, M. C. Integrating compression and execution in columnoriented database systems. Proc. of SIGMOD (2006).
  2. AILAMAKI, A., DEWITT, D. J., HILL, M. D., AND SKOUNAKIS, M. Weaving relations for cache performance. In The VLDB Journal (2001), pp. 169-180.
  3. BANGA, G., DRUSCHEL, P., AND MOGUL, J. C. Resource containers: A new facility for resource management in server systems. In Proc. of the 3rd OSDI (Feb. 1999), pp. 45-58.
  4. BARU, C. K., FECTEAU, G., GOYAL, A., HSIAO, H., JHINGRAN, A., PADMANABHAN, S., COPELAND, G. P., AND WILSON, W. G. DB2 parallel edition. IBM Systems Journal 34, 2 (1995), 292-322.
  5. BAVIER, A., BOWMAN, M., CHUN, B., CULLER, D., KARLIN, S., PETERSON, L., ROSCOE, T., SPALINK, T., AND WAWRZONIAK, M. Operating system support for planetary-scale network services. In Proc. of the 1st NSDI (Mar. 2004), pp. 253-266.
  6. BENTLEY, J. L., AND MCILROY, M. D. Data compression using long common strings. In Data Compression Conference (1999), pp. 287-295.
  7. BLOOM, B. H. Space/time trade-offs in hash coding with allowable errors. CACM 13, 7 (1970), 422-426.
  8. BURROWS, M. The Chubby lock service for looselycoupled distributed systems. In Proc. of the 7th OSDI (Nov. 2006).
  9. CHANDRA, T., GRIESEMER, R., AND REDSTONE, J. Paxos made live —— An engineering perspective. In Proc. of PODC (2007).
  10. COMER, D. Ubiquitous B-tree. Computing Surveys 11, 2 (June 1979), 121-137.
  11. COPELAND, G. P., ALEXANDER, W., BOUGHTER, E. E., AND KELLER, T. W. Data placement in Bubba. In Proc. of SIGMOD (1988), pp. 99-108.
  12. DEAN, J., AND GHEMAWAT, S. MapReduce: Simplified data processing on large clusters. In Proc. of the 6th OSDI (Dec. 2004), pp. 137-150.
  13. DEWITT, D., KATZ, R., OLKEN, F., SHAPIRO, L., STONEBRAKER, M., AND WOOD, D. Implementation techniques for main memory database systems. In Proc. of SIGMOD (June 1984), pp. 1-8.
  14. DEWITT, D. J., AND GRAY, J. Parallel database systems: The future of high performance database systems. CACM 35, 6 (June 1992), 85-98.
  15. FRENCH, C. D. One size fits all database architectures do not work for DSS. In Proc. of SIGMOD (May 1995), pp. 449-450.
  16. GAWLICK, D., AND KINKADE, D. Varieties of concurrency control in IMS/VS fast path. Database engineering Bulletin 8, 2 (1985), 3-10.
  17. GHEMAWAT, S., GOBIOFF, H., AND LEUNG, S.-T. The Google file system. In Proc. of the 19th ACM SOSP (Dec. 2003), pp. 29-43.
  18. GRAY, J. Notes on database operating systems. In Operating Systems —— An Advanced Course, vol. 60 of Lecture Notes in Computer Science. Springer-Verlag, 1978.
  19. GREER, R. Daytona and the fourth-generation language Cymbal. In Proc. of SIGMOD (1999), pp. 525-526.
  20. HAGMANN, R. Reimplementing the Cedar file system using logging and group commit. In Proc. of the 11th SOSP (Dec. 1987), pp. 155-162.
  21. HARTMAN, J. H., AND OUSTERHOUT, J. K. The Zebra striped network file system. In Proc. of the 14th SOSP (Asheville, NC, 1993), pp. 29-43.
  22. KX.COM. kx.com/products/database.php. Product page.
  23. LAMPORT, L. The part-time parliament. ACM TOCS 16, 2 (1998), 133-169.
  24. MACCORMICK, J., MURPHY, N., NAJORK, M., THEKKATH, C. A., AND ZHOU, L. Boxwood: Abstractions as the foundation for storage infrastructure. In Proc. of the 6th OSDI (Dec. 2004), pp. 105-120.
  25. MCCARTHY, J. Recursive functions of symbolic expressions and their computation by machine. CACM 3, 4 (Apr. 1960), 184-195.
  26. O’NEIL, P., CHENG, E., GAWLICK, D., AND O’NEIL, E. The log-structured merge-tree (LSM-tree). Acta Inf. 33, 4 (1996), 351-385.
  27. ORACLE.COM. www.oracle.com/technology/products/-database/clustering/index.html. Product page.
  28. PIKE, R., DORWARD, S., GRIESEMER, R., AND QUINLAN, S. Interpreting the data: Parallel analysis with Sawzall. Scientific Programming Journal 13, 4 (2005), 227-298.
  29. RATNASAMY, S., FRANCIS, P., HANDLEY, M., KARP, R., AND SHENKER, S. A scalable content-addressable network. In Proc. of SIGCOMM (Aug. 2001), pp. 161-172.
  30. ROWSTRON, A., AND DRUSCHEL, P. Pastry: Scalable, distributed object location and routing for largescale peer-to-peer systems. In Proc. of Middleware 2001 (Nov. 2001), pp. 329-350.
  31. SENSAGE.COM. sensage.com/products-sensage.htm.Product page.
  32. STOICA, I., MORRIS, R., KARGER, D., KAASHOEK, M. F., AND BALAKRISHNAN, H. Chord: A scalable peer-to-peer lookup service for Internet applications. In Proc. of SIGCOMM (Aug. 2001), pp. 149-160.
  33. STONEBRAKER, M. The case for shared nothing. Database Engineering Bulletin 9, 1 (Mar. 1986), 4-9.
  34. STONEBRAKER,M., ABADI, D. J., BATKIN, A., CHEN, X., CHERNIACK, M., FERREIRA, M., LAU, E., LIN, A., MADDEN, S., O’NEIL, E., O’NEIL, P., RASIN, A., TRAN, N., AND ZDONIK, S. C-Store: A columnoriented DBMS. In Proc. of VLDB (Aug. 2005), pp. 553-564.
  35. STONEBRAKER, M., AOKI, P. M., DEVINE, R., LITWIN, W., AND OLSON, M. A. Mariposa: A new architecture for distributed data. In Proc. of the Tenth ICDE (1994), IEEE Computer Society, pp. 54-65.
  36. SYBASE.COM. www.sybase.com/products/databaseservers/sybaseiq. Product page.
  37. ZHAO, B. Y., KUBIATOWICZ, J., AND JOSEPH, A. D. Tapestry: An infrastructure for fault-tolerant wide-area location and routing. Tech. Rep. UCB/CSD-01-1141, CS Division, UC Berkeley, Apr. 2001.
  38. ZUKOWSKI, M., BONCZ, P. A., NES, N., AND HEMAN, S. MonetDB/X100 —— A DBMS in the CPU cache. IEEE
    Data Eng. Bull. 28, 2 (2005), 17-22.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章