Scuba: Diving into Data at Facebook
概要
Facebook很重視性能監(jiān)控。一些性能問題可能會(huì)影響超過10億用戶,所以我們跟蹤了成千上萬的服務(wù)器,每天上百PB的網(wǎng)絡(luò)流量,每天上百個(gè)代碼變更,以及許多其他指標(biāo)。我們對(duì)時(shí)延性的要求是,在事件發(fā)生后的一分鐘內(nèi),如一個(gè)客戶電話請(qǐng)求,一個(gè)提交了bug報(bào)告,一份新的代碼變更, 能及時(shí)更新到圖表,并在監(jiān)控系統(tǒng)中展示出來。
Scuba是Facebook的數(shù)據(jù)管理系統(tǒng),用于大部分的實(shí)時(shí)分析。Scuba是一個(gè)快速的、可擴(kuò)展的、分布式的、內(nèi)存式的 Facebook 自研數(shù)據(jù)庫。它目前吞吐率為每秒數(shù)百萬行(事件)流入,并以同樣的速度過期數(shù)據(jù)進(jìn)行流出。Scuba存儲(chǔ)后端在數(shù)百臺(tái)服務(wù)器上,每臺(tái)服務(wù)器上的數(shù)據(jù)完全在內(nèi)存中,每臺(tái)服務(wù)器內(nèi)存規(guī)格為 144 GB RAM。為了處理每個(gè)查詢,Scuba 會(huì)從所有的數(shù)據(jù)中聚合服務(wù)器以處理每天處理近百萬次查詢。
在 Facebook, Scuba 廣泛應(yīng)用于交互式、臨時(shí)性的分析查詢,這些查詢運(yùn)行在在一秒內(nèi)完成對(duì)實(shí)時(shí)數(shù)據(jù)的處理。
1. 介紹
在Facebook,無論是診斷性能回歸還是衡量基礎(chǔ)設(shè)施變化帶來的影響,我們都希望用有效數(shù)據(jù)來衡量。Facebook基礎(chǔ)設(shè)施團(tuán)隊(duì)依靠的是在實(shí)時(shí)數(shù)據(jù)監(jiān)控以確保網(wǎng)站始終運(yùn)行順利。我們的需求包括能在非常短的延遲(通常在一分鐘以內(nèi))從運(yùn)行Facebook的網(wǎng)絡(luò)服務(wù)器上查詢到發(fā)生的事件。查詢數(shù)據(jù)的靈活性和速度對(duì)于診斷出問題根因帶來不少收益。識(shí)別問題的根本原因往往是由于各子系統(tǒng)之間復(fù)雜的依賴關(guān)系,很難在短時(shí)間內(nèi)完成。然而,一旦出現(xiàn)了沒有在幾分鐘或幾小時(shí)未解決的問題。那 Facebook 的10億用戶就會(huì)變得不快樂,從而對(duì) Facebook 整體發(fā)展不利。
為了解決上述問題, 起初,我們依靠的是預(yù)先匯總的圖表和一套精心管理、手工編碼的腳本,通過MySQL數(shù)據(jù)庫的形式管理數(shù)據(jù)。到了2011年,這個(gè)解決方案變得過于僵化和緩慢。它無法跟上不斷增長(zhǎng)的數(shù)據(jù)吞吐率和查詢效率。而 Facebook內(nèi)部的其他查詢系統(tǒng),比如Hive[20]和Peregrine[13],在數(shù)據(jù)被提供給查詢之前,查詢數(shù)據(jù)被寫入HDFS,有很長(zhǎng)的(典型的一天)延遲,而查詢本身需要幾分鐘的時(shí)間來運(yùn)行。
因此,我們建立了Scuba,一個(gè)快速、可擴(kuò)展、內(nèi)存數(shù)據(jù)庫。Scuba 是我們收集和分析來自各種系統(tǒng)的數(shù)據(jù)的方式的一個(gè)重大演變,正是這些系統(tǒng)保證了網(wǎng)站每天的正常運(yùn)行。我們現(xiàn)在使用 Scuba 能對(duì)大多數(shù)實(shí)時(shí)的、結(jié)構(gòu)化的人工數(shù)據(jù)進(jìn)行分析。我們將在本文后面將 Scuba 與其他數(shù)據(jù)管理系統(tǒng)進(jìn)行比較,但據(jù)我們了解,沒有任何其他系統(tǒng)能像 Scuba 一樣快速地吞吐數(shù)據(jù)并進(jìn)行復(fù)雜的查詢。
如今,Scuba運(yùn)行在數(shù)百臺(tái)服務(wù)器上,每臺(tái)服務(wù)器有144 GB內(nèi)存,在一個(gè)無共享架構(gòu)的集群中。它在內(nèi)存中為1000多個(gè)表存儲(chǔ)了大約70TB的壓縮數(shù)據(jù),通過在所有服務(wù)器上隨機(jī)分配每個(gè)表來分配內(nèi)存。Scuba每秒可處理數(shù)百萬行。由于 Scuba 是內(nèi)存綁定的,它能以同樣的速度過期掉老數(shù)據(jù)。為了限制數(shù)據(jù)量,Scuba允許行指定一個(gè)可選的采樣率,這表明Scuba只包含原始事件的一小部分(通常是100分之一到100萬分之一)。這種采樣對(duì)于像 Facebook 客戶端請(qǐng)求這樣每秒發(fā)生數(shù)百萬次的事件是十分必要的。采樣可以是統(tǒng)一的,也可以是基于一些關(guān)鍵數(shù)據(jù),比如用戶ID等。Scuba在計(jì)算匯總時(shí),會(huì)對(duì)采樣率進(jìn)行聚合補(bǔ)償。
除了提供一個(gè) SQL 查詢接口(對(duì)于一個(gè) SQL 子集,包括分組和聚合,但不包括連接表),Scuba 提供了一個(gè) GUI,可以生成時(shí)間序列圖、餅圖、列值分布,以及除文本選項(xiàng)之外的其他十幾種數(shù)據(jù)的可視化。圖1顯示了一個(gè)時(shí)間序列圖,在Scuba GUI中對(duì)頁面流量進(jìn)行了一周的比較。在后臺(tái),一個(gè)聚合樹將每個(gè)查詢分發(fā)到每個(gè)服務(wù)器,然后收集結(jié)果發(fā)回客戶端。
雖然Scuba是為了支持性能分析而建立的,但它很快就成為了在其他時(shí)間敏感數(shù)據(jù)上執(zhí)行探索性查詢的首選系統(tǒng)。Facebook的許多團(tuán)隊(duì)都在使用Scuba。
移動(dòng)開發(fā)團(tuán)隊(duì)使用Scuba來跟蹤哪些用戶在運(yùn)行不同的移動(dòng)設(shè)備、操作系統(tǒng)和Facebook應(yīng)用的版本。
廣告開發(fā)團(tuán)隊(duì)利用Scuba 來監(jiān)控人們對(duì)廣告的印象、點(diǎn)擊和收入的變化。當(dāng)出現(xiàn)下降時(shí),他們可以迅速將其縮小到特定的國(guó)家、廣告類型或服務(wù)器集群,并確定根本問題。
SRE 團(tuán)隊(duì)過使用Scuba觀察服務(wù)器錯(cuò)誤。當(dāng)發(fā)生峰值時(shí),他們可以精確地指出是否是由于特定端點(diǎn)中的錯(cuò)誤、特定數(shù)據(jù)中心或服務(wù)器集群中的服務(wù),或數(shù)據(jù)中心的部分物理問題。
錯(cuò)誤報(bào)告監(jiān)測(cè)每小時(shí)運(yùn)行數(shù)千次查詢,以尋找Facebook用戶報(bào)告的錯(cuò)誤數(shù)量高峰,按幾十個(gè)人口統(tǒng)計(jì)維度(位置、年齡、好友數(shù)等)進(jìn)行分組。

總的來說,用戶會(huì)先提出高級(jí)別的匯總查詢,以識(shí)別數(shù)據(jù)中的有趣現(xiàn)象,然后再深入挖掘(因此被稱為Scuba),以找到感興趣的基礎(chǔ)數(shù)據(jù)點(diǎn)。在上述所有情況下,能夠沿著多個(gè)維度對(duì)數(shù)據(jù)進(jìn)行臨時(shí)分解是至關(guān)重要的。
同時(shí) Scuba 也是 Facebook 代碼回歸分析工具、bug 報(bào)告監(jiān)控工具、實(shí)時(shí)帖子監(jiān)控工具(例如,有多少 Facebook 帖子提到了電影 "Argo"?)以及許多其他工具的基礎(chǔ)引擎。Scuba的主要特點(diǎn)是,即使在掃描數(shù)百GB的數(shù)據(jù)時(shí),查詢的執(zhí)行時(shí)間也不到一秒鐘,而且結(jié)果通常是實(shí)時(shí)的,超過一分鐘前發(fā)生的事件。
在第 2 節(jié)中,我們描述了 Scuba 在 Facebook 具體落地的一些用例,包括性能監(jiān)控、趨勢(shì)發(fā)現(xiàn)和模式挖掘。第3節(jié)詳細(xì)描述了Scuba的架構(gòu)、存儲(chǔ)和查詢功能。在第 4 節(jié)中,我們提出了 Scuba 查詢執(zhí)行的簡(jiǎn)單分析模型。在第 5 節(jié)中,我們通過實(shí)驗(yàn)對(duì) Scuba 進(jìn)行了具體評(píng)估。我們用真實(shí)的數(shù)據(jù)和查詢來研究它的加速和擴(kuò)展特性。在第 6 節(jié)中,我們將 Scuba 與業(yè)界相關(guān)工作進(jìn)行比較。在第 7 節(jié)中,我們以列出 Scuba 與其他大多數(shù)數(shù)據(jù)庫系統(tǒng)的不同之處作為結(jié)論。通過上面這些差異使得Scuba更適合我們?cè)贔acebook的使用。
2. Scuba 使用場(chǎng)景
Scuba目前存儲(chǔ)了1000多個(gè)表。在本節(jié)中,我們將描述Scuba的幾個(gè)代表性用例。
2.1 性能分析
Scuba最原始也是最常見的用途是用于實(shí)時(shí)性能監(jiān)控。Julie 負(fù)責(zé)監(jiān)控 facebook.com 的性能。她會(huì)首先查看Scuba儀表板上的幾十個(gè)圖表,這些圖表顯示了服務(wù)器上的CPU負(fù)載;緩存請(qǐng)求、緩存命中和緩存丟失的次數(shù);網(wǎng)絡(luò)吞吐量;以及許多其他指標(biāo)。這些圖表比較了一周與一周前的性能差異,如圖-1。每當(dāng)她發(fā)現(xiàn)一個(gè)顯著的性能差異時(shí),她就會(huì)通過不同的列(通常包括堆棧痕跡)進(jìn)行深入研究,細(xì)化查詢,直到她能將差異鎖定在一個(gè)特定的代碼塊上,并填寫一份緊急錯(cuò)誤報(bào)告。
Julie的儀表盤可以在不超過幾秒鐘的數(shù)據(jù)上運(yùn)行預(yù)制查詢。性能錯(cuò)誤往往在引入后的幾分鐘到幾小時(shí)內(nèi)就能被及時(shí)發(fā)現(xiàn)(并修復(fù)?。?- 而且這些錯(cuò)誤還在網(wǎng)站的一小部分上進(jìn)行測(cè)試。這些性能圖表中的峰值警報(bào)可以使她的初始監(jiān)控自動(dòng)化。在Facebook的所有服務(wù)器上實(shí)時(shí)記錄和導(dǎo)入數(shù)據(jù)會(huì)太過昂貴;所以 Julie 的表格中包含了大約萬分之一的事件樣本(但不同的表格和事件類型會(huì)有所不同)。Scuba會(huì)記錄采樣率并進(jìn)行補(bǔ)償。
2.2 趨勢(shì)分析
Scuba的另一個(gè)時(shí)間敏感型的使用場(chǎng)景是趨勢(shì)發(fā)現(xiàn)。Eric 想尋找數(shù)據(jù)內(nèi)容的趨勢(shì)。他從用戶帖子中提取詞語集,并尋找詞語頻率隨時(shí)間和許多維度的峰值:國(guó)家、年齡、性別等。和 Julie一樣,Eric也在分析秒速時(shí)時(shí)彩數(shù)據(jù)。他為Facebook的傳播熱點(diǎn)建立了一個(gè)工具團(tuán)隊(duì),以圖表方式顯示有多少帖子提到了當(dāng)前的短語。例如,在奧斯卡頒獎(jiǎng)典禮之前,這個(gè)工具就被用來實(shí)時(shí)查看過去一小時(shí)內(nèi)有多少帖子包含了競(jìng)爭(zhēng)電影的名字。與Julie不同的是,Eric通常會(huì)編寫新的自定義查詢,因?yàn)樗趪L試新的趨勢(shì)分析思路。他還會(huì)編寫自定義的Javascript函數(shù)來計(jì)算數(shù)據(jù)的統(tǒng)計(jì)數(shù)據(jù),比如整數(shù)列之間的共變性。
2.3 模式挖掘
產(chǎn)品分析和模式挖掘是Scuba的第三個(gè)用例。與Julie和Eric不同,Bob不是軟件工程師。他是一名產(chǎn)品專家,他需要分析不同的 Facebook 用戶如何應(yīng)對(duì)網(wǎng)站或移動(dòng)應(yīng)用的變化。他根據(jù)不同的維度,如用戶的位置和年齡、產(chǎn)品(設(shè)備、操作系統(tǒng)和構(gòu)建)和錯(cuò)誤報(bào)告中的關(guān)鍵詞,尋找特定的模式,而不知道哪些維度可能很重要。鮑勃在不知道數(shù)據(jù)是如何被記錄的,也不知道哪些列可能存在的情況下,查看許多表中的數(shù)據(jù)。他尋找他能找到的任何模式。他使用 Scuba 是為了以毫秒為單位運(yùn)行滾動(dòng)查詢,而不是在 Hive 中需要幾分鐘。
3. Scuba 總覽
在本節(jié)中,我們將提供Scuba的架構(gòu)概述。如圖2所示,Scuba的存儲(chǔ)引擎由許多獨(dú)立的服務(wù)器組成,每個(gè)服務(wù)器被劃分為稱為 "葉子節(jié)點(diǎn)"(或葉子)的邏輯存儲(chǔ)單元。cpu核心的數(shù)量決定了葉子的數(shù)量,目前每臺(tái)服務(wù)器有8個(gè)。每個(gè)葉子包含了大部分表的數(shù)據(jù)分區(qū),所有的查詢都會(huì)進(jìn)入所有的葉子節(jié)點(diǎn),如下所述?,F(xiàn)在我們介紹一下Scuba的數(shù)據(jù)模型。
3.1 數(shù)據(jù)模型
Scuba為其用戶提供了一個(gè)標(biāo)準(zhǔn)的數(shù)據(jù)模型。每個(gè)表都有包含四種可能類型的數(shù)據(jù)列的行。
整數(shù)。整數(shù)用于聚合、比較和分組。時(shí)間戳也存儲(chǔ)為整數(shù)。
字符串:字符串用于比較和分組。字符串用于比較和分組。
字符集:字符串集用于表示,比如說,F(xiàn)acebook帖子中的單詞或特征集,F(xiàn)acebook帖子中的某個(gè)單詞,或者是某一用戶真實(shí)的功能集(如圖搜索、新聞源重新設(shè)計(jì)等)。都使用字符串集來表示。
字符串的矢量。字符串的Vectors是有序的,多用于堆棧痕跡,順序?qū)?yīng)堆棧級(jí)別。
請(qǐng)注意,不支持浮點(diǎn)數(shù);在許多葉子上的浮點(diǎn)數(shù)上的聚合可能會(huì)導(dǎo)致太多準(zhǔn)確度上的錯(cuò)誤。作為替代,Scuba 建議用戶選擇他們關(guān)心的小數(shù)點(diǎn)位數(shù),例如 5,并將 trunc(X ? 105) 存儲(chǔ)為一個(gè)整數(shù),而不是浮點(diǎn) X。 由于 Scuba 捕獲的數(shù)據(jù)是關(guān)于時(shí)間變化的現(xiàn)象,所以每一行都有一個(gè)強(qiáng)制性的時(shí)間戳。這些時(shí)間戳代表實(shí)際事件(客戶端請(qǐng)求、錯(cuò)誤報(bào)告、帖子等)的時(shí)間。任何表都可以有任意數(shù)量的一種或多種類型的列。所有的表都包含整數(shù)和字符串;只有一些表包含字符串的集合或向量。
3.2 數(shù)據(jù)結(jié)構(gòu)
圖3顯示了Scuba對(duì)每種數(shù)據(jù)類型所使用的壓縮方法??梢杂肗個(gè)字節(jié)-1位自然表示的整數(shù),直接用N個(gè)字節(jié)編碼。字典編碼是指每個(gè)字符串在字典中存儲(chǔ)一次,其索引在字典里(一個(gè)整數(shù))存儲(chǔ)在行中。字符串列可以被壓縮或不壓縮存儲(chǔ),這取決于有多少不同的值。對(duì)于壓縮后的字符串列,每個(gè)索引使用表示最大索引所需的位數(shù)來存儲(chǔ)。未壓縮的列存儲(chǔ)原始字符串及其長(zhǎng)度。對(duì)于字符串集,索引被排序和delta編碼,然后每個(gè)索引被Fibonacci編碼。(斐波那契編碼使用的是可變位數(shù)。)編碼后的索引在行中連續(xù)存儲(chǔ)。對(duì)于向量,有一個(gè)2字節(jié)的字符串計(jì)數(shù)和一個(gè)1字節(jié)大小的最大字典索引的位數(shù)。然后,每個(gè)索引使用大小位數(shù)連續(xù)存儲(chǔ)在行中。所有的字典都是每個(gè)葉子的局部,每個(gè)列的字典都是獨(dú)立的。與在每列中存儲(chǔ)8個(gè)字節(jié)的整數(shù)和原始字符串相比,壓縮數(shù)據(jù)使其體積減少了6倍以上(每個(gè)表的情況不同)。
Scuba目前以行的順序存儲(chǔ)表,因?yàn)樗畛醯挠美诿看尾樵冎卸紩?huì)訪問表的大部分列。鑒于Scubas的用例從那時(shí)起變得更加通用,我們現(xiàn)在正在探索面向列的存儲(chǔ)布局。其他人[18,8]已經(jīng)表明,列存儲(chǔ)一般可以得到更好的壓縮和更好的緩存定位。
Scuba 的數(shù)據(jù)模型有兩個(gè)關(guān)鍵點(diǎn)與標(biāo)準(zhǔn)關(guān)系模型不同。首先,沒有創(chuàng)建表聲明類型;每當(dāng)葉子第一次接收到數(shù)據(jù)時(shí),就會(huì)在每個(gè)葉子節(jié)點(diǎn)上創(chuàng)建一個(gè)表。由于葉子在不同的時(shí)間接收數(shù)據(jù),表可能只存在于一些葉子上,并且可能在每個(gè)葉子上有不同的模式。然而,盡管模式不同,Scuba通過將任何缺失的列視為空值,向用戶展示了一個(gè)單一的表映像。其次,表的行中的列可能被自動(dòng)地填充;在一個(gè)表中有 2 或 3 個(gè)不同的行模式或一個(gè)列隨著時(shí)間的推移改變其類型(通常是為了實(shí)現(xiàn)更好的壓縮)是很常見的。這兩種差異加在一起,讓Scuba無需任何復(fù)雜的模式演化命令或工作流,就能讓表適應(yīng)用戶的需求。這種適應(yīng)性是Scuba的優(yōu)勢(shì)之一。
3.3 數(shù)據(jù)提取, 分發(fā)與生命周期
圖2顯示了數(shù)據(jù)導(dǎo)入Scuba的吞吐路徑。Facebook 的代碼庫其中包含日志調(diào)用,用于將數(shù)據(jù)導(dǎo)入 Scuba。當(dāng)事件發(fā)生時(shí),這些調(diào)用會(huì)被執(zhí)行,并且(在根據(jù)可選的采樣率剔除部分?jǐn)?shù)據(jù)之后)日志條目被寫入Scribe。Scribe 是一個(gè)開源的分布式消息系統(tǒng),用于收集、聚合和以低延遲交付大量日志數(shù)據(jù)。它由Facebook開發(fā),并在Facebook廣泛使用[5]。然后,一個(gè)尾隨者進(jìn)程訂閱了為Scuba準(zhǔn)備的主題,并通過Scuba的Thrift API將每一批新的行發(fā)送到Scuba。(Thrift[7]是一個(gè)軟件庫,它為使用它定義的任何接口實(shí)現(xiàn)了跨語言的RPC通信)。這些傳入的行完全描述了它們自己,包括它們的Schema。
對(duì)于每一批傳入的行,Scuba會(huì)隨機(jī)選擇兩個(gè)葉子節(jié)點(diǎn),并將該批行發(fā)送到有更多可用內(nèi)存的葉子上。因此,每個(gè)表的行最終會(huì)被隨機(jī)分區(qū)到集群中的所有葉子上。在任何表上都沒有索引,盡管每個(gè)批次中的行在很短的時(shí)間內(nèi)都有時(shí)間戳(然而,這些時(shí)間窗口可能在批次之間重疊,因?yàn)閿?shù)據(jù)是在多個(gè)服務(wù)器上生成的)。
接收批處理的葉子節(jié)點(diǎn)將批處理文件的gzip壓縮副本存儲(chǔ)到磁盤上,以便持久化。然后它讀取新行的數(shù)據(jù),壓縮每一列,并將行添加到內(nèi)存中的表中。從一個(gè)事件發(fā)生到它被存儲(chǔ)在內(nèi)存中并可供用戶查詢的時(shí)間通常在一分鐘之內(nèi)。

內(nèi)存(不是CPU)是Scuba的緊缺資源。我們目前每隔2-3周增加新機(jī)器,以跟上表和數(shù)據(jù)的增長(zhǎng)速度。由于Scuba的目的是為了分析今天的數(shù)據(jù),同時(shí)可能會(huì)進(jìn)行周與周之間的比較,所以我們以接收新數(shù)據(jù)的同樣速度刪除舊數(shù)據(jù),以限制表的大小。數(shù)據(jù)被修剪的原因有兩種。
數(shù)據(jù)生命周期:由時(shí)間戳決定的行是否太老了。
數(shù)據(jù)大小: 該表是否已經(jīng)超過了空間限制,而這一行是: 表中最古老的一個(gè)。
通常情況下, 大多數(shù)表的默認(rèn)限制為30天1和100GB,盡管對(duì)于像fbflow這樣保存網(wǎng)絡(luò)流量數(shù)據(jù)的高容量表和記錄廣告點(diǎn)擊和印象等創(chuàng)收數(shù)據(jù)的廣告指標(biāo)有更高的限制。每隔15分鐘,一個(gè)cron作業(yè)就會(huì)驅(qū)逐超過其生命周期限制的數(shù)據(jù)。如果表超過了它的空間限制,表的最舊數(shù)據(jù)就會(huì)被驅(qū)逐,直到它低于其限制。
為了讓一些數(shù)據(jù)保留的時(shí)間超過空間限制,Scuba 還提供了數(shù)據(jù)的子采樣。在這種情況下,超過一定生命周期的的行的統(tǒng)一部分會(huì)被保留,其余部分會(huì)被刪除。在未來,我們希望探索更復(fù)雜的抽樣形式,如分層抽樣,這中抽樣可能會(huì)選擇一組更有代表性的行。
3.4 查詢模型
Scuba提供了三種查詢接口,如圖2右圖所示。
圖1中所示的基于網(wǎng)絡(luò)的界面允許用戶發(fā)出基于表格的查詢,并從12種可視化方式中選擇一種,包括表格、時(shí)間序列圖、餅圖、疊加區(qū)域圖等。圖4、圖5和圖6顯示了另外三種可視化方式。在不同的可視化界面之間的切換只需要幾秒鐘的時(shí)間。
支持命令行界面接受SQL的查詢。
支持基于Thrift的API允許從PHP、C++、Java、Python、Javascript等語言的應(yīng)用程序代碼中進(jìn)行查詢。
SQL接口和GUI本身使用Thrift接口向Scuba的后臺(tái)發(fā)送查詢。腳本也可以使用SQL或Thrift接口發(fā)出查詢。最后,我們提供了一種機(jī)制支持用Javascript編寫的用戶定義函數(shù)進(jìn)行查詢。
Scuba查詢具有以下SQL查詢的表達(dá)能力。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="sql" cid="n81" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">SELECT column, column, ...,
aggregate(column), aggregate(column), ...
FROM table
WHERE time >= min-timestamp
AND time <= max-timestamp
[AND condition ...]
GROUP BY column, column, ...
ORDER BY aggregate(column)
LIMIT number</pre>
Scuba 的 SQL 支持的聚合函數(shù)包括傳統(tǒng)的計(jì)數(shù)、最小、最大、總和和平均函數(shù),以及其他通用函數(shù),如總/分鐘、百分比和直方圖。WHERE子句必須包含一個(gè)時(shí)間范圍,LIMIT子句的默認(rèn)值是100,000行,以避免分組時(shí)的內(nèi)存問題和客戶端的渲染問題。GROUP BY和ORDER BY子句完全是可選的。
任何與字符串的比較都可能包括一個(gè)正則表達(dá)式。字符集的條件是 set-column 包括 string-list 的 any/all/none,set-column 為空。對(duì)字符串向量的條件是 vector-column 包括 string-list 的 any/all/none/start/end/within。字符串列表中字符串的順序很重要。
Scuba 中不支持 join 表查詢。當(dāng)需要合并來自多個(gè)來源的數(shù)據(jù)時(shí),通常在將數(shù)據(jù)移植到Scuba之前進(jìn)行連接,保證 Scuba 中的已經(jīng)是連接過的數(shù)據(jù)。

3.5 執(zhí)行查詢
注: fanout 指數(shù)據(jù)扇出
圖7顯示了 Scuba 如何執(zhí)行用戶查詢的步驟分解。聚合器和葉子之間的所有通信都是通過Thrift進(jìn)行的。具體查詢步驟如下:
客戶端找到 Scuba 集群中的一個(gè)根聚合器并發(fā)送一個(gè)查詢。Root Aggregator 收到查詢,解析它,并驗(yàn)證它,以確保查詢格式良好。
Root Aggregator 在集群中識(shí)別出另外四臺(tái)機(jī)器,作為下一級(jí)的Intermediate Aggregator。這一步創(chuàng)建了一個(gè)五臺(tái)機(jī)器的 fanouts(其他四臺(tái)機(jī)器加上自己)。Root Aggregator用一個(gè) sum 和一個(gè) count 來替換任何平均函數(shù)(因此可以在最后進(jìn)行聚合),并將查詢發(fā)送給Intermediate Aggregators。
Intermediate Aggregator 再創(chuàng)建五個(gè)fanouts,并傳播查詢,直到每臺(tái)機(jī)器上的(唯一)葉子聚合器收到查詢。
Leaf Aggregator將查詢發(fā)送到機(jī)器上的每個(gè)葉子節(jié)點(diǎn)服務(wù)器上并行處理。
Leaf Aggregator 從每個(gè)葉子節(jié)點(diǎn)服務(wù)器收集結(jié)果,并對(duì)它們進(jìn)行聚合。聚合結(jié)果可以進(jìn)行任何排序和限制約束,然而,對(duì)于它的限制,默認(rèn)使用max(5 ? limit,100),確保最后最高限制的所有組都能在樹上一路傳遞。Leaf Aggregator還收集統(tǒng)計(jì)每個(gè)Leaf是否包含該表,它處理了多少行,以及有多少行滿足條件并對(duì)結(jié)果有貢獻(xiàn)。Leaf Aggrega-tor將其結(jié)果和統(tǒng)計(jì)數(shù)據(jù)返回給調(diào)用它的Intermediate Aggregator。
每個(gè)Intermediate Aggregator將收到的部分結(jié)果進(jìn)行整合,并將其傳播到聚合樹上。
Root Aggregator 計(jì)算最終結(jié)果,包括任何平均值和百分比,并應(yīng)用所有預(yù)設(shè)的的排序和限制條件。
Root Aggregator將結(jié)果返回給等待的客戶端,通常在幾百毫秒內(nèi)。
關(guān)于Leaf Server如何處理查詢的幾個(gè)細(xì)節(jié)很重要。首先,每個(gè)Leaf Server可能包含零個(gè)或多個(gè)表的分區(qū),這取決于表的大小和表存在的時(shí)間。非常新的或非常小的表可能只存儲(chǔ)在我們集群中數(shù)千個(gè)葉子中的幾個(gè)或幾百個(gè)葉子上。
其次,Leaf Server必須掃描表的每個(gè)分區(qū)中時(shí)間范圍與查詢時(shí)間范圍重疊的行。
非重疊的分區(qū)被跳過。這些分區(qū)的時(shí)間范圍是 Scuba 唯一的 "索引 "形式。


第三,Leaf服務(wù)器優(yōu)化了每個(gè)字符串列謂詞的正則表達(dá)式匹配。每當(dāng)字符串列使用一個(gè)字典(大致對(duì)應(yīng)于每當(dāng)字符串值很可能在列中重復(fù)的時(shí)候),Leaf服務(wù)器就會(huì)維護(hù)一個(gè)每查詢的緩存,其中包含對(duì)每個(gè)字符串值匹配表達(dá)式的結(jié)果。這個(gè)緩存是以字符串的字典索引為索引的。
第四,如果一個(gè)聚合器或葉子服務(wù)器在超時(shí)窗口內(nèi)(如10毫秒)沒有響應(yīng),它的結(jié)果就會(huì)從最終計(jì)算中省略。我們發(fā)現(xiàn),在實(shí)踐中,這種方法效果很好,因?yàn)樵诨卮餝cuba查詢時(shí)涉及大量的樣本。少量數(shù)據(jù)的缺失并不會(huì)對(duì)平均和百分位數(shù)計(jì)算產(chǎn)生不利影響,通過忽略一些葉子實(shí)現(xiàn)的低得多的響應(yīng)時(shí)間彌補(bǔ)了缺失數(shù)據(jù)。此外,Scuba 維護(hù)并檢查一個(gè)獨(dú)立的服務(wù),以獲得每個(gè)查詢的每個(gè)表的預(yù)期行數(shù)。然后,它使用這個(gè)計(jì)數(shù)來估計(jì)數(shù)據(jù)的部分,以確保數(shù)據(jù)的準(zhǔn)確性。
但數(shù)據(jù)準(zhǔn)確性實(shí)際上是缺失的。如果分?jǐn)?shù)是99.5%或更少,Scuba 會(huì)在GUI中打印一個(gè)警告。我們還在努力為那些需要100%準(zhǔn)確結(jié)果的客戶自動(dòng)重復(fù)查詢。
最后,每臺(tái)物理機(jī)器上都運(yùn)行著多個(gè) Leaf 服務(wù)器和一個(gè) Aggregator 服務(wù)器。每臺(tái)機(jī)器都可以在聚合樹的任何級(jí)別上提供聚合器服務(wù)器。
目前,聚合樹的 fanouts 是五個(gè)。我們?cè)囼?yàn)了 2,4,5,6 副本數(shù)的fanouts,經(jīng)驗(yàn)上發(fā)現(xiàn)5個(gè)fanouts能產(chǎn)生最好的響應(yīng)時(shí)間。獨(dú)立地,Rosen等人[14]對(duì)聚合樹的理論分析表明,響應(yīng)時(shí)間最小的聚合樹的fanouts是一個(gè)常數(shù),與樹中葉子節(jié)點(diǎn)的數(shù)量無關(guān)。他們的實(shí)證分析也表明,在他們的系統(tǒng)中,fanouts為5時(shí)導(dǎo)致響應(yīng)時(shí)間最小。

4. Scuba 的性能分析模型
如上一節(jié)所述,Scuba使用聚合樹來執(zhí)行用戶查詢。在本節(jié)中,我們構(gòu)建了一個(gè)簡(jiǎn)單的系統(tǒng)分析模型。通過這個(gè)模型幫助我們了解單個(gè)查詢的性能特征。 圖8描述了這個(gè)模型的參數(shù)。我們首先描述用于查詢處理的聚合樹的參數(shù)。聚合樹中fanout F和N臺(tái)機(jī)器的預(yù)期級(jí)別數(shù)L如公式1所示。

大多數(shù)聚合器的實(shí)際 fanouts 量為 F 。然而,當(dāng) Scuba 集群中的機(jī)器數(shù)量 N 不是 F 的完美冪數(shù)時(shí),最低一級(jí)的中間聚合器的 fanouts 量小于 F。等式 2 顯示了聚合樹中倒數(shù)第二層的fanouts。

F L-1代表聚合樹中L-1層的聚合器數(shù)量。因此,R代表在樹的最后一級(jí),從F L-1中間聚合器中的每一個(gè)到達(dá)所有N個(gè)葉子聚合器的fanouts。回想一下,每臺(tái)機(jī)器都有一個(gè)Leaf Aggregator)。 現(xiàn)在,我們可以用等式3描述L層的fanouts。

等式(3)中的最后一種情況描述了從葉子Aggregator到同一臺(tái)機(jī)器上的葉子節(jié)點(diǎn)的fanoutD。 樹中的每個(gè)Aggregator執(zhí)行以下步驟。
將查詢分發(fā)到每個(gè)子Aggregator并等待結(jié)果。
在收到每個(gè)子節(jié)點(diǎn)的結(jié)果時(shí),將其納入。當(dāng)所有子代都有響應(yīng)或查詢超時(shí)時(shí),停止等待。
將合并的聚合結(jié)果和響應(yīng)統(tǒng)計(jì)信息返回給調(diào)用者。
請(qǐng)注意,一旦查詢被Aggregator轉(zhuǎn)發(fā)給它的子代,子代就會(huì)并行進(jìn)行。所以總的響應(yīng)時(shí)間為在公式4中,用L級(jí)的聚合樹計(jì)算的查詢由TL表示。

展開式(4)并結(jié)合式(3)可得式5。

TL因此是任何查詢的預(yù)測(cè)時(shí)間(在沒有查詢爭(zhēng)用的情況下)。我們通過在每個(gè)查詢中插入TA、TD、TG和TS的實(shí)際值,并將它們與我們的實(shí)驗(yàn)結(jié)果進(jìn)行比較,來驗(yàn)證(并完善)這個(gè)模型。然而,我們并沒有在這里提出比較。
5. 實(shí)驗(yàn)性評(píng)估
在本節(jié)中,我們介紹了在160臺(tái)機(jī)器的測(cè)試集群上測(cè)量Scuba的響應(yīng)時(shí)延和擴(kuò)展性相關(guān)的實(shí)驗(yàn)結(jié)果。
5.1 實(shí)驗(yàn)環(huán)境搭建
我們測(cè)試集群中的機(jī)器是英特爾Xeon E5-2660 2.20 GHz機(jī)器,內(nèi)存為144 GB[19]。有四個(gè)機(jī)架,每個(gè)機(jī)架有40臺(tái)機(jī)器,用10G以太網(wǎng)連接。操作系統(tǒng)是CentOS 5.2版本。 在這些實(shí)驗(yàn)中,我們將集群中的機(jī)器數(shù)量從10臺(tái)變化到160臺(tái)。在每個(gè)實(shí)驗(yàn)中,每臺(tái)機(jī)器有8個(gè)Leaf Nodes和1個(gè)Aggregator。每個(gè)Aggregator總是作為葉子Aggregator,并可以另外作為中間和根Aggregator。
5.2 實(shí)驗(yàn)數(shù)據(jù)和查詢
實(shí)驗(yàn)的目的是為了隔離第4節(jié)中模型的各種參數(shù),呈現(xiàn)最基礎(chǔ)的 benchmark。因此,我們使用1個(gè)包含29小時(shí)價(jià)值的真實(shí)數(shù)據(jù)的表(從我們的生產(chǎn)集群復(fù)制)和2個(gè)非常簡(jiǎn)單的查詢。表中的數(shù)據(jù)總量約為1.2TB。除非另有說明,每個(gè)葉子有1GB;每臺(tái)機(jī)器有8個(gè)葉子,160臺(tái)機(jī)器。(1 ? 8 ? 160 = 1280) 我們運(yùn)行了兩個(gè)不同的查詢。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="sql" cid="n142" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">SELECT count(), SUM(column1) as sum1,
SUM(column2) as sum2
FROM mytable
WHERE time >= now()-33600</pre>
上面SQL中顯示的第一個(gè)查詢,在葉子上隔離掃描時(shí)間。它掃描了3個(gè)、6個(gè)或全部29個(gè)小時(shí)的數(shù)據(jù)(取決于常量),計(jì)算出3個(gè)聚合指標(biāo),并將這3個(gè)數(shù)字(和查詢統(tǒng)計(jì))傳遞到聚合樹上(僅)。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="sql" cid="n144" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">SELECT count(), sum(column1) as sum1,
service,
(time - now())/6060 + now() as minute,
FROM mytable
WHERE time >= now()-3*3600
and time <= now()
GROUP BY service, minute
ORDER BY sum1 DESC
LIMIT 1800</pre>
第二個(gè)查詢比較復(fù)雜,尤其是在SQL中,如上圖所示。該查詢以 1 分鐘的粒度生成過去 3、6 或 29 小時(shí)的時(shí)間序列圖,為前 10 個(gè)服務(wù)中的每個(gè)服務(wù)繪制一條線。同樣的查詢?cè)赟cuba GUI中更容易執(zhí)行,如圖9所示。該查詢?yōu)槊總€(gè)服務(wù)產(chǎn)生2個(gè)聚合指標(biāo),每分鐘。1800=180分鐘?10個(gè)服務(wù)的限制。這個(gè)查詢通過,并在聚合樹的每一級(jí)聚合2個(gè)度量,每個(gè)度量都有1800點(diǎn),其聚合時(shí)間TA是明顯的。

5.3 單機(jī)實(shí)驗(yàn)
第一組實(shí)驗(yàn)測(cè)試單個(gè)客戶端的查詢延遲。對(duì)于這些實(shí)驗(yàn),我們使用29小時(shí)數(shù)據(jù)生命周期的版本的每個(gè)查詢,并運(yùn)行每個(gè)查詢200次。我們繪制了平均響應(yīng)時(shí)間,誤差條表示最小和最大響應(yīng)時(shí)間。
5.3.1 加速查詢
我們首先測(cè)量了分布在20臺(tái)機(jī)器集群中的數(shù)據(jù)的單次查詢的速度。我們將每個(gè)Leaf的數(shù)據(jù)量從1GB到8GB不等。因此,數(shù)據(jù)總量從160GB到整整1.2TB不等。 圖10顯示了結(jié)果。每個(gè)葉子掃描數(shù)據(jù)的時(shí)間與數(shù)據(jù)量成正比。然而,聚合成本與每個(gè)葉子的數(shù)據(jù)量無關(guān),它是查詢和集群大小的函數(shù)。在這個(gè)實(shí)驗(yàn)中,集群大小是恒定的。20臺(tái)機(jī)器,扇出量為5,樹上有3個(gè)層次(1個(gè)根聚合器,5個(gè)中間聚合器,20個(gè)葉聚合器)。掃描查詢只經(jīng)過聚合樹上的一個(gè)點(diǎn),所以聚合需要的時(shí)間可以忽略不計(jì)。時(shí)間序列查詢需要在樹的每一級(jí)聚合大量的點(diǎn),所以需要更長(zhǎng)的時(shí)間。
5.3.2 擴(kuò)展
接著,當(dāng)我們將集群中的機(jī)器數(shù)量從10臺(tái)變化到160臺(tái)(每次將機(jī)器數(shù)量增加一倍)時(shí),我們會(huì)衡量規(guī)模的擴(kuò)大。每個(gè)Leaf有1GB的數(shù)據(jù)。 圖11顯示,掃描數(shù)據(jù)的時(shí)間(在每個(gè)Leaf上并行完成)是恒定的。聚合成本隨著N的增長(zhǎng)而呈對(duì)數(shù)增長(zhǎng)。由于對(duì)于掃描查詢來說,聚合成本可以忽略不計(jì),所以隨著機(jī)器數(shù)量的增加,其響應(yīng)時(shí)間是恒定的。然而,時(shí)間序列查詢需要在每個(gè)聚合器處聚合許多點(diǎn),其響應(yīng)時(shí)間隨著聚合器的數(shù)量和聚合樹的層數(shù)增加而增加。第4節(jié)中提出的模型對(duì)幫助我們理解這些擴(kuò)展結(jié)果非常有用。

5.4 多機(jī)實(shí)驗(yàn)
最后一個(gè)實(shí)驗(yàn)測(cè)試的是隨著客戶端數(shù)量從1個(gè)增加到32個(gè),查詢延遲和吞吐量。每個(gè)客戶端連續(xù)發(fā)出200個(gè)查詢,它們之間沒有時(shí)間間隔。在這個(gè)實(shí)驗(yàn)中,我們使用160臺(tái)機(jī)器,每個(gè)Leaf有1GB的數(shù)據(jù)。我們還使用了掃描和時(shí)間序列查詢的3小時(shí)、6小時(shí)和29小時(shí)變體。3小時(shí)變體只需要掃描每個(gè)Leaf處大約10%的數(shù)據(jù)。
圖12顯示了當(dāng)我們改變客戶端數(shù)量時(shí),每個(gè)查詢的吞吐量。首先要注意的是,對(duì)于每個(gè)查詢,吞吐量隨著客戶端數(shù)量的增加而上升,直到葉子上的CPU達(dá)到飽和。之后,吞吐量趨于平緩。對(duì)于所有的查詢,在8個(gè)客戶端之后,吞吐量是持平的。接下來的無表點(diǎn)是,在相同的時(shí)間范圍內(nèi),掃描查詢的吞吐量都比它們的時(shí)間序列查詢對(duì)應(yīng)的吞吐量高。這一點(diǎn)并不奇怪,因?yàn)閽呙璨樵兊乃俣雀臁W詈?,?duì)于給定的客戶端數(shù)量,隨著查詢的時(shí)間范圍(因此掃描的數(shù)據(jù)量)的增加,每種查詢類型的吞吐量都會(huì)下降。


圖13顯示,查詢的響應(yīng)時(shí)間與客戶端數(shù)量成正比增加,符合預(yù)期。
6.相關(guān)工作
與Scuba相關(guān)的工作可分為四類。
首先,有其他的系統(tǒng)用于臨時(shí)性的實(shí)時(shí)分析。HyPer[11]也是將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,但是是在一臺(tái)巨型的、昂貴的機(jī)器上。另一方面,Scuba使用相對(duì)便宜的商品計(jì)算機(jī)集群,并且通過增加更多的機(jī)器輕松擴(kuò)展。HyPer也不使用壓縮,因此對(duì)于同樣數(shù)量的數(shù)據(jù),它需要更多的內(nèi)存。
Powerdrill[10]和Dremel[12]是Google的兩個(gè)用于分析的數(shù)據(jù)管理系統(tǒng)。兩者和Scuba一樣,都是高度分布式的,而且擴(kuò)展性很好。Dremel提供了比Scuba復(fù)雜得多的半結(jié)構(gòu)化和稀疏數(shù)據(jù)模型;據(jù)報(bào)道,Powerdrill的速度比Dremel快得多,但仍需要30-40秒/查詢。在這兩個(gè)系統(tǒng)中,數(shù)據(jù)的主副本都住在磁盤上,所以存儲(chǔ)的數(shù)據(jù)量不那么重要。
Splunk[6]也是一個(gè)導(dǎo)入日志數(shù)據(jù)、分析數(shù)據(jù)并以圖表形式查看的系統(tǒng)。它的目的是針對(duì)在 "云 "中產(chǎn)生和分析的數(shù)據(jù)。我們沒有關(guān)于它無論是導(dǎo)入還是查詢數(shù)據(jù)的速度的數(shù)據(jù)。
其次,有多種系統(tǒng)使用壓縮來重新減少內(nèi)存和/或磁盤的占用。Westman等人[21]采用基于行的布局,發(fā)現(xiàn)字典在壓縮率和CPU使用量之間提供了很好的權(quán)衡。C-Store[18]和Vertica、SAP Hana[15]、Dremel和Powerdrill都采取了基于列的方法,我們接下來想嘗試一下,以獲得更好的壓縮效果。 第三,上述系統(tǒng)都不能用準(zhǔn)確率來換取響應(yīng)時(shí)間,Scuba有意這么做。然而,BlinkDB[9]可以在有界時(shí)間內(nèi)或有界精度的情況下,在采樣數(shù)據(jù)集上產(chǎn)生結(jié)果。雖然BlinkDB在獲取查詢之前需要預(yù)先計(jì)算分層樣本,但我們希望通過實(shí)驗(yàn)并優(yōu)化其底層技術(shù)來更好地約束和報(bào)告Scuba的不準(zhǔn)確度。 最后,Scuba中的所有數(shù)據(jù)都有時(shí)間戳,很多分析都是基于時(shí)間的。在20世紀(jì)80年代末,Snodgrass創(chuàng)建了TQuel[16,17]來推理數(shù)據(jù)的時(shí)間和間隔。我們應(yīng)該重新審視這項(xiàng)工作,看看是否有Scuba應(yīng)該加入的功能。
7. 總結(jié)
Scuba與大多數(shù)數(shù)據(jù)庫系統(tǒng)有多種不同,文章所描述的這些都集中在Scuba適合我們?cè)贔acebook的使用案例上。
Scuba驅(qū)逐數(shù)據(jù)的速度與它攝入數(shù)據(jù)的速度一樣快,因?yàn)樗械谋頂?shù)據(jù)都存儲(chǔ)在內(nèi)存中,而內(nèi)存是稀缺資源。驅(qū)逐是自動(dòng)的,不過每個(gè)表保留多少數(shù)據(jù)的參數(shù)是可以調(diào)整的。
Scuba 設(shè)計(jì)上期望表包含的是采樣數(shù)據(jù)而不是原始數(shù)據(jù),因?yàn)榇鎯?chǔ)每個(gè)事件都會(huì)有太多的數(shù)據(jù)。采樣率列會(huì)被特殊處理,查詢結(jié)果包含一個(gè)原始計(jì)數(shù)和一個(gè)根據(jù)表中的采樣率調(diào)整的計(jì)數(shù)。(可以有多個(gè)不同的采樣率,每行可以有一個(gè)。)
Scuba 的數(shù)據(jù)導(dǎo)入就是在代碼中插入,并創(chuàng)建一個(gè)進(jìn)程來監(jiān)聽這些事件。不需要任何模式聲明;模式是從日志中推導(dǎo)出來的,它可以隨著時(shí)間的推移而變化。
Scuba并不打算成為一個(gè)完整的SQL數(shù)據(jù)庫,它支持分組和聚合,但不支持連接或嵌套查詢。它支持分組和聚合,但不支持連接或嵌套查詢。它支持整數(shù)和字符串,但不支持浮動(dòng),盡管它也添加了字符串的集合和向量(但不支持類型的任意嵌套)。 我們想對(duì)Scuba進(jìn)行一些修改。它目前是面向行的,盡管我們正在探索面向列的布局是否會(huì)更好。Scuba可以使用本地警報(bào);此外,支持用戶在Scuba查詢結(jié)果之上寫警報(bào)。隨著用戶群的增長(zhǎng),Scuba還需要繼續(xù)擴(kuò)展。
本文介紹的模型和實(shí)驗(yàn)是弄清它目前的擴(kuò)展情況的第一步。 盡管如此,自兩年前首次編寫Scuba以來,Scuba在Facebook的用戶數(shù)、數(shù)據(jù)數(shù)和查詢數(shù)都在飛速增長(zhǎng)。Scuba提供了導(dǎo)入和查詢數(shù)據(jù)的靈活性和速度,這對(duì)Facebook的實(shí)時(shí)性能和數(shù)據(jù)分析至關(guān)重要。