【问题标题】:How do I do lots of processing without gobbling cpu?如何在不占用 CPU 的情况下进行大量处理?
【发布时间】:2008-12-21 22:15:17
【问题描述】:

我知道问题标题不是最好的。让我解释一下。

我进行了大量的文本处理,将自然语言转换为 xml。这些文本文件上传得相当快并被放入队列中。从那里它们被一个接一个地拉到后台工作程序中,该工作程序调用我们的解析器(使用 boost 精神)将文本转换为 xml 并将相关部分加载到我们的数据库中。

解析器一次可以执行大约 100 个这样的操作。我在后台工作人员上有限速器,现在只经常轮询我们的队列,因此它的执行速度不那么快。我现在不能抛出多个后台工作人员,因为我的 http 请求开始下降 - 后台工作人员和网络服务器存在于同一台机器上,我相信这是因为 cpu 使用率下降80-95%,虽然我们也可以使用更多的内存。

我需要更好地扩展它。你会怎么做呢?

在回答几个问题时:

  • 我们使用亚马逊网络服务,因此购买廉价的额外硬件与生成一个新的亚马逊实例有点不同——也许有人编写了一些代码来根据负载量自动生成实例?

  • 我们确实有一个 http 服务器,它只是将我们的文件塞入一个队列,所以它受到影响的唯一原因是因为 cpu 正忙于处理大量与解析相关的东西

  • 我已经对我们的后台工作人员进行了速率限制,尽管我们没有在解析器本身中使用它

  • 我还没有尝试过,但我过去使用过它——我需要为此写下一些基准

  • 解析器与 Web 服务器完全分离——我们有 nginx/merb 作为我们的 Web/应用程序服务器,还有一个调用 c++ 的 rake 任务作为我们的后台工作程序——但它们确实存在于同一台机器上

【问题讨论】:

    标签: c++ ruby memory cpu scaling


    【解决方案1】:

    也许只是将后台工作人员置于较低的调度优先级(例如使用nice)会有所帮助。这意味着您的服务器可以在需要时处理请求,但是当它不忙时,您可以全力以赴地处理文本。

    我认为它会给你带来比任意错开后台工作人员更多的好处。

    【讨论】:

    • 正确。使用 100% CPU 是可以的,只要你在其他地方需要它时让出它。仍然会有一些小打击,但不应该是世界末日。
    【解决方案2】:

    我会买几台便宜的电脑,然后对它们进行文本处理。正如 Jeff 在他的 latest post 中所说,“始终尝试首先通过使用更快的硬件来解决性能问题。”

    【讨论】:

    • 我认为该评论在台式计算机类型环境中是有意义的。但是,在许多情况下它没有意义,例如当您需要以便宜的方式构建大量东西(嵌入式系统)和/或便携性(手持设备)或电源(无线)是主要目标时。
    【解决方案3】:

    我不确定我是否完全遵循了您的问题,但听起来您有一个 HTTP 引擎来提供工作待处理队列。正确的?后台线程正在处理这些队列请求并完成繁重的工作,对吗?

    因此,听起来后台进程受计算限制,而前台进程本质上受 I/O 限制……或者至少受新工作提交速率的限制。

    优化此类进程的最佳方法是将后台进程设置为低于前台进程的优先级。这可确保后台进程保持有工作要做。然后设置进程之间的队列深度,使其大小限制为您希望一次待处理的最大工作量。

    【讨论】:

      【解决方案4】:

      如果您有此功能,我做过的一件事就是将这些解析服务移至云托管服务。

      我已将我的一些分布式服务(搜索引擎、群发电子邮件、错误记录)从我的主计算机移到云计算服务上,这对我们的主 Web 服务器来说是一个非常好的负载。

      此外,云计算变得更加便宜,并且几乎可以无限扩展。

      【讨论】:

        【解决方案5】:

        我不明白为什么你会担心你的 CPU 处于 100%。如果需要执行一项工作,并且它不受 IO 限制,那么您的 CPU 应该为 100%。

        剩下的是:

        • 您是否有足够的 CPU 在可用时间内完成所有需要完成的工作?

        如果不是,您需要更多机器、更快的 CPU 或 CPU 效率更高的算法。前两种选择可能比第三种便宜 - 取决于您企业的规模!

        • 是否有一些工作需要比其他工作更具响应性?

        听起来好像有。听起来您希望 HTTP 服务器具有响应性,而解析器作业可以按照自己的速度完成(只要队列清空速度快于填充速度)。正如其他人指出的那样,nice 告诉操作系统分配低优先级进程,在高优先级进程获得所需的 CPU 周期后“剩余”(尽管它并不像那样黑白分明)。

        【讨论】:

          【解决方案6】:

          我假设您有多个线程,每个线程属于两个组之一

          • 下载文本文件的 A 组
          • 将文本转换为 xml 的 B 组

          如果您认为 B 组限制了您的吞吐量,我会将其线程设置为较低的优先级。如果工作量足够,CPU 仍会 100% 使用,但不会影响下载。

          如果我的上述假设是正确的,那么您还应该使用多核和多 cpu 机器,因为您的性能应该可以在更多 CPU 的情况下很好地扩展。

          【讨论】:

          • 如果您继续以较高的速率获取文件,但以较低的速率处理它们,那么溢出队列只是时间问题。
          • 嗯,在达到某个阈值后停止获取新数据应该很明显。问题是数据处理正在从数据采集中占用所有 CPU。如果他们设法将某种自然语言转换为我期望的某种东西,如果陈述不是他们想知道的。
          • 如果队列溢出是一种风险,那么显然您没有能力提供您想要提供的服务:获得更多硬件或更快的算法。限制提交只是承认您无法处理负载。
          【解决方案7】:

          如果您在处理中断请求时遇到问题,您可以尝试提高 CPU 绑定任务的友好度。然后是 HTTP 服务器的好处。基本上,尽量利用系统的调度器来发挥自己的优势,不要把所有任务都一视同仁。

          【讨论】:

            【解决方案8】:

            我不知道您使用的是什么操作系统,但它们中的大多数都具有指定线程/进程优先级的功能。只要解析器进程的优先级低于 HTTP 进程,应该就可以了。

            【讨论】:

              【解决方案9】:

              我会把解析器放在它自己的机器上。这样就不会影响网络服务器。

              如果您没有购买另一台机器的预算,则使用虚拟化(如果您的 Web 服务器托管在 Ubuntu 或 CentOS 上,OpenVZ 很酷)来限制解析器的 CPU 配额。

              【讨论】:

                【解决方案10】:

                永远不要忘记电费/托管价格。尝试使用探查器查找代码中的瓶颈。如果你从来没有这样做过,我相信你可以将 CPU 消耗降低到 25-50%

                【讨论】:

                  猜你喜欢
                  • 2011-11-17
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-11-26
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多