【问题标题】:Engineering scalability into an application应用程序的工程可扩展性
【发布时间】:2009-07-02 12:38:49
【问题描述】:

这意味着什么 - 将可扩展性工程化到应用程序中。是否存在可以使应用程序更具可扩展性的设计模式?这个问题主要是在 Web 应用程序或基于 SOA 中间件的应用程序的上下文中。

【问题讨论】:

    标签: scalability


    【解决方案1】:

    当我想到“大规模应用”时,我想到了三件截然不同的事情:

    1. 将跨大型横向扩展集群(远大于 1024 个内核)运行的应用程序。

    2. 将处理比物理内存大得多的数据集的应用程序。

    3. 具有非常大的代码源库的应用程序。

    每种“可扩展性”都会带来不同的复杂性,并需要不同的折衷方案。

    横向扩展应用程序通常依赖于使用 MPI 来协调各种进程的库。一些应用程序是“令人尴尬的并行”,并且需要在不同进程之间进行很少(甚至不需要)通信以完成任务(例如渲染动画电影的不同帧)。这种风格的应用程序往往会受到基于 CPU 时钟频率或内存带宽的性能限制。在大多数情况下,添加更多内核几乎总是会增加应用程序的“可扩展性”。其他应用程序需要不同进程之间的大量消息流量,以确保解决方案取得进展。这种风格的应用程序往往会受到节点之间互连的整体性能的限制。这些消息密集型应用程序可能受益于非常高的带宽、低延迟的互连(例如 InfiniBand)。这种应用程序的工程可扩展性始于最小化所有进程对共享文件或资源的使用。

    第二种可扩展风格是在少量服务器(包括单个 SMP 风格服务器)上运行的应用程序,但要处理非常大的数据集或大量事务。向系统添加物理内存通常可以提高应用程序的可扩展性。但是,在某些时候,物理内存将被耗尽。在大多数情况下,性能瓶颈将与系统的磁盘 I/O 性能有关。在这些情况下,添加高性能持久存储(例如剥离的硬盘驱动器阵列),甚至向某种 SAN 添加高性能互连可以帮助提高应用程序的可扩展性。这种应用程序的工程可扩展性从算法决策开始,该决策将最大限度地减少重复接触相同数据(或设置相同基础设施)的需要,而不是完成任务所需的次数(例如,打开与数据库的持久连接,而不是打开每个事务的新连接)。

    最后,还有与源代码库的整体大小相关的可扩展性的情况。在这些情况下,良好的软件工程实践可以帮助最大限度地减少冲突,并保持代码库的清洁。 Large Scale C++ Software Design 这本书是我遇到的第一本书,它真正接受了为大型源代码库软件开发提供最佳实践的挑战。本书侧重于将 C++ 作为实现语言,但指南和实践可以应用于任何项目或语言。这种应用程序的工程可扩展性涉及对代码结构做出高级决策,以最大限度地减少代码库中的依赖关系(例如,没有一个 .h 在更改时会强制重建整个代码库,使用构建尽可能重用 .o 的系统)。

    【讨论】:

      【解决方案2】:

      从广义上讲,可扩展性意味着系统负载的增加可以通过相应地减少为服务负载而必须编组的资产的增加来处理。

      如果您的网络应用程序的负载增加了 100 倍,您会怎么做?

      可扩展性的一个基本原则是识别和消除处理中的潜在瓶颈,包括限制任务的并行化。但这只是一种味道;我相信你会得到很多其他同样有效的答案。

      编辑:请注意,瓶颈不仅发生在实际的任务处理中。它们可以是整体流程设置、必要的硬件操作、维护任务、重新设计/重构,应有尽有。

      【讨论】:

      • 这是事实,但是,当显着降低系统负载时,可扩展性也是一个问题。您可能经常在系统中“缩减”时遇到性能问题。因此,广义上的可扩展性与资源或客户数量的增减变化有关。
      【解决方案3】:

      以下是一些关于 Web 应用程序可扩展性的重要资源,可帮助您入门:Todd Hoff 的 highscalability.com、Theo Schlossnagle 的 Scalable Internet Architectures 和 Cal Henderson 的 Building Scalable Web Sites。 Highscalability.com 会为您指出许多值得一读的演示文稿和文章,包括 this one from Danga 关于他们如何在 LiveJournal 的发展过程中对其进行扩展。

      【讨论】:

        【解决方案4】:

        我认为当您谈论网络时,您主要关心的是:

        • 对您的代码进行分区,以便在必要时沿多个服务器垂直划分(针对一个请求)。
        • 调整您的代码,使所有数据(尤其是会话数据)都保存在某种全局存储(如数据库)中,而不是本地保存在文件系统中。
        • 负载平衡。

        这样,您可以将一台服务器扩展到任意多个层(应用层、缓存层、数据库层),并在出现扩展问题时水平扩展这些层。

        【讨论】:

          【解决方案5】:

          可扩展性意味着如果负载/数据可以通过某个度量 N 来衡量,即用户数、每天完成的事务总数等,并具有一些固定的响应要求 t,则可以重新配置应用程序以处理任意 N 给定 O(f(n)) 的资源增加,其中 f(n) 是 N 在相同响应时间 t 内的线性或接近线性函数。

          通常这意味着应用程序使用分布式架构,以便可以线性添加更多服务器、应用程序服务器、Web 服务器、数据库服务器以处理更多用户。 IE。要处理两倍的用户,您需要添加两倍的数据库服务器、网络服务器、机器等。

          即使在理论上这通常也是不可能的,因为分发请求通常需要树状结构,因此缩放因子为 O(n * log(N))。在实践中,由于可以在树中使用较大的分支因子,并且分配成本与整体事务成本相比较小,因此 log(N) 因子并不显着。

          【讨论】:

            猜你喜欢
            • 2011-05-29
            • 2015-05-25
            • 2011-03-28
            • 1970-01-01
            • 2014-09-13
            • 2014-12-28
            • 2011-07-09
            • 2012-07-30
            • 2011-12-26
            相关资源
            最近更新 更多