99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀Apache Spark源碼走讀_數(shù)據(jù)分析師
Apache Spark源碼走讀_數(shù)據(jù)分析師
2014-12-14
收藏

Apache Spark源碼走讀_數(shù)據(jù)分析師

Spark是發(fā)源于美國加州大學(xué)伯克利分校AMPLab的集群計算平臺,它立足于內(nèi)存計算,性能超過Hadoop百倍,即使使用磁盤,迭代類型的計算也會有10倍速度的提升。Spark從多迭代批量處理出發(fā),兼收并蓄數(shù)據(jù)倉庫、流處理和圖計算等多種計算范式,是罕見的全能選手。Spark當下已成為Apache基金會的頂級開源項目,擁有著龐大的社區(qū)支持——活躍開發(fā)者人數(shù)已超過Hadoop MapReduce)。這里,我們?yōu)榇蠹曳窒碓S鵬的“Apache Spark源碼走讀”系列博文,從源碼方面對這個流行大數(shù)據(jù)計算框架進行深度了解。

  以下為博文

  楔子

  源碼閱讀是一件非常容易的事,也是一件非常難的事。容易的是代碼就在那里,一打開就可以看到。難的是要通過代碼明白作者當初為什么要這樣設(shè)計,設(shè)計之初要解決的主要問題是什么。

  在對Spark的源碼進行具體的走讀之前,如果想要快速對Spark的有一個整體性的認識,閱讀Matei Zaharia做的Spark論文是一個非常不錯的選擇。

  在閱讀該論文的基礎(chǔ)之上,再結(jié)合Spark作者在2012 Developer Meetup上做的演講Introduction to Spark Internals,那么對于Spark的內(nèi)部實現(xiàn)會有一個比較大概的了解。

  有了上述的兩篇文章奠定基礎(chǔ)之后,再來進行源碼閱讀,那么就會知道分析的重點及難點。

  基本概念(Basic Concepts)

  1. RDD——Resillient Distributed Dataset 彈性分布式數(shù)據(jù)集。

  2. Operation——作用于RDD的各種操作分為transformation和action。

  3. Job——作業(yè),一個JOB包含多個RDD及作用于相應(yīng)RDD上的各種operation。

  4. Stage——一個作業(yè)分為多個階段。

  5. Partition——數(shù)據(jù)分區(qū), 一個RDD中的數(shù)據(jù)可以分成多個不同的區(qū)。

  6. DAG——Directed Acycle graph,有向無環(huán)圖,反應(yīng)RDD之間的依賴關(guān)系。

  7. Narrow dependency——窄依賴,子RDD依賴于父RDD中固定的data partition。

  8. Wide Dependency——寬依賴,子RDD對父RDD中的所有data partition都有依賴。

  9. Caching Managenment——緩存管理,對RDD的中間計算結(jié)果進行緩存管理以加快整體的處理速度。

  編程模型(Programming Model)

  RDD是只讀的數(shù)據(jù)分區(qū)集合,注意是數(shù)據(jù)集。

  作用于RDD上的Operation分為transformantion和action。 經(jīng)Transformation處理之后,數(shù)據(jù)集中的內(nèi)容會發(fā)生更改,由數(shù)據(jù)集A轉(zhuǎn)換成為數(shù)據(jù)集B;而經(jīng)Action處理之后,數(shù)據(jù)集中的內(nèi)容會被歸約為一個具體的數(shù)值。

  只有當RDD上有action時,該RDD及其父RDD上的所有operation才會被提交到cluster中真正的被執(zhí)行。

  從代碼到動態(tài)運行,涉及到的組件如下圖所示。

  演示代碼

  運行態(tài)(Runtime view)

  不管什么樣的靜態(tài)模型,其在動態(tài)運行的時候無外乎由進程,線程組成。

  用Spark的術(shù)語來說,static view稱為dataset view,而dynamic view稱為parition view。關(guān)系如圖所示

  在Spark中的task可以對應(yīng)于線程,worker是一個個的進程,worker由driver來進行管理。

  那么問題來了,這一個個的task是如何從RDD演變過來的呢?下節(jié)將詳細回答這個問題。

  部署(Deployment view)

  當有Action作用于某RDD時,該action會作為一個job被提交。

  在提交的過程中,DAGScheduler模塊介入運算,計算RDD之間的依賴關(guān)系。RDD之間的依賴關(guān)系就形成了DAG。

  每一個JOB被分為多個stage,劃分stage的一個主要依據(jù)是當前計算因子的輸入是否是確定的,如果是則將其分在同一個stage,避免多個stage之間的消息傳遞開銷。

  當stage被提交之后,由taskscheduler來根據(jù)stage來計算所需要的task,并將task提交到對應(yīng)的worker。

  Spark支持以下幾種部署模式,Standalone、Mesos和YARN。這些部署模式將作為taskscheduler的初始化入?yún)ⅰ?/span>

  RDD接口(RDD Interface)

  RDD由以下幾個主要部分組成

  partitions——partition集合,一個RDD中有多少data partition

  dependencies——RDD依賴關(guān)系

  compute(parition)——對于給定的數(shù)據(jù)集,需要作哪些計算

  preferredLocations——對于data partition的位置偏好

  partitioner——對于計算出來的數(shù)據(jù)結(jié)果如何分發(fā)

  緩存機制(caching)

  RDD的中間計算結(jié)果可以被緩存起來,緩存先選Memory,如果Memory不夠的話,將會被寫入到磁盤中。

  根據(jù)LRU(last-recent update)來決定哪先內(nèi)容繼續(xù)保存在內(nèi)存,哪些保存到磁盤。

  容錯性(Fault-tolerant)

  從最初始的RDD到衍生出來的最后一個RDD,中間要經(jīng)過一系列的處理。那么如何處理中間環(huán)節(jié)出現(xiàn)錯誤的場景呢?

  Spark提供的解決方案是只對失效的data partition進行事件重演,而無須對整個數(shù)據(jù)全集進行事件重演,這樣可以大大加快場景恢復(fù)的開銷。

  RDD又是如何知道自己的data partition的number該是多少?如果是HDFS文件,那么HDFS文件的block將會成為一個重要的計算依據(jù)。

  集群管理(cluster management)

  task運行在cluster之上,除了Spark自身提供的Standalone部署模式之外,Spark還內(nèi)在支持Yarn和mesos。

  Yarn來負責計算資源的調(diào)度和監(jiān)控,根據(jù)監(jiān)控結(jié)果來重啟失效的task或者是重新distributed task一旦有新的node加入cluster的話。本文:CDA數(shù)據(jù)分析師官網(wǎng)

  這一部分的內(nèi)容需要參Yarn的文檔。

  小結(jié)

  在源碼閱讀時,需要重點把握以下兩大主線。

  靜態(tài)view 即 RDD,transformation and action

  動態(tài)view 即 life of a job, 每一個job又分為多個stage,每一個stage中可以包含多個rdd及其transformation,這些stage又是如何映射成為task被distributed到cluster中

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }