云计算提供了一个极具吸引力的经济实惠的计算平台。用户不再需要购买和配置物理服务器,以及所有相关的时间、精力和前期成本,而只需点击几下鼠标,就可以以每小时不到 10 美分的低廉价格租用云中的“服务器”。云提供商通过提供虚拟机 (VM) 而不是物理计算机来降低成本。关键的推动因素是虚拟化软件,称为虚拟机监控器 (VMM),它模拟物理机器。用户安全地隔离在他们的“客户机”VM 中,并且他们全然不知自己通常与许多其他人共享物理机器(“主机”)。
云对于敏捷组织来说是一种福音。使用物理服务器,用户只能眼巴巴地等待其他人(缓慢地)批准服务器购买、下订单、运送服务器,以及安装和配置操作系统 (OS) 和应用程序堆栈。云用户不再需要等待数周才能获得其他人的交付,而是可以控制整个过程,并在几分钟内创建新的独立服务器。
不幸的是,很少有云服务器是独立的。受快速实例化和按使用付费模型的驱动,云服务器通常是可变池的一部分,该池包含配置相似的服务器,执行与并行计算、数据挖掘或提供网页相关的动态和可扩展任务。由于它们反复从相同的静态模板启动新实例,商业云未能完全兑现真正按需计算的承诺。在实例化服务器后,云用户仍然需要管理集群成员资格并代理新服务器的添加。
SnowFlock 通过 VM 克隆来解决这些问题,这是我们提出的云 API 调用。就像应用程序代码通常通过系统调用接口调用操作系统服务一样,现在它也可以通过类似的接口调用云服务。凭借 SnowFlock 的 VM 克隆,资源分配、集群管理和应用程序逻辑可以在编程中交织在一起,并作为一个单一的逻辑操作处理。
VM 克隆调用实例化多个云服务器,这些服务器是原始父 VM 的完全副本,直到克隆为止。从逻辑上讲,克隆继承了其父级的所有状态,包括 OS 和应用程序级别的缓存。此外,克隆会自动添加到内部私有网络中,从而有效地加入动态可扩展的集群。新的计算资源(封装为相同的 VM)可以即时创建,并可以根据需要动态利用。
为了具有实际用途,VM 克隆必须是可应用的、高效的和快速的。在本章中,我们将描述 SnowFlock 的 VM 克隆实现如何有效地融入多种不同的编程模型和框架、如何实现将应用程序运行时和提供者开销降至最低,以及如何使用它在五秒钟内创建数十个新 VM。
通过 C、C++、Python 和 Java 的绑定,为 VM 克隆提供编程控制的 API,SnowFlock 非常灵活且用途广泛。我们在几个完全不同的系统的原型实现中成功使用了 SnowFlock。在并行计算场景中,我们通过显式克隆协同在多个物理主机上分配负载的工作 VM 来取得了优异的效果。对于使用消息传递接口 (MPI) 并通常在专用的服务器集群上运行的并行应用程序,我们修改了 MPI 启动管理器,为每个运行按需提供一个新的克隆集群,从而为未修改的应用程序提供了良好的性能和更少的开销。最后,在一个完全不同的用例中,我们使用 SnowFlock 来提高弹性服务器的效率和性能。如今的基于云的弹性服务器会根据需要启动新的、冷启动的工作进程来服务需求高峰。通过克隆运行的 VM,SnowFlock 使新的工作进程上线的速度提高了 20 倍,并且由于克隆继承了其父级的热缓冲区,因此它们更快地达到峰值性能。
顾名思义,VM 克隆与其父 VM(几乎)完全相同。实际上,为了避免诸如 MAC 地址冲突之类的問題,存在一些必要的细微差别,但我们稍后会讨论。要创建克隆,必须使整个本地磁盘和内存状态可用,这让我们面临第一个主要的设计权衡:我们应该预先复制该状态还是按需复制?
实现 VM 克隆最简单的方法是调整标准 VM “迁移”功能。通常,当运行的 VM 需要移至不同的主机时,例如当主机变得过载或必须停机维护时,就会使用迁移。由于 VM 纯粹是软件,因此它可以封装在一个数据文件中,然后可以将其复制到新的、更合适的主机,在那里它会在短暂中断后恢复执行。为了实现这一点,现成的 VMM 会创建一个包含 VM “检查点”的文件,包括其本地文件系统、内存映像、虚拟 CPU (VCPU) 寄存器等。在迁移中,新启动的副本会替换原始副本,但该过程可以更改以产生克隆,同时保持原始副本运行。在这个“急切”过程中,整个 VM 状态都会预先传输,这会提供最佳的初始性能,因为 VM 的整个状态在执行开始时就已到位。急切复制的缺点是,在执行开始之前必须完成复制整个 VM 的繁琐过程,这会显着减慢实例化速度。
SnowFlock 采用的另一个极端是“延迟”状态复制。SnowFlock 不会复制 VM 可能需要的所有内容,而是只传输开始执行所需的重要位,并在克隆需要时才传输状态。这有两个优点。首先,它通过在最开始尽可能少地做工作来最大限度地减少实例化延迟。其次,它通过只复制克隆实际使用的状态来提高效率。当然,这种好处的产出取决于克隆的行为,但很少有应用程序访问内存中的每个页面和本地文件系统中的每个文件。
但是,延迟复制的优点并非免费的。由于状态传输被推迟到最后一刻,因此克隆需要等待状态到达才能继续执行。这种情况类似于将内存交换到时间共享工作站的磁盘:应用程序会阻塞,等待从高延迟源获取状态。在 SnowFlock 的情况下,阻塞会在一定程度上降低克隆的性能;减速的严重程度取决于应用程序。对于我们发现这种降级对高性能计算应用程序的影响很小,但克隆的数据库服务器可能在最初的性能很差。需要注意的是,这是一个瞬态效应:在几分钟内,大多数必要的状态都会被传输,并且克隆的性能会与父级的性能相匹配。
顺便说一句,如果您精通 VM,您可能想知道“实时”迁移使用的优化在这里是否有用。实时迁移经过优化以缩短原始 VM 挂起与新副本恢复执行之间的时间间隔。为了实现这一点,虚拟机监控器 (VMM) 会在原始 VM 仍在运行时预先复制 VM 的状态,以便在挂起它之后,只需要传输最近更改的页面。此技术不会影响迁移请求与副本开始执行之间的时间间隔,因此不会减少急切 VM 克隆的实例化延迟。
SnowFlock 使用名为“VM 分叉”的原语实现 VM 克隆,它类似于标准 Unix fork
,但有一些重要的区别。首先,VM 分叉不是复制单个进程,而是复制整个 VM,包括所有内存、所有进程和虚拟设备,以及本地文件系统。其次,VM 分叉不会生成在同一物理主机上运行的单个副本,而是可以同时在多个物理主机上并行生成多个副本。最后,VM 可以分叉到不同的物理服务器,让您根据需要快速增加云的占地面积。
以下概念是 SnowFlock 的关键
我们使用 Xen 虚拟化系统实现了 SnowFlock,因此为了清楚起见,引入一些 Xen 特定的术语很有用。在 Xen 环境中,VMM 被称为管理程序,VM 被称为域。在每台物理机器(主机)上,都有一个特权域,称为“域 0”(dom0),它可以完全访问主机及其物理设备,并且可以用于控制称为“域 U”(domU)的其他客户机或“用户”VM。
总的来说,SnowFlock 包括一组对 Xen 管理程序的修改,使它能够在访问缺失的资源时平滑地恢复,以及一组在 dom0 中运行并协同传输缺失的 VM 状态的辅助进程和系统,以及对克隆 VM 内部执行的操作系统的某些可选修改。主要有六个组件。
mcdist
):这个父级系统可以有效地将 VM 状态信息同时分发给所有克隆。mcdist
按需提供给所有克隆。图 18.1:SnowFlock VM 复制架构
从图示的角度来看,图 18.1 描述了克隆 VM 的过程,显示了四个主要步骤:(1) 挂起父 VM 以生成架构描述符;(2) 将该描述符分发到所有目标主机;(3) 启动大部分状态为空的克隆;以及 (4) 按需传播状态。该图还描述了使用 mcdist
进行多播分发,以及通过客户机启发避免获取。
如果您有兴趣尝试 SnowFlock,它提供两种版本。原始多伦多大学 SnowFlock 研究项目的文档和开源代码1。如果您想尝试工业级版本,GridCentric Inc. 提供免费的非商业许可证2。由于 SnowFlock 包含对 hypervisor 的修改,并且需要访问 dom0,因此安装 SnowFlock 需要在主机上具有特权访问权限。因此,您需要使用自己的硬件,并且不能在商业云环境(例如亚马逊 EC2)中作为用户尝试它。
在接下来的几节中,我们将介绍协同实现即时高效克隆的不同部分。我们将描述的所有部分都如图 18.2所示协同工作。
图 18.2:SnowFlock 的软件组件
SnowFlock 的关键设计决策是将 VM 状态的复制推迟到延迟运行时操作。换句话说,复制 VM 的内存是一个后期绑定操作,可以提供许多优化机会。
执行此设计决策的第一步是生成 VM 状态的架构描述符。这是用于创建克隆 VM 的种子。它包含创建 VM 并使其可调度所需的绝对最小值。顾名思义,此绝对最小值包含底层架构规范所需的数据结构。在 SnowFlock 的情况下,架构是 Intel x86 处理器要求和 Xen 要求的组合。因此,架构描述符包含诸如页表、虚拟寄存器、设备元数据、墙上时钟时间戳等数据结构。我们建议感兴趣的读者参考 [LCWB+11],以深入了解架构描述符内容的描述。
架构描述符具有三个重要属性:首先,它可以在短时间内创建;200 毫秒并不罕见。其次,它很小,通常比原始 VM 的内存分配小三个数量级(对于 1 GB VM,为 1 MB)。第三,可以在不到一秒钟的时间内(通常为 800 毫秒)从描述符创建克隆 VM。
当然,问题是,在从描述符创建克隆 VM 时,它们会丢失大部分内存状态。以下部分将解释我们如何解决这个问题,以及如何利用它带来的优化机会。
克隆 VM 后,它会成为其子级或克隆的父级。像所有负责任的父母一样,它需要照顾其后代的福祉。它通过设置一组服务来实现这一点,这些服务按需为克隆 VM 提供内存和磁盘状态。
创建架构描述符时,VM 会在整个过程中暂停。这样,VM 内存状态就会稳定下来;在实际暂停 VM 并从执行中取消调度之前,内部 OS 驱动程序会静止到一个状态,从该状态,克隆可以在其新的封闭 VM 中重新连接到外部世界。我们利用这种静止状态来创建“内存服务器”或 memserver
。
内存服务器将为所有克隆提供它们从父级需要的内存位。内存以 x86 内存页(4 KB)的粒度进行传播。在最简单的情况下,内存服务器等待来自克隆的页面请求,并一次服务一个页面,一次服务一个克隆。
但是,这是父 VM 继续执行所需的相同内存。如果我们允许父级继续修改此内存,我们将为克隆 VM 提供损坏的内存内容:所提供的内存将不同于克隆时的内存,克隆将非常困惑。用内核破解术语来说,这无疑会导致堆栈跟踪。
为了规避这个问题,一个经典的 OS 概念来解救:写时复制或 CoW 内存。通过借助 Xen hypervisor,我们可以从父 VM 中所有内存页中删除写入权限。当父级实际上试图修改一个页面时,就会触发硬件页错误。Xen 知道发生了什么,并制作了该页面的副本。父 VM 被允许写入原始页面并继续执行,而内存服务器则被告知使用副本,该副本保持只读。以这种方式,克隆时的内存状态保持冻结,以便克隆不会感到困惑,而父级可以继续执行。COW 的开销很小:例如,当创建新进程时,Linux 会使用类似的机制。
克隆通常会受到称为“命运决定论”的生存综合征的影响。我们希望克隆是为了单一目的而创建的:例如,将 X 链的 DNA 与数据库的 Y 段进行比对。此外,我们希望创建一组克隆,以便所有兄弟姐妹都做同样的事情,也许将相同的 X 链与数据库的不同段进行比对,或者将不同的链与相同的 Y 段进行比对。因此,克隆将在其内存访问中表现出大量的时序局部性:它们将使用相同的代码和大量通用数据。
我们通过 mcdist
(我们自己的针对 SnowFlock 量身定制的多播分发系统)利用时序局部性的机会。Mcdist 使用 IP 多播将同一个数据包同时分发给一组接收方。它利用网络硬件并行性来减少内存服务器的负载。通过在第一次请求页面的响应中发送回复到所有克隆,由于克隆具有相似的内存访问模式,因此每个克隆的请求都充当其兄弟姐妹的预取。
与其他多播系统不同,mcdist
不必可靠,不必以有序方式传递数据包,也不必将回复原子地传递给所有预期接收方。多播纯粹是一种优化,并且仅需确保将数据包传递给明确请求页面的克隆。因此,设计简洁优雅:服务器只需多播响应,而客户端如果在请求中未收到回复,则超时并重试请求。
mcdist
中包含三个针对 SnowFlock 的特定优化。
mcdist
服务器会忽略此类请求中的所有请求,除了第一个请求。SnowFlock 克隆由于其短暂的生命周期和命运决定论,很少使用其磁盘。SnowFlock VM 的虚拟磁盘容纳根分区,其中包含二进制文件、库和配置文件。重量级数据处理是通过合适的 文件系统完成的,例如 HDFS 或 PVFS。因此,当 SnowFlock 克隆决定从其根磁盘读取时,它们通常会由内核文件系统页面缓存满足其请求。
话虽如此,我们仍然需要在克隆需要访问磁盘的罕见情况下,为克隆提供访问虚拟磁盘的权限。我们在这里采用了阻力最小的路径,并通过密切遵循内存复制设计来实现磁盘。首先,在克隆时会冻结磁盘状态。父 VM 继续以 CoW 方式使用其磁盘:写入发送到后备存储中的一个单独位置,而克隆期望的磁盘视图保持不变。其次,使用 mcdist
将磁盘状态多播到所有克隆,使用相同的 4 KB 页面粒度,并且在相同的时序局部性期望下。第三,克隆 VM 的复制磁盘状态是严格短暂的:它存储在一个稀疏平面文件中,该文件一旦克隆被销毁就会被删除。
克隆在从架构描述符创建时是空壳,因此和其他人一样,它们需要父母的大量帮助才能成长:子 VM 会搬出去,并在发现缺少某些东西时立即回家,要求父母立即发送过来。
创建后附加到每个克隆的 memtap
进程是克隆的生命线。它映射克隆的所有内存,并根据需要按需填充它。它从 Xen hypervisor 那里获得了重要帮助:克隆的内存页面的访问权限被关闭,并且由第一次访问页面引起的硬件错误由 hypervisor 路由到 memtap
进程中。
在最简单的化身中,memtap
进程只需向内存服务器请求出错的页面,但也有更复杂的情况。首先,memtap
帮助程序使用 mcdist
。这意味着,在任何时候,任何页面都可能由于其他克隆请求而到达——异步预取的魅力。其次,我们允许 SnowFlock VM 是多处理器 VM。否则,就没有什么乐趣了。这意味着需要并行处理多个错误,甚至可能针对同一个页面。第三,在更高版本中,memtap
帮助程序可以显式地预取一批页面,由于 mcdist
服务器没有保证,因此这些页面可以以任何顺序到达。任何这些因素都可能导致并发噩梦,而我们拥有所有这些因素。
整个 memtap
设计以页面存在位图作为中心。当处理架构描述符以创建克隆 VM 时,会创建和初始化位图。位图是一个平面位数组,其大小由 VM 内存可容纳的页面数决定。Intel 处理器有方便的原子位突变指令:设置位,或进行测试和设置,可以保证与同一盒中的其他处理器的原子性。这使我们能够在大多数情况下避免锁定,从而允许不同保护域中的不同实体访问位图:Xen hypervisor、memtap
进程以及克隆的来宾内核本身。
当 Xen 处理由于第一次访问页面而引起的硬件页错误时,它会使用位图来确定是否需要提醒 memtap
。它还使用位图将依赖于同一个缺失页面的多个出错虚拟处理器排队。Memtap 缓冲到达的页面。当它的缓冲区已满或明确请求的页面到达时,VM 会暂停,并且位图用于丢弃任何已到达但已存在的重复页面。然后,将任何剩余的必要页面复制到 VM 内存中,并设置相应的位图位。
我们刚刚提到,克隆内部运行的内核可以看到页面存在位图,并且修改位图不需要锁定。这为克隆提供了强大的“启蒙”工具:它们可以通过修改位图并假装页面存在来阻止页面的获取。从性能方面来看,这样做非常有用,并且在页面在使用之前会被完全覆盖的情况下,这样做是安全的。
这种情况很常见,可以避免获取操作。内核中的所有内存分配(使用 `vmalloc`、`kzalloc`、`get_free_page`、用户空间 `brk` 等)最终都由内核页分配器处理。通常,页面由管理更细粒度块的中间分配器请求:slab 分配器、用户空间进程的 glibc malloc 分配器等。但是,无论是显式分配还是隐式分配,一个关键的语义含义始终成立:没有人关心页面包含的内容,因为它的内容将被任意覆盖。那么为什么要获取这样的页面呢?没有理由这样做,经验表明避免这种获取非常有利。
到目前为止,我们一直关注如何高效地克隆 VM 的内部机制。虽然自我封闭的系统很有趣,但我们需要将注意力转向将使用该系统的用户:应用程序。
VM 克隆通过简单的 SnowFlock API 提供给应用程序,如 图 18.1 所示。克隆基本上是一个两阶段的过程。首先,您请求克隆实例的分配,但由于生效的系统策略,该分配可能小于请求的分配。其次,您使用分配来克隆您的 VM。一个关键的假设是您的 VM 侧重于单个操作。VM 克隆适用于单个应用程序 VM,例如 Web 服务器或渲染农场组件。如果您有 100 个进程的桌面环境,其中多个应用程序同时调用 VM 克隆,那么您将陷入混乱。
sf_request_ticket(n) |
请求 `n` 个克隆的分配。返回一个描述 `m≤n` 个克隆分配的 `ticket`。 |
sf_clone(ticket)
|
使用 `ticket` 分配克隆。返回克隆 `ID`,`0≤ID<m`。 |
sf_checkpoint_parent()
|
准备父 VM 的不可变检查点 `C`,以便在任意时间后创建克隆。 |
sf_create_clones(C, ticket)
|
与 `sf_clone` 相同,使用检查点 `C`。克隆将在调用相应的 `sf_checkpoint_parent()` 的位置开始执行。 |
sf_exit()
|
对于子进程 `(1≤ID<m)`,终止子进程。 |
sf_join(ticket)
|
对于父进程 `(ID = 0)`,阻塞直到 `ticket` 中的所有子进程都到达其 `sf_exit` 调用。此时,所有子进程都被终止,并且 `ticket` 被丢弃。 |
sf_kill(ticket)
|
仅限父进程,丢弃 `ticket` 并立即杀死所有关联的子进程。 |
表 18.1:SnowFlock VM 克隆 API
该 API 只是将消息编组并发布到 XenStore,XenStore 是 Xen 用于控制平面事务的共享内存低吞吐量接口。SnowFlock 本地守护程序 (SFLD) 在管理程序上执行,并侦听此类请求。消息被解编组、执行,并将请求发布回去。
程序可以通过 API 直接控制 VM 克隆,该 API 可用于 C、C++、Python 和 Java。利用程序执行的 shell 脚本可以使用提供的命令行脚本。并行框架(如 MPI)可以嵌入 API:MPI 程序可以使用 SnowFlock,而无需知道,也不需要修改其源代码。位于 Web 服务器或应用程序服务器前面的负载均衡器可以使用该 API 克隆其管理的服务器。
SFLD 协调 VM 克隆请求的执行。它们创建和传输架构描述符,创建克隆的 VM,启动磁盘和内存服务器,并启动 `memtap` 辅助进程。它们是负责管理物理集群中 VM 的小型分布式系统。
SFLD 将分配决策委托给中央 SnowFlock 主守护程序 (SFMD)。SFMD 只与相应的集群管理软件接口。我们没有看到重新发明轮子的必要性,并将资源分配、配额、策略等决策委托给合适的软件,例如 Sun Grid Engine 或 Platform EGO。
克隆后,克隆的 VM 中的大多数进程都不知道它们不再是父进程,并且现在运行在一个副本中。在大多数方面,这很好,不会造成任何问题。毕竟,操作系统的首要任务是将应用程序与底层细节隔离开来,例如网络标识。但是,为了使转换顺利,需要设置一组机制。问题的核心在于管理克隆的网络标识;为了避免冲突和混淆,我们必须在克隆过程中引入一些细微的变异。此外,由于这些调整可能需要更高层的适应,因此会插入一个钩子来允许用户配置任何必要的任务,例如(重新)安装依赖于克隆标识的网络文件系统。
克隆诞生在一个大多没有预料到它们的世界上。父 VM 是一个网络的一部分,该网络最有可能由 DHCP 服务器管理,或者通过系统管理员用来完成工作的无数其他方法之一进行管理。我们没有假设一个必然不灵活的场景,而是将父进程及其所有克隆放置在它们自己的专用虚拟网络中。来自同一个父进程的克隆都被分配了一个唯一的 ID,并且它们在此专用网络中的 IP 地址在克隆时会自动设置为 ID 的函数。这保证了系统管理员不需要干预,并且永远不会发生 IP 地址冲突。
IP 重新配置直接由我们放在虚拟网络驱动程序上的钩子执行。但是,我们也对驱动程序进行了调整,使其自动生成合成 DHCP 响应。因此,无论您选择哪个发行版,您的虚拟网络接口都将确保将正确的 IP 坐标传播到来宾操作系统,即使您是从头开始重新启动。
为了防止来自不同父进程的克隆与彼此的虚拟专用网络发生冲突,并且为了防止相互的 DDoS 攻击,克隆虚拟网络在以太网(或第 2 层)级别被隔离。我们劫持了一系列以太网 MAC OUI 3 并将其专门用于克隆。OUI 将是父 VM 的函数。就像 VM 的 ID 决定其 IP 地址一样,它也决定其非 OUI 以太网 MAC 地址。虚拟网络驱动程序将 VM 认为自己拥有的 MAC 地址转换为根据其 ID 分配的 MAC 地址,并过滤掉所有进出具有不同 OUI 的虚拟专用网络的流量。这种隔离等效于通过 `ebtables` 可以实现的隔离,但实现起来要简单得多。
让克隆只相互通信可能很有趣,但还不够有趣。有时,我们会希望我们的克隆能够回复来自互联网的 HTTP 请求,或者挂载公共数据存储库。我们为任何一组父进程和克隆配备了一个专用的路由器 VM。这个微型 VM 执行从克隆到互联网的流量的防火墙、流量限制和 NAT。它还限制了到父 VM 和知名端口的入站连接。路由器 VM 很轻量级,但它代表了网络流量的单点集中,这会严重限制可扩展性。相同的网络规则可以以分布式方式应用到每个运行克隆 VM 的主机上。我们还没有发布那个实验补丁。
SFLD 分配 ID,并向虚拟网络驱动程序传授它们应该如何配置自己:内部 MAC 和 IP 地址、DHCP 指令、路由器 VM 坐标、过滤规则等。
通过调整 Xen 管理程序并延迟传输 VM 的状态,SnowFlock 可以在几秒钟内生成数十个运行中的 VM 的克隆。因此,使用 SnowFlock 克隆 VM 是瞬时且实时的,它通过自动化集群管理和为应用程序提供对云资源的更大的程序化控制来提高云可用性。SnowFlock 还通过将 VM 实例化速度提高 20 倍,以及通过利用父进程的热内存操作系统和应用程序缓存来提高大多数新创建的 VM 的性能,从而提高云敏捷性。SnowFlock 高效性能的关键在于避免不必要的页面获取的启发式算法,以及允许克隆兄弟姐妹协作预取其状态的多播系统。它所需要的只是巧妙地应用了一些行之有效的技术,一些障眼法,以及大量工业级的调试工作。
我们在整个 SnowFlock 体验中吸取了两个重要的教训。第一个是经常被低估的 KISS 原则的价值。我们原本打算实施复杂的预取技术来缓解克隆在启动时发出的大量内存页面请求。这可能出乎意料,但并非必要。该系统在许多基于单一原则的工作负载中表现良好:根据需要带来内存。页面存在位图也是简单性的价值的另一个例子。一个具有清晰原子访问语义的简单数据结构极大地简化了原本可能是一件可怕的并发问题,多个虚拟 CPU 会争抢页面更新,而页面则会通过多播异步到达。
第二个教训是规模并不在于谎言。换句话说,准备好让你的系统崩溃,并在每次将你的规模提高到 2 的幂时发现新的瓶颈。这与上一课密切相关:简单而优雅的解决方案可扩展性良好,并且随着负载的增加不会隐藏令人不快的意外。这个原则的一个主要例子是我们的 `mcdist` 系统。在大规模测试中,基于 TCP/IP 的页面分发机制对于数百个克隆来说惨败。Mcdist 的成功得益于其极其受限和定义明确的角色:客户端只关心自己的页面;服务器只关心维护全局流量控制。通过保持 `mcdist` 的谦虚和简单,SnowFlock 能够极好地扩展。
如果您想了解更多信息,您可以访问多伦多大学网站 1 获取根据 GPLv2 许可的学术论文和开源代码,以及 GridCentric 4 获取工业级实现。
http://sysweb.cs.toronto.edu/projects/1
http://www.gridcentriclabs.com/architecture-of-open-source-applications
http://www.gridcentriclabs.com/