背景描述
??spark是一個(gè)優(yōu)秀的面向大數(shù)據(jù)的數(shù)據(jù)計(jì)算引擎,并且針對(duì)不同的應(yīng)用場(chǎng)景,spark本身提供了一些很好的工具如對(duì)于數(shù)據(jù)分析計(jì)算我們可以選用spark sql牍白,對(duì)于智能推薦可以選擇mllib等首有,它在數(shù)據(jù)批處理和實(shí)時(shí)計(jì)算方面都表現(xiàn)出了良好的性能。
??一般開發(fā)一個(gè)spark應(yīng)用的基本流程如下幾部:
???1.創(chuàng)建spark context俏橘;
???2.從spark session作為入口允华,讀取數(shù)據(jù),然后通過rdd進(jìn)行迭代運(yùn)算寥掐;
???3.處理計(jì)算結(jié)果靴寂;
??在編譯好完成的應(yīng)用jar后,使用spark提供的submit腳本來把應(yīng)用提交給spark集群進(jìn)行執(zhí)行計(jì)算召耘。
一些問題
??上述spark的功能開發(fā)及部署流程從使用上來說并沒有問題百炬,但是如果考慮項(xiàng)目工程開發(fā)的易用性及可靠性,當(dāng)spark應(yīng)用運(yùn)行較多時(shí)(如果同時(shí)運(yùn)行幾百個(gè)spark任務(wù))污它,會(huì)顯得捉襟見肘剖踊,下面列舉幾個(gè)可以思考的問題:
??1.提交spark application的host默認(rèn)最多啟動(dòng)16個(gè)進(jìn)程的限制,怎樣去做橫向擴(kuò)容轨蛤;
??2.不同開發(fā)人員開發(fā)的不同spark應(yīng)用如何管理(實(shí)際每個(gè)jar多是一個(gè)功能)蜜宪;
??3.spark的應(yīng)用功能怎樣和平臺(tái)的其他服務(wù)組件更好的交互,最好開發(fā)的這些spark功能能夠以接口的方式
提供給其他服務(wù)方調(diào)用祥山;
實(shí)踐方法探討
??我們打算將之前寫的每個(gè)spark的應(yīng)用封裝為restful接口對(duì)外提供相應(yīng)的服務(wù)圃验,可以使用springboot來快速構(gòu)建這樣的功能,每個(gè)restful接口可獨(dú)立對(duì)外提供服務(wù)缝呕,如果使用springboot來開發(fā)澳窑,接下來需要面對(duì)的問題可能是spark應(yīng)用本身的特性所帶來的問題,先不考慮分布式多實(shí)例服務(wù)供常,可以先來看看單個(gè)服務(wù)創(chuàng)建有什么樣的困難或問題摊聋,如對(duì)于一個(gè)spark應(yīng)用來說單個(gè)spark context是獨(dú)占JVM的,按照使用springboot構(gòu)建服務(wù)的想法栈暇,當(dāng)一個(gè)請(qǐng)求到達(dá)并成功運(yùn)行時(shí)麻裁,這個(gè)springboot的啟動(dòng)實(shí)例是不能處理其他請(qǐng)求的。另外容易想到的是源祈,一個(gè)spark任務(wù)執(zhí)行煎源,從任務(wù)初始化創(chuàng)建再到真正計(jì)算是相當(dāng)花費(fèi)時(shí)間的,所以可以考慮外部服務(wù)調(diào)用spark功能接口為異步方式香缺,即提交spark應(yīng)用后手销,通過輪訓(xùn)的方式來查看任務(wù)的執(zhí)行狀態(tài)。
??實(shí)際上現(xiàn)在也有一些還算比較優(yōu)秀的開源框架用于解決spark應(yīng)用服務(wù)化的問題图张,如spark job server和livy,由于目前我們的spark集群使用的是standalone模式锋拖,集群資源的分配為自定義實(shí)現(xiàn)诈悍,當(dāng)在請(qǐng)求的服務(wù)端主機(jī)上進(jìn)行spark context創(chuàng)建時(shí),會(huì)有資源限制兽埃;另外由于團(tuán)隊(duì)資源的限制侥钳,開源框架雖然功能多,但是我們使用到的必定非常有限讲仰,而且還會(huì)有spark版本的影響慕趴,在想升級(jí)spark集群版本時(shí),也會(huì)受到相應(yīng)的限制鄙陡,所以從簡(jiǎn)化易用的角度冕房,可以自己著手來對(duì)spark的功能服務(wù)化做一個(gè)自定義的開發(fā)。
初步需要解決的問題
- One Spark Context,One JVM,需要知道哪個(gè)JVM(springboot)可用趁矾,然后分發(fā)請(qǐng)求耙册;
- 提交任務(wù)接口和查詢狀態(tài)接口分離;
- 創(chuàng)建spark context一般需要15s~30s毫捣,為了提供一些任務(wù)的執(zhí)行速度详拙,可以先將spark context初始化好,然后再通過接口進(jìn)行計(jì)算蔓同,所以需要有初始化和釋放接口饶辙。
實(shí)現(xiàn)
??分析到這里,應(yīng)該可以著手來實(shí)現(xiàn)它斑粱,這里有一個(gè)初步實(shí)現(xiàn)的demo,工程名稱philomel弃揽,它使用springboot作為基本構(gòu)建框架,使用我們熟悉的 web開發(fā)方式進(jìn)行開發(fā)则北,不過對(duì)于spark的應(yīng)用開發(fā)矿微,我們這里選擇scala語言。
??當(dāng)一個(gè)springboot實(shí)例啟動(dòng)后尚揣,可以將它看作可提交spark應(yīng)用的客戶端涌矢,當(dāng)請(qǐng)求到達(dá)后,創(chuàng)建并生成spark任務(wù)后快骗,它又是spark中的driver負(fù)責(zé)與集群中的master和worker進(jìn)行交互娜庇。
??對(duì)于philomel實(shí)例的分發(fā)調(diào)用,可以在前面實(shí)現(xiàn)一個(gè)這樣的philomel實(shí)例分配調(diào)度服務(wù)方篮,這個(gè)服務(wù)需要知道當(dāng)前有哪些philomel實(shí)例已啟動(dòng)思灌,并且哪些實(shí)例已在使用,哪些處于空閑狀態(tài)恭取。
??除了philomel實(shí)例資源調(diào)度服務(wù),在大數(shù)據(jù)平臺(tái)中可能還會(huì)有一些其他性質(zhì)的服務(wù)熄守,比如流程調(diào)度引擎或數(shù)據(jù)查詢服務(wù)等蜈垮,這些服務(wù)需要一些治理手段來配合耗跛,并通過微服務(wù)的方式進(jìn)行部署以及對(duì)外輸出能力,但是philomel本身攒发,我們不打算將這些啟動(dòng)實(shí)例納入到微服務(wù)的管理架構(gòu)中來调塌,簡(jiǎn)單的它只向分發(fā)調(diào)度它的模塊通知位置信息和幾個(gè)應(yīng)用消息。
應(yīng)用架構(gòu)
按照前面的描述惠猿,先打算按如下圖方式進(jìn)行應(yīng)用架構(gòu)的設(shè)計(jì)
??整個(gè)大數(shù)據(jù)平臺(tái)的后端服務(wù)羔砾,可以使用微服務(wù)的思路來完成構(gòu)建,通過一個(gè)api網(wǎng)關(guān)來進(jìn)行各個(gè)服務(wù)模塊間的請(qǐng)求調(diào)用偶妖,使用服務(wù)注冊(cè)發(fā)現(xiàn)中心來對(duì)所有的服務(wù)實(shí)例進(jìn)行治理(比如springcloud中的eureka)姜凄。從圖中可以看出所有外部使用spark的功能都需要請(qǐng)求philomel服務(wù),它提供的了開發(fā)的spark業(yè)務(wù)功能的restful接口趾访。
??關(guān)于調(diào)用過程中產(chǎn)生的數(shù)據(jù)和配置數(shù)據(jù)态秧,可以使用redis和mysql來存儲(chǔ),運(yùn)行時(shí)數(shù)據(jù)存放在redis中(如job編碼,spark app id等)扼鞋,配置數(shù)據(jù)存放在mysql數(shù)據(jù)庫中(如為了運(yùn)維可視化申鱼,配置的philomel的部署host信息和當(dāng)前philomel實(shí)例使用情況等信息)。
消息交互
??philomel調(diào)度服務(wù)負(fù)責(zé)直接與philomel實(shí)例進(jìn)行交互云头,它負(fù)責(zé)將其他業(yè)務(wù)模塊的請(qǐng)求分發(fā)給空閑的philomel實(shí)例進(jìn)行spark任務(wù)的執(zhí)行捐友,從提交一個(gè)spark任務(wù)請(qǐng)求到執(zhí)行完成整個(gè)生命周期,目前是通過異步的方式來實(shí)現(xiàn)溃槐,消息交互方式可參考下圖所示:
未來優(yōu)化
??目前我們的業(yè)務(wù)場(chǎng)景以spark sql的應(yīng)用為主匣砖,比如通過spark sql從hive或hbase表中查詢業(yè)務(wù)數(shù)據(jù)并輸出到指定的數(shù)據(jù)源中(如redis,kafka或ftp等),在實(shí)踐中上述應(yīng)用服務(wù)架構(gòu)已能很好的服務(wù)于當(dāng)前的業(yè)務(wù)竿痰,spark集群規(guī)模在80+脆粥,可同時(shí)支持200+的spark任務(wù)執(zhí)行,而且當(dāng)philomel實(shí)例數(shù)量預(yù)估不足時(shí)在不影響運(yùn)行業(yè)務(wù)的情況下可以進(jìn)行手動(dòng)橫向擴(kuò)容影涉。
??未來打算在Paas平臺(tái)的基礎(chǔ)上变隔,通過將philomel制作成docker image,通過k8s進(jìn)行編排調(diào)度,可以對(duì)philomel實(shí)例進(jìn)行彈性分配蟹倾。