通过mod_wsgi运行Django时,我应该在WSGIDaemonProcess中指定多少个进程?


23

假设我在一个盒子上有两个站点(超级用户和Serverfault)从它们自己的Apache虚拟主机运行。这两个站点均由Django驱动,并通过mod-wsgi在Apache上运行。该站点之一的典型配置文件如下所示:

WSGIDaemonProcess serverfault.com user=www-data group=www-data processes=5

主机是一台运行Ubuntu的Linux计算机,具有4GB的RAM。谁能建议我为我的2个站点在上面指定的处理数量?假设它们的流量与实际的Superuser和Serverfault站点相同。

Answers:


22

那么,多少流量实际的超级用户和Serverfault的网站有哪些?如果假设没有足够的信息来简化答案,那么假设就没什么用...

最坏情况下的进程计数应该是您希望站点能够处理的每秒请求的峰值数,除以如果所有这些请求都采取了最慢的操作,则一个进程可以处理的每秒请求数(因此该操作的处理时间的倒数)。根据您的要求/秒的置信区间和时间测量,添加您认为合适的任何软化因子。

平均案件计数是相同的,但是您将请求/秒除以每个操作每秒请求的加权平均值(权重是您希望执行该特定操作的请求的百分比)。再次,软糖因素是有用的。

您可以在计算机上运行多少个进程的实际上限由每个进程占用的内存量决定;对一个进程进行假脱机处理,然后使用真实的数据集(如果您仅使用玩具数据集进行测试,例如50或100)对它执行各种内存消耗大的操作(通常会检索和处理大量数据的操作)行,那么如果您的操作之一检索并操作了表中的每一行,那么当该表增长到10,000行时,这将不是一个很好的衡量标准),以查看内存使用量迅速膨胀到什么地方。您可以使用脚本来人为地限制每个进程的内存使用量,该脚本可以使达到一定内存使用量阈值的工作人员重新获得收入,如果将该阈值设置得太低,则有可能引起讨厌的问题。

获得内存使用量后,您将扣除一定数量的内存用于系统开销(我自己喜欢512MB),如果在同一台计算机(例如数据库)上运行其他进程,则再减去一堆,然后还有更多的方法可以确保您不会用完磁盘缓存空间(取决于磁盘工作集​​的大小,但是我会再使用不少于512MB的空间)。那就是您将内存量除以每个进程的内存使用量以获得上限。

如果您需要为峰值负载提供服务的进程数大于盒子上可以容纳的进程数,则您需要更多的计算机(或者在最简单的情况下,将数据库移至另一台计算机)。

您已经拥有将网站精简到一个简单的SF帖子中的多年经验。


进程/线程数的另一个重要因素是处理单个请求需要花费多长时间,以及在所有可能的时间长度上的总体分布。换句话说,在任何时候需要处理多少个请求,而这些请求所花费的时间要大于平均响应时间。因此,它不只是理论上的请求/秒那么简单,而是那些运行时间较长的请求的影响可能很大,并且不适当地决定了总体配置参数。FWIW mod_wsgi 3.0将包括一些内置的统计信息收集,以尝试捕获与此有关的数据以帮助配置。
Graham Dumpleton,2009年

@Graham:重读我的答案,我详细介绍了这个问题。Requests / sec只是响应时间的倒数,用整数req / sec进行分频比将其乘以十进制要容易得多。
womble

但是,您不能只关注最坏情况的响应,也不能关注平均值。需要根据落入时间段的请求百分比(即跨所有可能时间的分布)以某种方式对它进行加权。如果您确实花费了最坏情况的响应时间,那么您将提出不切实际的要求。这个问题真的很难知道要使用什么公式。这就是为什么在mod_wsgi 3.0中将有内置的统计信息收集功能,该功能收集线程利用率以及在任何时间使用多少线程按计数和时间的百分比。
Graham Dumpleton 09年

3
问题可能是您只在查看进程的地方,因为我担心每个进程的线程如何使用它作为因素,而这并不那么简单。换句话说,该WSGIDaemonProcess指令指示5个进程,每个进程默认情况下使用15个线程。就我在您的说明中所读到的一样,它是假设单线程进程。如果没有,请向我指出您的模型如何满足GIL周围的线程以及争用/扩展问题。因此,请确定您的描述仅对单线程进程有效,我不会争论。
Graham Dumpleton 09年

2
在您99%确定Python代码和所有依赖项都是线程安全的之前,“多线程Apache + multiprocess-wsgi”方法不是最好的选择吗?
TomaszZieliński,2010年

9

womble的回答很棒,尽管有点难以理解和适用于没有经验的人。我想给出一些经验数字,以及“简单内容”与“电子商务”应用程序的比较。

根据mod_wsgi的适当配置来设置不同用例的内容不多,因此我希望可以在此处使用一些散文。

A)CMS网站和微型网站

我们运行着几个客户网站,其中大多数主要是托管django CMS的内容网站或微型网站,一些自定义表单,有时还有Celery用于计划的后台任务。这些站点不需要资源,其中几个可以在具有32 GB RAM的单个4核心Intel Xeon上并行运行。这是我们用于每种此类站点的配置:

WSGIDaemonProcess example.com user=www-data processes=2 maximum-requests=100

我说的是一台服务器上大约40个站点​​,其中大多数站点都处于待机状态。站点有2个进程(默认情况下每个进程有15个线程),尽管站点分配服务器资源的能力受到限制,但它们是富裕的。使用(CMS)应用程序的简单性质可以证明为什么此设置足够充分:完成任何请求都不会花费超过几毫秒的时间。Apache将始终保持放松,CPU负载也将保持放松。

B)电子商务网站

我们所做的更为复杂的站点的特点是,本地操作的计算成本仍然较低,但是外部依赖项(例如提供预订数据的Web服务)的交易时间却很昂贵。具有外部请求的操作占用线程的时间更长,因此您需要更多线程来满足相同数量的用户(与上面的简单CMS站点相比)。更糟糕的是,当外部服务无法立即响应请求时(有时持续几秒钟),线程有时会被阻塞。这可能会导致令人讨厌的副作用,即线程将请求发送到同一服务的队列排队,直到所有可用的mod_wsgi线程用完并阻止等待。

对于这些情况,我们尝试使用6流程时并没有太大的差异,但最终却12看到了性能和操作稳定性的无与伦比的提升:

WSGIDaemonProcess example.com user=www-data processes=12 maximum-requests=100

通过保持良好的响应速度,站点可以轻松地处理150个和250个并行用户的一些简单负载测试(而使用这些2过程,站点无法同时满足50个用户的需求)。在该负载下,具有32 GB RAM的2 CPU 6核心Intel Xeon的CPU使用率远低于25%,RAM使用率也几乎恒定地保持在25%以下。请注意,我们在这里仅将一个专用机器用于单个站点,因此我们不会窃取其他站点可能需要的资源。

结论

使用更多的进程是允许Apache使用还是不使用可用系统资源之间的权衡。如果要在“攻击”条件下保持稳定的服务器系统(而不是网站!),请保持较低的数量。如果希望Apache在需要时帮助您使用系统资源(CPU,RAM),请选择一个更大的数字。您可以进行多高的计算,就像上面接受的答案中概述的那样,最终受可用的CPU能力和RAM限制。

(PS:我将我的枕头下的modwsgi项目Wiki 的ConfigurationDirectives部分保留下来,以进行类似Apache的背景阅读。另外,请确保理解并监视Apache服务器的打开连接。)


很棒的帖子,但是为什么不设置线程数呢?由于Python的GIL否定了线程的许多优势,我假设您想拥有比线程更多的进程,但是指定线程数是否有任何优势?
塞林2015年

根据文档,默认threads值为15 。我认为明确指定没有优势。实际上,我记得由于某种原因而忽略了它:关于SO的一些帖子或一些文档的一部分建议忽略该值以避免副作用(我知道,这听起来很奇怪)。不幸的是,我现在找不到那个来源。对于其余的问题(GIL),抱歉,您可能比我更专业。
Peterino

感谢您的经验配置。但是,请记住,根据这篇文章 You should never use maximum-requests in a production system unless you understand the implications and have a specific temporary need.
raratiru
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.