Jenkins Kubernetes Slave 調度效率優化小記

Jenkins K8S Slave 調度效率優化

by kimminjava


使用kubernetes爲測試工具Gatling進行大規模壓測,壓測期間發現Jenkins調度壓測實例較慢,單批幾百實例須要十分鐘左右也不能保證完整調度。git

結合Jenkins Master源碼Jenkins Kubernetes插件源碼,對調度進行了細節的優化。調優過程當中目標實例個數都設爲300,調優後能夠大致上容許一分鐘內從Jenkins Master調度完畢。若是目標實例個數線性增長,調度的時間也不會有明顯變化。
通過調優後,目前生成動態Jenkins Slave主要的耗時瓶頸是在Jenkins Master的任務隊列的填充上,目前可能已經將消費者端監聽隊列而且計算期待實例個數的算法調整到了最aggressive的策略,可是生產者喂Queue的效率低下致使消費者出於飢餓狀態。github

繼續對Queue生產者端進行調優,應該須要修改Jenkins Master的源碼而且會對正常的構建任務進Queue產生未知影響,可能短時間不會考慮。算法

若是要對Jenkins Master進行調優,能夠從如下幾點着手:異步

  1. Jenkins的Master核心是由一系列定時任務組織起來的,目前瓶頸是在Jenkins Master的Queue生產者端,主要是調度任務在多級的Queue裏面狀態遷移,這個作Queue內Job狀態遷移核心任務的執行間隔在Jenkins源碼裏面是hardcode爲5秒鐘,因此最壞狀況下一個任務須要等待5s,纔會在Queue內變化一次狀態,即便發生了狀態變化,沒有進入Pending狀態的Job也不會被算進NodeProvisioner的期待Slave列表中。那麼咱們能夠修改這裏的間隔來加速調度。
  2. Jenkins的Slave生成的任務是由一個Jenkins各組件共享的線程池來執行的,這個線程池使用的是java.util.concurrent.ExecutorService的newCachedThreadPool,池內用容量爲0的java.util.concurrent.SynchronousQueue來維繫生產者消費者的關係,之因此用這個線程池是爲了讓生產者進程當沒有分配到線程時阻塞在submit方法。可是因爲這種線程池對突來的大量任務會作緩衝致使一些任務沒有辦法當即調度,優化能夠使用一個預聲明線程充足的有界隊列替換掉當前線程池

Jenkins Master和Kubernetes插件之間的關係的是什麼?

大致上,Kubernetes插件只是實現了Jenkins Master裏Cloud類的provision接口ComputerLauncher的launch接口,provision接口是Jenkins Master想要生成一個Slave的時候調用的,那麼Kubernetes插件只奉命作事和Kubernetes APIserver通訊按照Pod Template建立一個用做Slave的Pod進行工做,launch接口是用來讓Jenkins Master的啓動一個Slave的,可是因爲Kubernetes裏面容器實例的建立是異步的過程,因此插件裏launch只是在作輪詢Pod狀態來等待Pod建立完畢結束launch的過程。Kubernetes的Scale效率遠大於目前壓測實例的建立效率,因此咱們定位瓶頸也是從Jenkins Master和Kubernetes插件上開始。工具


Jenkins Master參數優化

快照間隔/調度間隔參數

按從消費者到生產者的順序進行分析,首先咱們把Jenkins Master計算集羣負載的快照間隔hudson.model.LoadStatistics.clock從10秒縮短到了2秒,btw,Jenkins Master防守式地用時間戳快照間隔最小限定到了1秒,可是爲了可能更快的進行調度。咱們而且且將進行provision的間隔hudson.slaves.NodeProvisioner.recurrencePeriod從6秒縮短到了2秒,這裏參數比較危險的是當provision間隔小於快照間隔,可能致使短期內無限建立slave的bug。性能

冷啓動初次調度等待參數

Jenkins服務啓動後的第一次provision是由參數hudson.slaves.NodeProvisioner.initialDelay決定的,這個參數是爲了確保讓靜態的Jenkins Slave和Master創建起來鏈接,因爲咱們使用的Kubernetes插件其實並不存在雙向的通訊,因此咱們把初始的調度delay從100秒縮小到了20秒。測試

快照存儲EMA(Exponential Moving Average)變化參數

hudson.model.LoadStatistics.decay用於EMA抑制負載的抖動,這個參數本來的意義是用於抑制評估master負載的抖動,而且容許給使用者人肉反應時間來終止一些畸形的Job。默認decay是0.9。好比上一次快照負載爲1,那麼下次入隊列的快照評分就會是**_1 + (1-0.9)*當前負載_**,咱們把快照decay設成了0.1,容許負載大幅度變化。從而每次provision的時候,Jenkins Master評估的負載就是在當前儘量真實的負載之上評估的新實例個數。這個也是主要提高調度性能的參數之一。優化

EMA Threshold對浮點型負載進行整數對齊的參數
hudson.slaves.NodeProvisioner.MARGIN_DECAY
hudson.slaves.NodeProvisioner.MARGIN
hudson.slaves.NodeProvisioner.MARGIN0

如上圖所示,把調整這裏的參數使負載作整數對齊的時候儘可能向上對齊,從而多provision一個slave,以此來提升效率。插件

其餘

另外發現一處可能的BUG,提交給了社區。

https://github.com/jenkinsci/kubernetes-plugin/pull/248

相關文章
相關標籤/搜索