We continue topic  -bash: fork: Cannot allocate memory issue in EC2 (Wordpress) environment and now e can talk about second step: Apache optimization. The reason is kernel may kill your processes. The kernel would only kill a process under exceptional circumstances such as extreme resource starvation (think mem+swap exhaustion). In this situation your EC2 will work fine but your website / ssh access or something else will not. How we can resolve it?

Trim Down Module Loading

In your httpd.conf fine LoadModule block and comment all LoadModule except next:

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so

If your website uses multi-language support  you don't need comment next loading:

LoadModule negotiation_module modules/mod_negotiation.so

in other case (your website don't need multi-language support) comment next rows in the httpd.conf:

LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW


ForceLanguagePriority Prefer Fallback

Apache MPM Prefork Module optimization

This module controls the number of processes and spare processes Apache will start and run. This is especially important if you are running a small VPS that is handling MySQL and Apache.

Find block IfModule prefork.c in your httpd.conf file.

MinSpareservers and MaxSpareServers control the number of spare processes your web server is permitted to run.

StartServers controls how many are started by default.

ServerLimit controls the maximum configured value for MaxClients.

MaxRequestsPerChild limits the number of requests a child server will handle during it’s life.

Reducing MaxClients on a webserver that is serving dynamic content (e.g. WordPress) can make a big difference. If you experience a traffic spike on your VPS and your MaxClients is set too high your server will more than likely get stuck in an endless loop of swapping pages from physical memory to virtual memory, commonly referred to as thrashing. The accepted way of calculating an appropriate MaxClients value is dividing your total available system memory by the size per Apache process. For example, if you had a 500MB left for Apache to use and each Apache process was using around 10MB you would set your MaxClients to (512-12) / 10 = 50. To check real time memory usage on your VPS use top. As well we can safely reduce MaxRequestsPerChild and realize a small gain.

New set of values may be ( Remember these are not concrete “best” values, they depend on the size of your VPS and how small or large you Apache process is)

StartServers       3
MinSpareServers    3
MaxSpareServers   10
ServerLimit      50
MaxClients       50
MaxRequestsPerChild  2000

Optimize KeepAlive parameter

KeepAlive allows your visitors to issue multiple requests over the same TCP connection, in theory this helps improve latency because your visitors can request your webpage, images, and javascripts all over one connection. Unfortunately, Apache must use a worker process to service each and every request. The worker process stays busy servicing each request for a full 15 seconds by default, even if your visitor is no longer using it! This means you have less worker processes available on your system at any given time. With the limited system resources you have on your small VPS we always want open worker processes to be actually working. One way of accomplishing this is turning off KeepAlive. You need to setup KeepAlive Off in httpd.conf file.

f you have a site with lots of images and javascripts it is usually better leave KeepAlive turned on and make some additional tweaks. In this case you need to decrease KeepAliveTimeout 2 for 2 seconds and increase MaxKeepAliveRequests 200.

Timeout settings

Another minor tweak that will give you a small performance boost as well as help reduce the effects of a DOS attack is changing the TimeOut Directive. This directive tells Apache how many seconds to wait while receiving an incoming request, processing it, and sending back a response. Timeout 40

Last step - restart your httpd service

service httpd restart

Prevent killing MySQL

Now MySQL. Every process has a priority that oom-killer considers when it is going to kill some process. You can see the priority in /proc file system:

cat /proc/`pidof mysqld`/oom_adj

By default all user processes get 0. The possible values vary from -16 to 16. -16 means the oom-killer will kill the process the last, 16 means the most likely to kill. If /proc/$(pidof mysqld)/oom_adj is -17 oom-killer will never kill the process.

So I put a script in cron that periodically checks oom_adj of mysqld process and sets it to -17 if it’s different:

[root@app-01 cron.d]# cat twindb-oom # Prevent MySQL process to be killed by oom-killer */5 * * * * root mysql_pid=`pidof mysqld`; if ! test -z "$mysql_pid"; then if [ "`cat /proc/$mysql_pid/oom_adj`" -ne -17 ]; then echo -17 > /proc/$mysql_pid/oom_adj; fi ; fi