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

图片

图片

前言python

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


1.热迁移基本概念介绍算法


迁移模型
缓存


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

图片

 1‑1  迁移模型服务器


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


迁移过程
app



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

Pre-copy过程:socket

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中查找,找到了进行异或运算,而后增量传输。若是没找到,则要先将该页面进行缓存(以便下次进行查找、对比),而后再完整的将该页面传输到对端。

优化效果测试


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

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

二、开启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):

image.png

 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漫谈

图片

相关文章
相关标签/搜索