背景
云主机创建有两种方式,一种通过镜像下载来创建,另一种通过快照回滚来创建, 前者是通用的传统方式,后者依赖于CBS云盘能力。 随着CBS云盘使用越来越广泛,腾讯云主机创建也由原来的镜像下载切换到CBS云盘快照回滚模式。
通过传统镜像下载的方式来创建云主机,在云主机拉起前,需要将整个镜像文件都下载到宿主机上,所以云主机的创建时间很大程度上依赖所选取的镜像和当时下载镜像的带宽。当遇到比较大的镜像时,云主机创建时间经常会达到几百秒,这样的用户体验不是太好; 另外,当批量创建时,需要消耗大量的内网带宽资源,需要在尽量占用网络带宽的同时做好Qos,保证不影响用户的正常使用。
使用云盘快照回滚的方式来创建云主机,不需要提前下载镜像,而是在云主机拉起时,优先将要访问的数据从快照系统搬迁到CBS云盘系统中。 我们观察到,云主机拉起过程中访问的数据量和镜像大小并不是严格的线性关系,即便是较大的镜像,在云主机拉起时也只会访问到很少一部分数据,搬迁流程如下:
当有快照回滚请求时,我们首先会在后台启动一个任务,将快照数据按顺序从COS读出写入到存储池中,同时我们不会阻碍用户对回滚磁盘的正常读写。 当有用户请求过来时(步骤1),会先在driver中检查对应lba的快照数据是否已经被写入,如果写入则IO直接下发(步骤7),否则,会阻塞IO并先给scheduler发送trigger请求(步骤3),scheduler会优先将trigger请求处理,交给搬迁模块将对应的快照数据从COS读出,写入到存储池(步骤3、4、5),等写入完毕后,scheduler先记录搬迁bitmap到zk并给driver返回trigger response和当前的快照数据回滚进度(步骤6),driver收到后则不再阻塞io, 让其正常下发(步骤7)。
聚焦延迟和并发,云主机创建优化之路
云盘快照回滚优先搬迁关键数据这种机制为我们批量创建云主机奠定了基础,在此基础上,我们还围绕着延迟和并发这两点做了一系列优化。
transfer增加cache
子机批量创建时,经常是使用同一个镜像克隆出几百或上千台子机,如果所有数据都从COS系统拉取,对COS的读压力会非常大,会触发COS的Qos流控。为了让批量创建时读取镜像的流量不再受限于COS的带宽, 我们在transfer中增加了cache,每个transfer中都缓存镜像的部分数据块,一旦命中transfer的cache就不再从COS拉取数据,这样每个transfer只需拉取一次镜像; 当cache流量达到瓶颈时,可以通过临时增加节点来增加带宽,具备水平扩展能力。
在增加了cache后,我们对transfer部署也做了优化,每个zone都部署了若干个节点,当有数据块搬迁请求时,任务总是会优先落到和CBS盘底层存储节点相同zone的transfer上,这样就可以实现就近搬迁。
通过cache优化,可以将单个数据块的搬迁耗时从100+ms降低到10+ms, 大大降低了IO延迟。
scheduler性能优化
在快照回滚创建云主机过程中,核心处理逻辑在scheduler,因为client端每个IO trigger请求都要经过scheduler, 并且由于每个由trigger触发的快照数据块搬迁都要在zk里记录起来, 所以scheduler的负载以及zk写入能力会直接影响到整个快照系统的吞吐。
首先,我们优化了scheduler,将请求接收、处理以及与后端交互部分的逻辑拆开来,形成流水线,尽量减少因某个请求处理慢导致其他请求排队的情况, 每个部分都由一个线程池来并行处理,尽量将整机的计算能力利用起来;
其次,针对zk写入压力大的问题,我们将写入zk的数据做了分类,变化不频繁的一些元数据还是写入zk; 而记录trigger搬迁状态的那些元数据,需要频繁修改,这部分数据不适合存zk,我们将其offload到一个qps更高的存储系统上,这样一来,scheduler的处理能力得到了成倍的增长。
另外,为防止回滚的流量影响到其他用户对磁盘的正常使用,我们在scheduler做了必要的Qos。 首先限制落到同一个副本组的回滚带宽, 在整个副本组带宽空闲时,回滚流量不能超过限制; 而当整个副本组的带宽达到上限时,回滚带宽会自动回退,优先保证用户的正常IO延迟。其次,当同时有顺序搬迁任务和trigger请求任务时,优先处理trigger请求任务,保证用户体验。
最后,我们通过对scheduler改造,做到水平可扩展, 使其不再成为性能瓶颈。
买盘调度
当用快照回滚的方式批量创建云主机时, 会将快照数据写入新创建的所有CBS云盘。 如果大量的云盘落在同一个副本组,则会造成这个副本组写入流量过大,触发前一节提到的副本组回滚带宽限制。为避免这个问题,我们加入一个调度系统,在批量购买云盘时,从副本组剩余容量、已创建的volume数、回滚带宽、副本组写入带宽四个纬度综合考量,把同一批次创建的CBS云盘尽量打散到多个副本组。这样一来,首先可以保证在创建时,单个副本组不会成为流量热点;其次可以在一定程度上保证所有的副本组在创建时流量均衡,将整个存储池的带宽充分利用起来;最后,同一批次购买的CBS云盘打散,可以将用户因为某个副本组出故障受到的影响降到最低。
减少子机拉起时的数据量
前面主要从降低延迟和增大回滚带宽角度去考虑如何优化,目的是让后端系统能够承载更大的回滚带宽,提升快照数据搬迁效率。如果在快照数据搬迁过程中,CBS云盘有IO访问到还未搬迁的数据块,就会产生一个trigger请求,后台系统需要优先搬迁trigger请求对应位置的快照数据,这对scheduler会造成额外的负担,所以如何减少子机拉起时产生的IO trigger,减少对后端系统的压力,对云主机并发创建很有意义。
对子机拉起过程进行分析,我们发现,在子机拉起过程中,文件系统扩容和配置文件修改都会在后端产生不少io trigger。 文件系统扩容一般发生在快照里的文件系统size小于要回滚的CBS云盘size,在这种场景下,需要先将原文件系统的元数据全部读到内存中,修改后再写入。像ext系列文件系统的元数据是散落在每个块组中的,所以读元数据会变成随机读操作,几乎每个随机读都会产生一个trigger,触发后端快照数据块搬迁,而文件系统的block大小远小于快照粒度,这里相当于发生了读写放大; 为此,我们通过修改文件系统配置,让所有元数据集中,这样读元数据就变成了顺序读写,这样就可以将请求合并,从而减少后端压力。 经过优化后,文件系统扩容时,后端IO压力可以降低到原来的五分之一,耗时降低到原来的四分之一。
其次,对于配置文件修改,如果直接在原文件上修改,既要读写文件元数据,又要读写文件数据,开销比较大;所以改成删除+写新文件的方式,这样不需要读文件数据,可以有效减少IO。
总结:
通过上述几个层面的技术优化,目前,腾讯云已经可以做到八千台子机并发创建,为客户提供更好的服务体验。后续,我们的优化还会一直进行下去,欢迎大家给我们提出宝贵意见。