optimizing apache/mysql on Linode 1024

Hi,

I have a linode1024, Apache with one site only.

The site can not take 10 to 15 requests at a time, I have around 5K page views daily but expecting 50K soon, the server runs out of memory very quickly. I need help finding the problem in the following configuration.

ps. I have W3Totalcache in-place configured with page caching and MAXCDN.

For apache2.conf I have the following settings

 <ifmodule mpm_prefork_module="">StartServers          2
    MinSpareServers       6
    MaxSpareServers      12
    MaxClients          48
    MaxRequestsPerChild   6000</ifmodule> 

Httpd.conf is blank

For MySQL, my.cnf has the following values:

key_buffer        = 16M
max_allowed_packet    = 16M
thread_stack        = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
#max_connections        = 100
#table_cache            = 64
#thread_concurrency     = 10
#
# * Query Cache Configuration
#
query_cache_limit    = 1M
query_cache_size        = 16M

Any tips will be appreciated, I thought a VPS with 1GB memory should easily handle more connections, just can't find the problem, thanks

10 Replies

I had memory problems until I switched to MPMworkermodule instead of prefork. After that I had no memory problems at all.

I do believe there's some issues with the default modphp from apache and mpmworker, but if you use PHP-FPM/FastCGI with pools it shouldn't be a problem, AFAIK.

Your KeepaliveTimeout should be in the single digits, perhaps 2 or 3 seconds instead of the extra-long default. That's the #1 eater of otherwise-idle connections.

And yes, if you ditch modphp and move to php-fpm, you can also ditch mpm-prefork and set the world on fire accordingly. I handle about 120,000 hits/day on vBulletin with a 1 GB VPS, Apache, and PHP-FPM with room to spare (I could resize down to 512 MB…), which replaces a previous VPS with 4 GB, Apache, and modphp, which occasionally slammed itself into the turf…

@hoopycat:

Your KeepaliveTimeout should be in the single digits, perhaps 2 or 3 seconds instead of the extra-long default. That's the #1 eater of otherwise-idle connections.

And yes, if you ditch modphp and move to php-fpm, you can also ditch mpm-prefork and set the world on fire accordingly. I handle about 120,000 hits/day on vBulletin with a 1 GB VPS, Apache, and PHP-FPM with room to spare (I could resize down to 512 MB…), which replaces a previous VPS with 4 GB, Apache, and modphp, which occasionally slammed itself into the turf…

Thanks for the tips, decreasing the KeepAlive Timeout has helped a lot.

I was not able to switch to php-fpm as it turned out to be a complicated thing ( the site went down and I had to revert to an old backup! )

I'm interested to know about your Apache configurations, will it be possible to mention what other settings you have in there, the default file I have is way too long and I believe that's one of the issues. here is the whole file I have:

ServerRoot "/etc/apache2"
LockFile /var/lock/apache2/accept.lock
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 8
 <ifmodule mpm_prefork_module="">StartServers          2
    MinSpareServers       6
    MaxSpareServers      12
    MaxClients          48
    MaxRequestsPerChild   6000</ifmodule> 

 <ifmodule mpm_worker_module="">StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0</ifmodule> 

 <ifmodule mpm_event_module="">StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxRequestsPerChild   0</ifmodule> 

User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

AccessFileName .htaccess

 <files ~="" "^\.ht"="">Order allow,deny
    Deny from all
    Satisfy all</files> 

DefaultType text/plain

HostnameLookups Off

ErrorLog /var/log/apache2/error.log

LogLevel warn

Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

Include /etc/apache2/httpd.conf

Include /etc/apache2/ports.conf

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Include /etc/apache2/conf.d/

Include /etc/apache2/sites-enabled/

Thanks

The best answer really is worker and fpm, but failing that, you'll want to bring the number of Apache processes under control such that you never run out of RAM. I don't use Apache, but I believe lowering maxclients significantly is what you want (IIRC it's the number of simultaneous clients handled, and there's no point serving a zillion people in parallel); I'll let others chime in on how to accomplish this.

My configuration goes a little something like this:

ServerRoot "/etc/apache2"
LockFile /var/lock/apache2/accept.lock
PidFile /var/run/apache2.pid
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
 <ifmodule mpm_worker_module="">StartServers          4
    MaxClients            1024
    MinSpareThreads       64
    MaxSpareThreads       192
    ThreadsPerChild       64
    MaxRequestsPerChild   0</ifmodule> 
User www-data
Group www-data
AccessFileName .htaccess
 <files ~="" "^\.ht"="">Order allow,deny
    Deny from all</files> 
DefaultType text/plain
HostnameLookups Off
ErrorLog /var/log/apache2/error.log 
LogLevel warn
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/ports.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
ServerRoot "/etc/apache2"
LockFile /var/lock/apache2/accept.lock
PidFile /var/run/apache2.pid
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
 <ifmodule mpm_worker_module="">StartServers          4
    MaxClients            1024
    MinSpareThreads       64
    MaxSpareThreads       192
    ThreadsPerChild       64
    MaxRequestsPerChild   0</ifmodule> 
User www-data
Group www-data
AccessFileName .htaccess
 <files ~="" "^\.ht"="">Order allow,deny
    Deny from all</files> 
DefaultType text/plain
HostnameLookups Off
ErrorLog /var/log/apache2/error.log 
LogLevel warn
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/ports.conf

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" host=%{Host}i proxy=%{X-Urmom-Proxy}i time=%T pid=%P remotehost=%h remoteport=%{remote}p" proxied
CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined
ServerTokens Prod 
ServerSignature On 
TraceEnable On 

 <virtualhost *:80="">ServerName example.com
  ServerAlias www.example.com dev.example.com 
  DocumentRoot /home/www/example.com/current/htdocs
  RewriteEngine On
  SetEnvIf ^X-Forwarded-Protocol$ "^ssl$" HTTPS=on
  <ifmodule rpaf_module="">RPAFenable On
    RPAFsethostname On
    RPAFproxy_ips 192.0.2.1 192.0.2.2 127.0.0.1</ifmodule> 
  <directory home="" www="" example.com="" current="" htdocs="">Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all</directory> 
  <directory>Options FollowSymLinks
    AllowOverride None</directory> 
  <location server-status="">SetHandler server-status
    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1</location> 
  <location example_fpm_status="">Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1</location> 
  Alias /php5.fcgi /home/www/example.com/current/htdocs/../php5.fcgi
  FastCGIExternalServer /home/www/example.com/current/htdocs/../php5.fcgi -flush -host 127.0.0.1:5301
  AddType application/x-httpd-fastphp5 .php
  Action application/x-httpd-fastphp5 /php5.fcgi
  LogLevel info
  ErrorLog /var/log/apache2/example-error.log
  CustomLog /var/log/apache2/example-access.log proxied
  RewriteEngine On
  RewriteLog /var/log/apache2/example-rewrite.log
  RewriteLogLevel 1</virtualhost> 

Again, though, this assumes mpm-worker, which assumes that I am not using mod_php.

For what it's worth, I use prefork + mod_php without any problems on my 1024, managing around ~150k hits or ~40k page views per day (and that's just on the main "flagship" site; there are a few other domains hosted on this particular box that have significantly lower traffic). I've been on such a setup since porting to Linode from my previous VPS host, and it has served me well enough to that I haven't bothered tweaking it much further.

The only thing I would really add beyond what's been already mentioned is to trim down your list of loaded modules to just what you need. The more modules you have loaded, the more memory each child process uses. I trimmed the default Fedora-installed module list by about half (and could probably trim a few more if I bothered to dig a bit deeper into what's actually being used). If you're not doing server side includes, WebDAV, or other fancier things, there's no point having all that loaded into memory. It's more secure, too, since that's less potentially exploitable code running that an attacker might try to access.

Here's a few relevant bits from my config file since you asked for them:

Timeout 60
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 5

 <ifmodule prefork.c="">StartServers       5
MinSpareServers    5
MaxSpareServers   20
ServerLimit       75
MaxClients        75
MaxRequestsPerChild  1000</ifmodule> 

I also use moddeflate and modexpires to cut down heavily on unnecessary traffic. As for improving your MySQL overhead, a PHP opcode/variable cache will help immensely. (I personally use XCache, but there are a number of excellent options.)

Thanks all.

It seems like I have a problem with the wordpress plugins and theme.

I tried keeping prefork and using the same settings as mentioned by jtdarlington, the site become unstable and most of the times it doesn't get a response from the server, So i had to revert back to my original settings keeping my original settings:

Timeout 300
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 5
 <ifmodule mpm_prefork_module="">StartServers          2
    MinSpareServers       6
    MaxSpareServers      12
    MaxClients          48
    MaxRequestsPerChild   6000</ifmodule> 

I also tested Nginx with phpfpm and phpapc on a new linode 1GB, as per the following link: http://www.ewanleith.com/blog/900/10-mi … -15-server">http://www.ewanleith.com/blog/900/10-million-hits-a-day-with-wordpress-using-a-15-server

Still no luck once I loaded my plugins and theme.

My challenge is still to find a more effective setup keeping the same website, I still need to try replacing prefork and mod_php with worker and fpm as hoopycat suggested, I'm trying to figure out how to do that.

I will post results here once I reach optimal settings here when done. Thanks for your time.

@isamj:

Thanks all.

It seems like I have a problem with the wordpress plugins and theme.

I tried keeping prefork and using the same settings as mentioned by jtdarlington, the site become unstable and most of the times it doesn't get a response from the server, So i had to revert back to my original settings keeping my original settings:

Timeout 300
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 5
 <ifmodule mpm_prefork_module="">StartServers          2
    MinSpareServers       6
    MaxSpareServers      12
    MaxClients          48
    MaxRequestsPerChild   6000</ifmodule> 

I also tested Nginx with phpfpm and phpapc on a new linode 1GB, as per the following link: http://www.ewanleith.com/blog/900/10-mi … -15-server">http://www.ewanleith.com/blog/900/10-million-hits-a-day-with-wordpress-using-a-15-server

Still no luck once I loaded my plugins and theme.

My challenge is still to find a more effective setup keeping the same website, I still need to try replacing prefork and mod_php with worker and fpm as hoopycat suggested, I'm trying to figure out how to do that.

I will post results here once I reach optimal settings here when done. Thanks for your time.

You say it's a forum theme, does that mean the site works fine with the default Wordpress theme? What do the logs say? Load/memory-usage? Maybe there's simply something wrong with the theme, rather than apache/PHP.

I'd agree with Nuvini. The site I mentioned runs a WordPress site as one of the secondary domains, complete with third-party plugins and a theme. Try disabling all plugins switch to the default theme first, then bounce Apache to make sure it's fresh. If it works fine then, your problem is the theme and/or plugins, not Apache.

If can't resolve your issue, I suggest you change setting:

MaxKeepAliveRequests 100
KeepAliveTimeout 2
 <ifmodule mpm_prefork_module="">StartServers          2
    MinSpareServers       6
    MaxSpareServers       8
    MaxClients          48
    MaxRequestsPerChild   500</ifmodule> 

Then monitor you memory usage with top command, with "netstat -ln |grep 80" monitor your connection.

If your connection always great then 6, you can add the value of MaxSpareServers.

If never use swap, then you can add the value of MaxRequestsPerChild.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct