大家好,欢迎大家来参加我们的演讲我们的演讲主题是CPU Burst避免不必要的CPU线流同时获得高CPU用率和应用程序性能我是今天的第一位演讲者,常怀心另外一位是我的同事,丁天琛我们都是阿里云内核研发团队的工程师什么是CPU Burst?CPU Burst是Limix内核里一个CPU最远使用的新特性这是容器用户都很关心的话题今天主要从以下四方面介绍CPU Burst的特性CPU Limix的支持背景CPU Burst的设计CPU Burst的负面影响最后是如何使用CPU Burst的特性首先让我们关注CPU Limix的相关背景以及当前存在的问题在K8s中如何设置CPU资源使用呢通过这个样率我们可以看到CPU资源使用是用CPU Requests和CPU Limits来表示的CPU Requests代表CPU资源的最低需求它影响容器调度如果节点上的空闲CPU资源比容器的CPU Requests还要少容器就不会调度到这个节点上CPU Limits是容器CPU使用的上限它确保CPU使用不超过这个限制样率容器的CPU资源下限是0.5CPU资源上限是1CPU在Linux内核中CPU Requests使用CFSShare机制应用进程按照Share份额分CPU时间容器获得的CPU时间由它的Share份额在所有Share份额中所占的比例决定通过CPU C Group里面的CPU.Share文件可以查询或者设置容器的Share份额用一个具体的例子来说明如何使用Share机制保证容器的CPU使用下限最初调度节点空闲它有32个CPU可用然后调度来一个CPU Requests为8个CPU的容器由于没有其他容器的存在它的Share份额占100%容器可以使用的CPU资源上限和下限都是32个CPU继续向这个节点调度一个Request8CPU的容器出现了CPU竞争这时候我们仍然关注第一个容器它的份额占比变成了50%在CPU竞争中可以获得总CPU时间的50%即至少使用32个CPU的一半16个CPU继续往这个节点调度一个Request16CPU的PODCPU竞争更多了第一个容器的Share份额变成25%竞争时可以获得总CPU时间的25%即保证至少使用8个CPU最后所有CPU资源都分配完其他有CPU Requests的设置的容器都不能调度到这个节点上这样通过K8SCPU Requests分配节点的CPU资源CPU Requests又使用Share份额分配节点上的CPU时间保证了容器CPU资源使用的下限接下来介绍CPU Limits和CPU资源上限设置CPU Limits可以把容器的CPU使用限制下来避免单个容器过度使用CPU资源影响其他容器K8S的CPU Limits使用Linux中的CFS Bandwidth Control机制来设置CPU使用的上限CPUC股仆谱中有两个接口与此相关CPU.CFS Period US和CPU.CFS Quota US后面我们把他们简称为Pirate和QuotaPirate是带宽控制的周期Quota是每个周期内CPU使用时间的限制每个周期内CPU使用时间被限制到Quota样率表示的容器CPU Limits为0.2个CPU当CPU使用时间超过Quota容器任务会被限流样率中任务使用20毫秒CPU之后需要等待80毫秒直到当前周期结束之后每个周期的CPU使用时间都不能超过Quota容器的CPU使用被限制到0.2个CPU这是K8S通过CFS带宽控制限制容器CPU使用上限的原理CFS带宽控制还提供了三个指标来表示其工作过程分别是NarParis表示应用使用CFS带宽控制的周期技术NarSluTode表示应用被限流的周期技术SluTime表示应用被限流的CPU时间技术使用CFS带宽控制可以把应用的CPU使用限制到CPU Limits很多时候这种限制会影响到应用延迟假设应用需要连续使用30毫秒CPU来处理请求在没有CPU限制的情况下可以在30毫秒内完成请求如果设置CPU Limits为0.2个CPU使用20毫秒CPU时间之后应用进程会被限流在下一个100毫秒周期内继续使用10毫秒才能完成请求处理一共用11110毫秒我们可以注意到CPU平均的利用率在这里并没有超过CPU Limits的限制整个300毫秒过程中的平均CPU利用率是0.1个CPU而CPU Limits这里的设置是0.2个CPU在这种情况下限流仍然导致请求的处理时间增加了80毫秒因此我们认为这是一个需要改善的问题这种延迟问题普遍往事的在KBS社区有很多相关讨论这里我们截取了两条大家可以通过链接阅读相关内容接下来让我们看看当前这个问题是如何解决的第一种方法是增加CPU Limits设置既然设置CPU Limits导致限流那么很自然的想法是增加CPU Limits的限制甚至完全取消它来消除CPU限流这种解法会导致一些问题我们分两种情况来讨论如果容器Request和Limit相等提升Limits同时也提高了RequestRequest提升前面我们介绍会影响容器调度因此节点上的容器数目会变少最终的结果是CPU的利用率变低在KBS中KBS等级微Garantee类型的容器满足这种情况如果容器的QS类型是其他可以保持Request不便放大CPU Limit或者取消CPU Limit设置这时候有CPU资源上限过度承诺的风险在这种情况下Linux里CFS公平调度会按照优先级来分配CPU资源但允许用户使用更多的CPU资源的策略可能会成为问题有些情况下这不是问题很多时候这的确是个问题特别是当我们想要把资源以一分钱一分货的方式提供给用户并且保证应用性能带一致性除了调整CPU Limits之外还有另外一种缓解延迟问题的方法那就是放大Quota和Period要设置CPU Limits为0.2个CPUQuota和Period可以是20毫秒和100毫秒也可以是40毫秒和200毫秒放大到Quota 40毫秒Period200毫秒配置之后对CPU突发使用是更有好的仍然用前面的例子来进行说明在Quota 20毫秒Period100毫秒配置下30毫秒CPU突发使用被线流放大配置到Quota 40毫秒Period200毫秒配置下30毫秒CPU突发使用不会被线流避免了线流引起的延迟问题而这种方法其实也有问题一旦CPU突发使用超过Quota应用进程会面临更长时间的CPU线流当Period是100毫秒的时候线流对长不超过100毫秒而Period放大到200毫秒之后应用进程被线流可能线流之后可能需要等待将近200毫秒另外内核有Period最大值的限制一秒用户不能把它放大很多倍会限制这种方法的使用效果总结一下不必要的CPU线流问题影响运用性能当前在不改变内核功能的前提下在CPU Limits上的调整或是放大Quota和Period都不能很好的解决问题既然不改变内核功能的解决方法不够好我们把关注点也放到Linux内核里面在CFS带宽控制的基础上提出了突发的CPU带宽控制也就是CPU Burst特性接下来我们介绍CPU Burst如何从根本上解决这种不必要的线流问题CPU Burst特性打破了之前CPU使用超过Quota就线流的限制允许一定程度的突发使用不使用CPU Burst的情况下会出现CPU线流之前我们介绍过这个过程使用CPU Burst之后中间周期借用到CPU时间没有发生CPU线流这些CPU时间来自之前未充分使用的CPU资源应用的突发使用需求得到满足应用的性能也得到提醒这里准备了更强劲的过程演示来说明运行过程中CPU时间是如何累计和使用的我们引入了一个Burst Buffer来记录累计下来的CPU时间0毫秒第一个周期开始时Burst Buffer里的CPU时间是0本周期内应用进程没有任何CPU使用在100毫秒处周期结束时20毫秒CPU时间在Burst Buffer里累计下来在第二个周期内应用进程产生30毫秒CPU使用的需求在不使用CPUBurst的情况下应用进程在使用CPU时间超过COTA20毫秒之后被线流引起延迟问题使用CPUBurst的是应用进程使用20毫秒CPU时间之后继续使用Burst Buffer里的CPU时间运行10毫秒不产生CPU线流周期结束时Burst Buffer里浸扣出10毫秒CPU时间剩110毫秒CPU时间以上是Burst Buffer理CPU时间累计和使用的演示使用CPUBurst之后应用的CPU使用还会射到线据吗继续用对3个周期的CPU使用进行说明之前的演示里200毫秒周期开始时Burst Buffer里有10毫秒CPU时间并且后续没有CPU需求让我们看看当第三个周期内继续有CPU使用的需求时会发生什么当第三个周期内应用的CPU使用时间到达30毫秒时Code和Burst Buffer提供的CPU时间用完应用进程仍然会被线流周期结束时Burst Buffer里的CPU时间剩余0毫秒把三个周期放一起看三个周期的CPU使用分别是0毫秒30毫秒30毫秒一共60毫秒正好对应到300毫秒时间内的0.2个CPU这说明使用CPUBurst时仍然提供了CPULimit的上线限制总结下使用CPUBurst之后的CPU时间情况在不使用CPUBurst的情况下应用进程在一个周期内的CPU时间被限制严格不能超过Quota使用CPUBurst之后应用进程在一个周期内的CPU时间最大是Quota和Burst Buffer里的CPU时间之合由于Burst Buffer里累计的CPU时间来自之前周期内的CPU不充分使用整体来看仍然满足CPU使用时间低于CPULimit的约束要使用CPUBurst的功能需要通过C Group文件系统的CPU.CFSBurstUS接口它表示允许累计的CPU时间最大值默认0表示关闭不使用CPUBurst为了表示Burst Buffer里CPU时间的使用情况我们在CPU.State接口里面还加入了NrBurst和BurstTime两个统计项NrBurst代表应用使用Burst Buffer里CPU时间的周期数如果没有CPUBurst的特性这些周期在这些周期内都会产生CPU限流BurstTime是应用使用Burst Buffer里的CPU时间之合看了这么多样例也是CPUBurst特性的实际效果怎么样呢在一个对比验证中平均延迟从超过30毫秒下降到9毫秒延迟的99%成为从超过500毫秒下降到27.32毫秒这是CPUBurst效果比较明显的一个场景在POD的应用配置了较多的GC限乘数因此表现出比较突发的CPU使用CPUBurst起到了很好的优化效果在另外一个应用上观察到平均延迟27%的下降从1310毫秒下降到952毫秒上面主要介绍了CPUBurst的正面效果那么我在这里来简单讲讲这个特性会不会产生一些副作用这个也是当时我们希望把CPUBurst的特性合入上游社区时遇到的Mantana的一些挑战先来简单介绍一下问题CPUBurst引入之后它改变了原有的CFS带宽控制的逻辑在没有CPUBurst的时候Quota能很好的限制每个容器的CPU使用率比如说我们现在有两个任务任务一和任务二它们的Quota各自都是50%那么在一个周期内当任务一使用完它的50%的CPU资源时就会被限留然后让出CPU那么剩下的50%的CPU时间就会交给任务二来使用我们原先可以通过配置所有任务的Quota总和不超过100%的整体CPU时间这样一个手段就能够保障整体调度的稳定性和任务的实施性接下来让我们看看引入了CPUBurst之后会发生什么接着上面的例子我们设置任务一的BurstBurst大小为整个周期的CPU时间的10%而且它通过第一个周期已经充满了Burst现在任务一耗尽了分配给它的50%的CPU资源后由于CPUBurst它会从自己的文化中额外获得10%的资源它现在总共就获得了60%的CPU时间那这就导致任务二在这个周期内只能使用剩下40%的资源了这样这个任务二就无法预期完成任务这部分的任务就会被推迟到后面的周期这就出现了Miss Deadline我们再往后看任务二可能不只出现一次延期因为本应在上个周期完成的任务被推迟到了下个周期它后去产生的计算需求也会被一并往后推从而出现持续延期的情况这就造成了整个调度系统可能不稳定以用Mantella的话来说就是可能出现Unbounded Fail于是我们就需要知道这种任务持续被延期的情况会持续多久并且这种现象发生的概率有多少能够回答我们这些问题的就是WCET这个指标它的含义是任务在最坏情况下的执行时间在没有CPU Buzz的时候CPU在每个周期都能将所有的任务完成反过来说也就是所有容器提交的任务是一定能在一个周期内完成的那么他们的最坏执行时间就小于一个周期了在引入了CPU Buzz之后最坏执行时间这个指标就可能会超过一那么当它大于一的时候我们认为此时的调度系统是处于不稳定的状态的为了球写这个指标我们使用了排队论进行建模文特凯罗方法来计算根据排队论模型CPU作为服务台所有容器提交的任务需求按相同的建格到达这个建格也就是周期在这里给出了我们工具的地址可以对理论的一些分布和场景进行模拟也可以在实际场景下采集数据然后根据结果估计CPU Buzz的对该场景的影响输入一个容器每周期产生的计算需求的分布整台服务器上容器的总数还有设置开启CPU Buzz的Buffer的大小我们可以模拟计算得到最坏执行时间的期望和它大于一的概率也就是造成不稳定的概率下面是一些结果的展示我们先挑一种典型的情况作为例子在这个场景中每个容器每个周期产生的需求按复制出分布整台服务器一共有20个容器国法的大小设置为扩大的一倍这张图是最坏执行时间的期望随着平均CPU利用率产生的变化我们可以看到在平均负载低于70%的环境中CPU Buzz的几乎没有影响而我们大部分日常生产环境都是满足这种情况的而对于那些负载一直很高的环境这时候CPU Buzz的本身也不会帮上什么忙这时候还是建议提高配置或者减少负载在后面两页我们列出了更加详细的实验数据这一页是每个容器在每个周期按复制出分布产生计算需求的实验结果我们还改变了其他的一些参数比如说整台服务器上的容器总数M还有国法的大小我们通过设置整台服务器上的容器的数量从10,20,到30变化国法的大小设置为扩大的一倍,两倍或无穷大来考察在不同场景下CPU Buzz的对调度系统的影响大家可以看一下上面列出的实验结果图能得到一些明显的结论那么一般来说平均负载越高容器总数越少最快时间时间就越长也就意味着对调度系统的影响越大平均负载越高影响越大这是个显然的结论关于后者也就是容器总数越少影响越大这个结论呢是因为独立同分布的情况下容器数量越多整体产生的需求就越趋于平均这种情况下超出Quota需求的容器和低于Quota从而控除CPU时间的容器更可能互补这一点可以参照中心极限定力他们也是类似的Buffer的改变对最坏执行时间的影响也在我们的预期之内提高Buffer会使得CPU Buzz发挥更好的效果从而对单台容器的优化收益更加明显但同时可能会增加最坏执行时间意味着可能会增大对相连容器的干扰这一页是容器安帕雷托分布产生需求的实验结果得到的结论与上一页也是类似的从而可以说明我们的结论在大部分常见分布中都是成立的同时这些数据也可以为设置Buffer大小时作为参考我们建议根据具体业务场景的计算需求和服务器商部署的容器总数还有自己的实际需求来决定比如说如果希望增加整体系统的吞吐量以及在平均符合不高的情况下优化容器性能可以增大Buffer反之如果希望保证调度的稳定性和任务的实施性在整体符合较高的情况下减少容器之间的影响可以适当的减小Buffer一般而言在低于70%平均CPU利用率的场景中CPU Burst不会对相力容器造成较大影响大家可以放心地启用这个功能最后我们介绍怎么才能使用到CPU Burst的特性CPU Burst的特性带5.14版本合入到内核主线如果想带发行版中使用可以在Analysis OS 8.2以及后续版本中使用Analysis OS 8是OpenAnalysis社区推出的完全开源中立开放的发行版它支持多计算架构也面向云端场景优化完全兼容SynthOS 8软件生态Analysis OS 8只在为广大开发者和用为人员提高稳定高性能安全可靠开源的操作系统服务对容器用户来说我们正在推动K8S社区对CPU Burst的特性的支持在阿里云K8S产品中对CPU Burst的功能的支持预计在今年12月份发布以上就是我们今天关于CPU Burst特性的全部介绍感谢大家的参与