提高 mod_perl 网站性能:第1部分

在接下来的文章系列中,我们将讨论 mod_perl 性能问题。我们将尽可能多地查看由 mod_perl 驱动的服务的各个方面:硬件、软件、Perl 编码以及最终 mod_perl 特定的方面。

全景图

为了尽可能让用户的网页浏览体验痛苦最小,必须尽最大努力从服务器中榨取最后一滴性能。有许多因素会影响网站的可用性,但速度是最重要的因素之一。这适用于任何 Web 服务器,而不仅仅是 Apache,因此了解这一点非常重要。

我们如何衡量服务器的速度?由于用户(而不是计算机)是与网站互动的人,因此一个好的速度测量方法是点击链接或按下 提交 按钮的那一刻到结果页面完全渲染的那一刻之间经过的时间。

请求和回复被分成数据包。一个请求可能由几个数据包组成;回复可能有成千上万个。每个数据包都必须从一个机器传输到另一个机器,可能需要通过许多互连节点。我们必须测量从请求的第一个数据包离开用户的机器到回复的最后一个数据包返回到那里所经过的时间。

Web 服务器只是数据包在传输过程中遇到的实体之一。如果我们从浏览器到服务器再返回,那么它们可能通过许多不同的实体以不同的路径传输。在数据包被您的服务器处理之前,它们可能需要通过代理(加速器)服务器,如果请求包含多个数据包,则数据包可能通过不同的路径以不同的到达时间到达服务器。因此,可能有一些到达较早的数据包需要等待其他数据包,然后才能重新组合成请求消息的一部分,然后由服务器读取。然后整个过程反过来重复。

您可以努力调整 Web 服务器的性能,但如果网络接口卡(NIC)或服务器与网络之间的连接缓慢,则可能白费力气。这就是为什么考虑整个情况并意识到服务器和 Web 之间可能的瓶颈非常重要。

当然,如果用户连接速度慢,您几乎无能为力。您可能需要调整脚本和 Web 服务器以快速处理传入的请求,因此您只需要少量工作服务器,但您可能会发现服务器进程都在忙于等待慢速客户端接受它们的响应。

但是有技术可以应对这种情况。例如,您可以压缩响应。如果您提供的是纯文本响应,那么 gzip 压缩有时可以将响应大小减少 10 倍。

当您试图为用户提供最佳服务时,应该分析所有涉及的组件,而不仅仅是 Web 服务器或 Web 服务器执行的代码。Web 服务就像一辆汽车:如果某个部件或机制损坏,则汽车可能无法平稳运行,并且如果未修复而过度推挤,则汽车甚至可能完全停止。

让我再次强调:如果您想在 Web 服务业务中取得成功,那么您应该开始关注客户的浏览体验,而不仅仅是您的代码基准有多好。

操作系统和硬件分析

本系列之前的文章

寻找 mod_perl ISP...或者成为一家 ISP

您需要知道的 Perl - 第3部分

你需要知道的Perl - 第2部分

你需要知道的Perl

无需超级用户权限安装mod_perl

30分钟学会mod_perl

为什么选择mod_perl?

在开始优化服务器配置和学习编写更高效的代码之前,你需要考虑硬件和操作系统将会面临的需求。在你一开始没有选择合适的平台的情况下,花很多时间和金钱在配置调整和代码优化上,发现服务器的性能不佳是没有意义的。

由于硬件平台和操作系统正在快速发展(甚至在你阅读这篇文章的时候),以下建议性讨论必须是通用的,不提及特定供应商的名称。

选择合适的操作系统

我将尝试讨论你应寻找哪些特性和功能来支持启用了mod_perl的Apache服务器,然后当你知道你从你的OS中需要什么时,你可以出去找到它。访问你感兴趣的操作系统网站。你可以通过搜索新闻组和邮件列表档案中的相关讨论来衡量用户的观点。Deja - http://deja.com 和 eGroups - http://egroups.com 是很好的例子。我将把这个粉丝研究留给你。但最好的办法可能是向mod_perl用户提问,因为他们知道得最多。

稳定性和鲁棒性需求

一个操作系统最重要的特性可能是稳定性和鲁棒性。你从事的是互联网业务。你不像传统企业那样保持正常的上午9点到下午5点的工作时间。你24小时开放。你不能承受离线的代价,因为你的客户会去另一个服务(除非你有垄断……)。如果你选择的操作系统每天崩溃,那么首先进行一点调查。可能有一个简单的理由你可以解决。有些操作系统除非你每天重启两次,否则无法工作。你不想使用这种类型的操作系统,不管操作系统的供应商销售部门有多好。不要跟随花哨的广告;而是遵循开发者的建议。

一般来说,使用该操作系统一段时间的人可以告诉你很多关于其稳定性的信息。问问他们。尽量找到在做类似事情的人,他们甚至可能在使用相同的软件。经常会有兼容性问题要解决。你可能需要熟悉修补和编译你的操作系统。

良好的内存管理的重要性

你希望有一个有良好内存管理实现的操作系统。有些操作系统因其内存消耗者而闻名。相同的代码在一个操作系统上可能比另一个操作系统多使用两倍的内存。如果mod_perl进程的大小是10Mb,并且你运行了数十个这样的进程,那么这绝对会累积起来!

拒绝内存泄漏

一些操作系统及其库(例如C运行时库)存在内存泄漏问题。泄漏是指某个进程请求一块内存进行临时存储,但随后没有释放它。这块内存直到请求它的进程死亡,不再可用于任何目的。你无法承受这样的泄漏。单个mod_perl进程有时在终止之前会服务数千个请求。所以如果每个请求都发生泄漏,那么内存需求可能会变得巨大。当然,你的代码也可能导致内存泄漏,但这很容易检测和解决。当然,我们可以减少在进程生命周期内需要服务的请求数量,但这可能会降低性能。

内存共享能力是必需的

您需要一个具有良好内存共享功能的操作系统。如果您在服务器启动时预加载Perl模块和脚本,那么它们将在生成的子进程之间共享(至少在进程生命周期的某个部分——内存页面可以变成“脏”并停止共享)。这个功能可以大幅减少内存消耗!

当然,您不希望使用一个没有内存共享功能的操作系统。

支持的真正成本

如果您是一家大公司,那么您可能不会介意再支付1000美元购买一些带有捆绑支持的精美操作系统。但如果您的资源有限,那么您会寻找更便宜或免费的操作系统。免费并不意味着不好,有时恰恰相反。免费操作系统可以拥有您能找到的最好的支持。有些确实如此。

这很容易理解——大多数人都不富裕,如果操作系统能完成他们的工作,他们就会首先尝试使用更便宜或免费的操作系统。由于它确实符合他们的需求,许多人继续使用它,并最终足够了解它,能够为遇到麻烦的人提供支持。他们为什么要免费做这件事呢?一个原因是出于互联网初期的精神,当时没有商业互联网,人们互相帮助,因为有人首先帮助他们。我就在那里,我被那种精神所感动,我渴望保持这种精神。

但是,让我们回到现实世界。我们生活在一个物质世界,我们的老板付钱给我们以保持系统运行。因此,如果您觉得自己无法提供支持,并且您不信任现有的免费资源,那么您必须为一家公司支持的操作系统的支持付费,并对任何问题进行指责。您的老板希望能够在项目中由于使用的外部产品导致的问题时起诉某人。如果您购买了一个产品,并且销售该产品的公司声称提供支持,那么您就有某人可以起诉或至少可以指责。

如果我们选择开源软件,它失败了,我们也没有人可以起诉……错误——在过去的几年里,许多公司已经意识到开源产品的优点,并开始为这些产品提供官方支持。所以您的老板不能轻易地拒绝您使用开源操作系统的建议。您可以像使用任何其他商业操作系统供应商一样获得付费支持。

还要记住,您在操作系统和软件上的花费越少,您就越能在更快、更强大的硬件上投入更多。当然,对于一些公司来说,钱不是问题,但对于许多公司来说,这是一个重大问题。

哎呀……停售的产品

这个危险组中的操作系统往往由一家公司或组织开发。

您可能会发现自己处于这样的境地:您已经投入了大量的时间和金钱来开发与您选择的操作系统捆绑的一些专有软件(例如编写一个利用操作系统某些专有功能的mod_perl处理程序,该处理程序将无法在其他操作系统上运行)。一切都在控制之中,性能很棒,您在工作路上唱着快乐的歌曲。然后,有一天,供应您心爱操作系统的公司破产了(现在这种情况并不罕见),或者他们生产了一个不兼容的新版本,并且不会支持旧版本(这种情况经常发生)。您被困在了他们的早期杰作中,没有支持,也没有源代码!您该怎么办?投入更多的钱将软件移植到另一个操作系统……

免费和开源的操作系统可能不太容易受到这种问题的困扰。开发通常由许多公司和开发者分担。因此,如果一个开发了内核重要部分的人失去了兴趣,那么另一个人会接手这个任务继续下去。当然,如果明天有更好的项目出现,开发者可能会迁移到那里,最终停止开发。但在实践中,人们通常会得到对旧版本的支持,并帮助他们迁移到当前版本。开发通常是渐进的,而不是革命性的,所以升级不会那么痛苦,而且通常会有很多关于即将到来的变化的预告,这样你就有时间为此做准备。

当然,在开源操作系统中,你可以拥有源代码!所以你总是可以自己尝试,但不要低估其中所需的工作量。操作系统中包含了成千上万的人年工作量。

跟上操作系统版本发布

积极开发的操作系统通常会努力跟上最新的技术发展,并不断优化内核和操作系统的其他部分,使其变得更好、更快。如今,互联网和一般网络是系统开发者最热门的话题。有时候,将操作系统升级到最新稳定版可以节省你昂贵的硬件升级费用。另外,记得当你购买新硬件时,最新的软件可能会最大限度地利用它。

如果一个新产品通过与同一系列先前产品的向后兼容性支持旧产品,那么你可能无法获得新产品所有功能的全部好处。也许如果你购买该产品较老型号,你几乎可以得到相同的功能,而花费却少得多。

选择合适的硬件

有时最昂贵的机器并不一定是提供最佳性能的那个。你对平台硬件的要求基于许多方面,并影响许多组件。让我们讨论其中的一些。

在讨论中,我会使用你可能会不熟悉的术语

  • 集群:一组连接在一起以在合理时间内完成一个大或多个小计算任务的机器。集群还可以用于提供“故障转移”,即如果一台机器出现故障,其进程将转移到另一台机器,而不会中断服务。你还可以将一台机器关闭进行维护(或升级),同时保持你的服务运行——主要服务器将不会将请求发送到已关闭的机器。
  • 负载均衡:用户被分配到你的其中一台机器,但它可能无法承受重负载。你可以使用集群方法将负载分配到多台机器上。用户最初访问的是中央服务器,它作为分发器工作,只是将请求重定向到其他机器。有时中央服务器还会收集结果并将它们返回给用户。你还可以获得集群的优势。
  • 网络接口卡(NIC):允许你将机器连接到网络的硬件组件。它执行数据包的发送和接收,较新的卡可以加密和解密数据包,并执行数字签名和验证。这些卡有不同的速度类别,从10Mbps到10Gbps甚至更快。最常用的NIC卡是实现以太网网络协议的卡。
  • 随机存取存储器(RAM):这是你电脑中的内存。(单位为8Mb、16Mb、64Mb、256Mb等。)
  • 廉价磁盘阵列 (RAID):一组物理磁盘,通常被操作系统视为单个磁盘处理,并且通常由硬件强制实现这种效果。使用RAID的原因通常是为了实现高速数据传输,但也可能是为了获得足够的磁盘容量或高可靠性。冗余意味着即使在磁盘发生故障的情况下,系统仍能继续运行。RAID阵列有各种类型,以及实现它们的不同方法。一些系统提供对多个驱动器故障的保护,而一些(“热插拔”)系统允许在不停止操作系统的情况下更换驱动器。

根据预期网站流量所需的机器性能

如果你正在建立一个粉丝网站,并且你想用mod_perl留言板让你的朋友们感到惊讶,那么任何旧的486机器都可以做到。如果你从事严肃的业务,那么构建一个可扩展的服务器很重要。如果你的服务成功并且变得流行,那么流量可能会每几天翻一番,你应该准备好添加更多资源来满足需求。虽然我们可以更精确地定义Web服务器的可扩展性,但重要的是要确保你可以在不投入大量额外软件开发资金的情况下添加更多功率到你的 webserver(s)(如果你添加更多的服务器,你将需要一些软件工作来连接你的服务器)。这意味着你应该选择可以与其他机器通信并成为集群一部分的硬件和操作系统。

另一方面,如果你为大量流量做好准备,并购买一台巨型机器来为你工作,那么如果你的服务没有像你想象的那样成功,会发生什么?那么你浪费了太多的钱,同时更快的核心和其他硬件组件已经发布;所以你失败了。

智慧和预言,这就是全部 :)

单一强大机器与多台较弱机器

让我们从一个断言开始,即4年前的处理器仍然强大并且可以得到很好的使用。现在让我们说,对于一定数量的钱,你可能会买一台非常强大的新机器,或者大约10台较旧但非常便宜的机器。我主张,通过将10台旧机器连接成集群并部署负载均衡,你将能够处理比一台单机多五倍的服务请求。

为什么是这样?因为一般来说,新机器的性能提升微乎其微,而价格却很高。10台机器将进行比一台单机更快的磁盘I/O操作,即使新磁盘相当快。是的,你有更多的管理开销,但你仍然有可能拥有它,因为不久后你刚刚购买的新机器可能无法承受负载。然后你将不得不购买更多的设备,并考虑如何实现负载均衡和Web服务器文件系统分布。

为什么我这么确信?看看互联网上最繁忙的服务:搜索引擎、Web/电子邮件服务器等——它们中的大多数都使用集群方法。你可能并不总是注意到它,因为它们将真实的实现细节隐藏在代理服务器后面。

获得快速互联网连接

你有了最好的硬件,但服务仍然很慢。确保你有快速的互联网连接。不要像你的ISP声称的那样快,但要快到应该有的程度。ISP可能有一个很好的互联网连接,但将许多客户端放在同一条线上。如果这些是重量级客户端,那么你的流量将不得不共享同一条线,你的吞吐量将受到影响。考虑一个专用连接,并确保它真正是专用的。不要信任ISP,检查它!

连接到互联网的想法有点误导。许多网站托管和机架托管公司有大量的带宽,但仍然有糟糕的连接。公共交换,如MAE-East和MAE-West,经常过载,但许多ISP仍然依赖这些交换。

私有对等意味着提供商可以更快地交换流量。

此外,如果你的网站对全球有影响,请确认ISP有良好的全球连接。如果网站将要被某个国家或地区的人大量访问,那么你的服务器可能应该放在那里。

糟糕的连接会直接影响你的机器性能。以下是一位开发者曾在mod_perl邮件列表上讲述的故事

10%的包丢失在上游提供商有什么关系和机器内存有什么关系?

是的……很多。在一周噩梦期间,盒子位于一个自己带宽问题严重的提供商的下游……人们通过这个链接连接到网站,包丢失如此严重,以至于重新传输和TCP停滞让httpd重量级应用比正常情况下持续更长的时间……他们不会以高速度甚至调制解调器速度发送数据,而是会卡在1k/秒或停滞不前……人们会按停止并刷新,httpd在写入时超时需要300秒,但没有人响应……这是一个噩梦。这些问题直到我把盒子移到一个靠近一些良好主干的地方才消失。

注意,如果有代理,这只会让轻量级httpd被占用,假设页面足够小可以放入缓冲区。如果你是一个繁忙的互联网网站,那么你总是有一些慢速客户端。这在基准测试中很难模拟。

调整I/O性能

如果你的服务是I/O密集型(在磁盘上执行大量读写操作),那么你需要一个非常快的硬盘,尤其是如果你需要关系型数据库,它们是主要的I/O流创建者。因此,你不应该花钱在显卡和显示器上!一张便宜的卡和一台14英寸的单色显示器对于Web服务器来说就足够了;你可能会用telnetssh来访问它的大多数时间。寻找性价比最高的硬盘。当然,四处询问,避免那些因磁头碰撞和其他灾难而有坏名声的硬盘。

如果你有一个巨大的数据集要服务(现在什么是巨大的数据集?千兆字节、太字节?)或者你预计会有非常大的网站流量,那么你必须考虑RAID或类似的系统。

好的,你有一个快速的硬盘,接下来是什么?你需要一个快速的硬盘控制器。可能有一个集成在计算机的主板上。如果控制器不够快,那么你应该买一个更快的。别忘了可能需要禁用原始控制器。

内存多少才算足够?

你需要多少RAM?现在,你可能会听到:“内存很便宜,买的越多越好。”但是多少才算足够?答案是相当直接的:你不希望你的机器进行交换。当CPU需要将某物写入内存,但内存已满时,它会将最不常使用的内存页交换出去到磁盘。这意味着你必须承受将数据写入磁盘的时间惩罚。如果另一个进程随后引用了刚好在刚刚交换出去的页面上的一些数据,那么CPU会再次将其交换回来,可能交换出一些其他进程很快就会需要的其他数据。如果继续下去,CPU和磁盘开始疯狂地在圈子里旋转,而无法完成任何实际的工作。RAM越少,这种场景出现的频率就越高。更糟糕的是,你可能会耗尽交换空间,然后你的麻烦就真的开始了。

你如何做出决定?你知道你的服务器期望以多高的速度服务页面,以及平均服务一个页面需要多长时间。现在你可以计算出你需要多少个服务器进程。如果你知道你的服务器可以增长的最大规模,那么你就知道你需要多少内存。如果你的操作系统支持内存共享,那么你可以在服务器启动时预先加载模块和脚本,这样可以最大限度地利用这个特性,因此你需要的内存将比计算的要少。

不要忘记其他重要的系统进程也需要内存,所以你应该不仅为Web服务器规划内存,还要考虑其他组件。记住,请求可能会排队,因此你可以允许客户端等待几秒钟,直到有服务器可以为其提供服务。大多数时候,你的服务器不会达到最大负载,但你应该准备好应对高峰。你需要为高峰情况预留至少20%的空闲内存。许多网站在发布关于它们的重大新闻后不久就会崩溃,因为突然出现了意外的请求量。(类似于Slashdot效应。)如果你即将宣布一些酷的东西,那么要意识到可能产生的后果。

获取容错CPU

确保CPU在规范范围内运行。许多机器发货时CPU时钟速度、电源电压等设置不正确。有时没有安装冷却风扇。它可能无效,因为电缆组件阻碍了风扇叶片。像有缺陷的RAM一样,过热的处理器会导致各种奇怪且不可预测的事情发生。一些CPU已知在某些情况下存在严重的错误。尽量别买到这种CPU。

本系列之前的文章

寻找 mod_perl ISP...或者成为一家 ISP

您需要知道的 Perl - 第3部分

你需要知道的Perl - 第2部分

你需要知道的Perl

无需超级用户权限安装mod_perl

30分钟学会mod_perl

为什么选择mod_perl?

检测和避免瓶颈

你可能使用了最昂贵的组件,但性能仍然很差。为什么?让我介绍一个令人烦恼的词:瓶颈。

一台机器是由许多组件组成的集合。几乎任何一个组件都可能导致瓶颈。

如果你有一个快速的处理器但少量内存,那么内存很可能是瓶颈。处理器将得不到充分利用,通常它会等待内核交换内存页面,因为内存太小,无法容纳最繁忙的页面。

如果你有大量内存、快速处理器、快速磁盘,但慢速的磁盘控制器,那么磁盘控制器将是瓶颈。性能仍然会很差,而且你会浪费金钱。

慢速的NIC也可能造成瓶颈,并使整个服务运行缓慢。这是一个最重要的组件,因为Web服务器比磁盘更受网络限制(即网络流量比磁盘利用率高)。

解决硬件需求冲突

可能发生的情况是,你正在使用的软件组件的组合产生了对调整参数优化的冲突需求。如果你可以将组件分离到不同的机器上,那么你可能会发现这种方法(一种类型的集群)可以解决问题,成本比购买更快的硬件要低得多,因为你可以分别调整机器以适应它们应该执行的任务。

例如,如果你需要运行关系型数据库引擎和mod_perl服务器,那么将它们放在不同的机器上可能是明智的,因为虽然RDBMS需要非常快的磁盘,但mod_perl进程需要大量内存。因此,通过将它们放在不同的机器上,可以轻松地为每个机器分别优化,以最佳方式满足每个软件组件的需求。


参考资料

标签

反馈

这篇文章有问题吗?请帮助我们通过在GitHub上打开一个问题或拉取请求。