Jenkins Kubernetes Slave 调度效率优化小记
Jenkins K8S Slave 调度效率优化#
by kimmin
使用kubernetes为测试工具Gatling进行大规模压测,压测期间发现Jenkins调度压测实例较慢,单批几百实例需要十分钟左右也不能保证完整调度。
结合Jenkins Master源码 和Jenkins Kubernetes插件源码,对调度进行了细节的优化。调优过程中目标实例个数都设为300,调优后可以大体上允许一分钟内从Jenkins Master调度完毕。如果目标实例个数线性增加,调度的时间也不会有明显变化。
经过调优后,目前生成动态Jenkins Slave主要的耗时瓶颈是在Jenkins Master的任务队列的填充上,目前可能已经将消费者端监听队列并且计算期待实例个数的算法调整到了最aggressive的策略,但是生产者喂Queue的效率低下导致消费者出于饥饿状态。
继续对Queue生产者端进行调优,应该需要修改Jenkins Master的源码并且会对正常的构建任务进Queue产生未知影响,可能短期不会考虑。
如果要对Jenkins Master进行调优,可以从以下几点着手:
- Jenkins的Master核心是由一系列定时任务组织起来的,目前瓶颈是在Jenkins Master的Queue生产者端,主要是调度任务在多级的Queue里面状态迁移,这个做Queue内Job状态迁移核心任务的执行间隔在Jenkins源码里面是hardcode为5秒钟,所以最坏情况下一个任务需要等待5s,才会在Queue内变化一次状态,即使发生了状态变化,没有进入Pending状态的Job也不会被算进NodeProvisioner的期待Slave列表中。那么我们可以修改这里的间隔来加速调度。
- 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
Jenkins Kubernetes Slave 调度效率优化小记的更多相关文章
- TKE 用户故事 | 作业帮 Kubernetes 原生调度器优化实践
作者 吕亚霖,2019年加入作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进.推动实施容器化改造.服务治理.GO微服务框架.DevOps的落地实践. 简介 调度系统的本质是为计算服务/任 ...
- 基于Kubernetes构建企业Jenkins master/slave CI/CD平台
搭建平台目的: k8s中搭建jenkins master/slave架构,解决单jenkins执行效率低,资源不足等问题(jenkins master 调度任务到 slave上,并发执行任务,提升任务 ...
- kubernetes跑jenkins动态slave
使用jenkins动态slave的优势: 服务高可用,当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master 容器,并且将 Volume ...
- 【我的Android进阶之旅】Jenkins挂载slave节点,增强分布式编译的效率
由于公司的Jenkins任务越来越多,而且所有的Android Jenkins任务都在同一台服务器上进行编译,而且该服务器配置Jenkins任务最多3个任务同时运行,所以有时候大家一起编译的时候,只能 ...
- 第十四章 kubernetes 核心技术-调度器
一.概述 一个容器平台的主要功能就是为容器分配运行时所需要的计算,存储和网络资源.容器调 度系统负责选择在最合适的主机上启动容器,并且将它们关联起来.它必须能够自动的处 理容器故障并且能够在更多的主机 ...
- jenkins中slave节点连接的两种常用方式
我们在使用jenkins的时候,一般来说肯定是有slave节点的,本来网上也有好多关于jenkins节点配置的教程,我也就不写了.简单说明一下:任务一般是在slave上面运行的.当然不是讲master ...
- 转: 调整 Linux I/O 调度器优化系统性能
转自:https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html 调整 ...
- Kubernetes容器调度
Kubernetes的调度器是Kubernetes众多组件的一部分,独立于API服务器之外.调度器本身是可插拔的,任何理解调度器和API服务器之间调用关系的工程师都可以编写定制的调度器.本文后面的介绍 ...
- Hadoop YARN:调度性能优化实践(转)
https://tech.meituan.com/2019/08/01/hadoop-yarn-scheduling-performance-optimization-practice.html 文章 ...
随机推荐
- python之路第二篇(基础篇)
入门知识: 一.关于作用域: 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 10 == 10: name = 'allen' print name 以下结论对吗? ...
- AMD、CMD、CommonJs规范
AMD.CMD.CommonJs规范 将js代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS.AMD和CMD.接下来我们看一下这几种规范. 一.模块化规范 C ...
- PL/SQL 三个小例子
/* SQL语句 员工集合:select to_char(hiredate,'yyyy') from emp --> 光标 --> 循环--> 退出条件:notfound 变量 co ...
- JavaWeb之response响应中文乱码问题
response向页面响应中文乱码问题 字节流 * 有可能乱码,与中文转换成字节数组.浏览器打开的默认字符编码有关 * 解决方式:将中文转成字节数组的时候和浏览器默认打开的时候采用的字符集一致 re ...
- CMD(SA400 Command)
一.CMD模糊查询: 命令行键入:CRT,WRK,ADD,CPY,DSP,CHG,CLR,FND,RTV*等. 二.CMD分类查询: 命令行键入:GO CMD xxx eg:GO CMD FILE,G ...
- MTV模型
django的MTV分别代表: model(模型):负责业务对象与数据库的对象(orm) template(模板):负责把页面展示给用户 view(视图):负责业务逻辑,并在适当的时候调用model和 ...
- 【NOIP2015提高组】 Day2 T3 运输计划
题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如: ...
- 在WebBrowser控件使用js调用C#方法
有时我们需要在WebBrowser控件中嵌入了网页,然后通过html页面调用后台方法,如何实现呢?其实很简单,主要有三步: 在被调用方法所属的类上加上[ComVisible(true)]标签,意思就是 ...
- LeetCode 283. Move Zeroes (移动零)
Given an array nums, write a function to move all 0's to the end of it while maintaining the relativ ...
- LeetCode 191. Number of 1 bits (位1的数量)
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...