Starting LAMP On Low Memory VMs

  • 11 April 2016
  • ADM

 

Starting LAMP On Low Memory VMs - images/logos/lamp.jpg

 

If you are using a dedicated server with a few GB of RAM then you will not have this problem. But if you are running cloud computing with small virtual server like vultr.com then you may end up in this problem: the mysql/mariadb server will run out of memory.

Problem

My server is running MariaDB 5.5 and this is the log file /var/log/mariadb/mariadb.log:

Starting LAMP On Low Memory VMs - /images/MysqlOutOfMemory.png

The problem occurs on mariadb and the system closed the service, but is not the only service that it might crash.

Solution

To fix the problem need totweak all major services from the system, in this case: Apache, MariaDB, PHP.

Step 1 - Apache

Timeout

The default timeout is 60 (seconds)....and is much than needed. I will turn this down to the 20-30 second range.

KeepAlive

Enabling KeepAlive can avoid generating/killing to many apache child threads, but if your users tend to only view a page or two, this makes no difference, because apache only persists the thread for a given connection. If you have high user engagement, you probably want KeepAlive on, but you should tune it down to keep your total apache thread count low.

MaxKeepAliveRequests and KeepAliveTimeout

If you enabled KeepAlive on your low memory server, you should reduce the MaxKeepAliveRequests and KeepAliveTimeout.

When starting up, mysql server it allocates all the RAM it needs. By default, it will use around 400MB of RAM, which isn't much ona database server with 4GB of RAM, but it is quite significant for a small virtual machine.

Prefork Module or Worker Module

This is where we can tell apache only generate a fewer number of processes. The defaults here are high, limiting you to a max of 256 servers.You can play with the MinSpareServers, MaxSpareServers, StartServers and MaxRequestsPerChild. Before adding this setting you need to check if you are running on prefork or worker module. Alternatively you can add the settings for both modules.

The http config file is located here: /etc/httpd/conf/httpd.conf

To edit the file with vi editor run the command:

[root@admfactory.com ~]# vi /etc/httpd/conf/httpd.conf

Add the following data to the config file.

Timeout 30
 KeepAlive On
 MaxKeepAliveRequests 50
 KeepAliveTimeout 10
 
 <IfModule prefork.c>
     StartServers          3
     MinSpareServers       2
     MaxSpareServers       5
     MaxClients            10
     MaxRequestsPerChild   1000
 </IfModule>
 
 <IfModule worker.c>
     StartServers          3
     MinSpareServers       2
     MaxSpareServers       5
     MaxClients            10
     MaxRequestsPerChild   1000
 </IfModule>

To check if you are running on prefork or worker module you can run the following command:

[root@admfactory.com ~]# httpd -V

The output for this command will look like this:

[root@admfactory.com ~]# httpd -V
 Server version: Apache/2.4.6 (CentOS)
 Server built:   Nov 19 2015 21:43:13
 Server's Module Magic Number: 20120211:24
 Servers loaded: APR 1.4.8, APR-UTIL 1.5.2
 Compiled using: APR 1.4.8, APR-UTIL 1.5.2
 Architecture:   64-bit
 Server MPM:     <b>prefork</b>
   threaded:     no
     forked:     yes (variable process count)
 Server compiled with....
  -D APR_HAS_SENDFILE
  -D APR_HAS_MMAP
  -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
  -D APR_USE_SYSVSEM_SERIALIZE
  -D APR_USE_PTHREAD_SERIALIZE
  -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
  -D APR_HAS_OTHER_CHILD
  -D AP_HAVE_RELIABLE_PIPED_LOGS
  -D DYNAMIC_MODULE_LIMIT=256
  -D HTTPD_ROOT="/etc/httpd"
  -D SUEXEC_BIN="usr/sbin/suexec"
  -D DEFAULT_PIDLOG="/run/httpd/"
  -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
  -D DEFAULT_ERRORLOG="logs/error_log"
  -D AP_TYPE_CONFIG_FILE="conf/mime.types"
  -D SERVER_CONFIG_FILE="conf/httpd.conf"

Dont't forget to restart apache after the config change. From CentOS the command line would be:

[root@admfactory.com ~]# systemctl restart httpd.service

Step 2 - MySQL/MariaDB

We can disable Performance Schema by putting this under the [mysqld] section configuration from my.cnf file.

The my.cnf config file is located here: /etc/my.cnf

performance_schema = off
Other setting that can be done if you are using InnoDB as engine is to decrease the buffer pool size. To do that put under the [mysqld] section the following line:
innodb_buffer_pool_size = 2M
Don't forget to restart apache after the config change. From CentOS the command line would be:
[root@admfactory.com ~]# systemctl restart mariadb.service

Step 3 - PHP

For PHP you can reduce the memory limit. to do that edit /etc/php.ini and add the following line:

memory_limit = 128M

Don't forget to restart apache httpd after the config change.

Conclusions

The values used in this tutorial are not necessary the best. You can tweak and see what values works better for your server. To see the differences between memory usage before and after you can use the free -M command.