




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Sawzall海量數(shù)據(jù)分析:Sawzall并行處理收件人:發(fā)件人:崮山路上走9遍抄送:日期:2005-07-22關(guān)于:Interpreting the Data:Parallel Analysis with Sawzall作者Rob Pike, Sean Dorward, Robert Griesemer, Sean QuinlanGoogle, Inc.(Draft submitted to Scientific Programming Journal)概要超大量的數(shù)據(jù)往往會(huì)采用一種平面的正則結(jié)構(gòu),存放于跨越多個(gè)計(jì)算機(jī)的多個(gè)磁盤(pán)上。這方面的例子包括了電話(huà)通話(huà)記錄,網(wǎng)絡(luò)日志,web文檔庫(kù)等等。
2、只要這些超大量的數(shù)據(jù)集不能裝在單個(gè)關(guān)系數(shù)據(jù)庫(kù)里邊的時(shí)候,傳統(tǒng)的數(shù)據(jù)庫(kù)技術(shù)對(duì)于研究這些超大數(shù)據(jù)集來(lái)說(shuō)那就是沒(méi)有意義的。此外,對(duì)于這些數(shù)據(jù)集的分析可以展示成為應(yīng)用簡(jiǎn)單的,便于分布式處理的計(jì)算方法:比如過(guò)濾,聚合,統(tǒng)計(jì)抽取,等等。我們?cè)谶@里介紹這樣一種這樣的自動(dòng)化分析系統(tǒng)。在過(guò)濾階段,查詢(xún)請(qǐng)求通過(guò)一種全新的編程語(yǔ)言來(lái)快速執(zhí)行,把數(shù)據(jù)處理到聚合階段。無(wú)論過(guò)濾階段還是聚合階段都是分布在上百臺(tái)甚至上千臺(tái)計(jì)算機(jī)上執(zhí)行的。他們的結(jié)果通過(guò)比較并且保存到一個(gè)文件。這個(gè)系統(tǒng)的設(shè)計(jì)-包括分成兩階段,以及這種新式的編程語(yǔ)言,聚合器的特性-都是在數(shù)據(jù)和計(jì)算分布在很多臺(tái)機(jī)器上的情況下,內(nèi)嵌使用并行機(jī)制的。1介紹有不少數(shù)據(jù)集
3、都是超大的,或者非常動(dòng)態(tài),或者就是因?yàn)樘孔玖?,而不能有效地通過(guò)關(guān)系數(shù)據(jù)庫(kù)進(jìn)行管理。典型的場(chǎng)景是一組大量無(wú)格式文件-有時(shí)候是上petabytes(2的50次方1,125,899,906,842,624)-分布在多個(gè)計(jì)算機(jī)上的多個(gè)磁盤(pán)上。這些文件都包含了無(wú)數(shù)的記錄,這些記錄是通常會(huì)通過(guò)一個(gè)軸來(lái)組織,比如通過(guò)時(shí)間軸或者地理軸進(jìn)行組織。例如:這堆文件可能包含一個(gè)web網(wǎng)頁(yè)倉(cāng)庫(kù),用來(lái)構(gòu)造internet搜索引擎的索引系統(tǒng),或者這堆文件用來(lái)記錄上千臺(tái)在線(xiàn)服務(wù)器的健康日志,或者用來(lái)記錄電話(huà)呼叫記錄或者商業(yè)交易日至,網(wǎng)絡(luò)包記錄,web服務(wù)器查詢(xún)記錄,或者高級(jí)一點(diǎn)的數(shù)據(jù)比如衛(wèi)星圖像等等。但是對(duì)這些數(shù)據(jù)的分析經(jīng)
4、常可以表示成為簡(jiǎn)單的操作,遠(yuǎn)比普通SQL查詢(xún)要簡(jiǎn)單得操作來(lái)完成。舉一個(gè)例子,我們通常會(huì)統(tǒng)計(jì)滿(mǎn)足某條件的記錄數(shù),或者抽取這些記錄,或者查詢(xún)異常記錄,或者構(gòu)造記錄中某一個(gè)域值的頻率柱狀圖。另一方面,查詢(xún)也可能會(huì)較為復(fù)雜,但是這些查詢(xún)依舊可以展示成為通過(guò)一系列簡(jiǎn)單查詢(xún)來(lái)完成,這些簡(jiǎn)單查詢(xún)都可以簡(jiǎn)單映射到這些文件的記錄集上。圖1:5組機(jī)架,每組有50-55臺(tái)計(jì)算機(jī),每臺(tái)計(jì)算機(jī)有4個(gè)磁盤(pán)。這樣一個(gè)架構(gòu)可以有到250TB的待分析數(shù)據(jù)量。我們可以在250臺(tái)以上的計(jì)算機(jī)上分別執(zhí)行過(guò)濾來(lái)極大的的提高并行度,并且把他們的結(jié)果通過(guò)網(wǎng)絡(luò)匯聚到一起(參見(jiàn)弧線(xiàn))由于數(shù)據(jù)記錄存放在多臺(tái)計(jì)算機(jī)上,那么用這些計(jì)算機(jī)本身的能力來(lái)
5、進(jìn)行分析的方法就相當(dāng)有效。特別是,當(dāng)單獨(dú)每一個(gè)步驟都可以表示成為每次對(duì)獨(dú)立的記錄進(jìn)行操作的時(shí)候,我們就可以把計(jì)算分布到所有這些機(jī)器上,這樣就能達(dá)到相當(dāng)高的吞吐量。(前邊提及的每個(gè)例子都有這樣的特點(diǎn))。這些簡(jiǎn)單操作都要求一個(gè)聚合的階段。例如,如果我們統(tǒng)計(jì)記錄數(shù),我們需要把每一個(gè)機(jī)器統(tǒng)計(jì)出來(lái)的記錄數(shù)相加,作為最終的輸出結(jié)果。所以,我們把我們的計(jì)算分成兩個(gè)階段。第一個(gè)階段我們對(duì)每一條記錄分別計(jì)算,第二個(gè)階段我們聚合這些結(jié)果(圖2)。本論文描述的系統(tǒng)更進(jìn)一步考慮了這個(gè)問(wèn)題。我們用一個(gè)全新的編程語(yǔ)言來(lái)進(jìn)行第一個(gè)階段的分析,從處理粒度上,它一次處理一條記錄,并且在階段2嚴(yán)格限制預(yù)先定義的處理階段1產(chǎn)出物的
6、聚合器處理的集合。通過(guò)約束本模式的計(jì)算量,我們可以達(dá)到非常高的吞吐量。雖然并非所有的計(jì)算都能適合這樣的模式,但是僅僅通過(guò)不多的代碼就能夠驅(qū)動(dòng)上千臺(tái)機(jī)器并行計(jì)算還是很劃算的。RAW DATA圖2:總體數(shù)據(jù)流圖,過(guò)濾,聚合和比較。每一步都比上一步產(chǎn)生更少的數(shù)據(jù)。當(dāng)然,我們還有很多小問(wèn)題要解決。計(jì)算必須要分解成為小塊并且分布到每一個(gè)存儲(chǔ)數(shù)據(jù)的節(jié)點(diǎn)上進(jìn)行執(zhí)行,盡量讓計(jì)算和數(shù)據(jù)在一臺(tái)機(jī)器上以避免網(wǎng)絡(luò)瓶頸。由于使用的機(jī)器越多,那么越有可能有機(jī)器會(huì)在運(yùn)算中宕機(jī),所以,必須系統(tǒng)必須要有容錯(cuò)能力。這些都是困難但是有趣的問(wèn)題,但是他們都必須能夠在沒(méi)有人為干預(yù)的情況下完成。Google有好幾個(gè)這樣的基礎(chǔ)架構(gòu),包括G
7、FS9和MapReduce8,通過(guò)容錯(cuò)技術(shù)和可靠性設(shè)計(jì)來(lái)提供了一個(gè)非常強(qiáng)大的框架,可以用來(lái)實(shí)現(xiàn)一個(gè)很大的,分布式處理的并行系統(tǒng)。因此我們著重于我們的目標(biāo):清晰的表達(dá)分析處理,并且迅速執(zhí)行分析處理。2總覽簡(jiǎn)要而言,我們的系統(tǒng)通過(guò)處理用戶(hù)提交的用特別設(shè)計(jì)的編程語(yǔ)言寫(xiě)成的查詢(xún),并發(fā)的在分布到大量機(jī)器上的記錄集中,進(jìn)行記錄級(jí)別的查詢(xún),并且搜集查詢(xún)結(jié)果,通過(guò)一組高性能的聚合器進(jìn)行查詢(xún)結(jié)果的匯聚。這兩部發(fā)呢別執(zhí)行,通常分布到不同的計(jì)算機(jī)集群上。這樣的處理典型類(lèi)型是并發(fā)處理分布在成百上千臺(tái)計(jì)算機(jī)上的gigabyte或者數(shù)Tbyte數(shù)據(jù)。一個(gè)簡(jiǎn)單的分析可能需要花去一個(gè)CPU好幾個(gè)月的時(shí)間,但是通過(guò)上千臺(tái)計(jì)算機(jī)
8、的并行處理,只需要幾個(gè)小時(shí)的時(shí)間就能處理完。有兩個(gè)條件決定著系統(tǒng)的設(shè)計(jì)。首先,如果查詢(xún)操作是對(duì)記錄間可交換的,就是說(shuō)記錄處理的先后順序是不重要的。我們于是可以用任意的順序來(lái)處理這個(gè)查詢(xún)操作。第二,如果聚合操作是可交換的,中間結(jié)果的處理順序是不重要的。此外,如果他們也是可結(jié)合的,中間處理結(jié)果可以被任意分組或者分成不同的步驟進(jìn)行聚合。舉一個(gè)例子,對(duì)于統(tǒng)計(jì)數(shù)量包括匯總數(shù)量來(lái)說(shuō),無(wú)論中間結(jié)果如何的累加或者分組結(jié)合累加,他們最終的結(jié)果都不會(huì)受到影響。這個(gè)交換性和結(jié)合性的約束并不算過(guò)分苛刻,他們可以提供很廣闊的查尋范圍,包括:統(tǒng)計(jì),篩選,取樣,柱狀圖,尋找常見(jiàn)項(xiàng)目,等等。雖然聚合器組是有限的,但是對(duì)于查詢(xún)
9、階段來(lái)說(shuō),應(yīng)當(dāng)包括更加通用的內(nèi)容,我們介紹一種新的解釋執(zhí)行的程序語(yǔ)言Sawzall 與生產(chǎn)便攜往復(fù)式電鋸的Milwaukee Electronic Tool Corporation的商標(biāo)無(wú)關(guān)(解釋語(yǔ)言的性能已經(jīng)足夠了:因?yàn)槌绦蚨鄶?shù)都是比較小的,而且他們需要處理的數(shù)據(jù)往往很大,所以往往是受I/O的限制,這在性能的章節(jié)有所討論)一個(gè)分析操作如下:首先輸入被分解成為要被處理的數(shù)據(jù)小塊,也許是一組獨(dú)立的文件或者一組記錄,這些記錄或者文件分布于多個(gè)存儲(chǔ)節(jié)點(diǎn)上。數(shù)據(jù)小塊可以遠(yuǎn)遠(yuǎn)多于計(jì)算機(jī)的數(shù)量。其次,Sawzall解釋器開(kāi)始處理每一個(gè)小塊數(shù)據(jù)。這個(gè)處理跨越了大量機(jī)器,也許數(shù)據(jù)和機(jī)器綁定在一起,也可能數(shù)據(jù)在
10、臨近的機(jī)器上而不在一起。Sawzall程序分別處理每一個(gè)輸入記錄。每一個(gè)記錄的輸出結(jié)果,0個(gè)或者多個(gè)中間結(jié)果值-整數(shù),字串,key-value pairs,tuple等等-將和其他記錄的輸出值合并。這些中間結(jié)果于是被發(fā)送到運(yùn)行聚合器的進(jìn)一步處理的結(jié)點(diǎn)上,這些節(jié)點(diǎn)比較和減少中間結(jié)果,并且構(gòu)造終結(jié)結(jié)果。在一個(gè)典型的運(yùn)行中,主要的計(jì)算機(jī)集群會(huì)運(yùn)行Sawzall,并且小一點(diǎn)的集群會(huì)運(yùn)行聚合器,這樣的結(jié)構(gòu)反映不僅是體現(xiàn)在計(jì)算量的差異,也體現(xiàn)在網(wǎng)絡(luò)負(fù)載的均衡考慮;每一個(gè)步驟,數(shù)據(jù)流量都比上一個(gè)步驟要少(參見(jiàn)圖2)。當(dāng)所有的處理都完成之后,結(jié)果將被排序,格式化,并且保存到一個(gè)文件。3例子用這個(gè)簡(jiǎn)單的例子可以
11、更清楚的表達(dá)這樣的想法。我們說(shuō)我們的輸入是一個(gè)由浮點(diǎn)數(shù)記錄組成的文件集合。這個(gè)完整的Sawzall程序?qū)?huì)讀取輸入并且產(chǎn)生三個(gè)結(jié)果:記錄數(shù),值得總合,并且值得平方和。count:table sum of int;total:table sum of float;sum_of_squares:table sum of float;x:float=input;emitcount-1;emitsum-x;emitsum_of_squares - x*x;前三行定義了聚合器:計(jì)數(shù)器,合計(jì),平方和。關(guān)鍵字table定義了聚合器類(lèi)型;在Sawzall中,即使聚合器可能是單例的,也叫做table。這些特定的
12、table是屬于合計(jì)的table;他們把輸入的整數(shù)或者浮點(diǎn)數(shù)的值進(jìn)行累加。對(duì)于每一個(gè)輸入的記錄,Sawzall初始化預(yù)定義的變量input來(lái)裝載尚未處理的輸入記錄二進(jìn)制串。因此,行:x: float = input;把輸入記錄從它對(duì)外的表示轉(zhuǎn)換成為內(nèi)嵌的浮點(diǎn)數(shù),并且保存在本地變量x。最后,三個(gè)emit語(yǔ)句發(fā)送中間結(jié)果到聚合器。當(dāng)程序執(zhí)行的時(shí)候,程序?qū)γ恳粋€(gè)輸入記錄只執(zhí)行1次。程序定義的本地變量每次重新創(chuàng)建,但是程序定義的table會(huì)在所有執(zhí)行中共享。處理過(guò)的值會(huì)通過(guò)全局表進(jìn)行累加。當(dāng)所有記錄都處理了以后,表中的值保存在一個(gè)或者多個(gè)文件中。接下來(lái)的幾節(jié)講述了本系統(tǒng)所基于的部分Google的基礎(chǔ)架
13、構(gòu):協(xié)議buffers,Google文件系統(tǒng),工作隊(duì)列,MapReduce。后續(xù)章節(jié)描述語(yǔ)言和其他系統(tǒng)的詳盡部分。4協(xié)議Buffer雖然在最開(kāi)始已經(jīng)考慮了定義服務(wù)器之間的消息通訊,Google的協(xié)議Buffer也同樣用于描述保存在磁盤(pán)的持久化存儲(chǔ)的記錄格式。這個(gè)協(xié)議Buffer的用處很類(lèi)似XML,但是要緊湊的多,通過(guò)一個(gè)二進(jìn)制的表示以及一個(gè)外部的數(shù)據(jù)描述語(yǔ)言(DataDescription Language DDL)是的協(xié)議編譯器能夠把協(xié)議編譯成為各種語(yǔ)言的支持代碼。DDL構(gòu)造一個(gè)清晰,緊湊,可擴(kuò)展的針對(duì)二進(jìn)制記錄的描述,并且對(duì)記錄的字段進(jìn)行命名。雖然二進(jìn)制格式已經(jīng)是相當(dāng)緊湊的,但是常常還會(huì)在
14、保存到磁盤(pán)的時(shí)候再進(jìn)行一個(gè)壓縮,包裹一個(gè)壓縮層。協(xié)議編譯器讀取DDL描述并且產(chǎn)生用于對(duì)數(shù)據(jù)的:組織,訪(fǎng)問(wèn),列集及散列處理的代碼。編譯時(shí)候的標(biāo)志指定了輸出的語(yǔ)言:C+,Java,Python,等等。這個(gè)產(chǎn)生的代碼通過(guò)嵌入應(yīng)用程序中,能夠提供對(duì)數(shù)據(jù)記錄高效簡(jiǎn)潔的訪(fǎng)問(wèn)。同時(shí),也應(yīng)該提供驗(yàn)證和調(diào)試保存的協(xié)議buffer的工具包我們系統(tǒng)操作的大部分?jǐn)?shù)據(jù)集都是按照協(xié)議buffer約定的格式存儲(chǔ)的記錄。協(xié)議編譯器通過(guò)增加對(duì)Sawzall的擴(kuò)展來(lái)提供在新語(yǔ)言下的協(xié)議buffer的高效IO性能。5Google文件系統(tǒng)(GFS)我們系統(tǒng)訪(fǎng)問(wèn)的數(shù)據(jù)集通常保存在GFS內(nèi),就是Goole的文件系統(tǒng)9。GFS提供一個(gè)可靠
15、的分布式存儲(chǔ)系統(tǒng),它可以通過(guò)分布在上千臺(tái)計(jì)算機(jī)的64M”塊”組織成為上Petabyte級(jí)別的文件系統(tǒng)。每一個(gè)塊都有備份,通常是3個(gè)備份,在不同的計(jì)算機(jī)節(jié)點(diǎn)上,這樣GFS可以無(wú)縫的從磁盤(pán)或者計(jì)算機(jī)的故障中容錯(cuò)。GFS是一個(gè)應(yīng)用級(jí)別的文件系統(tǒng),有著傳統(tǒng)的分級(jí)的命名機(jī)制。數(shù)據(jù)集本身通常用一個(gè)常規(guī)的結(jié)構(gòu)存放,這些結(jié)構(gòu)存放在很多獨(dú)立的GFS文件中,每一個(gè)GFS文件大小接近1G。例如,一個(gè)文檔倉(cāng)庫(kù)(web搜索器機(jī)器人探索結(jié)果),包含數(shù)十億HTMLpages,可能會(huì)存放在上千個(gè)文件中,每一個(gè)文件壓縮存放百萬(wàn)級(jí)別的文檔,每個(gè)文檔大概有數(shù)K字節(jié)大小。6工作隊(duì)列和MapReduce把工作安排到一組計(jì)算機(jī)集群上進(jìn)行
16、工作的處理軟件叫做(稍稍有點(diǎn)容易誤解)工作隊(duì)列。工作隊(duì)列很有效的在一組計(jì)算機(jī)及其磁盤(pán)組上創(chuàng)建了一個(gè)大尺度的分時(shí)共享機(jī)制。它調(diào)度任務(wù),分配資源,報(bào)告狀態(tài),并且匯集結(jié)果。工作隊(duì)列和Condor15等其他系統(tǒng)比較類(lèi)似。我們經(jīng)常把工作隊(duì)列集群和GFS集群部署在相同的計(jì)算機(jī)集群上。這是因?yàn)镚FS是一個(gè)存儲(chǔ)系統(tǒng),CPU通常負(fù)載不太高,在CPU空閑階段可以用來(lái)運(yùn)行工作隊(duì)列任務(wù)。MapReduce8是一個(gè)運(yùn)行在工作隊(duì)列上的應(yīng)用程序庫(kù)。它提供三個(gè)主要功能。首先,它提供一個(gè)給予大量數(shù)據(jù)的并行處理的程序運(yùn)行模式。第二,它把應(yīng)用從運(yùn)行在分布式程序的細(xì)節(jié)中隔離出來(lái),包括類(lèi)似數(shù)據(jù)分布,調(diào)度,容錯(cuò)等等。最后,當(dāng)發(fā)現(xiàn)條件許可
17、時(shí),各個(gè)計(jì)算機(jī)或者存儲(chǔ)自己的GFS數(shù)據(jù)節(jié)點(diǎn)上的應(yīng)用程序可以執(zhí)行計(jì)算,減少網(wǎng)絡(luò)的流量。就是MapReduce名字說(shuō)明的含義,這個(gè)執(zhí)行模式分成兩個(gè)步驟:第一個(gè)步驟是把一個(gè)執(zhí)行操作映射到數(shù)據(jù)集合的全部元素;第二個(gè)步驟是簡(jiǎn)化第一個(gè)步驟地輸出結(jié)果,并且產(chǎn)生最終的應(yīng)答。例如,一個(gè)使用MapReduce的排序程序?qū)?huì)映射一個(gè)標(biāo)準(zhǔn)的排序算法到數(shù)據(jù)集和的每一個(gè)文件上,接下來(lái)就是運(yùn)行一個(gè)合并排序程序來(lái)簡(jiǎn)化第一個(gè)步驟出來(lái)的單獨(dú)結(jié)果,并且產(chǎn)生最終地輸出。在上千臺(tái)機(jī)器的Cluster中,一個(gè)MapReduce程序可以用每秒排序1G數(shù)據(jù)的速度排序上TB的數(shù)據(jù)9。我們的數(shù)據(jù)處理系統(tǒng)是基于MapReduce的最上層的。Saw
18、zall解釋器運(yùn)行在映射步驟。這是在大量機(jī)器上并發(fā)完成的,每一個(gè)執(zhí)行實(shí)例處理一個(gè)文件或者一個(gè)GFS塊。Sawzall程序?qū)γ恳粋€(gè)數(shù)據(jù)集的記錄執(zhí)行只執(zhí)行一次。映射步驟地輸出是一個(gè)數(shù)據(jù)項(xiàng)的集合,并且是交給聚合器去處理。聚合器在簡(jiǎn)化/減少的步驟運(yùn)行來(lái)合并結(jié)果成為最終的輸出結(jié)果。接下來(lái)的章節(jié)講述這些處理的細(xì)節(jié)。7Sawzall語(yǔ)言概覽作為一種查詢(xún)語(yǔ)言,Sawzall是一種類(lèi)型安全的腳本語(yǔ)言。由于Sawzall自身處理了很多問(wèn)題,所以完成相同功能的代碼就簡(jiǎn)化了非常多-與MapReduce的C+代碼相比簡(jiǎn)化了10倍不止。Sawzall語(yǔ)法和表達(dá)式很大一部分都是從C照搬過(guò)來(lái)的;包括for循環(huán),while循環(huán)
19、,if語(yǔ)句等等都和C里邊的很類(lèi)似。定義部分借鑒了傳統(tǒng)Pascal的模式:i:int;# a simple integer declaration;i:int=0;# a declaration with an initial value;基本類(lèi)型包括整數(shù)(int),是64位有符號(hào)值;浮點(diǎn)數(shù)(float),是一個(gè)double精度的IEEE浮點(diǎn)數(shù);以及很類(lèi)似整數(shù)的time和fingerprint。time是毫秒級(jí)別的時(shí)間,并且函數(shù)庫(kù)包括了對(duì)這個(gè)類(lèi)型的轉(zhuǎn)換和操作。fingerprint是一個(gè)執(zhí)行定義的hash值,可以很容易通過(guò)建立數(shù)據(jù)的fingerprint來(lái)構(gòu)造聚合器索引。同時(shí),Sawzall也有
20、兩種基本的數(shù)組類(lèi)型:bytes,類(lèi)似C的unsigned char的數(shù)組;string,string用來(lái)存放UNICODE的字符串。在Sawzall中沒(méi)有”字符”類(lèi)型;byte數(shù)組和string的基本元素是int,而雖然int的容量遠(yuǎn)比字節(jié)或者字符串的基本元素來(lái)得大。復(fù)合類(lèi)型包括數(shù)組,maps(本文檔中是可以重載概念),tuples。數(shù)組是用整數(shù)作為下標(biāo)檢索的,maps是結(jié)合了數(shù)組或者Python字典的類(lèi)型,可以用任意類(lèi)型檢索,可以根據(jù)需要建立無(wú)序的索引。最后tuples是對(duì)數(shù)據(jù)的任意分組,類(lèi)似C或者PASCAL的結(jié)構(gòu)類(lèi)型。任何類(lèi)型都可以有一個(gè)正式的名字。類(lèi)型轉(zhuǎn)換操作是把數(shù)據(jù)從一種類(lèi)型轉(zhuǎn)換成為
21、另一種類(lèi)型,并且Sawzall提供了很廣泛的類(lèi)型轉(zhuǎn)換。例如,把一個(gè)字符串表示的浮點(diǎn)數(shù)轉(zhuǎn)換成為一個(gè)浮點(diǎn)數(shù):f: float;s: string = 1.234;f = float(s);部分轉(zhuǎn)換是可以帶參數(shù)的:string(1234, 16)就可以把一個(gè)整數(shù)轉(zhuǎn)換成為一個(gè)16進(jìn)制的字符串。并且:string(utf8_bytes, UTF-8)轉(zhuǎn)換一個(gè)UTF-8的byte數(shù)組成為一個(gè)unicode字符串。為了方便起見(jiàn),并且為了避免某些語(yǔ)言定義上的啰嗦,編譯器可以在初始化定義的時(shí)候隱含的左適當(dāng)?shù)霓D(zhuǎn)換操作(使用缺省的轉(zhuǎn)換參數(shù))。因此:b: bytes = Hello, world!n;等價(jià)于顯示的轉(zhuǎn)換
22、:b: bytes = bytes(Hello, world!n, UTF-8);任何類(lèi)型的值都可以轉(zhuǎn)換成為字符串,這是為了調(diào)試的方便考慮。Sawzall最重要的轉(zhuǎn)換是和協(xié)議buffer相關(guān)的。Sawzall有一個(gè)編譯時(shí)刻參數(shù):proto,有點(diǎn)類(lèi)似C的#include指令,可以從一個(gè)定義了Sawzall tuple類(lèi)型的文件加載DDL協(xié)議buffer。通過(guò)tuple描述,就可以轉(zhuǎn)換輸入的協(xié)議buffer到Sawzall的值了。對(duì)于每一個(gè)輸入記錄,解釋器都需要把這個(gè)由二進(jìn)制數(shù)組表達(dá)的值初始化到特定的輸入變量中,尤其是轉(zhuǎn)換到協(xié)議buffer類(lèi)型的輸入變量中去。Sawzall程序?qū)τ诿恳粋€(gè)記錄的執(zhí)行
23、都是由下邊這條語(yǔ)句隱式執(zhí)行的:input: bytes = next_record_from_input();因此,如果文件:some_to包含了類(lèi)型Record的協(xié)議buffer的定義,那么下邊的代碼會(huì)把每一個(gè)輸入記錄分析道變量r中:proto some_to # define Recordr: Record = input; # convert input to RecordSawzall有很多其他的傳統(tǒng)特性,比如函數(shù)以及一個(gè)很廣泛的選擇基礎(chǔ)函數(shù)庫(kù)。在基礎(chǔ)函數(shù)庫(kù)中是給調(diào)用代碼使用的國(guó)際化的函數(shù),文檔分析函數(shù)等等。7.1輸入和聚合雖然在語(yǔ)句級(jí)別Sawz
24、all是一個(gè)很傳統(tǒng)的語(yǔ)言,但是它有兩個(gè)非常不尋常的特性,都在某種意義上超越了這個(gè)語(yǔ)言本身:1 Sawzall程序定義了對(duì)于數(shù)據(jù)的單個(gè)記錄的操作。這個(gè)語(yǔ)言沒(méi)有提供任何可以同時(shí)處理多條記錄的方法,以及沒(méi)有提供通過(guò)一個(gè)輸入記錄的值來(lái)影響另一個(gè)記錄的方法。2 這個(gè)語(yǔ)言為一個(gè)輸出時(shí)emit語(yǔ)句,這個(gè)語(yǔ)句發(fā)送數(shù)據(jù)到一個(gè)外部的聚合器來(lái)匯聚每一個(gè)記錄的結(jié)果并且在聚合器進(jìn)行結(jié)果的加工和處理。因此普通的Sawzall程序行為是使用輸入變量,用轉(zhuǎn)換操作把輸入的記錄分析到一個(gè)數(shù)據(jù)結(jié)構(gòu),檢查數(shù)據(jù),并且處理成一些值。我們?cè)诘谌?jié)可以看到這種模式的一個(gè)簡(jiǎn)單例子。下邊是一個(gè)更有代表性的Sawzall程序例子。對(duì)于給定的我們?cè)?/p>
25、代碼管理系統(tǒng)的源代碼提交記錄集合,這個(gè)程序會(huì)用分鐘級(jí)別的分辨率,給出周的提交變化頻率表。proto tosubmitsthroughweek: table summinute: int of count: int;log: P4ChangelistStats = input;t: time = log.time; # microsecondsminute: int = minuteof(t)+60*(hourof(t)+24*(dayofweek(t)-1);emit submitsthroughweekminute - 1;這個(gè)程序一開(kāi)始從文件to引入
26、了協(xié)議buffer描述。在這個(gè)文件中定義了類(lèi)型: P4ChangelistSTats(程序員必須明確知道這個(gè)類(lèi)型是從proto引入的,而且還要知道這個(gè)是由協(xié)議bufferDDL定義的)接下來(lái)就是定義了submitsthroughweek。它定義了一個(gè)sum值得table,這個(gè)table使用一個(gè)整數(shù)minute作為下標(biāo)。注意index值在table定義的時(shí)候是給出了一個(gè)可選的名字(minute)。這個(gè)名字沒(méi)有任何語(yǔ)義,但是使得這個(gè)定義更容易理解,并且提供了一個(gè)聚合輸出的域標(biāo)簽。log的定義把輸入的byte數(shù)組轉(zhuǎn)換成為Sawzall的類(lèi)型:P4ChangelistStats,這個(gè)轉(zhuǎn)換是用(prot
27、o語(yǔ)句引入的代碼轉(zhuǎn)換的),這個(gè)類(lèi)型是tuple類(lèi)型,保存在輸入變量log里邊。接著我們把time值取出來(lái),并且接著就保存到變量t中。接下來(lái)的定義有著更復(fù)雜的初始化表達(dá)式,這個(gè)表達(dá)式使用了一部分內(nèi)嵌的函數(shù),用來(lái)從time值來(lái)計(jì)算基準(zhǔn)的周分鐘基線(xiàn)數(shù)字 這個(gè)意思是轉(zhuǎn)換time成為周的基本分鐘數(shù)字。最后,emit語(yǔ)句通過(guò)增加該分鐘的數(shù)字來(lái)統(tǒng)計(jì)這個(gè)提交情況??偨Y(jié)一下,這個(gè)程序,對(duì)于每一個(gè)記錄,都取得時(shí)間戳,把時(shí)間轉(zhuǎn)換成為本周的分鐘數(shù),然后在這周的對(duì)應(yīng)分鐘發(fā)生次數(shù)增加1。并且,隱式的,這個(gè)會(huì)重新取下一個(gè)記錄進(jìn)行循環(huán)處理。當(dāng)我們?cè)谌康奶峤蝗罩旧线\(yùn)行這個(gè)程序,這個(gè)記錄跨越了很多個(gè)月,并且輸出結(jié)果,我們可以看
28、到一個(gè)按照分鐘區(qū)分的聚合的周活動(dòng)趨勢(shì)。輸出結(jié)果可能像這樣的:submitsthroughweek0 = 27submitsthroughweek1 = 31submitsthroughweek2 = 52submitsthroughweek3 = 41.submitsthroughweek10079 = 34當(dāng)使用圖像表達(dá),那么這個(gè)圖就像圖三一樣。我們舉這個(gè)例子要表達(dá)的意思當(dāng)然不是說(shuō)這個(gè)提交源碼的頻率數(shù)據(jù)如何如何,而是說(shuō)這個(gè)程序怎樣產(chǎn)生抽取這個(gè)數(shù)據(jù)出來(lái)。圖3:周源代碼提交頻率。本圖從周一早上凌晨0點(diǎn)開(kāi)始。7.2聚合器補(bǔ)充說(shuō)明因?yàn)槟承┰?,我們?cè)诒菊Z(yǔ)言之外完成聚合。應(yīng)該由一個(gè)傳統(tǒng)的語(yǔ)言來(lái)用語(yǔ)言處
29、理能力本身來(lái)處理結(jié)果,但是由于聚合的算法可能會(huì)相當(dāng)?shù)膹?fù)雜,最好用某種形式的機(jī)器語(yǔ)言來(lái)實(shí)現(xiàn)。更重要的是,雖然在語(yǔ)言層面上隱藏了并行的機(jī)制,但是在過(guò)濾階段和聚合階段劃一條清晰的界限能夠有助于更高級(jí)別的并行處理。在Sawzall中不存在記錄的多樣性的,在Sawzall典型任務(wù)就是在上百或者上千臺(tái)機(jī)器上并發(fā)操作上百萬(wàn)條記錄,集中精力在聚合器上可以創(chuàng)造出很不尋常的聚合器。現(xiàn)在已經(jīng)有許多聚合器;下邊是一個(gè)不完整的列表: 搜集器c:table collection of string;一個(gè)簡(jiǎn)單的輸出結(jié)果列表,這個(gè)結(jié)果在列表中是任意順序的。 采樣器s:table sample(100) of string類(lèi)似
30、搜集器,但是存的是無(wú)偏差的輸出結(jié)構(gòu)的采樣值。這個(gè)采樣的大小是用參數(shù)體現(xiàn)的。 累加s:table sum of (count:int,revenue:float);所有輸出結(jié)果的合計(jì)。這個(gè)輸出結(jié)果必須是算數(shù)的或者可以以算術(shù)為基礎(chǔ)的(也就是可累加的,by 譯者),就像例子中的tuple結(jié)構(gòu)那樣(也就是說(shuō)一般可以是sum of int,也可以像上邊說(shuō)的一樣,可以用sum of (count:int,revenue:float)這樣的tuple結(jié)構(gòu)。對(duì)于復(fù)合值,元素是按照內(nèi)部的項(xiàng)進(jìn)行累加的。在上邊的例子,如果count始終為1,那么平均revenue可以在處理完和以后用revenue除以count來(lái)得
31、到。 最大值m:table maximum(10) of string weight length: int;取得最大權(quán)重的值。每一個(gè)值都有一個(gè)權(quán)重,并且最終選擇的值是根據(jù)最大權(quán)重來(lái)選擇的。這個(gè)參數(shù)(例子中是10)規(guī)定了需要保留的最終輸出的值數(shù)量。權(quán)重是以明確的keyword來(lái)描述的,并且它的類(lèi)型(這里是int)是在這里定義的,它的值是emit語(yǔ)句給出的。對(duì)上邊例子來(lái)說(shuō),emit語(yǔ)句如下:emit m - s weight len(s);這樣將會(huì)在結(jié)果中放置最長(zhǎng)的字符串。 分位數(shù)q:table quantile(101) of response_in_ms:int;是用輸出的值來(lái)構(gòu)造一個(gè)每個(gè)概
32、率增量分位數(shù)的累計(jì)概率分布(算法是一個(gè)Greenwald和Khanna的分布式算法10)。這個(gè)例子可以用來(lái)查看系統(tǒng)的響應(yīng)變化的分布情況。通過(guò)參數(shù)101,這個(gè)參數(shù)用來(lái)計(jì)算百分點(diǎn)。第50個(gè)元素是中間點(diǎn)的響應(yīng)時(shí)間,第99個(gè)元素是99%的響應(yīng)時(shí)間都小于等于第99個(gè)元素。 最常見(jiàn)c:table top(10) of language: string;top table評(píng)估這個(gè)值是否最常見(jiàn)(與之對(duì)應(yīng)的,maximun table找到最高權(quán)重的值,而不是最常見(jiàn)的值)例如:emit t - language_of_document(input);將會(huì)從文檔庫(kù)中建立10個(gè)最常見(jiàn)的語(yǔ)言。對(duì)于很大的數(shù)據(jù)集來(lái)說(shuō),它可
33、能需要花費(fèi)過(guò)大的代價(jià)來(lái)找到精確的出席頻率的order,但是可以有很有效的評(píng)估算法。top table是用了Charikar,Chen,Farach-Colton5的分布式算法。算法返回的最常見(jiàn)的頻率是極為接近真實(shí)的出現(xiàn)頻率。因?yàn)樗慕粨Q性和結(jié)合性也不是完全精確的:改變處理的輸入記錄先后順序確實(shí)會(huì)影響到最終的結(jié)果。作為彌補(bǔ)措施,我們?cè)诮y(tǒng)計(jì)元素個(gè)數(shù)之外,也要統(tǒng)計(jì)這些個(gè)數(shù)的誤差。如果這個(gè)誤差和元素個(gè)數(shù)相比比較小,那么結(jié)果的正確度就比較高,如果錯(cuò)誤相對(duì)來(lái)說(shuō)比較大,那么結(jié)果就比較差。對(duì)于分布不均勻的大型數(shù)據(jù)集來(lái)說(shuō),top table工作的很好。但是在少數(shù)情況下比如分布均勻的情況下,可能會(huì)導(dǎo)致工作的不是很
34、成功。 取唯一u:table unique(10000) of string;unique table是比較特別的。它報(bào)告的是提交給他的唯一數(shù)據(jù)項(xiàng)的估計(jì)大小。sum table可以用來(lái)計(jì)算數(shù)據(jù)項(xiàng)的總和個(gè)數(shù),但是一個(gè)unique table會(huì)忽略掉重復(fù)部分;最終計(jì)算輸入值集合得大小。unique table同樣特別無(wú)論輸入的值是什么類(lèi)型,它的輸出總是一個(gè)count。這個(gè)參數(shù)是給出了內(nèi)部使用的table大小,這個(gè)是用來(lái)內(nèi)部作評(píng)估是用的內(nèi)部表;10000的參數(shù)值會(huì)讓最終結(jié)果有95%的概率正負(fù)2%的誤差得到正確的結(jié)果(對(duì)于N,標(biāo)準(zhǔn)偏差是大概N*參數(shù)*(-1/2))有時(shí)候也會(huì)有新的聚合器出來(lái)。雖然聚合器
35、用處很大,但是增加一個(gè)新的聚合器還算容易。聚合器的實(shí)現(xiàn)復(fù)雜在需要支持所有解釋器所支持的數(shù)據(jù)類(lèi)型。聚合器的實(shí)現(xiàn)還需要效驗(yàn)?zāi)承╊?lèi)型(校驗(yàn)參數(shù)值和元素類(lèi)型),并且對(duì)保存和讀取數(shù)據(jù)作打包。對(duì)于簡(jiǎn)單的聚合器,類(lèi)似sum,就沒(méi)有什么其他的要求了。對(duì)于更復(fù)雜的聚合器,類(lèi)似分位數(shù)和top,必須注意要選擇一個(gè)符合交換律和結(jié)合律的算法,并且這個(gè)算法要在分布式處理上有足夠的效率。我們最小的聚合器實(shí)現(xiàn)上大概只用了200行C+代碼,最大的聚合器用了大概1000行代碼。有些聚合器可以作為map階段來(lái)處理數(shù)據(jù),這樣可以降低聚合器的網(wǎng)絡(luò)帶寬。例如sum table可以本地作各個(gè)元素的累加,只是最后把本部分的小計(jì)發(fā)往遠(yuǎn)端的聚合
36、器。用MapReduce的詞語(yǔ)來(lái)說(shuō),這就是MapReduce的合并階段,一種在map和reduce中間的優(yōu)化階段。7.3帶索引的聚合器聚合器可以是帶索引的,這個(gè)可以使得每一個(gè)索引下標(biāo)的值都有一個(gè)單獨(dú)的聚合器。這個(gè)index可以是任意的Sawzall類(lèi)型,并且可以是一個(gè)聚合器的多維的結(jié)構(gòu)下標(biāo)。例如,如果我們檢查web服務(wù)器的log,table:table top(1000)country:stringhour:int of request:string;可以用來(lái)找到每一個(gè)國(guó)家每一個(gè)小時(shí)的最常用的請(qǐng)求字串。當(dāng)新的索引值產(chǎn)生的時(shí)候,就會(huì)動(dòng)態(tài)產(chǎn)生一個(gè)獨(dú)立的聚合器,某種意義上比較類(lèi)似map,但是是和所有
37、運(yùn)行的機(jī)器無(wú)關(guān)。聚合階段會(huì)比較每一個(gè)索引下標(biāo)對(duì)應(yīng)的值,并且產(chǎn)生適當(dāng)?shù)木酆现到o每一個(gè)索引值。作為整理的一部分,數(shù)據(jù)值將按照索引排序,這樣使得從不同機(jī)器上合并最終結(jié)果比較容易。當(dāng)任務(wù)完成的時(shí)候,輸出值就按照索引進(jìn)行排序了,這就意味著聚合器的輸出是索引順序的。index本身就是構(gòu)造了一個(gè)有用的信息。就像上邊講述的web服務(wù)器的例子,當(dāng)運(yùn)行完以后,在country索引的記錄中就構(gòu)造了請(qǐng)求接收到的國(guó)家集合。另外,index的引入使得可以用index對(duì)結(jié)果集進(jìn)行分類(lèi)。table sumcountry:string of int產(chǎn)生的索引結(jié)果將會(huì)等同于去掉重復(fù)項(xiàng)以后的table collection of
38、country:string的結(jié)果值。8System Model下邊介紹本語(yǔ)言的基本特性,通過(guò)對(duì)數(shù)據(jù)分析的建立,我們可以給出高級(jí)別的系統(tǒng)模式概覽。系統(tǒng)運(yùn)行是基于一個(gè)批處理的模式的:用戶(hù)提交一個(gè)工作,這個(gè)工作分布在一個(gè)固定的文件集合上,并且在執(zhí)行完成以后搜集輸出的結(jié)果。輸入格式和數(shù)據(jù)源(通常是文件集)以及輸出目標(biāo)都是在程序語(yǔ)言外指定的,通過(guò)執(zhí)行工作的參數(shù)形式來(lái)遞交給系統(tǒng)進(jìn)行執(zhí)行。當(dāng)系統(tǒng)接收到一個(gè)工作請(qǐng)求,Sawzall處理器就開(kāi)始效驗(yàn)這個(gè)程序是否語(yǔ)法正確。如果語(yǔ)法正確,源代碼就發(fā)送給各個(gè)將被執(zhí)行的機(jī)器,每一個(gè)機(jī)器就開(kāi)始分析代碼并且開(kāi)始執(zhí)行。每一個(gè)執(zhí)行的機(jī)器的輸出都分不到一組文件中,每一個(gè)文件都部
39、署在一個(gè)聚合器機(jī)器上。這個(gè)輸出結(jié)果拆分到不同的機(jī)器上,是為了能讓聚合器并行工作。我們給予特定的table和他上邊的相關(guān)索引來(lái)確定這些分布在各個(gè)文件中的值。基于table的類(lèi)型,輸入table的值可以是最終格式的值,也可以是某種中間結(jié)果的值,這些中間結(jié)果便于進(jìn)行合并或者處理。這種合并處理必須能夠良好的結(jié)合起來(lái)才能工作的一個(gè)步驟。某些工作由于十分巨大,而結(jié)合率允許他們拆成多個(gè)小塊,并行運(yùn)行,最后再合并在一起。(這是本系統(tǒng)的一個(gè)優(yōu)勢(shì),優(yōu)于平坦模式的MapReduce;因?yàn)镸apReduce可能會(huì)在一個(gè)需要運(yùn)行幾天幾周的任務(wù)上出問(wèn)題)通常,分解處理以后的數(shù)據(jù)要比輸入要小得多,但是也會(huì)有某些關(guān)鍵的應(yīng)用不
40、是這樣的。例如,我們的程序可以用一個(gè)帶索引的collection table來(lái)對(duì)數(shù)據(jù)作多維的組織,在這樣的情況下,輸出結(jié)果就可能比輸入要多。Sawzall中一個(gè)常用的輸入是把結(jié)果數(shù)據(jù)注入一個(gè)傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)中,以備后續(xù)的分析。通常這些都是有不同的用戶(hù)程序來(lái)注入,也許是用Python,它把數(shù)據(jù)轉(zhuǎn)換成為通過(guò)SQL指令建立的表。我們以后也許會(huì)提供更多的直接方法來(lái)完成八結(jié)果注入到數(shù)據(jù)庫(kù)的動(dòng)作。Sawzall的結(jié)果有時(shí)也用于其它Sawzall程序的輸入,這個(gè)就是鏈?zhǔn)教幚?。鏈?zhǔn)教幚淼暮?jiǎn)單例子就是精確計(jì)算輸出的”top 10”列表。Sawzall的top table雖然高效,但是他不精確。如果需要精確的結(jié)果
41、,那么就需要分為兩個(gè)步驟。第一步創(chuàng)建一個(gè)帶索應(yīng)的sum table來(lái)統(tǒng)計(jì)輸入值得頻率;第二個(gè)步驟是用一個(gè)maximum table來(lái)選擇最常見(jiàn)的頻率。這樣可能有點(diǎn)笨,但是這種方法依舊是非常高效的方法來(lái)計(jì)算多維的table。9例子這里是另外一個(gè)完整的例子,演示了Sawzall在實(shí)際中如何使用。這里是處理一個(gè)web文檔庫(kù),并且產(chǎn)生一個(gè)結(jié)果:對(duì)于每一個(gè)web服務(wù)器,那一個(gè)page有著最高的Page Rank13?答曰來(lái)說(shuō),那一個(gè)是最多l(xiāng)ink指向的page?proto“to”max_pagerank_uri:table maximun(1)domain:string of u
42、rl:stringweight pagerank:int;doc: Document = input;url:string = doc.url;emit max_pagerank_urldomain(url) - urlweight doc.pagerank;protocol buffer 的格式是在”to”中定義的。這個(gè)table是max_pagerank_url,并且會(huì)紀(jì)錄每一個(gè)索引中最高權(quán)重的值。這個(gè)索引是domain,值是URL,權(quán)重勢(shì)document的PageRank。程序處理輸入的紀(jì)錄,解出URL,并且執(zhí)行相關(guān)的emit語(yǔ)句。它會(huì)調(diào)用庫(kù)函數(shù) domain(u
43、rl)來(lái)解出URL所對(duì)應(yīng)的domain,并且使用這個(gè)domain作為index,把URL作為值,并且用這個(gè)document對(duì)應(yīng)的PageRank作為權(quán)重。當(dāng)這個(gè)程序在一個(gè)數(shù)據(jù)倉(cāng)庫(kù)上運(yùn)行的時(shí)候,輸出對(duì)于大部分site,most-linked網(wǎng)頁(yè)是-真是令人驚訝。Acrobat 下載站點(diǎn)是的top page,并且連接到的就是連接到連接最多的圖庫(kù)站點(diǎn),并且是最多引用的夜生活page。因?yàn)槭怯肧awzall能簡(jiǎn)單表達(dá)這樣的計(jì)算,所以程序是又簡(jiǎn)潔又優(yōu)美。即使用了MapReduce,等價(jià)的C+程序也要好幾百行代
44、碼。下邊是一個(gè)例子,使用了多維索引的聚合器。我們目的是通過(guò)檢索搜索log,建立一個(gè)查詢(xún)發(fā)起點(diǎn)的世界地圖。proto“to”queries_per_degree: table sumlat:intlon:int of int;log_record:QueryLogProto = input;loc:Location = locationinfo(log_record.ip);emit queries_per_degreeeint(loc.lat)int(loc.lon) - 1;這個(gè)程序相當(dāng)直接,我們引入查詢(xún)log的DDL,定義一個(gè)用了經(jīng)緯作索引的table,并且從log
45、中解包查詢(xún)。接著我們是用內(nèi)嵌函數(shù)把這個(gè)IP地址對(duì)應(yīng)到請(qǐng)求及其的位置(可能是ISP的位置),并且為每一個(gè)經(jīng)緯點(diǎn)增加1。int(loc.lat)把loc.lat,一個(gè)浮點(diǎn)值轉(zhuǎn)換成為一個(gè)整數(shù),截?cái)喑蔀橐粋€(gè)維數(shù)下標(biāo)。對(duì)于高分辨的地圖來(lái)說(shuō),可能要求更精細(xì)的計(jì)算。這個(gè)程序的輸出是一個(gè)數(shù)組,可以用來(lái)構(gòu)造一個(gè)地圖,參見(jiàn)圖4。10執(zhí)行模式在語(yǔ)句級(jí)別,Sawzall是一個(gè)常規(guī)的語(yǔ)言,但是從更高的角度看,他有一些特點(diǎn),所有的設(shè)計(jì)目的都是為了并行計(jì)算。當(dāng)然,最重要的是,一次處理一個(gè)紀(jì)錄。這就意味著,其他紀(jì)錄的處理將不消耗額外的內(nèi)存(除了在語(yǔ)言本身外把結(jié)果提交給聚合器)。Sawzall在上千臺(tái)機(jī)器上并行執(zhí)行,是Sawz
46、all的一個(gè)設(shè)計(jì)目的,并且系統(tǒng)要求這些機(jī)器之間沒(méi)有額外的通訊。唯一的通訊就是從Sawzall的執(zhí)行結(jié)果下載到聚合器。圖四:查詢(xún)分布為了強(qiáng)調(diào)這點(diǎn),我們用計(jì)算輸入記錄數(shù)的數(shù)量來(lái)入手。就像我們之前看到的這個(gè)程序:count:table sum of int;emit count - 1;這個(gè)程序?qū)⑼瓿山y(tǒng)計(jì)記錄數(shù)的工作。與之對(duì)比的是,如下的一個(gè)錯(cuò)誤的程序:count:int = 0;count +;這個(gè)程序?qū)⒉荒芙y(tǒng)計(jì)記錄數(shù),因?yàn)?,?duì)于每一個(gè)記錄來(lái)說(shuō),count都被設(shè)置成為0,然后再+,最后結(jié)果就扔掉了。當(dāng)然,并行到大量機(jī)器上執(zhí)行,扔掉count的效率當(dāng)然很高。在處理每一個(gè)記錄之前,Sawzall程序都
47、會(huì)回到初始的狀態(tài)。類(lèi)似的,處理完成一條記錄,并且提交了所有的相關(guān)的數(shù)據(jù)給聚合器后,任何執(zhí)行過(guò)程中使用到的資源變量臨時(shí)空間等等都可以被廢棄。Sawzall因此使用的是一個(gè)arena allocator11(單向遞增分配,場(chǎng)地分配策略,就是說(shuō),從一個(gè)內(nèi)存池中通過(guò)單向增加一個(gè)指針的方式來(lái)分配內(nèi)存,類(lèi)似零散內(nèi)存的管理方式)。當(dāng)一個(gè)記錄都處理完成之后,就釋放到初始狀態(tài)。在某些情況下,重新初始化是不需要的。例如,我們可能會(huì)創(chuàng)建一個(gè)很大的數(shù)組或者影射表來(lái)對(duì)每條記錄進(jìn)行分析。為了避免對(duì)每條記錄都作這樣的初始化,Sawzall有一個(gè)保留字static可以確保這個(gè)變量只初始化一次,并且是在處理每條記錄的最開(kāi)始的初
48、始化的時(shí)候執(zhí)行。這就是一個(gè)例子:staticCJK: mapstring of string = “zh” : “Chinese”,“jp”:”Japanese”,“ko”,”Korean”,;CJK變量會(huì)在初始化的時(shí)候創(chuàng)建,并且作為處理每條記錄的初始化的時(shí)候都保留CJK變量的值。Sawzall沒(méi)有引用類(lèi)型;它是純粹值語(yǔ)義的。數(shù)組和maps也可以作為值來(lái)是用(實(shí)現(xiàn)的時(shí)候,在大部分情況下,用copy-on-write引用計(jì)算來(lái)提高效率)。某些時(shí)候這個(gè)比較笨拙-在一個(gè)函數(shù)中修改一個(gè)數(shù)組,那么這個(gè)函數(shù)必須返回一個(gè)函數(shù)-但是在典型的Sawzall程序中,這個(gè)并沒(méi)有太大的影響。但是這樣的好處,就可以使得
49、并發(fā)處理記錄的時(shí)候,不需要擔(dān)心同步問(wèn)題或者擔(dān)心交叉使用的問(wèn)題,雖然實(shí)現(xiàn)上很少會(huì)用到這個(gè)情況。11語(yǔ)言的Domain相關(guān)特性為了解決domain操作的問(wèn)題,Sawzall有許多domain相關(guān)的特性。有一部分已經(jīng)討論過(guò)了,本節(jié)討論的是剩下的一部分。首先,跟大部分”小語(yǔ)言”2所不同,Sawzall是一個(gè)靜態(tài)類(lèi)型語(yǔ)言。主要是為了可靠性的考慮。Sawzall程序在一次運(yùn)行中,會(huì)是用數(shù)小時(shí),乃至好幾個(gè)月的CPU時(shí)間,一個(gè)遲綁定(late-arising)動(dòng)態(tài)類(lèi)型錯(cuò)誤導(dǎo)致的代價(jià)就有可能太大。另外,還有一個(gè)潛在的原因,聚合器使用完整的Sawzall類(lèi)型,靜態(tài)類(lèi)型會(huì)讓聚合器的實(shí)現(xiàn)比較容易。類(lèi)似的爭(zhēng)議也在分析輸
50、入?yún)f(xié)議buffer上;靜態(tài)類(lèi)型可以精確檢測(cè)輸入的類(lèi)型。同樣的,也會(huì)因?yàn)楸苊饬诉\(yùn)行時(shí)刻動(dòng)態(tài)類(lèi)型檢測(cè)而提高整個(gè)的性能。最后,便以時(shí)候類(lèi)型檢查和強(qiáng)制類(lèi)型轉(zhuǎn)換要求程序員精確的指出類(lèi)型轉(zhuǎn)換。唯一的例外是在變量初始化的時(shí)候,但是就算在這個(gè)時(shí)候,類(lèi)型以就是清晰而且程序也是類(lèi)型安全的。從另外的角度上看,強(qiáng)類(lèi)型保證了變量的類(lèi)型一定可知,在初始化的時(shí)候容易處理。例如:t:time=”Apr 1 12:00:00 PST 2005”;這樣的初始化就很容易理解,而且還是類(lèi)型安全的。并且有一些基本類(lèi)型的屬性也是主機(jī)相關(guān)的。比如處理log記錄的time stamps的時(shí)候,這個(gè)time基本類(lèi)型就是依賴(lài)于log記錄的tim
51、e stamps的;對(duì)于它來(lái)說(shuō),如果要支持夏令時(shí)的時(shí)間處理就太過(guò)奢侈了。更重要的是(近來(lái)比較少見(jiàn)了),這個(gè)語(yǔ)言定義了用UNICODE表示string,而不是處理一組擴(kuò)展字符集編碼的變量。由于處理大量數(shù)據(jù)集的需要,我們有賦予這個(gè)語(yǔ)言?xún)蓚€(gè)特性:處理未定義的值,處理邏輯量詞。下兩節(jié)詳細(xì)描述這個(gè)特性。11.1 未定義的值Sawzall沒(méi)有提供任何形式的異常處理機(jī)制。相反,他有自己的未定義值得處理概念,用來(lái)展示錯(cuò)誤的或者不確定的結(jié)果,包括除0錯(cuò),類(lèi)型轉(zhuǎn)換錯(cuò)誤,I/O錯(cuò)誤,等等。如果程序在初始化以外的地方,嘗試去讀一個(gè)未定義的值,它會(huì)崩潰掉,并且報(bào)告一個(gè)失敗。def()斷言,用于檢測(cè)這個(gè)值是否一定定義了;如果這個(gè)值是一個(gè)確定值,他返回true,否則返回false。他的通常用法如下:v: Value = maybe_undefined();if (def(v) compute(v);下面是一個(gè)必須處理未定義值得例子。我們?cè)趒uery-mapping程序中擴(kuò)展一個(gè)時(shí)間軸。原始程序使用函數(shù)locationinfo()來(lái)通過(guò)外部數(shù)據(jù)庫(kù)判定IP地址的位置。當(dāng)IP地址不能在數(shù)據(jù)庫(kù)中找到的時(shí)候,這個(gè)程序是不穩(wěn)定的。在這種情況下,loc
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版二手房屋買(mǎi)賣(mài)合同變更協(xié)議
- 絲網(wǎng)合同標(biāo)準(zhǔn)文本制作
- 新員工試崗協(xié)議書(shū)正規(guī)范例二零二五年
- 二零二五電影導(dǎo)演聘用合同
- 商鋪?zhàn)赓U合同匯編二零二五年
- 倉(cāng)儲(chǔ)返利合同樣本
- 內(nèi)控評(píng)價(jià)咨詢(xún)合同模板二零二五年
- 鄉(xiāng)村少年宮輔導(dǎo)員考核細(xì)則
- 二零二五車(chē)輛抵押擔(dān)保合同
- 2025年空間環(huán)境藝術(shù)設(shè)計(jì)項(xiàng)目合作計(jì)劃書(shū)
- Unit 2 Go for it!Understanding ideas教學(xué)設(shè)計(jì) -2024-2025學(xué)年外研版(2024)七年級(jí)英語(yǔ)下冊(cè)
- 浙江省金麗衢十二校2025屆高三下學(xué)期二模試題 地理 含解析
- 【+初中語(yǔ)文+】《山地回憶》課件+統(tǒng)編版語(yǔ)文七年級(jí)下冊(cè)
- 2025-2030中國(guó)建筑裝飾行業(yè)十四五發(fā)展分析及投資前景與戰(zhàn)略規(guī)劃研究報(bào)告
- (一模)2025年廣東省高三高考模擬測(cè)試 (一) 語(yǔ)文試卷語(yǔ)文試卷(含官方答案)
- 管理學(xué)基礎(chǔ)-形考任務(wù)一-國(guó)開(kāi)-參考資料
- 3.3 服務(wù)業(yè)區(qū)位因素及其變化-以霸王茶姬為例【知識(shí)精研】同步教學(xué)課件(人教2019必修第二冊(cè))
- 2024年員工知識(shí)產(chǎn)權(quán)與保密協(xié)議范本:企業(yè)知識(shí)產(chǎn)權(quán)保護(hù)實(shí)務(wù)3篇
- JGJ46-2024 建筑與市政工程施工現(xiàn)場(chǎng)臨時(shí)用電安全技術(shù)標(biāo)準(zhǔn)
- GB 17790-2008家用和類(lèi)似用途空調(diào)器安裝規(guī)范
- 土地評(píng)估剩余法測(cè)算表
評(píng)論
0/150
提交評(píng)論