HTTP 500(内部服务器错误)通过apache处理并发MySQL请求



我已经建立了一个维基百科数据库,其中:

  • 一(1)台主机正在运行mysqld,运行数据库;我已经安装了mariadb-server软件包
  • 我在4个不同的表中存储了1600万页(页面、文本、修订、重定向;每个表有1600万行,后者约700万行)。/var/lib/mysql/ibdata1的大小:88 GiB
  • 请求通过http服务器(apache2)提供,使用MediaWiki,就像在wikipedia.org中一样
  • 另一台机器上的一个单线程工作程序通过http向数据库发送2.31亿个请求,超时时间为200-500毫秒;许多单个请求甚至在200毫秒时超时

问题是,由于"HTTP 500"(内部服务器错误),大多数请求都没有得到服务。少数请求(100-200)可以正常处理,但当启动请求数超过1'000的请求时,大多数情况下我都会收到"内部服务器错误"。

以下是正在进行的实验中的快照:

  • 38086个请求:HTTP 200 OK
  • 1200226请求:HTTP 500 Internal Server Error
  • 74280个请求:超时

特别是,以下是mysqld服务器上/var/log/apache2/error.log的一个小摘录:

[Mon Apr 18 02:42:43.492142 2016] [:error] [pid 70738] [client 172.16.96.23:41031] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/cache/LocalisationCache.php on line 262
[Mon Apr 18 02:42:53.184116 2016] [:error] [pid 70665] [client 172.16.96.23:57976] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/parser/Preprocessor_DOM.php on line 1123
[Mon Apr 18 02:43:19.389313 2016] [:error] [pid 70745] [client 172.16.96.6:38824] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/Sanitizer.php on line 1087
[Mon Apr 18 02:43:22.188122 2016] [:error] [pid 69251] [client 172.16.96.6:55869] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/title/MediaWikiTitleCodec.php on line 377
[Mon Apr 18 02:43:38.404148 2016] [:error] [pid 70919] [client 172.16.96.6:60524] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/parser/Preprocessor_DOM.php on line 1124
[Mon Apr 18 02:43:42.188143 2016] [:error] [pid 69534] [client 172.16.96.6:51519] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/parser/Preprocessor_DOM.php on line 1119
[Mon Apr 18 02:42:23.004116 2016] [:error] [pid 70550] [client 172.16.96.23:35259] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /home/wikiadmin/mediawiki-1.26.2/includes/Message.php on line 260

我正在寻找如何从服务器端通过提供更多请求来改善这种情况的想法。作为MySQL和数据库的新手,我已经进行了研究,并提出了不同的建议,比如(I)数据库碎片化;(ii)MySQL集群等;然而,既然有这么多建议,我不知道该朝哪个方向走。

是MySQL问题还是HTTP/MediaWiki问题?

您正在执行的任务称为负载测试您看到的结果完全在正常服务器行为的范围内。

当请求超时时,意味着您的web服务器过载,无法在TCP/IP请求超时限制内响应请求。它由客户端机器控制:用于向Apache web服务器发出请求的机器。客户端机器在放弃之前会重试几次,这取决于操作系统。一台标准配置的Windows机器需要72秒才能放弃。

当Apache服务器接受一个请求时,会发生500个错误,但用PHP编写的媒体wiki代码在30秒限制之前没有完成。这个限制是PHP配置的一部分。您可以通过编辑php.ini文件来更改它。但这无济于事。您的web服务器机器——运行Apache/PHP/mediawiki服务器的机器严重过载,并且试图同时做太多事情。如果你给PHP超过30秒的运行时间,服务器就会尝试一次做更多的事情,而且这些事情都需要更长的时间。

我无法从你的问题中判断你是在使用MySQL还是MariaDb来托管你的数据库。但这并不重要。你不会收到错误,告诉你你的数据库在这个负载下崩溃。

是你的网络服务器在负载下崩溃了。它似乎做得很优雅。。。根据我的经验,你所施加的负载完全有可能导致网络服务器崩溃。对我来说,这看起来像是一个成功的负载测试:测试完成时有超时,但没有崩溃。

通常,运行您模拟的生产工作负载类型的系统使用多个负载平衡的web服务器(每个运行Apache/PHP/mediawiki),这些服务器都使用一个数据库。AWS Elastic Beanstalk就是一个负载平衡系统的例子。还有其他的。

在你的网络服务器机器上添加处理器核心或RAM可能也会有所帮助,但不会有多大帮助。您需要多个服务器才能扩展。

还有人建议您避免在将系统扩展到比实际工作负载大得多时浪费金钱和电力。这是一个明智的建议。

这既不是mysql问题,也不是HTTP/mediawiki问题。从你的问题描述来看,听起来你没有足够的硬件来处理你发送的请求量。

2.31亿的请求太多了。一大堆。1000个并行请求也是如此。你真的希望你的网站能有这么多吗?如果你这样做,你将需要为它获得合适的硬件。

与其他一些http服务器相比,Apache占用了更多的资源。阅读https://serverfault.com/questions/7778/suggest-a-lightning-fast-feature-light-secure-linux-web-server-to-serve-static用于选择更好的http服务器。您可以启用opcache或使用php加速器。确保您使用的是mysqli或pdo,而不是php中的mysql。确保你的服务器上有足够的ram,这样ram中的数据就不必交换了。增加InnoDB的缓冲区大小。你也可以使用谷歌应用引擎等网络服务。这样你就不必自己担心基础设施了。

最新更新