您的位置:首页 > 其它

【干货分享】虚拟机热迁移性能优化

2021-02-02 00:06 260 查看


前言

去年,工信部印发《推动企业上云实施指南(2018-2020年)》,旨在推动行业企业在生产、经营、管理中积极上云。上云简而言之,就是指企业将原有IT基础设施转变或迁移到云基础设施中,而业务在云环境中运行的边界通常就是容器和虚拟机。虚拟机作为一个较安全的解决方案在生产环境中得到了广泛的应用,尤其虚拟机的热迁移技术,作为一个杀手级的解决方案更是在数据中心大受欢迎。原因在于,通过热迁移技术可以在用户无感知的情况下实现故障转移、负载均衡和版本升级等数据中心的刚需操作。但是,在实际落地过程中往往由于现网环境的复杂性,诸如网络带宽压力、服务器负载过高、业务虚拟机的体量过大、页面刷新速度频繁等一系列问题,导致虚拟机迁移失败。因此本文通过介绍热迁移的基本概念,分析瓶颈之所在,并就现有的优化技术底层原理进行剖析,依据不同业务场景进行针对性的优化。


1.热迁移基本概念介绍


迁移模型


热迁移是指将正在运行的虚拟机在不同的物理机之间进行移动,期间不能断开来自客户的连接。虚拟机的内存,存储和网络连接都从源端转移到目的端。

图 1‑1  迁移模型


热迁移时通常需要迁移两部分数据,一是当前虚拟机的内存数据,另一个是磁盘数据。现网中考虑到性能通常会使用共享存储,且虚拟机迁移失败大多都是由于内存数据始终迁移不完导致的。因此,本文只讨论内存数据的迁移。下面就虚拟机的内存迁移过程做详细说明。


迁移过程



内存迁移的过程有两种实现方式,分别是pre-copy和post-copy,鉴于官方默认的方式是pre-copy,且post-copy迁移失败会产生不可逆的伤害,在生产环境中风险太大而很少被采用,因此这里只讨论前者。

Pre-copy过程:

1)  开启脏页跟踪2)  拷贝所有的内存页到目的端3)  继续拷贝在第2步拷贝过程中弄脏的内存页4)  一直重复第3步直到剩下的内存页足够小5)  关闭虚拟机6)  拷贝剩下的内存页和虚拟机状态信息7)  在目的端启动这个虚拟机

图 1‑2  迁移过程[1]

由于迁移的过程中虚拟机不关机,所以会出现原来的内存都迁移完了,但是新的内存页又随之产生的情况;或者原来的内存页被修改,这部分内存页面需要重新传输。如果页面产生或者修改的过于频繁,并且长时间持续这种状态,会导致脏页源源不断,无穷匮也。


瓶颈


可以看到,上述过程的关键在于第3步,即持续的拷贝弄脏的页面直到剩下的内存页足够小,小到可以在下一次一次性传输完。可问题的关键就在于脏页产生速度太快导致每个下一次都传输不完,迁移过程就一直耗在这里,最终超时->中断迁移过程->迁移失败!


可见,热迁移的瓶颈在于:脏页的产生速率 > 数据传输速率。


2.优化方案


找准缺口,顽石可破。既然已经知道瓶颈所在,那么解决这个问题的方法就有两个,一则增大网络的传输速率(如使用万兆网卡),二则是减小脏页的产生速度。但即便是万兆网卡,只要虚拟机写操作够密集,且带宽资源还要分配给其他业务,总会出现部分脏页来不及传送的情况。因此在尽可能提供良好传输环境的前提下,还要同时从数据如何最小化传输这个方向发力,两手都要硬,两手都要抓。只要优化得当,理想情况下即便是低速设备也能完成高脏页率的迁移任务!目前就后者(减少数据生成速率)进行展开讨论,这里介绍两种方法,分别是:

1)  XBZRLE

2)  auto-converge。


2.1 XBZRLE



减小脏页产生速率,归根结底还是为了减少在网络中传输的数据量。XBZRLE和Multi-threads的实现正是基于这个思路。这两种方法都是对即将传输的数据进行压缩处理后开始迁移。但在实现上又略有不同,限于篇幅这里只讨论XBZRLE。

原理


想减少数据量的传输?首先得搞清楚数据是如何在源端和目的端流动的:

图 2‑1  默认迁移内存过程


如图2-1,假如src端虚拟机有三个内存页面,待全部传输到目标端后,由于源端又弄脏了其中一个页面,此时,热迁移需要把这个页面再重传一次,即使该页面只有一个字节的修改。而使用了XBZRLE之后,数据又是如何传输的呢?

图 2‑2  启动XBZRLE后迁移内存过程


如图2-2,全量内存拷贝完成之后,但凡有脏数据产生,仅传输新产生的脏数据,即增量传输。举例说明,假如源端对一个4K的内存页面修改了1byte,未使用该技术时,整个4K页面需要重传,但此时只需传输这 1 byte。4K和1byte,其间数据量相去4096倍之巨,性能提升自然不可与之前等量齐观。那么问题来了,怎么知道一个页面的那些内容被修改了呢?


XBZRLE(Xor Binary Zero Run-Length-Encoding),翻译过来就是把修改后的页面同之前传输过的页面进行一个异或操作,异或的结果就是发生变化的数据块,然后传输这部分差异数据到目标端,目标端接受到数据后再将它apply到对应的页面上。具体过程如下图所示:


图 2‑3  XBZRLE作用原理流程图[2]


到这里可能有一个疑问,既然要进行异或操作,修改前的内存页哪儿来呢?是不是需要提前保留?


答案是:要得!为了解决这个问题,XBZRLE中引入cache,即对原始的内存数据进行缓存,页面传输前都要先在cache中查找,找到了进行异或运算,然后增量传输。如果没找到,则要先将该页面进行缓存(以便下次进行查找、对比),然后再完整的将该页面传输到对端。

优化效果测试


本次测试的目的主要有两点:

1、关闭和开启XBZRLE算法对迁移效果的影响。

2、开启XBZRLE算法的情况下,不同cache size对迁移效果的影响。
  • 未开启XBZRLE算法时进行热迁移:

从测试的数据可以看出来,在脏页率分别为1M/s、4M/s、10M/s和20M/s时,如果没有开启XBZRLE,热迁移是不会成功的。

  • 开启XBZRLE算法进行热迁移:

可以看到,同样的负载在开启XBZRLE算法的情况下,局势反转,全部顺利迁移。说明在开启XBZRLE算法的情况下进行迁移可以很大程度上提高热迁移的成功率。此外,顺便统计了不同脏页率的情况下迁移耗费的时间,以便在探讨实验二cache size对迁移效果的影响时做对比。如下表所示:(横坐标:每秒产生的脏页,单位:M/s。纵标值:迁移耗费的时间,单位:s)


图 2‑4  不同脏页率完成迁移耗费时间统计


从统计图表可以看到不同脏页率下完成迁移大概需要的时间,同时也能反映出脏页率越大,迁移完成所耗费的时间也越长。嗯,这也符合常理。

接下来看实验二:cache size 对迁移效果的影响

由于默认的cache size为64M,以上的测试都是在该默认设置下进行的,这里探讨在其他条件尽可能相同的情况下,对应cachesize 分别为64M、128M、256M和512M时,完成迁移所需时间之间的关系。这里统一设置虚拟机的脏页率为150M/s,测试结果如下图(横坐标:cache size,单位:M。纵标值:迁移耗费的时间,单位:s):

图 2‑5 不同cache size下完成迁移耗费时间统计


从图表可以看出两个重要信息:

1)  cache size越大,迁移所耗费的时间越少,即迁移的效果越好。

2)  当前设置的脏页率为150M/s,远大于实验一中的脏页率,但是迁移所需的时间却远远小于实验一,更能说明cache size对XBZRLE的加持效果。

因此,cache size的合理设置在一定情况下可以提升热迁移的性能。看到图表中cache size在512M时和256M几乎没什么大的提升可能会有疑问,这说明就当前的虚拟机负载256M的cache size就已经完全完全够用了。所以cache size并不是越大越好,要根据虚拟机的负载来合理分配,在迁移性能和资源消耗之间寻求一个最佳平衡。


此外,通过测试发现,为虚拟机分配的cache size对物理服务器的影响很小,因此在迁移过程中如果观测到cache missing过高,调整cache size时可以不用太担心是否会对物理机造成压力,酌情进行分配,坚持够用、不浪费原则即可。


在弄清楚了XBZRLE算法的原理和实际优化效果后,可以根据业务场景按需进行调整。需要说明的是,该算法并不是默认开启的,nova侧提供的热迁移仅仅提供了一个默认p2p + tunnelled的基本迁移方式,若想启用需要指定libvirt的python接口对上提供的VIR_MIGRATE_COMPRESSED宏。该宏在解析到libvirt层时,支持两种压缩算法,如果不具体指定,默认即为XBZRLE。


2.2 auto-converge 



如果说XBZRLE算法的目的是为了减少在网络中传输的数据量,那么auto-converge则是真正从源头上减少数据的生成。

原理


脏页产生的速度太快造成大量页面不能在热迁移设定的宕机时间内完成传输,最终导致虚拟机迟迟不能完成迁移,auto-converge的思想就是:与其扬汤止沸,不如釜底抽薪,既然脏页产生的速度太快了,那咱就让它慢点!减少虚拟机vcpu的执行时间,进而达到减少脏页产生的目的!但是减少vcpu的执行时间,减多少合适,以怎样的策略去处理才可以兼顾性能和灵活性是一个比较复杂的问题,现就现有的实现进行分析。


如果启用了auto-converge功能,在迁移增量数据时,如果产生的脏页数量超过上次传输的50%,默认情况下,QEmu会从削减20%的客户机vcpu执行时间开始。迭代几次后,如果还没有完成迁移,它将重复削减分配给vcpu 10%的运行时间。QEmu会一直削减vcpu直至99%。保证迁移可以在最缓慢的网络中完全完成,但代价就是虚拟机cpu性能被极大消耗。

优化效果测试


本次测试的主要目的是证明使用auto-converge的确可以提升热迁移的成功率。

从上次的测试中知道,在没有开启优化特性的时,即使1M/s的脏页率也不能迁移成功,这里通过开启auto-converge特性,分别在脏页率为1M/s, 10M/s, 100M/s的情况下测试多组数据,剔除毛刺数据后取其平均值。迁移成功的虚拟机耗费时间统计如下:(横坐标:每秒产生的脏页,单位:M/s。纵标值:迁移耗费的时间,单位:s)

图 2‑6 不同脏页率下完成迁移耗费时间统计


图表2‑6 中可以看出,即便脏页率达到100M/s,依然能够迁移成功,说明该功能确实可以提升热迁移的成功率。


此外,通过对比还可以发现,在同一脏页率下,使用auto-converge完成迁移所耗费的时间要远低于XBZRLE。但是在生产环境中我们不推荐按使用该特性,尤其应该避免在CPU和IO密集型的虚拟机上使用,因为auto-converge会不断降低被迁虚拟机的vcpu运行时间,因此可能会造成IO请求延迟,丢包甚至无响应的情况,影响用户体验,甚至正常的业务运行。



3.总结



虽然上述提到的优化特性都能够极大提升热迁移的效率,但是即便使用上述的优化手段也依然无法避免在一些大规格,高负载的场景下面临迁移失败的囧境。因此,完美的技术是不存在的,任何技术都有缺陷,不可能cover的了所有应用场景。譬如上述XBZRLE压缩算法,当一个页面的数据修改超过半数以上时,很明显这种算法带来的优势已经被压缩过程本身给榨干殆尽了;抑或当一个页面改动的数据比较小但是多且分散时,极端的例子比如每隔几个字节修改一两个字节,这种场景下XBZRLE就力不从心了。所以,热迁移过程中没有一劳永逸的解决方案,应该根据业务场景具体分析、灵活搭配、最大化释放各优化特性的潜力。


4.后续




上述介绍的热迁移方案主要应用于负载均衡和故障转移场景下,他们有一个共同点就是:虚拟机需要跨物理节点,这意味着虚拟机迁移时数据需要跨网络传输。文章开头我们提到生产环境中热迁移的另一个重要应用场景就是新功能上线或虚机版本升级,这种情况下热迁移会长时间拥塞网络带宽,这并不是用户所期待的,也不是作为一个有追求的技术人员应该视而不见的!因此,针对这种场景后续我们会推出本地热迁移的解决方案:虚拟机无需跨物理节点、无需占用网络、仅依靠unix socket在本地进行数据的传输,可以数十倍缩短迁移时间,提升迁移效率。给批量、自动化迁移带来极大的可能性。拭目以待吧! 



参考文献


[1]  http://www.slideshare.net/yamahata/yabusame-postcopy-live-migration-for-qemukvm?from_m_app=android

[2]  https://www.slideshare.net/blopeur/enhancing-live-migration-process-for-cpu-andor-memory-intensive-vms-running-enterprise-application-s


往期精选

1

【大云制造】为云而生 - 大云BEK内核

2

【干货分享】BC-MQ大云消息队列高可用设计之谈

3

【干货分享】Kubernetes容器网络之CNI漫谈


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: