session聚合統(tǒng)計(統(tǒng)計出訪問時長和訪問步長盗棵,各個區(qū)間的session數(shù)量占總session數(shù)量的比例)
如果不進(jìn)行重構(gòu),直接來實現(xiàn)北发,思路:
1纹因、actionRDD,映射成<sessionid,Row>的格式
2琳拨、按sessionid聚合瞭恰,計算出每個session的訪問時長和訪問步長,生成一個新的RDD
3狱庇、遍歷新生成的RDD惊畏,將每個session的訪問時長和訪問步長恶耽,去更新自定義Accumulator中的對應(yīng)的值
4、使用自定義Accumulator中的統(tǒng)計值颜启,去計算各個區(qū)間的比例
5偷俭、將最后計算出來的結(jié)果,寫入MySQL對應(yīng)的表中
普通實現(xiàn)思路的問題:
1农曲、為什么還要用actionRDD社搅,去映射驻债?其實我們之前在session聚合的時候乳规,映射已經(jīng)做過了。多此一舉
2合呐、是不是一定要暮的,為了session的聚合這個功能,單獨去遍歷一遍session淌实?其實沒有必要冻辩,已經(jīng)有session數(shù)據(jù)
之前過濾session的時候,其實拆祈,就相當(dāng)于恨闪,是在遍歷session,那么這里就沒有必要再過濾一遍了
重構(gòu)實現(xiàn)思路:
1放坏、不要去生成任何新的RDD(處理上億的數(shù)據(jù))
2咙咽、不要去單獨遍歷一遍session的數(shù)據(jù)(處理上千萬的數(shù)據(jù))
3、可以在進(jìn)行session聚合的時候淤年,就直接計算出來每個session的訪問時長和訪問步長
4钧敞、在進(jìn)行過濾的時候,本來就要遍歷所有的聚合session信息麸粮,此時溉苛,就可以在某個session通過篩選條件后
將其訪問時長和訪問步長,累加到自定義的Accumulator上面去
5弄诲、就是兩種截然不同的思考方式愚战,和實現(xiàn)方式,在面對上億齐遵,上千萬數(shù)據(jù)的時候寂玲,甚至可以節(jié)省時間長達(dá)半個小時,或者數(shù)個小時
開發(fā)Spark大型復(fù)雜項目的一些經(jīng)驗準(zhǔn)則:
1洛搀、盡量少生成RDD
2敢茁、盡量少對RDD進(jìn)行算子操作,如果有可能留美,盡量在一個算子里面彰檬,實現(xiàn)多個需要做的功能
3伸刃、盡量少對RDD進(jìn)行shuffle算子操作,比如groupByKey逢倍、reduceByKey捧颅、sortByKey(map、mapToPair)
shuffle操作较雕,會導(dǎo)致大量的磁盤讀寫碉哑,嚴(yán)重降低性能
有shuffle的算子,和沒有shuffle的算子亮蒋,甚至性能扣典,會達(dá)到幾十分鐘,甚至數(shù)個小時的差別
有shfufle的算子慎玖,很容易導(dǎo)致數(shù)據(jù)傾斜贮尖,一旦數(shù)據(jù)傾斜,簡直就是性能殺手(完整的解決方案)
4趁怔、無論做什么功能湿硝,性能第一
在傳統(tǒng)的J2EE或者.NET后者PHP,軟件/系統(tǒng)/網(wǎng)站開發(fā)中润努,我認(rèn)為是架構(gòu)和可維護(hù)性关斜,可擴(kuò)展性的重要 程度,遠(yuǎn)遠(yuǎn)高于了性能铺浇,大量的分布式的架構(gòu)痢畜,設(shè)計模式,代碼的劃分随抠,類的劃分(高并發(fā)網(wǎng)站除外)
大數(shù)據(jù)中裁着,比如MapReduce、Hive拱她、Spark二驰、Storm,我認(rèn)為性能的重要程度秉沼,遠(yuǎn)遠(yuǎn)大于一些代碼的規(guī)范桶雀,和設(shè)計模式,代碼的劃分唬复,類的劃分矗积;大數(shù)據(jù),大數(shù)據(jù)敞咧,最重要的棘捣,就是性能主要就是因為大數(shù)據(jù)以及大數(shù)據(jù)項目的特點,決定了休建,大數(shù)據(jù)的程序和項目的速度乍恐,都比較慢