性能一直是網站成功的關鍵。愈來愈多的研究已經證實,無論是小型電商,仍是像沃爾瑪那樣的連鎖店,即便是頁面加載時間方面的細微改善,均可以帶來更多的業務,更多的廣告收入,更多的用戶粘性和更多的客戶滿意度。javascript
在過去幾年,Web開發者都是基於改善硬件或者提升帶寬速度來優化用戶體驗。可是最近幾年,爆炸式的移動Web瀏覽器的使用打破了這個途徑。低帶寬,高延遲,小內存,低處理器性能的移動設備環境,迫使開發者不得不想辦法經過優化前端頁面的性能來知足用戶的性能預期。php
在強調如何解決移動端性能問題上,這篇文章總結了一些前端優化的案例,而且歸納了一些加速頁面的方法和策略。css
爲何性能會影響這麼多
不論你的頁面設計地多麼有趣、漂亮、交互性好,無論是在桌面仍是移動設備上,若是頁面須要花2到3秒時間去渲染展現,那麼用戶都會很快變得不耐煩的。能夠預期的是,在頁面還在加載的時候,用戶頗有可能從瀏覽購買的行爲轉變爲點擊回退鍵或者是關閉瀏覽器的行爲。html
不到1秒鐘的延遲甚至也會顯著地影響收入。在2006年,當時還在Google工做的Marissa Mayer說,因爲用戶表示但願在一個搜索頁上看到多於10個搜索結果,Google就實驗性地修改成30個。可是讓人吃驚的是,在這個實驗裏,流量和投資都減小了20個百分點,顯然是因爲更多的搜索結果致使多花費了半秒時間來加載頁面。^5前端
用戶的指望老是在不斷的提高。2009年,Forrester研究所的Akamai的一項研究發現代表,網頁響應時間可容忍的閥值是2秒,一旦網頁相應時間超過3秒,會有40%的用戶放棄瀏覽頁面。一年以後,Akamai的另外一項研究代表,超過3秒放棄瀏覽頁面的用戶比例上升到了57%。^1,7html5
此外,移動端的用戶但願移動設備上的頁面性能不亞於桌面PC。由Tealeaf科技(如今已經併入IBM)委託的「Harris的互動2011移動交互調查」顯示,在前一年有過移動消費經歷的成年人中,有85%但願移動設備上的體驗能與手提電腦或者PC上的體驗至關,甚至於更好。而且有63%的人表示,一旦他在移動設備上的交易遇到了一個問題,他們就不會再想經過其餘渠道去購買這個公司的其餘產品了。^10換句話說,差勁的移動頁面性能會影響到公司其餘各類平臺的銷售,這其中固然也包括線下的實體店。java
移動流量正在迅速增加。對許多消費者而言,他們的手機或者平板設備已經成爲他們瀏覽網絡的主要入口了,可是其性能表現卻差強人意。2011年2月,Compuware公司委託Equation 研究所作的一項研究代表,幾乎一半的移動用戶(46%)表示他們手機上的網站加載速度過慢。60%的用戶但願頁面能在3秒或者更少的時間內加載完成,74%的用戶表示,當單個頁面加載時間花費5秒或者更多的時候,他們會選擇離開這個頁面。在2012年,由Strangeloop網絡(現已併入Redware)發起的一項針對200家領先的電子商務網站研究代表,3G網絡環境下,平均加載時間爲11.8秒(圖1),而在LTE(4G)環境下,加載時間只有輕微的改善,爲8.5秒。^8node
移動設備表現性能的三種影響因素
正如上文所說的,移動設備天生有下面三種性能限制:帶寬低,內存小,處理器性能低。這些性能挑戰又加上一些其餘的問題,例如:jquery
網頁比之前更大。根據HTTP Archive網站的分析,如今平均的一個web頁面須要加載超過1MB的數據,其中包含有圖片,Javascript,CSS(Cascading Style Sheets)等。更大的網頁會影響桌面PC的顯示性能。對於移動端的性能 — 特別是3G環境下的性能 — 影響更嚴重。這個影響會在從此的三年更加明顯。以如今的頁面增加速度來講,到2015年,平均的頁面大小會達到2MB。ios
延遲相差巨大。對LTE來講,延遲大概有34ms,對3G來講,延遲大概有350毫秒甚至更多。移動端的延遲性惟一不變的就是延遲時間永遠是不定的,即便是在同一個地點,每次的延遲都是不定的。這是因爲大量的數據是經過信息塔進行傳輸的。所以諸如天氣,甚至是持有者所面向的方向都有可能成爲影響因素。
下載速度相差巨大。下載速度的範圍從3G環境下的1Mbps到LTE環境下的31Mbps。把這個和美國平均的帶寬15Mbps相比是一個頗有意思的事情,3G環境比平均帶寬慢了15倍,而LTE卻能達到平均帶寬的2倍那麼快。
M.SITES並不能徹底解決移動端性能的問題。
許多網站建設者嘗試針對多用戶訪問,大網頁和低流量鏈接的訪問頁面,開發出短小,快速,精簡的m.sites;可是,這些嘗試並無什麼用,當用戶有選擇權的時候,高達35%的移動用戶會選擇瀏覽完整的網站。
這些選擇瀏覽完整網站的用戶顯然比瀏覽m.sites的用戶更有購買慾望。一個研究代表,移動端每$7.00的消費中,有$5.50是來自於網站的網站瀏覽,只有$1.00是來自於m.sites,剩下的$0.50則是來自於客戶端。^9
解決問題
改善網站性能的主要策略並無由於從PC變成手機或者平板設備而有變化,只是會參雜一些小的策略。
不論在PC仍是在移動瀏覽器上,頁面展現須要的時間裏,只有20%是用來讀取頁面的HTML的。剩下的80%是用來加載額外的像樣式表、腳本文件、或者圖片這樣的資源和執行客戶端的程序。
三個主要的改善性能的策略是:
- 減小每一個頁面須要獲取額外資源的HTTP請求數
- 減小每一個請求加載的大小
- 優化客戶端執行的優先級和腳本執行的效率
因爲移動網絡一般比桌面機器的網絡慢,因此減小請求數和請求加載量是很是重要的。因爲移動端的瀏覽器解析HTML和執行JavaScript的效率比桌面PC低,因此優化客戶端程序也是很是關鍵的。另外,移動端瀏覽器的緩存大小比桌面PC低,因此須要有方法能重複利用本地的緩存資源。
文章剩餘部分總結了能解決這些問題的方法。雖然這些方法大均可以自動化解決,固然也能夠由有經驗的前端工程師來手動解決。關鍵就是要知道人工解決這些技術的方法如何控制資源的請求。一般在CMS(內容管理系統)或者其餘Web應用中,有些頁面包含一些自動生成好的或者離線的HTML片斷、CSS或者Javascript文件,這樣的頁面開發者就不須要去優化它們了。
減小請求
最大的性能漏洞就是一個頁面須要發起幾十個網絡請求來獲取諸如樣式表、腳本或者圖片這樣的資源。這個在相對低帶寬和高延遲的移動設備鏈接上來講影響更嚴重。CDNs(內容分發網絡)把資源放在離用戶地理位置更近的地方對解決這個問題能起到很大做用,可是比起獲取請求,大量的請求對頁面加載時間的影響更爲嚴重。並且最近的發現代表,CDNs對移動端用戶的性能影響愈來愈低。
下面的章節討論了簡化HTTP請求的幾種方法。
整合資源
對開發者來講,將Javascript代碼和CSS樣式放到公共的文件中供多個頁面共享是一種標準的優化方法。這個方法能很簡單的維護代碼,而且提升客戶端緩存的使用效率。
在Javascript文件中,要確保在一個頁面中相同的腳本不會被加載屢次。當大團隊或者多個團隊合做開發的時候,這種冗餘的腳本就很容易出現。你可能會對它的發生頻率並不低感到很是吃驚。
Sprites是css中處理圖片的一項技術。Sprites就是將多張圖片整合到一個線性的網狀的大圖片中。頁面就能夠將這個大圖片一次性獲取回來而且作爲css的背景圖,而後使用css的背景定位屬性展現頁面須要的圖片部分。這種技術將多個請求整合成一個,能顯著地改善性能。
實現小貼士:平穩地改進可是須要對資源有控制權限。根據開發者的網站不一樣權限,一些資源並不須要被整合起來(例如,一些由CMS生成的資源)。還有,對於一些外部域引用的資源,強行整合可能會致使問題。須要注意的是,整合資源對手機瀏覽器來講是一把雙刃劍。整合資源確實會在首次訪問減小請求,可是大的資源文件可能會致使緩存失效,因此,須要當心地使用各類技術整合資源,以達到優化本地存儲的目的。
使用瀏覽器緩存和本地緩存
如今全部的瀏覽器都會使用本地資源去緩存住那些被Cache-Control或者Expires頭標記的資源,這些頭能標記資源須要緩存的時間。另外,ETag(實體標籤)和Last-Modified頭來標識當資源過時後是否須要從新請求。瀏覽器爲了減小沒必要要的服務器請求,儘量地從本地緩存中獲取資源,而且將那些已通過期的、或者當緩存空間減少的時候將那些好久不用的資源進行清理。瀏覽器緩存一般包括圖片,CSS,Javascript代碼,這些緩存能合理地提升網站的性能。(好比爲了支持後退和前進的按鈕,使用一個單獨的緩存來保存整個渲染的頁面)。
移動瀏覽器緩存,一般是比桌面PC小的多,這就致使了緩存的數據會很常常被清理。HTML5的緩存基於瀏覽器緩存提供了一個很好的替換方案。Javascript的localStorage已經在全部主流的桌面和移動端瀏覽器上都實現了。使用腳本代碼能簡便地支持HTML5的localStorage操做,能夠讀寫鍵值數據,每一個域名大概有5MB的容量。雖然不一樣的移動瀏覽器上讀寫速度相差很大,可是localStorage大容量的緩存使得它很適合做爲客戶端的緩存。從localStorage獲取資源明顯快於從服務器上獲取資源,並且在大多數移動設備上也比依靠緩存頭或者瀏覽器的本地緩存更靈活可靠。這是移動瀏覽器比桌面PC更有優點的一個地方,在桌面PC上,本地緩存仍然優先使用標準的瀏覽器緩存,致使桌面PC本地緩存的性能落後於移動瀏覽器。
實現小貼士:須要進一步考慮。雖然localStorage的機制易於實現,可是它的一些控制機制倒是很是複雜的。你須要考慮到緩存帶給你的全部問題,好比緩存失效(何時須要刪除緩存?),緩存丟失(當你但願數據在緩存中的時候它並不在怎麼辦?),還有當緩存滿的時候你怎麼辦?
首次使用的時候在HTML中嵌入資源
HTML的標準是使用連接來加載外部資源。這使得更容易在服務器上(或者在CDN上)操做更新這些資源,而不是在每一個頁面上修改更新這些資源。根據上文討論的,這種模式也使得瀏覽器能從本地緩存而不是服務器上獲取資源。
可是對尚未緩存到瀏覽器localStorage的資源來講,這種模式對網站的性能有負面的影響。通常來講,一個頁面須要幾十個單獨的請求來獲取資源從而渲染頁面。因此說,從性能的角度來講,若是一個資源沒有很高的被緩存的概率的話,最好把它嵌入到頁面的HTML中(叫inlining),而不是使用連接外部。腳本和樣式是支持內嵌到HTML中的,可是圖片和其餘的二進制資源其實也是能夠經過內嵌包含base64編碼的文原本嵌入到HTML中的。
內嵌的缺點是頁面的大小會變得很是大,因此對於Web應用來講,關鍵的是可以跟蹤分析這個資源何時須要從服務端獲取,何時已經緩存到客戶端了。另外,在第一次請求資源後必須可以使用代碼在客戶端緩存資源,所以,在移動設備上,使用HTML5 localStorage能很好地作到內嵌。
實現小貼士:平穩處理。因爲不知道用戶是否已經訪問過這個頁面了,因此須要網站有機制能生成不一樣版本的頁面。
使用HTML5服務端發送事件
Web應用已經使用了各類從服務器上輪詢資源的方法來持續地更新頁面。HTML5的EventSource對象和Server-Sent事件能經過瀏覽器端的JavaScript代碼打開一個服務端鏈接客戶端的單向通道。服務端能夠使用這個寫通道來發送數據,這樣能節省了HTTP建立多個輪詢請求的消耗。這種方式比HTML的WebSocket更高效。WebSocket的使用場景是,當有許多客戶端和服務端的交互的時候(好比消息或者遊戲),在全雙工鏈接上創建一個雙向通道。
實現小貼士:須要進一步考慮。這個技術是基於具體的技術實現的。若是你的網站當前是使用其餘的Ajax或者Comet技術來輪詢的,轉變成Server-Sent 事件須要重構網站的Javascript代碼。
消除重定向
當用戶在一個移動設備上訪問桌面PC網站的時候,Web網站應用一般讀取HTTP的user-agent頭來判斷這個用戶是不是來自移動設備的。而後應用會發送帶有空HTTP body和重定向HTTP地址頭的HTTP 301(或者302)請求,把用戶重定向到網站的移動版本上去。可是,這個額外的客戶端和服務端的交互一般在移動網絡上會消耗幾百毫秒。所以,在原先的請求上傳遞移動的web頁會比傳遞一個重定向的信息並讓客戶端再請求移動頁面更快。
對於那些想要在移動設備上看桌面PC網站的用戶來講,你能夠在移動web頁面上提供一個連接入口,這樣也能同時表示你的網站是並不提倡這種行爲的。
實現小貼士:雖然這個技術在理論上是簡單的,可是實際上並不易於實施。因爲有些m.sites是宿主在其餘地方的,因此許多網站會選擇重定向到一個不一樣的服務器上。有的網站則是會在重定向請求的時候種植上Cookie告訴Web應用這個用戶是在使用移動設備。這種方法可能對web應用來講更容易控制。
減小資源負載
大小問題。渲染小頁面更快,獲取小資源也更快。減少每一個請求的大小一般不如減小頁面請求個數那麼顯著地提升性能。可是,有些技術在性能方面,特別是在須要對帶寬和處理器性能精打細算的移動設備環境下,仍然是能帶來很大利益的。
壓縮文本和圖像
諸如gzip這樣的壓縮技術,依靠增長服務端壓縮和瀏覽器解壓的步驟,來減小資源的負載。可是,通常來講,這些操做都是被高度優化過了。並且測試代表,壓縮對網站仍是起到優化性能的做用的。那些基於文本的響應,包括HTML,XML,JSON(Javascript Object Notation),Javascript,和CSS能夠減小大約70%的大小。
瀏覽器在Accept-Encoding請求頭中申明它的解壓縮技術,而且當它們接收到服務端返回的Content-Encoding響應頭標示的時候,就會按照這個響應頭自動作解壓操做。
實現小貼士:易於實現。若是設置正確的話,如今全部的Web服務器都支持壓縮響應。可是,也有一些桌面PC的安全工具會將請求頭中的Accept-Encoding頭去掉,這樣即便瀏覽器支持解壓縮,用戶也沒法獲取到壓縮後的響應。
代碼簡化
簡化一般是使用在腳本和樣式文件中,刪除一些沒必要要的字符,好比空格,換行符,或者註釋等。不須要暴露給外部的命名就能夠被縮短爲一個或者兩個字符,好比變量名。合適的簡化資源一般在客戶端不須要作任何其餘的處理,而且平均減小20%的資源大小。內嵌在HTML中的腳本和樣式文件也是能夠精簡的。有不少很好的庫來作精簡化的操做,這些庫通常也同時會提供合併多個文件這樣減小請求數的服務。
簡化帶來的好處並不侷限於減小帶寬和延遲,對於那些移動設備上緩存沒法保存的過大資源來講,也是頗有改善的。Gzip在這個方面並無任何幫助,由於資源是在被解壓後才被緩存起來的。
實現小貼士:易於實現。Google的Closure Compiler已經難以置信地完成了理解和簡化Javascript的工做。可是CSS的簡化則沒有那麼容易,由於對不一樣瀏覽器來講有不一樣的CSS技術能迷惑CSS簡化工具,而後讓CSS簡化後沒法正常工做。必需要注意的是,已經有這樣的案例了,即便只是刪除了沒必要要的字符,簡化工做也有可能破壞頁面。因此當你應用簡化技術以後,請作一下完整的功能測試工做。
調整圖片大小
圖片一般是佔用了Web頁面加載的大部分網絡資源,也佔用了頁面緩存的主要空間。小屏幕的移動設備提供了經過調整圖片大小來加速傳輸和渲染圖片資源的機會。若是用戶只是在小的移動瀏覽器窗口中看圖片的話,高分辨率的圖片就會浪費帶寬、處理時間和緩存空間。
爲了加速頁面渲染速度和減小帶寬及內存消耗,能夠動態地調整圖片大小或者將圖片替換爲移動設備專用的更小的版本。不要依靠瀏覽器來將高分辨率的圖片轉換成小尺寸的圖片,這樣會浪費帶寬。
另一個方法是先儘快加載一個低分辨率的圖片來渲染頁面,在onload或者用戶已經開始和頁面交互之後將這些低分辨率的圖片替換成爲高分辨率的圖片。
實現小貼士:特別應用在高度動態化的網站是有優點的。
使用HTML5和CSS 3.0來簡化頁面
HTML5包括了一些新的結構元素,例如header,nav,article和footer。使用這些語義化的元素比傳統的使用div和span標籤能使得頁面更簡單和更容易解析。一個簡單的頁面更小加載更快,而且簡單的DOM(Document Object Model)表明着更快的JavaScript執行效率。新的標籤能很快地應用在包括移動端的新瀏覽器版本上,而且HTML5設計讓那些不支持它的瀏覽器能平穩過渡使用新標籤。
HTML5的一些表單元素提供了許多新屬性來完成本來須要javascript來完成的功能。例如,新的placeholder屬性用於顯示在用戶輸入進入輸入框以前顯示的介紹性文字,autofocus屬性用於標示哪一個輸入框應當被自動定位。
也有一些新的輸入框元素能不用依靠Javascript就能夠完成一些通用的需求。這些新的輸入框類型包括像e-mail,URL,數字,範圍,日期和時間這樣須要複雜的用戶交互和輸入驗證的元素。在移動瀏覽器上,當須要輸入文本的時候,彈出的鍵盤一般是由特定的輸入框類型來作選擇的。不支持指定的輸入類型的瀏覽器就會只顯示一個文本框。
另外,只要瀏覽器支持內建的層次,圓角,陰影,動畫,過渡和其餘的圖片效果,CSS 3.0就能幫助你建立輕便簡易的頁面了,而這些圖片效果原先是須要加載圖片才能完成的。這樣,這些新特性就能加速頁面渲染了。
有不少Web站點都提供哪些移動或者桌面瀏覽器支持哪項性能的更新說明。(例如:http://caniuse.com/ 和 mobilehtml5.org)。
實現小貼士:須要進一步考慮。人工地作這些改動是很是複雜和耗時的。若是你使用CMS,它能夠幫你生成許多你不須要控制的HTML和CSS。
優化客戶端的程序處理
瀏覽器按照什麼順序來執行代碼生成一個頁面,和頁面複雜性及JavaScript的技術選擇,都對性能有很大的影響。特別在客戶端相對較慢的CPUs和少內存的移動端中尤其明顯。下面的章節提供一些策略來提高頁面處理的性能。
延遲渲染」BELOW-THE-FOLD」內容
能夠肯定的是若是咱們將不可見區域的內容延遲加載,那麼頁面就會更快地展示在用戶面前,這個區域叫作」below the fold」。爲了減小頁面加載後須要從新訪問的內容,能夠將圖片替換爲正確的高寬所標記的<img>標籤。
實現小貼士:平穩處理。一些好的Javascript庫能夠用來處理這些below-the-fold 延遲加載的圖像。^12
延遲讀取和執行的腳本
在一些移動設備上,解析Javascript代碼的速度能達到100毫秒每千字節。許多腳本的庫直到頁面被渲染之後都是不須要的加載的。下載和解析這些腳本能夠很安全地被推遲到onload事件以後來作。例如,一些須要用戶交互的行爲,好比託和拽,都不大可能在用戶看到頁面以前被調用。相同的邏輯也能夠應用在腳本執行上面。儘可能將腳本的執行延遲到onload事件以後,而不是在初始化頁面中重要的可被用戶看到的內容的時候執行。
這些延遲的腳本多是你本身寫的,更重要的是,也有多是第三方的。對廣告、社交媒體部件、或者分析的差勁的腳本優化會致使阻塞頁面的渲染,會增長珍貴的加載時間。固然,你須要當心地評估諸如jquery這樣爲移動網站設計的大型腳本框架,特別當你僅僅只是使用這些框架中的一些對象的時候更要當心評估。
實現小貼士:平穩處理。許多第三方的框架如今提供延遲加載的異步版本的API。開發者只須要將原先的邏輯轉化到這個異步版本。一些JavaScript要作延遲加載會有些複雜,由於在onload以後執行這些腳本須要注意不少注意事項。(例如,你有個腳本須要綁定到onload事件上,你須要作什麼?若是你將腳本延遲到onload事件以後,就必定就會失去不少執行的時機。)
使用Ajax來加強進程
Ajax(Asynchronous JavaScript and XML)是一項使用XHR(XMLHttpRequest)對象來從Web服務器上獲取數據的技術,它並不須要更新正在運行的頁面。Ajax能更新頁面上的某個部分而不須要從新構建整個頁面。它一般用來提交用戶的交互相應,可是也能夠用來先加載頁面的框架部分,而後當用戶準備好瀏覽網頁的時候再填充詳細的內容。
儘管是這個名字,可是XMLHttpRequest並不強制要求你只能使用XML。你能夠經過調用overrideMineType方法來制定」application/json」類型來使用json替換XML。使用JSON.parse會比使用原生的eval()函數快了幾乎兩倍,而且更爲安全。
同時,切記Ajax的返回響應也會得益於那些應用在普通的返回響應的優化技術上面。確保對你的Ajax返回響應使用了緩存頭,簡化,gzip壓縮,資源合併等技術。
實現小貼士:因爲這個技術是根據具體應用不一樣而不一樣的,因此很難量化。或許因爲跨域問題,你須要使用XHR2,這個技術能使用外部域的資源,從而能進行跨域的XHR請求。
根據網絡情況進行適配處理
因爲使用更多帶寬會使用更多移動網絡的費用,因此只有能檢測網絡的類型才能使用針對特定網絡的優化技術。例如,預加載將來使用到的請求是很是聰明的作法,可是若是用戶的帶寬很稀有,而且加載的有些資源是永遠不會用到的話,這個技術就是不合理的了。
在Android 2.2+,navigator.connection.type屬性的返回值能讓你區分Wifi和2G/3G/4G網絡。在Blackberry上,blackberry.network也能提供類似的信息。另外,服務端經過檢測請求中的User-Agent頭或者其餘的嵌入到請求中的信息能讓你的應用檢測到網絡情況。
實現小貼士:須要進一步考慮。檢測網絡信息的API最近已經有所變化了。^11 接口如今不是直接定義Wi-Fi,3G等網絡情況,而是給出了帶寬信息和諸如「很是慢,慢,快和很是快」這樣的建議。有個屬性能給出估計的MB/s值和一個「meterd」的Boolean值來表示它的可信度,可是對瀏覽器來講,很難根據這個來判斷環境。判斷當前網絡環境而後適配仍然是一種最好的方法,可是這種方法正在被考慮被替換。
對多線程來講儘可能使用HTML5的WEB WORKER特性
HTML5中的Web Worker是使用多個線程併發執行Javascript程序。另外,這種特別的多線程實現能減小困惑開發者多年的,在其餘平臺上遇到的問題。例如,當一個線程須要改變一個正在被其餘線程使用的資源該如何處理。在Web Worker中,子線程不能修改主用戶界面(UI)線程使用的資源。
對提升移動站點的性能來講,Web Worker中的代碼很適合用來預處理用戶完成進一步操做所須要的資源的,特別是在用戶的帶寬資源不緊缺的狀況下。在低處理器性能的移動設備上,過多的預加載可能會干擾當前頁面的UI響應。使用多線程代碼,讓Web Worker對象(而且儘量使用localStorage來緩存數據)在另一個線程中操做預加載資源,這樣就能不影響當前的UI表現了。
要特別說明的是,Web Worker只在Android 2.0以上的版本實現,並且iphone上的ios5以前的版本也不支持。在桌面PC上,老是落後的IE只在IE 10才支持Web Worker。
實現小貼士:平穩過渡。雖然這項技術並非很是難實現,可是對Web Workers來講,有一些限制須要強制遵照。Web Workers不能進入到頁面的DOM,也不能改變頁面上的任何東西。Web Worker很適合那種須要後臺計算和處理的工做。
將CLICK事件替換成TOUCH事件
在觸摸屏設備上,當一個用戶觸碰屏幕的時候,onclick事件並無當即觸發。設備會使用大約半秒(大多數設備差很少都是300毫秒)來讓用戶肯定是手勢操做仍是點擊操做。這個延遲會很明顯地影響用戶指望的響應性能。要使用touchend事件來替換才能解決。當用戶觸碰屏幕的時候,這個事件會當即觸發。
爲了要確保不會產生用戶不指望的行爲,你應該也要使用touchstart和touchmove事件。例如,除非同時有個touchstart事件在button上,不然不要判斷touchend事件在button上就意味着點擊行爲 — 由於用戶有可能從其餘地方觸碰開始,而後拖拽到button上觸碰結束的。你也能夠在touchstart事件以後使用touchmove事件來避免將touchend事件誤判爲點擊,固然前提是須要假設拖拽的手勢並非預期產生點擊行爲。
另外,你也須要去處理onclick事件來讓瀏覽器改變button的外觀從而標識爲已點擊的狀態,同時你也須要處理那些不支持touch事件的瀏覽器。爲了不代碼在touchend和onclick代碼中重複執行,你須要在確保用戶觸碰事件已經在touchend執行了以後,在click事件中調用preventDefault和stopPropagation方法。^4
實現小貼士:須要進一步考慮。這種技術須要更多工做才能在一個頁面中增長和維護連接。touch事件的代碼必須考慮其餘手勢,由於替換click的還有多是縮放或者敲擊動做。
支持SPDY協議
應用層HTTP和HTTPS協議致使的一些性能瓶頸,使得不管是桌面仍是移動端的網站都很是難受。在2009年,谷歌開始研發一種叫作SPDY(諧意是」speedy」)的協議來替換已有的協議,這種協議宣稱能突破這些限制。這個協議的目標是讓多種瀏覽器和多種Web服務都能支持,因此這個協議是開源的,可是初步地,只有Google的Chrome瀏覽器(在版本10及以後的)和google的站點支持。一旦一個Web服務支持SPDY,那麼它上面的全部站點均可以和支持這個協議的瀏覽器使用SPDY進行交互。將SPDY應用在25個top100的Internet網站上,Google收集到的數據是網站的速度會改善27%到60%不等。^2
SPDY自動使用gzip壓縮全部內容,和HTTP不一樣的是,它連header的數據也使用gzip壓縮。SPDY使用多線程技術讓多個請求流或者響應流能共用一個TCP鏈接。另外SPDY容許請求設置優先級,好比,頁面中心的視頻會比邊框的廣告擁有更高的優先級。
或許SPDY中最變革性的發明就是流是雙向的,而且能夠由客戶端或者服務端發起,這樣能使得信息能推送到客戶端,而不用由客戶端發起第一次請求。例如,當一個用戶第一次瀏覽一個站點,尚未任何站點的緩存,這個時候服務端就能夠在響應中推送全部的請求資源,而不用等候每一個資源被再次獨立請求了。做爲替換協議,服務端能夠發送暗示給客戶端,提示頁面須要哪些資源,同時也容許由客戶端來初始化請求。即便是使用後一種這樣的方式也比讓客戶端解析頁面而後本身發現有哪些資源須要被請求來得快。
雖然SPDY並無對移動端有什麼特別的設置,可是移動端有限的帶寬就使得若是支持SPDY的話,SPDY在減小移動網站的延遲是很是有用的。
實現小貼士:依據網站和服務的環境來進行平穩操做或進一步考慮。Google有一個SPDY模塊支持Apache2.2 – mod_spdy – 這個模塊是免費的;可是mod_spy有線程上的問題,而且和mod_php協做並非很好,因此要求你使用這個技術的時候要確保你的網站的正常運行。^6
永遠別忘記測試!
若是缺乏了持續和仔細的測試提醒,性能的優化就只是討論而已,是沒法完成的。若是沒有指定基準作比較,你係統上的任何改動都僅僅是理論而已。若是沒有真實的測試數據,猜想性能的瓶頸是毫無心義的。
有不少開源和通用的工具能進行集成測試,而且能進行不一樣地域和帶寬/延遲的測試。另外,RUM(real user monitoring)工具能將測試環境從實驗室變成不可預測的真實用戶行爲。
觀察移動設備的測試選擇和桌面場景同樣。若是你在選擇一個自動化的解決方案,請確保使用一個能持續測試,而且能區分出應用優化方法先後的變化的解決方案。
若是性能優化若是隻是在發展過程當中的一個步驟而已,它不會有什麼效果的。它必須成爲一個持續改善網站的一部分。
參考:
1. Bustos, L. 2009. Every second counts; how website performance impacts shopper behavior. GetElastic;http://www.getelastic.com/performance/.
2. Chromium Projects. SPDY: an experimental protocol for a faster Web;https://sites.google.com/a/chromium.org/dev/spdy/spdy-whitepaper.
3. Everts, T. 2013. Case study: how effective are CDNs for mobile visitors. Web Performance Today;http://www.Webperformancetoday.com/2013/05/09/case-study-cdn-content-delivery-network-mobile-3g/.
4. Fioravanti, R. 2011. Creating fast buttons for mobile Web applications. Google Developers;http://code.google.com/mobile/articles/fast_buttons.html.
5. Linden, G. 2006. Marissa Mayer at Web 2.0. Geeking with Greg;http://glinden.blogspot.com/2006/11/marissa-mayer-at-Web-20.html.
6. mod-spdy; http://code.google.com/p/mod-spdy/.
7. PhoCusWright. 2010. PhoCusWright/Akamai study on travel site performance;http://connect.phocuswright.com/2010/06/phocuswrightakamai-study-on-travel-site-performance/;http://www.akamai.com/dl/whitepapers/Akamai_PCW_Travel_Perf_Whitepaper.pdf.
8. Radware. 2011. Case studies from the mobile frontier: the relationship between faster mobile sites and business KPIS; http://www.strangeloopnetworks.com/resources/research/state-of-mobile-ecommerce-performance/.
9. Bixby, J. 2012. 2012 state of mobile e-commerce performance;http://www.strangeloopnetworks.com/resources/videos/case-studies-from-the-mobile-frontier-the-relationship-between-faster-mobile-sites-and-business-kpis-video/.
10. Tealeaf. 2011. Report on the Mobile Customer Experience. Based on the Harris Interactive 2011 Mobile Transactions Survey.
11. W3C. 2012. Network Information API; http://www.w3.org/TR/netinfo-api/.
12. YUI. ImageLoader. Yahoo! User Interface Library; http://yuilibrary.com/yui/docs/imageloader/.
簡介
Dremel 是Google 的「交互式」數據分析系統。能夠組建成規模上千的集羣,處理PB級別的數據。MapReduce處理一個數據,須要分鐘級的時間。做爲MapReduce的發起人,Google開發了Dremel將處理時間縮短到秒級,做爲MapReduce的有力補充。Dremel做爲Google BigQuery的report引擎,得到了很大的成功。最近Apache計劃推出Dremel的開源實現Drill,將Dremel的技術又推到了浪尖上。
Google Dremel設計
根據Google公開的論文《Dremel: Interactive Analysis of WebScaleDatasets》能夠看到Dremel的設計原理。還有一些測試報告。論文寫於2006年,公開於2010年,Google在處理大數據方面,果然有得天獨厚的優點。下面的內容,很大部分來自這篇論文。
隨着Hadoop的流行,大規模的數據分析系統已經愈來愈普及。數據分析師須要一個能將數據「玩轉」的交互式系統。如此,就能夠很是方便快捷的瀏覽數據,創建分析模型。Dremel系統有下面幾個主要的特色:
1, Dremel是一個大規模系統。在一個PB級別的數據集上面,將任務縮短到秒級,無疑須要大量的併發。磁盤的順序讀速度在100MB/S上下,那麼在1S內處理1TB數據,意味着至少須要有1萬個磁盤的併發讀! Google一貫是用廉價機器辦大事的好手。可是機器越多,出問題機率越大,如此大的集羣規模,須要有足夠的容錯考慮,保證整個分析的速度不被集羣中的個別慢(壞)節點影響。
2, Dremel是MR交互式查詢能力不足的補充。和MapReduce同樣,Dremel也須要和數據運行在一塊兒,將計算移動到數據上面。因此它須要GFS這樣的文件系統做爲存儲層。在設計之初,Dremel並不是是MapReduce的替代品,它只是能夠執行很是快的分析,在使用的時候,經常用它來處理MapReduce的結果集或者用來創建分析原型。
3, Dremel的數據模型是嵌套(nested)的。互聯網數據經常是非關係型的。Dremel還須要有一個靈活的數據模型,這個數據模型相當重要。Dremel支持一個嵌套(nested)的數據模型,相似於Json。而傳統的關係模型,因爲不可避免的有大量的Join操做,在處理如此大規模的數據的時候,每每是有心無力的。
4, Dremel中的數據是用列式存儲的。使用列式存儲,分析的時候,能夠只掃描須要的那部分數據的時候,減小CPU和磁盤的訪問量。同時列式存儲是壓縮友好的,使用壓縮,能夠綜合CPU和磁盤,發揮最大的效能。對於關係型數據,若是使用列式存儲,咱們都頗有經驗。可是對於嵌套(nested)的結構,Dremel也能夠用列存儲,很是值得咱們學習。
5, Dremel結合了Web搜索 和並行DBMS的技術。首先,他借鑑了Web搜索中的「查詢樹」的概念,將一個相對巨大複雜的查詢,分割成較小較簡單的查詢。大事化小,小事化了,能併發的在大量節點上跑。其次,和並行DBMS相似,Dremel能夠提供了一個SQL-like的接口,就像Hive和Pig那樣。
Google Dremel應用場景 設想一個使用場景。咱們的美女數據分析師,她有一個新的想法要驗證。要驗證她的想法,須要在一個上億條數據上面,跑一個查詢,看看結果和她的想法是否是同樣,她可不但願等太長時間,最好幾秒鐘結果就出來。固然她的想法不必定完善,還須要不斷調整語句。而後她驗證了想法,發現了數據中的價值。最後,她能夠將這個語句完善成一個長期運行的任務。
對於Google,數據一開始是放在GFS上的。能夠經過MapReduce將數據導入到Dremel中去,在這些MapReduce中還能夠作一些處理。而後分析師使用Dremel,輕鬆愉悅的分析數據,創建模型。最後能夠編製成一個長期運行的MapReduce任務。
這種處理方式,讓筆者聯想到Greenplum的Chorus. Chorus也能夠爲分析師提供快速的數據查詢,不過解決方案是經過預處理,導入部分數據,減小數據集的大小。用的是三十六計,走爲上計,避開的瞬時分析大數據的難題。Chorus最近即將開源,能夠關注下。
還有一點特別的就是按列存儲的嵌套數據格式。如圖所示,在按記錄存儲的模式中,一個記錄的多列是連續的寫在一塊兒的。在按列存儲中,能夠將數據按列分開。也就是說,能夠僅僅掃描A.B.C而不去讀A.E或者A.B.C。難點在於,咱們如何能同時高效地掃描若干列,並作一些分析。
Google Dremel數據模型
在Google, 用Protocol Buffer經常做爲序列化的方案。其數據模型能夠用數學方法嚴格的表示以下:
其中t能夠是一個基本類型或者組合類型。其中基本類型能夠是integer,float和string。組合類型能夠是若干個基本類型拼湊。星號(*)指的是任何類型均可以重複,就是數組同樣。問號(?)指的是任意類型都是能夠是可選的。簡單來講,除了沒有Map外,和一個Json幾乎沒有區別。
下圖是例子,Schema定義了一個組合類型Document.有一個必選列DocId,可選列Links,還有一個數組列Name。能夠用Name.Language.Code來表示Code列。
這種數據格式是語言無關,平臺無關的。能夠使用Java來寫MR程序來生成這個格式,而後用C++來讀取。在這種列式存儲中,可以快速通用處理也是很是的重要的。
上圖,是一個示例數據的抽象的模型;下圖是這份數據在Dremel實際的存儲的格式。
若是是關係型數據,而不是嵌套的結構。存儲的時候,咱們能夠將每一列的值直接排列下來,不用引入其餘的概念,也不會丟失數據。對於嵌套的結構,咱們還須要兩個變量R (Repetition Level) ,D (Definition Level) 才能存儲其完整的信息。
Repetition Level是記錄該列的值是在哪個級別上重複的。舉個例子說明:對於Name.Language.Code 咱們一共有三條非Null的記錄。
1, 第一個是」en-us」,出如今第一個Name的第一個Lanuage的第一個Code裏面。在此以前,這三個元素是沒有重複過的,都是第一個。因此其R爲0。
2, 第二個是」en」,出如今下一個Lanuage裏面。也就是說Lanague是重複的元素。Name.Language.Code中Lanague排第二個,因此其R爲2.
3,第三個是」en-gb」,出如今下一個Name中,Name是重複元素,排第一個,因此其R爲1。
咱們能夠想象,將全部的沒有值的列,設值爲NULL。若是是數組列,咱們也想象有一個NULL值。有了Repetition Level,咱們就能夠很好的用列表示嵌套的結構了。可是還有一點不足。就是還須要表示一個數組是否是咱們想象出來的。
Definition Level 是定義的深度,用來記錄該列是不是」想象」出來的。因此對於非NULL的記錄,是沒有意義的,其值必然爲相同。一樣舉個例子。例如Name.Language.Country,
· 第一個」us」是在R1裏面,其中Name,Language,Country是有定義的。因此D爲3。
· 第二個」NULL」也是在R1的裏面,其中Name,Language是有定義的,其餘是想象的。因此D爲2。
· 第三個」NULL」仍是在R1的裏面,其中Name是有定義的,其餘是想象的。因此D爲1。
· 第四個」gb」是在R1裏面,其中Name,Language,Country是有定義的。因此D爲3。
就是這樣,若是路徑中有required,能夠將其減去,由於required必然會define,記錄其數量沒有意義。
理解了如何存儲這種嵌套結構。寫沒有難度。讀的時候,咱們只讀其中部分字段,來構建部分的數據模型。例如,只讀取DocID和Name.Language.Country。咱們能夠同時掃描兩個字段,先掃描DocID。記錄下第一個,而後發現下一個DocID的R是0;因而該讀Name.Language.Country,若是下一個R是1或者2就繼續讀,若是是0就開始讀下一個DocID。
下圖展現了一個更爲複雜的讀取的狀態機示例。在讀取過程當中使用了Definition Level來快速Jump,提高性能。
到此爲止,咱們已經知道了Dremel的數據結構。就像其餘數據分析系統同樣,數據結構肯定下來,功能就決定了一大半。對於Dremel的數據查詢,必然是「全表掃描」,但因爲其巧妙的列存儲設計,良好的數據模型設計能夠迴避掉大部分Join需求和掃描最少的列。
Google Dremel查詢方式
Dremel能夠使用一種SQL-like的語法查詢嵌套數據。因爲Dremel的數據是隻讀的,而且會密集的發起屢次相似的請求。因此能夠保留上次請求的信息,還優化下次請求的explain過程。那又是如何explain的呢?
這是一個樹狀架構。當Client發其一個請求,根節點受到請求,根據metadata,將其分解到枝葉,直到到位於數據上面的葉子Server。他們掃描處理數據,又不斷彙總到根節點。
舉個例子:對於請求:
1
|
SELECT
A,
COUNT
(B)
FROM
T
GROUP
BY
A
|
根節點收到請求,會根據數據的分區請求,將請求變成能夠拆分的樣子。原來的請求會變爲:
1
|
SELECT
A,
SUM
(c)
FROM
(R1
UNION
ALL
... Rn)
GROUP
BY
A
|
R1,…RN是T的分區計算出的結果集。越大的表有越多的分區,越多的分區能夠越好的支持併發。
而後再將請求切分,發送到每一個分區的葉子Server上面去,對於每一個Server
1
|
Ri =
SELECT
A,
COUNT
(B)
AS
c
FROM
Ti
GROUP
BY
A
|
結構集必定會比原始數據小不少,處理起來也更快。根服務器能夠很快的將數據彙總。具體的聚合方式,能夠使用現有的並行數據庫技術。
Dremel是一個多用戶的系統。切割分配任務的時候,還須要考慮用戶優先級和負載均衡。對於大型系統,還須要考慮容錯,若是一個葉子Server出現故障或變慢,不能讓整個查詢也受到明顯影響。
一般狀況下,每一個計算節點,執行多個任務。例如,技巧中有3000個葉子Server,每一個Server使用8個線程,有能夠有24000個計算單元。若是一張表能夠劃分爲100000個區,就意味着大約每一個計算單元須要計算5個區。這執行的過程當中,若是某一個計算單元太忙,就會另外啓一個來計算。這個過程是動態分配的。
對於GFS這樣的存儲,一份數據通常有3份拷貝,計算單元很容易就能分配到數據所在的節點上,典型的狀況能夠到達95%的命中率。
Dremel還有一個配置,就是在執行查詢的時候,能夠指定掃描部分分區,好比能夠掃描30%的分區,在使用的時候,至關於隨機抽樣,加快查詢。
Google Dremel測試實驗
實驗的數據源以下表示。大部分數據複製了3次,也有一個兩次。每一個表會有若干分區,每一個分區的大小在100K到800K之間。若是壓縮率是25%,而且計入複製3份的事實的話。T1的大小已經達到PB級別。這麼小且巨量的分區,對於GFS的要求很高,如今的Hdfs穩定版恐怕受不了。接下來的測試會逐步揭示其是如何超過MR,並對性能做出分析。
表名 | 記錄數 | 大小(已壓縮) | 列數 | 數據中心 | 複製數量 |
T1 | 85 billion | 87 TB | 270 | A | 3× |
T2 | 24 billion | 13 TB | 530 | A | 3× |
T3 | 4 billion | 70 TB | 1200 | A | 3× |
T4 | 1+ trillion | 105 TB | 50 | B | 2× |
T5 | 1+ trillion | 20 TB | 30 | B | 3× |
列存測試
首先,咱們測試看看列存的效果。對於T1表,1GB的數據大約有300K行,使用列存的話壓縮後大約在375MB。這臺機器磁盤的吞吐在70MB/s左右。這1GB的數據,就是咱們的如今的測試數據源,測試環境是單機。
見上圖。
· 曲線A,是用列存讀取數據並解壓的耗時。
· 曲線B是一條一條記錄挨個讀的時間。
· 曲線C是在B的基礎上,加上了反序列化的時間。
· 曲線d,是按行存讀並解壓的耗時。
· 曲線e加上了反序列化的時間。由於列不少,反序列化耗時超過了讀並解壓的50%。
從圖上能夠看出。若是須要讀的列不多的話,列存的優點就會特別的明顯。對於列的增長,產生的耗時也幾乎是線性的。而一條一條該個讀和反序列化的開銷是很大的,幾乎都在原來基礎上增長了一倍。而按行讀,列數的增長沒有影響,由於一次性讀了所有列。
Dremel和MapReduce的對比測試
MR和Dremel最大的區別在於行存和列存。若是不能擊敗MapReduce,Remel就沒有意義了。使用最多見的WordCount測試,計算這個數據中Word的個數。
1
|
Q1:
SELECT
SUM
(CountWords(txtField)) /
COUNT
(*)
FROM
T1
|
上圖是測試的結果。使用了兩個MR任務。這兩個任務和Dremel同樣都運行在3000個節點上面。若是使用列存,Dremel的按列讀的MR只須要讀0.5TB的數據,而按行存須要讀87TB。 MR提供了一個方便有效的途經來說按行數據轉換成按列的數據。Dremel能夠方便的導入MapReduce的處理結果。
樹狀計算Server測試
接下來咱們要對比在T2表示使用兩個不一樣的Group BY查詢。T2表有24 billion 行的記錄。每一個記錄有一個 item列表,每一item有一個amount 字段。總共有40 billion個item.amount。這兩個Query分別是。
1
2
3
|
Q2:
SELECT
country,
SUM
(item.amount)
FROM
T2
GROUP
BY
country
Q3:
SELECT
domain,
SUM
(item.amount)
FROM
T2
WHERE
domain
CONTAINS
’.net’
GROUP
BY
domain
|
Q2須要掃描60GB的壓縮數據,Q3須要掃描180GB,同時還要過濾一個條件。
上圖是這兩個Query在不一樣的server拓撲下的性能。每一個測試都是有2900個葉子Server。在2級拓撲中,根server直接和葉子Server通訊。在3級拓撲中,各個級別的比例是1:100:2900,增長了100箇中間Server。在4級拓撲中,比例爲1:10:100:2900.
Q2能夠在3級拓撲下3秒內執行完畢,可是爲他提供更高的拓撲級別,對性能提高沒有裨益。相比之下,爲Q3提供更高的拓撲級別,性能能夠有效提高。這個測試體現了樹狀拓撲對性能提高的做用。
每一個分區的執行狀況
對於剛剛的兩個查詢,具體的每一個分區的執行狀況是這樣的。
能夠看到99%的分區都在1s內完成了。Dremel會自動調度,使用新的Server計算拖後腿的任務。
記錄內聚合
因爲Demel支持List的數據類型,有的時候,咱們須要計算每一個記錄裏面的各個List的聚合。如
1
2
3
4
5
6
7
|
Q4 :
SELECT
COUNT
(c1 > c2)
FROM
(
SELECT
SUM
(a.b.c.d) WITHIN RECORD
AS
c1,
SUM
(a.b.p.q.r) WITHIN RECORD
AS
c2
FROM
T3)
|
咱們須要count全部sum(a.b.c.d)比sum(a.b.p.q.r),執行這條語句實際只須要掃描13GB的數據,耗時15s,而整張表有70TB。若是沒有這樣的嵌套數據結構,這樣的查詢會很複雜。
擴展性測試
Dremel有良好的擴展性,能夠經過增長機器來縮短查詢的時間。而且能夠處理數以萬億計的記錄。
對於查詢:
1
|
Q5:
SELECT
TOP
(aid, 20),
COUNT
(*)
FROM
T4
WHERE
bid = fvalue1g
AND
cid = fvalue2g
|
使用不一樣的葉子Server數目來進行測試。
能夠發現CPU的耗時總數是基本不變的,在30萬秒左右。可是隨着節點數的增長,執行時間也會相應縮短。幾乎呈線性遞減。若是咱們使用經過CPU時間計費的「雲計算」機器,每一個租戶的查詢均可以很快,成本也會很是低廉。
容錯測試
一個大團隊裏面,總有幾個拖油瓶。對於有萬億條記錄的T5,咱們執行下面的語句。
1
|
Q6:
SELECT
COUNT
(
DISTINCT
a)
FROM
T5
|
值得注意的是T5的數據只有兩份拷貝,因此有更高的機率出現壞節點和拖油瓶。這個查詢須要掃描大約1TB的壓縮數據,使用2500個節點。
能夠看到99%的分區都在5S內完成的。不幸的是,有一些分區須要較長的時間來處理。儘管經過動態調度能夠加快一些,但在如此大規模的計算上面,很難徹底不出問題。若是不在乎太精確的結果,徹底能夠小小減小覆蓋的比例,大大提高相應速度。
Google Dremel 的影響
Google Dremel的能在如此短的時間內處理這麼大的數據,的確是十分驚豔的。有個伯克利分校的教授Armando Fox說過一句話「若是你曾事先告訴我Dremel聲稱其將可作些什麼,那麼我不會相信你能開發出這種工具」。這麼給力的技術,必然對業界形成巨大的影響。第一個被波及到的必然是Hadoop。
Dremel與Hadoop
Dremel的公開論文裏面已經說的很明白,Dremel不是用來替代MapReduce,而是和其更好的結合。Hadoop的Hive,Pig沒法提供及時的查詢,而Dremel的快速查詢技術能夠給Hadoop提供有力的補充。同時Dremel能夠用來分析MapReduce的結果集,只須要將MapReduce的OutputFormat修改成Dremel的格式,就能夠幾乎不引入額外開銷,將數據導入Dremel。使用Dremel來開發數據分析模型,MapReduce來執行數據分析模型。
Hadoop的Hive,Pig如今也有了列存的模式,架構上和Dremel也接近。可是不管存儲結構仍是計算方式都沒有Dremel精緻。對Hadoop實時性的改進也一直是個熱點話題。要想在Hadoop中山寨一個Dremel,而且相對現有解決方案有突破,筆者以爲Hadoop自身須要一些改進。一個是HDFS須要對併發細碎的數據讀性能有大的改進,HDFS須要更加的低延遲。再者是Hadoop須要不只僅支持MapReduce這一種計算框架。其餘部分,Hadoop都有對應的開源組件,萬事俱備只欠東風。
Dremel的開源實現
Dremel如今尚未一個能夠運行的開源實現,不過咱們看到不少努力。一個是Apache的Drill,一個是OpenDremel/Dazo。
OpenDremel/Dazo
OpenDremel是一個開源項目,最近更名爲Dazo。能夠在GoogleCode上找到http://code.google.com/p/dremel/。目前尚未發佈。做者聲稱他已經完成了一個通用執行引擎和OpenStack Swift的集成。筆者感受其越走越歪,離Dremel愈來愈遠了。
Apache Drill
Drill 是Hadoop的贊助商之一MapR發起的。Drill做爲一個Dremel的山寨項目,有和Dremel類似的架構和能力。他們但願Drill最終會想Hive,Pig同樣成爲Hadoop上的重要組成部分。爲Hadoop提供快速查詢的能力。和Dremel有一點不一樣,在數據模型上,開源的項目須要支持更標準的數據結構。好比CSV和JSON。同時Drill還有更大的靈活性,支持多重查詢語言,多種接口。
如今Drill的目標是完成初始的需求,架構。完成一個初始的實現。這個實現包括一個執行引擎和DrQL。DrQL是一個基於列的格式,相似於Dremel。目前,Drill已經完成的需求和架構設計。總共分爲了四個組件
· Query language:相似Google BigQuery的查詢語言,支持嵌套模型,名爲DrQL.
· Low-lantency distribute execution engine:執行引擎,能夠支持大規模擴展和容錯。能夠運行在上萬臺機器上計算數以PB的數據。
· Nested data format:嵌套數據模型,和Dremel相似。也支持CSV,JSON,YAML相似的模型。這樣執行引擎就能夠支持更多的數據類型。
· Scalable data source: 支持多種數據源,現階段以Hadoop爲數據源。
目前這四個組件在分別積極的推動,Drill也很是但願有社區其餘公司來加入。Drill但願加入到Hadoop生態系統中去。
最後的話
本文介紹了Google Dremel的使用場景,設計實現,測試實驗,和對開源世界的影響。相信不久的未來,Dremel的技術會獲得普遍的應用。