<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入探索云原生流水線的架構(gòu)設(shè)計(jì)

          共 5531字,需瀏覽 12分鐘

           ·

          2022-05-11 01:40

          本文約 4400 字,預(yù)計(jì)閱讀時(shí)間:12 分鐘



          目前,市面上的流水線/工作流產(chǎn)品層出不窮,有沒有一款工作流引擎,能夠同時(shí)滿足:


          • 支持各種任務(wù)運(yùn)行時(shí),包括 K8s JobK8s FlinkK8s SparkDC/OS JobDockerInMemory 等?

          • 支持快速對(duì)接其他任務(wù)運(yùn)行時(shí)?

          • 支持任務(wù)邏輯抽象,并且快速地開發(fā)自己的 Action

          • 支持嵌套流水線,在流水線層面進(jìn)行邏輯復(fù)用?

          • 支持靈活的上下文參數(shù)傳遞,有好用的 UI 以及簡(jiǎn)單明確的工作流定義?

          • ······




          那么,不妨試試 Erda Pipeline 吧~


           
          Erda Pipeline 是一款自研、用 Go 編寫的工作流引擎。作為基礎(chǔ)服務(wù),它在 Erda 內(nèi)部支撐了許多產(chǎn)品:
            


          • CI/CD
          • 快數(shù)據(jù)平臺(tái)
          • 自動(dòng)化測(cè)試平臺(tái)
          • SRE 運(yùn)維鏈路
          • ……


            
          Erda Pipeline 之所以選擇自研,其中最重要的三點(diǎn)是:
             


          1. 自研能更快地響應(yīng)業(yè)務(wù)需求,進(jìn)行定制化開發(fā);
          2. 時(shí)至今日,開源社區(qū)還沒有一個(gè)實(shí)質(zhì)上的流水線標(biāo)準(zhǔn),各種產(chǎn)品百花齊放;
          3. K8sDC/OS 等的 Job 實(shí)現(xiàn)都偏弱、上下文傳遞缺失,無法滿足我們的需求,更不用說靈活好用的 Flow  了,例如:嵌套流水線。


             
          本文我們將主要從架構(gòu)層面對(duì) Pipeline 進(jìn)行剖析,和大家一起來深入探索 Pipeline 的架構(gòu)設(shè)計(jì)。主要內(nèi)容包括以下幾個(gè)部分:



          • 整體架構(gòu)

          • 內(nèi)部架構(gòu)

          • 水平擴(kuò)展

          • 分布式架構(gòu)

          • 功能特性

          • 實(shí)現(xiàn)細(xì)節(jié)


                
          整體架構(gòu)




          • Pipeline 支持靈活的使用方式,目前支持  UI 可視化操作、OPENAPI 開放接口、CLI 命令行工具幾種方式。

          • 協(xié)議層面,在 Erda-Infra 微服務(wù)框架的加持下,以 HTTP 和 gRPC 形式對(duì)外提供服務(wù):在早期的時(shí)候,我們只提供了 HTTP 服務(wù),由于 Erda 平臺(tái)本身內(nèi)部是微服務(wù)架構(gòu),服務(wù)間調(diào)用就需要手動(dòng)編寫 HTTP 客戶端,不好自動(dòng)生成,麻煩且容易出錯(cuò)。后來我們改為使用 Protobuf 作為 IDL(Interface Define Language),在 Erda-Infra 中自動(dòng)生成 gRPC 的客戶端調(diào)用代碼和服務(wù)端框架代碼,內(nèi)部服務(wù)間的調(diào)用都改為使用 gRPC 調(diào)用。

          • 在中間件依賴層面,我們使用 ETCD 做分布式協(xié)調(diào),用 MySQL 做數(shù)據(jù)持久化。ETCD 我們也有計(jì)劃把它替換掉,使用 MySQL 來做分布式協(xié)調(diào)。

          • 最關(guān)鍵的任務(wù)運(yùn)行時(shí)(Task Runtime)層面,我們支持任務(wù)可以運(yùn)行在 K8s、DC/OS(分布式云 OS,在 2017-2019 年非常火)、用戶本地 Docker 環(huán)境等。

          • 我們還有開放的任務(wù)擴(kuò)展市場(chǎng),在平臺(tái)級(jí)別內(nèi)置了非常多的流水線任務(wù)擴(kuò)展,開箱即用。同時(shí),用戶也可以開發(fā)企業(yè)/項(xiàng)目/應(yīng)用/個(gè)人級(jí)別的任務(wù)擴(kuò)展,這部分功能在代碼層面已經(jīng)完全支持,產(chǎn)品層面正在開發(fā)中,在后續(xù)迭代中很快就可以和大家見面。


            
          內(nèi)部架構(gòu)




          使用 Erda-Infra 微服務(wù)框架開發(fā),功能模塊劃分清晰:


          • Server 層包括業(yè)務(wù)邏輯,對(duì) Pipeline 來說業(yè)務(wù)就是創(chuàng)建、執(zhí)行、重試、重試失敗節(jié)點(diǎn)等。

          • Modules 層提供不含業(yè)務(wù)邏輯的公共模塊,其余兩層均可調(diào)用,包括預(yù)校驗(yàn)機(jī)制、定時(shí)守護(hù)進(jìn)程、YAML 解析器、配置管理、事件管理等。

             


          Erda Pipeline 一直在踐行:“把復(fù)雜留給自己,把簡(jiǎn)單留給別人”。
            
           Pipeline 中,我們對(duì)一個(gè)任務(wù)執(zhí)行的抽象是 ActionExecutor。


              

          • Engine 層負(fù)責(zé)流水線的推進(jìn),包括:

            • Queue Manager 隊(duì)列管理器,支持隊(duì)列內(nèi)工作流的優(yōu)先級(jí)動(dòng)態(tài)調(diào)整、資源檢查、依賴檢查等。

            • Dispatcher 任務(wù)分發(fā)器,用于將滿足出隊(duì)條件的流水線分發(fā)給合適的 Worker 進(jìn)行推進(jìn)。

            • Reconciler 協(xié)調(diào)器,負(fù)責(zé)將一條完整的流水線解析為 DAG 結(jié)構(gòu)后進(jìn)行推進(jìn),直至終態(tài)。

          • 模塊內(nèi)部使用插件機(jī)制,對(duì)接各種任務(wù)運(yùn)行時(shí)。

          • AOP 擴(kuò)展點(diǎn)機(jī)制(借鑒 Spring),把代碼關(guān)鍵節(jié)點(diǎn)進(jìn)行暴露,方便開發(fā)同學(xué)在不修改核心代碼的前提下定制流水線行為。

            • 目前已經(jīng)有的一些擴(kuò)展點(diǎn)插件,譬如自動(dòng)化測(cè)試報(bào)告嵌套生成、隊(duì)列彈出前檢查、接口測(cè)試自動(dòng)登錄保持等。

            • 這個(gè)能力后續(xù)我們還會(huì)開放給調(diào)用方,包括用戶,去做一些有意思的事情。

          • 統(tǒng)一使用 Event,封裝了 WebHook / WebSocket / Metrics。


                   
          水平擴(kuò)展
            


           


          隨著 Pipeline 需要支撐的業(yè)務(wù)場(chǎng)景和數(shù)據(jù)量與日俱增,單實(shí)例的 Pipeline 穩(wěn)定性和推進(jìn)性能面臨著挑戰(zhàn)。


             


          Pipeline 的多實(shí)例方案如下:


          • Leader & Worker 模式,兩者在部署上不區(qū)分狀態(tài),僅為 Replicas 多實(shí)例:

            • 使用 ETCD 選舉,每個(gè)實(shí)例都可以是 Leader。

            • 只有 Leader 開啟 Queue Manager 和 Dispatcher,分發(fā)任務(wù)給 Worker。

            • Leader 本身也可以作為 Worker,支持單節(jié)點(diǎn)部署模式,Leader 必須開啟 Reconciler。

          • Dispatch 使用有界負(fù)載的一致性哈希算法:

            • 使用一致性哈希來分配任務(wù)。但一致性哈希會(huì)超載,例如某些熱點(diǎn)內(nèi)容會(huì)持續(xù)打到一個(gè)節(jié)點(diǎn)上。

            • 有界負(fù)載算法(The bounded-load algorithm):

              • 只要服務(wù)器未過載,請(qǐng)求的分配策略與一致性哈希相同。

              • 過載服務(wù)器的溢出負(fù)載將在可用服務(wù)器之間分配。

            • Pipeline 實(shí)例增減時(shí),已經(jīng)被分配的流水線不重新分配,盡可能減少切換成本,防止重復(fù)推進(jìn);新增的流水線使用一致性 Hash 算法進(jìn)行分配。


               
          在之前,我們使用過分布式鎖的方案來做多實(shí)例協(xié)調(diào)。和選舉比起來,競(jìng)爭(zhēng)會(huì)更大,在具體實(shí)現(xiàn)里,如果想要多實(shí)例同時(shí)推進(jìn)流水線,那競(jìng)爭(zhēng)的資源就是流水線 ID。每個(gè) ID 會(huì)請(qǐng)求一個(gè)分布式鎖,而且這個(gè)分布式鎖是阻塞性的,保證每個(gè)流水線 ID 一定會(huì)被推進(jìn),天然做了多節(jié)點(diǎn)重試。
             
          分布式架構(gòu)
            


          該分布式架構(gòu)是典型的 AP 模型,數(shù)據(jù)層面遵循最終一致性。


            
          這套分布式架構(gòu)的核心目標(biāo)(典型場(chǎng)景)是在網(wǎng)絡(luò)分區(qū)的情況下,保證邊緣集群的定時(shí)任務(wù)正常執(zhí)行。
            
          我們來對(duì)比一下原有部署架構(gòu)(運(yùn)行時(shí)以 K8s 為例):
              


          • 中心 Pipeline 直接負(fù)責(zé)流程推進(jìn),調(diào)用邊緣 K8s 創(chuàng)建 Job。

          • 當(dāng)網(wǎng)絡(luò)分區(qū)時(shí),原有部署架構(gòu)下,定時(shí)任務(wù)無法正常執(zhí)行。


            
          分布式架構(gòu)
            


          • 中心下發(fā)任務(wù)定義,由 Edge Pipeline 負(fù)責(zé)推進(jìn),直連 K8s,更加穩(wěn)定。

          • 在網(wǎng)絡(luò)分區(qū)恢復(fù)時(shí),主動(dòng)上報(bào)執(zhí)行數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)最終一致性。


              
          在代碼層面,我們使用同一份代碼構(gòu)建出同一個(gè)鏡像,通過配置(不同的部署模式)使得各個(gè)實(shí)例各司其職。
              
          另外,在數(shù)據(jù)同步時(shí),我們遇到了前端 JavaScript Number 類型 53位最大值問題,對(duì) SnowFlake ID 進(jìn)行了 64bit -> 53bit 的改造,在保證唯一性的前提下,盡可能地增加可用性(生命周期約為 10 年,同時(shí)支持 4096 個(gè)分布式節(jié)點(diǎn),每 10ms 可生成 64 個(gè) ID)。
             
          功能特性
            


          這里簡(jiǎn)單列舉一些比較常見的功能特性:


            


          • 配置即代碼
          • 擴(kuò)展市場(chǎng)豐富
          • 可視化編輯
          • 支持嵌套流水線
          • 靈活的執(zhí)行策略,支持 OnPush / OnMerge 等觸發(fā)策略
          • 支持工作流優(yōu)先隊(duì)列
          • 多維度的重試機(jī)制
          • 定時(shí)流水線及定時(shí)補(bǔ)償功能
          • 動(dòng)態(tài)配置,支持“值”和“文件”兩種類型,均支持加密存儲(chǔ),確保數(shù)據(jù)安全性
          • 上下文傳遞,后置任務(wù)可以引用前置任務(wù)的“值”和“文件”
          • 開放的 OpenAPI 接口,方便第三方系統(tǒng)快速接入


               
          一些實(shí)現(xiàn)細(xì)節(jié)
               
           如何實(shí)現(xiàn)上下文傳遞(值引用)




          在一條流水線中,節(jié)點(diǎn)間除了有依賴順序之外,一定會(huì)有數(shù)據(jù)傳遞的需求。


            


          值引用:


            

          • 每個(gè)節(jié)點(diǎn)的特殊輸出(按格式寫入指定文件或者打印到標(biāo)準(zhǔn)輸出)會(huì)被保存在 Pipeline 數(shù)據(jù)庫中;
          • 后續(xù)節(jié)點(diǎn)通過 outputs 語法聲明的表達(dá)式會(huì)在節(jié)點(diǎn)開始執(zhí)行前被替換為真正的值。


            
          舉例:
            


            

          如圖所示:第一個(gè)節(jié)點(diǎn) repo 拉取代碼;第二個(gè)節(jié)點(diǎn) build erda 則是構(gòu)建 Erda 項(xiàng)目。


           
          在例子中,第二步構(gòu)建時(shí)同時(shí)用到了 “值引用” 和 “文件引用” 兩種引用類型,是進(jìn)依次入代碼倉庫,指定 GIT_COMMIT 進(jìn)行構(gòu)建。
              
            
           如何實(shí)現(xiàn)上下文傳遞(文件引用)



          • 文件引用比值引用復(fù)雜,因?yàn)槲募臄?shù)據(jù)量比值大得多,不能存儲(chǔ)在數(shù)據(jù)庫中,而是存儲(chǔ)在卷中。
          • 這里又根據(jù)是否使用共享存儲(chǔ)而分為兩種情況,兩者的區(qū)別在于申請(qǐng)的卷的類型和個(gè)數(shù)。
          • 對(duì)于流水線使用者而言,沒有任何區(qū)別。


             


          使用共享存儲(chǔ)



          不使用共享存儲(chǔ)

           如何實(shí)現(xiàn)緩存加速


            

          在許多流水線場(chǎng)景中,同一條流水線的多次執(zhí)行之間是有關(guān)聯(lián)的。如果能夠用到上一次的執(zhí)行結(jié)果,則可以大幅縮短執(zhí)行時(shí)間。

            

          典型場(chǎng)景是 CI/CD 構(gòu)建,我們以 Java 應(yīng)用 Maven 構(gòu)建舉例:不但同一條流水線不同的多次執(zhí)行可以復(fù)用 ${HOME}/.m2 目錄(緩存目錄),甚至同一個(gè)應(yīng)用下的多個(gè)分支之間都可以使用同一個(gè)緩存目錄,就像本地構(gòu)建一樣~

            


          舉例:

             


          仍然使用前面的例子,在第二步 build erda 里加上 cache 即可。

             



            


           Action Agent
            
          在 Pipeline 里,每個(gè)節(jié)點(diǎn)都會(huì)對(duì)應(yīng)一個(gè) Action 類型,并且在擴(kuò)展市場(chǎng)中都可以找到。為了更加方便 Action 開發(fā)者進(jìn)行開發(fā),我們提供了很多便捷的機(jī)制。如:


              

          • 對(duì)敏感日志進(jìn)行脫敏處理,保證數(shù)據(jù)安全

          • 無感知的錯(cuò)誤分析和數(shù)據(jù)上報(bào)

          • 文件變動(dòng)監(jiān)聽及實(shí)時(shí)上報(bào)

          • ……


             


          上述所有機(jī)制都是由 Action Agent 程序完成的,它是一個(gè)靜態(tài)編譯的 Go 程序,可以運(yùn)行在任意 Action 鏡像中。Agent 完整的執(zhí)行鏈路如下:


             

           Action Executor 擴(kuò)展機(jī)制
            
          Pipeline 之所以好用,是因?yàn)樗峁┝遂`活一致的流程編排能力,并且可以很方便地對(duì)接其他單任務(wù)執(zhí)行平臺(tái),這個(gè)平臺(tái)本身不需要有流程編排的能力。




          在 Pipeline 中,我們對(duì)一個(gè)任務(wù)執(zhí)行的抽象是 ActionExecutor。一個(gè)執(zhí)行器只要實(shí)現(xiàn)單個(gè)任務(wù)的創(chuàng)建、啟動(dòng)、更新、狀態(tài)查詢、刪除等基礎(chǔ)方法,就可以注冊(cè)成為一個(gè) ActionExecutor:


          • 恰當(dāng)?shù)娜蝿?wù)執(zhí)行器抽象,使得 Batch/Streaming/InMemory Job 的配置方式和使用方式完全一致,流批一體,對(duì)使用者屏蔽底層細(xì)節(jié),做到無感知切換。

          • 在同一條流水線中,可以混用各種 ActionExecutor。


                   
          調(diào)度時(shí),根據(jù)任務(wù)類型智能調(diào)度到對(duì)應(yīng)的任務(wù)執(zhí)行器上,包括 K8sJob、Metronome Job、Flink Job、Spark Job 等等。
            


          Go 接口定義




             


           AOP 擴(kuò)展點(diǎn)機(jī)制


            


          AOP 擴(kuò)展點(diǎn)機(jī)制是借鑒 Java 里 Spring 的概念應(yīng)運(yùn)而生的。
             
          我們把代碼關(guān)鍵節(jié)點(diǎn)進(jìn)行暴露,方便開發(fā)同學(xué)在不修改核心代碼的前提下定制流水線行為。AOP 擴(kuò)展點(diǎn)機(jī)制已經(jīng)使用 Erda Infra 的模塊化思想重構(gòu),整個(gè)擴(kuò)展點(diǎn)的插件開發(fā)和編排更為靈活,如下圖所示:
            
          AOP 在 Pipeline 內(nèi)部的使用

          這個(gè)能力后續(xù)我們還會(huì)開放給用戶,讓用戶可以在 pipeline.yaml 中使用編程語言聲明和編排擴(kuò)展點(diǎn)插件,更靈活地控制流水線行為。

          END


          想要了解更多相關(guān)的內(nèi)容,歡迎掃描下方?? 關(guān)注 公眾號(hào),回復(fù)關(guān)鍵詞 [實(shí)戰(zhàn)群]  ,就有機(jī)會(huì)進(jìn)群和我們進(jìn)行交流~

          瀏覽 13
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  就爱添逼视频免费网站 | 日本A∨在线 | 停停色导航 | 玖玖精品在线播放 | 久久色在线播放 |