spark streming流式計算一架構設計
每一次分享文章都會糾結到底該從哪個地方開始講起,為了組織語言和文章引體會想很長時間。引體寫好後卻沒有了分享文章的慾望,最後就放棄了要寫一篇文章的想法。流式計算技術分享也是想了很久,好幾回編輯框都打開了最後還是放棄編寫了。今天,終於決定要寫一篇關於流式計算資料一致性保證的技術文件。
因為計算延遲和資料量的問題,越來越多的團隊將離線批處理任務轉化成流式計算任務。在離線任務中不需要考慮資料容錯以及資料一致性問題(增量計算部分設計),一旦資料計算出現問題,再次重跑 就可以了。但是流式計算需要考慮這些繁瑣的問題,在兩年的流式計算任務的開發中踩了很多的坑,也做了很多方案來解決這些問題,今天決定把這些問題以及解決方案分享出來。希望對大家在設計流式計算任務時有所幫助。
在流式計算架構設計中有兩個問題必須考慮清楚才能這首進行開發,否則花費大量人力開發出來的流式計算任務,數次重啟之後資料計算會出現大量誤差,甚至發現不了計算誤差,對整個業務線都會有很大的影響。再次重構這個代價還是相當沉重的。
問題一:應用之間耦合性
從技術角度上講沒有一個完美的架構適用於所有的場景,架構需要根據不同的場景設計不同的計算方案。大致可以將方案分為以上兩大類。
第一種(左圖)設計將所有相關的應用放在同一個sparkstream應用中,不同業務是不同子流(sparkStreaming)。這種設計排程起來比較方便,容錯設計一次就可以了。從整體叢集計算資源角度來看,對計算任務的計算資源比較節約。相同處理量和相同資源情況下,資料延遲也比較小,工作流依賴關係在程式碼中實現。程式碼更新和維護起來比較方便,當然太過龐大又會起到其他文虎。但是這種方案,卻有一個致命的缺陷--業務模組間強耦合。任何一個業務需要升級或者出錯,整個業務群牽連癱瘓,對於頻繁更新的業務線和不穩定的叢集就像是炸點一樣,是不是某個點就會爆炸。
第二種(右圖)將不同業務模組解耦通過kafka做訊息中介軟體,這種設計將業務族群切分成自單獨的spark streaming應用。好處是業務間耦合讀比較低,同級業務出現問題或者更新程式碼,不會相互影響。缺點是依賴關係控制比較複雜,每個都需要設計容錯模組,並且每個應用都需要預留cpu用來接受資料造成計算資源消耗大,kafka需要儲存多次資料等問題。
這兩種設計適用於不同的場景,做不同的偏向。
我們在開發過程中就遇到過需要使用第二中方式的場景,前端以600億+每天的速度向kafka叢集些資料。是關於運動軌跡和停留的資料,每天會產生大量的資料,去重和資料計算完之後又有80%的資料可以刪除。但是後續計算花費的時間比較長,邏輯經常被變更需要經常解除安裝流式更新再重啟。假如採用第一種策略,一旦計算遇到計算卡頓或者應用出bug,流式停止超過3小時以上,限於kafka叢集容量就會自動丟棄三四個小時之前的資料。這種就需要將資料清洗和資料處理分開成兩個流式應用。由於資料清洗和去重規則比較穩定,不會有大的變更且邏輯簡單,卸掉應用和當即的概率比較小。可以將清洗完的資料重新寫到Kafka。由於處理後資料量比較小,對於業務模組即使頻繁更新,長時間下線流式應用,也不會資料丟失資料。這樣就很大程度上解決了資料丟失風險和出錯的概率。到達資料預處理和業務處理解耦的目的。