2023-08-07 14:28:42
云计算 借助实时迁移技术,Linode 实例可在不中断服务的前提下在不同物理服务器之间移动。通过实时迁移工具移动 Linode 实例时,迁移过程对 Linode 实例中运行的进程是完全不可见的。这几乎成为一种决定性的技术,也成为云技术和非云技术之间的转折点。本文我们将深入了解这项技术背后的细节。
成都创新互联公司主营头屯河网站建设的网络公司,主营网站建设方案,手机APP定制开发,头屯河h5微信小程序开发搭建,头屯河网站营销推广欢迎头屯河等地区企业咨询
当开发者将工作负载部署到云计算平台时,往往并不需要考虑运行这些服务的底层硬件。在人们对“云” 的理想化印象中,硬件维护和物理限制往往是无形的,然而硬件不可避免需要时不时进行维护,这可能会导致停机。为避免这样的停机时间被转嫁给我们的客户,并真正实现云的承诺,Linode 提供了一种名为实时迁移(Live Migration)的工具。
借助实时迁移技术,Linode 实例可在不中断服务的前提下在不同物理服务器之间移动。通过实时迁移工具移动 Linode 实例时,迁移过程对 Linode 实例中运行的进程是完全不可见的。如果一台主机的硬件需要维护,即可通过实时迁移,将该主机上的所有 Linode 实例无缝转移到另一台主机中。迁移操作完成后,即可开始修理物理硬件,全过程中并不产生会影响到客户的停机时间。
这几乎成为一种决定性的技术,也成为云技术和非云技术之间的转折点。本文我们将深入了解这项技术背后的细节。
为庆祝 Linode 加入 Akamai 解决方案大家庭,现在注册 Linode,就可免费获得价值 100 美元的使用额度,可以随意使用 Linode 云平台提供的各种服务。立即点击这里了解详情并注册吧↓↓↓
出海云服务,Akamai 是您的不二之选!
和大部分新项目类似,Linode 的实时迁移也是这样启动的:进行大量研究,创建一系列原型,获得同事和管理层的大量帮助。我们的第一步是调查 QEMU 如何处理实时迁移。QEMU 是 Linode 使用的一种虚拟化技术,而实时迁移也是 QEUM 的一项功能。因此我们团队的重点是将这项技术引入 Linode,而非重新发明一个类似的技术。
那么实时迁移技术到底是如何以 QEMU 的方式实现的?整个过程分为以下四步:
这些步骤概括介绍了 QEMU 实时迁移的执行过程。然而依然需要通过包含很多手工操作的方式来精确指定目标 QEMU 实例的启动方式。此外,上述过程中的每个操作都必须在正确的时间执行。
在分析过 QEMU 开发者已经实现的技术后,我们该考虑具体用怎样的方式将其实给 Linode。这个答案恰恰是我们工作的重中之重。
在实时迁移工作流程的第 1 步,需要启动目标 QEMU 实例以接受传入的实施迁移连接。在实现这一步时,我们最初的想法是拿到当前 Linode 实例的配置文件,随后将其应用到目标计算机。理论上这应该很简单,但进一步思考就会发现,实际情况要复杂很多。尤其是,配置文件虽然可以告诉我们 Linode 实例是如何启动的,但并不一定可以完整描述启动后的 Linode 实例的完整状态。例如,用户可以在 Linode 实例启动完毕后通过热插拔的方式连接块存储设备,但这种情况并不会记录到配置文件中。
为了在目标主机上创建 QEMU 实例,必须对当前运行的 QEMU 实例进行剖析。我们通过检查 QMP 接口的方式对运行中的 QEMU 实例进行剖析,该接口为我们提供了与 QEMU 实例布局情况有关的丰富信息,但它无法帮助我们从来宾系统的视角了解实例内部正在发生的事情。例如,对于本地 SSD 和块存储,它只能告诉我们磁盘链接到哪里,以及虚拟磁盘连接到哪个虚拟化 PCI 插槽上。在查询 QMP 以及检查并分析了 QEMU 接口后,可以构建一个 Profile 来描述如何在目标位置创建一个完全相同的实例。
在目标计算机上,我们将收到完整的描述信息,借此了解源实例到底是什么样,随后就可以在目标位置忠实重建这个实例,但此时还有一个差异。这个差别主要在于,目标 QEMU 实例在启动时使用了一个选项,该选项可以让 QEMU 接受传入的迁移。
至此,实时迁移的记录过程已经基本结束,接下来需要看看 QEMU 是如何实现这些操作的。QEMU 进程树由一个控制进程和多个工作进程组成,其中一个工作进程负责返回 QMP 调用或处理实时迁移等任务,其他进程需要一对一映射至来宾 CPU。来宾环境与 QEMU 端的功能相互隔离,具体行为类似于独立的系统。
从这个意义来看,我们需要处理三层内容:
目标实例启动并准备好接受传入的迁移后,目标硬件会告知源硬件开始发送数据。源端会在收到这个信号后开始进行处理,并会在软件中告知 QEMU 开始传输磁盘内容。软件会自主监控磁盘传输进度,借此检查传输操作是否完成,并会在磁盘传输完成后自动开始迁移内存内容。此时软件依然会自主监控内存迁移进度,并在内存迁移完毕后自动切换至割接模式。上述全过程都是通过 Linode 的 40Gbps 网络进行的,因此网络方面的操作都可以快速完成。
割接操作是实时迁移过程中最重要的一环,只有理解了它,才能完全理解实时迁移操作。
在割接点状态下,QEMU 已经确认做好了所有准备,可以进行割接并在目标计算机上运行。源 QEMU 实例会让两端暂停运行,这意味着:
由于时间和网络请求均已停止,我们希望割接能尽量快速完成。然而为保证成功割接,还需要进行一些检查:
由于割接过程时间有限,我们希望能尽快完成上述操作。解决了这些问题后,即可继续进行割接了。源 Linode 实例会自动会自动收到 “割接完成” 信号并让目标实例运行起来。目标 Linode 实例会从源实例暂停时的状态恢复运行。源和目标实例上的其余内容则会被清理。如果目标 Linode 实例在未来某个时间需要再次进行实时迁移,则会重复执行上述步骤。
实时迁移的大部分过程都是直接实现的,但考虑到边缘案例后,该功能本身的开发也进行了大量扩展。这个项目的顺利完成很大程度上要归功于管理团队,他们坚信该工具有着极大的愿景,并提供了完成该任务所需的各项资源,另外当然也离不开坚信该项目能够成功完成的大量员工。
我们在下列这些领域遇到了很多边缘案例:
在向来宾操作系统呈现 CPU 方面,QEMU 有不同的选项。其中一个选项可将主机 CPU 的型号和功能(即 CPU 标记)直接传递给来宾系统。通过使用该选项,来宾即可不受约束地使用 KVM 虚拟化系统所支持的全部能力。当 Linode 首次采用 KVM 时(当时还没有实时迁移功能),为了实现最大化性能,我们就使用了该选项。然而在开发实时迁移功能的过程中,该选项为我们造成了很多挑战。
在实时迁移的测试环境中,源和目标主机是两台完全相同的计算机。但在现实世界中,我们的硬件集群并非 100% 完全相同的,计算机之间的某些配置差异可能导致产生不同的 CPU 标记。这很重要,因为当一个程序被载入 Linode 的操作系统后,Linode 会向该程序呈现 CPU 标记,为了充分利用这些标记,程序可以将软件中的特定部分载入内存。如果一个 Linode 实例被实时迁移到不支持该 CPU 标记的目标计算机,程序将会崩溃。这可能导致来宾操作系统崩溃,甚至导致 Linode 重启动。
我们发现有三个因素会影响到计算机的 CPU 标记如何呈现给来宾系统:
因此在实现实时迁移时,我们必须设法防止程序因为 CPU 标记的不匹配而崩溃。可行的选项有两个:
在决定对源和目标的 CPU 标记进行匹配后,我们使用下列两种方法的组合最终实现了目标:
第二种方法必须能快速执行,并且让我们的工作变得更复杂。某些情况下,我们需要针对超过 900 台计算机检查最多 226 个 CPU 标记。为所有这 226 个 CPU 标记编写检查代码本就很困难,而这些代码还需要不断进行维护。但 Linode 的创始人 Chris Aker 提出的一个惊人想法最终解决了这个问题。
方法的关键在于为所有 CPU 标记创建一个列表,并将其表示为一个二进制字符串。随后,可以使用 Bitwise and(“按位与”)运算来对比字符串。我们可以用下面这个简单的例子来演示这个算法。下面这段 Python 代码可以使用 “按位与” 对比两个数:
>>> 1 & 1
1
>>> 2 & 3
2
>>> 1 & 3
1
要理解为何“按位与” 运算能产生这样的结果,首先需要将数字用二进制形式表示。一起看看十进制的“2” 和“3” 在用二进制形式表示的情况下,“按位与” 是如何处理的:
>>> # 2: 00000010
>>> # &
>>> # 3: 00000011
>>> # =
>>> # 2: 00000010
“按位与” 会对比二进制的“数”,也就是两个不同数字中的“位”。该操作会从上述数字最右边的位开始向左处理:
因此完整结果的二进制表示就是 00000010,也就是十进制的 “2”。
对于实时迁移,CPU 标记完整列表会表示为一个二进制字符串,其中每一位都代表一个标记。如果一个位为 “0”,代表对应的标记不存在;如果某个位为“1”,则代表标记存在。例如,一个位可以代表 AES 标记,另一个位可以代表 MMX 标记。这些标记在二进制字符串中的位置会维护并记录在案,随后用于我们数据中心内的所有计算机。
相比维护一组 if 语句来检查某个 CPU 标记是否存在,这种列表的维护工作无疑更简单也更高效。例如,假设总共需要追踪并检查 7 个 CPU 标记,这些标记可以存储在一个 8 位数字中(多出的一位供未来进行扩展)。例如这样的字符串可能类似于 00111011,最右侧的一位代表 AES 已启用,右数第二位代表 MMX 已启用,右数第三位代表其他标记已启用,以此类推。
在下文的代码片段中,我们可以看到哪些硬件支持这些标记的组合,这段代码可以在一个周期内返回所有匹配的结果。如果用一组 if 语句进行对比,则需要更多周期才能获得所需结果。如果进行实时迁移的源计算机包含 4 个 CPU 标记,这种情况下就需要 203400 个周期才能找到匹配的硬件。
实时迁移操作会在源和目标计算机上针对 CPU 标记字符串执行 “按位与” 操作。如果两个计算机的 CPU 标记字符串运算结果相等,意味着目标计算机是兼容的。该过程可参考下列 Python 代码片段:
>>> # The b'' syntax below represents a binary string
>>>
>>> # The s variable stores the example CPU flag
>>> # string for the source:
>>> s = b'00111011'
>>> # The source CPU flag string is equivalent to the number 59:
>>> int(s.decode(), 2)
59
>>>
>>> # The d variable stores the example CPU flag
>>> # string for the source:
>>> d = b'00111111
>>> # The destination CPU flag string is equivalent to the number 63:
>>> int(d.decode(), 2)
63
>>>
>>> # The bitwise and operation compares these two numbers:
>>> int(s.decode(), 2) & int(d.decode(), 2) == int(s.decode(), 2)
True
>>> # The previous statement was equivalent to 59 & 63 == 59.
>>>
>>> # Because source & destination == source,
>>> # the machines are compatible
请注意,在上述代码片段中,目标计算机比源计算机支持更多的标记。此时可以认为目标计算机是兼容的,因为源的所有 CPU 标记都已包含在目标计算机中,这一点可以由 “按位与” 运算提供保证。
我们的内部工具可以使用上述算法得到的结果为可兼容的硬件构建一个列表。该列表会展示给我们的客户支持和硬件运维团队,这些团队可以使用我们的内部工具来编排不同的运维任务:
仅仅为了让软件能够“跑起来”,就需要进行大量的开发工作……
软件领域有一个话题很少被人讨论:优雅地处理失败。软件至少应该能够“跑起来”。为了实现这一点,往往需要进行大量开发工作,实时迁移功能的开发也是如此。我们花了很多时间考虑如果该工具无法正常运行要怎么办,以及该如何优雅地处理这种情况。我们考虑了很多场景,并确定了具体的应对方式:
o 解决方法:客户完全可以这样做。实时迁移会被打断,无法继续处理。这种处理方法是合适的,因为实时迁移可以稍后重试。
o 解决方法:通知源硬件,通过专门设计的内部工具在数据中心内自动选择另一个硬件。此外还将通知运维团队,以便调查失败的目标硬件。这种情况曾在生产环境中发生过,我们的实时迁移可以顺利应对。
o 解决方法:自主监测实时迁移进度,如果过去一分钟内没有产生任何进展,将会取消实时迁移并通知运维团队。这种情况在测试环境之外从未发生过,但我们也针对这种场景做好了充分准备。
o解决方法:如果实时迁移未进行到关键环节,将停止实时迁移,并在稍后重试。
o如果已进行到关键环节,则将继续迁移。这一点很重要,因为源 Linode 已被暂停,目标 Linode 需要处于启动状态才能继续恢复操作。
这些场景都已在测试环境中进行了模拟,我们认为上述行为也是不同情况下的最佳应对措施。
成功进行了数十万次实时迁移后,我们不免会考虑:“实时迁移的开发工作何时才能结束?” 随着时间推移,实时迁移这项技术的使用范围会越来越广,并且会不断完善,因此该项目似乎会永远持续下去。回答这个问题的一种方法是考虑该项目的大部分工作什么时候会结束。答案也很简单:为了获得可靠、可信赖的软件,我们的工作还将持续很久。
随着时间推移,Linode 会增加新的功能,我们也许要继续努力保证实时迁移可以兼容这些功能。引入某些新功能时,可能无需围绕实时迁移执行新的开发工作,但我们可能依然需要测试该功能是否可以按照预期正常工作。对于某些功能,则可能需要在开发的早期阶段,针对实时迁移进行必要的兼容性测试和相关工作。
和其他几乎所有软件类似,对于同一件事,通过不断研究,总能发现更好的实现方法。例如,从长远来看,为实时迁移功能开发更多模块化的集成方法,无疑可以降低维护负担。或者我们甚至可能将实时迁移的相关功能纳入到底层代码中,从而使其成为 Linode 一项拆箱即用的功能。
我们的团队已经考虑过所有这些选项,并且坚信驱动 Linode 平台的工具是活跃的,还会继续努力,使其不断进化和发展。
这篇文章的内容感觉还行吧?有没有想要立即在 Linode 平台上亲自尝试一下?别忘了,现在注册可以免费获得价值 100 美元的使用额度,快点自己动手体验本文介绍的功能和服务吧↓↓↓
出海云服务,Akamai 是您的不二之选!
欢迎关注 Akamai ,第一时间了解高可用的 MySQL/MariaDB 参考架构,以及丰富的应用程序示例。
网站标题:Linode实时迁移详解
本文来源:http://www.mswzjz.com/qtweb/news16/191966.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联