Apache is one of the popular webservers used widely. It is used in different MPM configuration based on kind of websites hosted, traffic, security needs. By default, it uses prefork. In this blog, we are going in detail about only prefork MPM. There is no explanation about any other MPM. If you are trying to understand apache prefork and looking for how it can be optimised, go ahead.
Prefork uses multiple processes and each process handles single connection at a time. It does not use thread. So each request is isolated from other and problem with one request does not affect other.
More details are available here. https://httpd.apache.org/docs/2.4/mod/prefork.html
Here we tried our best to explain by showing example from a test server. If you have any questions, please leave a comment.
Let’s start.
- First check which MPM is used by the apache
[root@apache ~]# httpd -V | grep “Server MPM” Server MPM: prefork |
- Check the prefork configurations used in apache conf file.
Ex:
<IfModule mpm_prefork_module> ServerLimit 10 StartServers 2 MinSpareServers 3 MaxSpareServers 4 MaxRequestWorkers 10 MaxConnectionsPerChild 20 </IfModule> |
Understanding directives
- ServerLimit:-
Maximum number of child processes that apache is allowed to run.
- StartServers:-
Number of child processes created during apache startup.
- MinSpareServers:-
Minimum number of idle child processes running. If apache parent process finds that there are idle child processes lesser than minispareservers, it will start the new child processes until it reaches the number setup in MinSpareServers directive.
- MaxSpareServers:-
Maximum number of idle child processes allowed to run. If apache parent process finds that there are idle child processes more than the number specified in MaxSpareServer directive, it will terminate them until it reaches the limit configured..
- MaxRequestWorkers:-
Maximum number of child processes allowed to run. In case of prefork, this is the number of concurrent requests that apache can handle. Because in prefork configuration, each child process handles one request at a time.
- MaxConnectionsPerChild:
If this value is set to 0, a child process will never die.
If this value is set to some value. For example let’s say 10. Then, the child process will die after handling 10 connections. This is recommended to set to some value such as 1000 or more for busy servers to avoid memory leak.
Getting better picture of apache prefork.
- As per the above configuration, StartServer is 2 and MinSpareServers is 3. So when apache is started, we should be able to find 3 child processes in few seconds.
[root@apache ~]# ps -C httpd PID TTY TIME CMD 1152 ? 00:00:00 httpd 1154 ? 00:00:00 httpd 1155 ? 00:00:00 httpd 1156 ? 00:00:00 httpd |
- Here, there are 4 processes instead of 3. This is because, the first process is parent process.
- To get better picture, run $pstree -alp and scroll through to find the processes.
├─httpd,1152 -DFOREGROUND │ ├─httpd,1154 -DFOREGROUND │ ├─httpd,1155 -DFOREGROUND │ └─httpd,1156 -DFOREGROUND |
- A test is made with 100 concurrent connections. But webserver is handling only 10 requests at a time and website was taking long time to load.
[root@apache ~]# ps -C httpd PID TTY TIME CMD 1152 ? 00:00:00 httpd 1367 ? 00:00:02 httpd 1661 ? 00:00:01 httpd 1670 ? 00:00:01 httpd 1671 ? 00:00:01 httpd 1680 ? 00:00:01 httpd 1681 ? 00:00:01 httpd 1682 ? 00:00:01 httpd 1688 ? 00:00:00 httpd 1689 ? 00:00:00 httpd |
[root@apache ~]# ss -tn src :80 or src :443 | wc -l 101 |
- Once all the requests are served, the child processes becomes idle. This is when parent process starts killing the children until it reaches MaxSpareServers limit.
- In this case, MaxSpareServers is set to 4.
├─httpd,1152 -DFOREGROUND │ ├─httpd,3750 -DFOREGROUND │ ├─httpd,3777 -DFOREGROUND │ ├─httpd,3786 -DFOREGROUND │ └─httpd,3805 -DFOREGROUND |
Lets change ServerLimit to 8 and see what happens to MaxRequestWorkers
[root@apache ~]# ps -C httpd PID TTY TIME CMD 3906 ? 00:00:00 httpd 4078 ? 00:00:05 httpd 4085 ? 00:00:05 httpd 4086 ? 00:00:04 httpd 4095 ? 00:00:04 httpd 4101 ? 00:00:04 httpd 4102 ? 00:00:04 httpd 4111 ? 00:00:03 httpd 4112 ? 00:00:03 httpd |
- Even though MaxRequestWorkers is 10, only 8 child processes are running. Because it cannot override the value set in ServerLimit.
Optimization
- The memory used by the apache is the total memory used by all the children processes and parent process. To find the total memory used by apache, run the following command.
[root@apache ~]# ps -C httpd -o rss | sed ‘1d’ | awk ‘{x += $1}END{print “Total Memory used (kb):
Total Memory usage: 78284 |
To find average memory used by each apache process, following command can be used.The memory usage is in kb. It is approximately 78MB here.
[root@apache ~]# ps -C httpd -o rss | sed ‘1d’ | awk ‘{x += $1;y += 1}END{print “Total Memory usage (KB): “ x “\nAverage memory usage (KB): “(x/y)}’
Total Memory usage (KB): 78284
Average memory usage (KB): 15656.8
Memory usage by each apache process is aproximately 16MB here.
You can also run the following command and check the first column.
[root@apache ~]# ps -C httpd -o rss,ucmd RSS CMD 14188 httpd 16028 httpd 16024 httpd 16024 httpd 16020 httpd |
Let’s allocate 400MB for apache and it should never cross this limit because there could be memory shortage in the server.Let’s say the server is having 1GB ram. 600MB of ram be required for other services such as mysql, exim, php etc.
Each process takes 16M and available ram for apache is 400MB.
Dividing 400 by 16 gives 25.
That means we can run maximum of 25 apache processes. If we exclude parent process, then it leaves us 24 child processes.
So MaxRequestWorkers can be up to 24 or Server limit can be set to 24.
Here it is set according to the memory capacity. But it may not be ideal if the cpu cores are less. During busy hours, the apache could be running maximum number of child processes and processing the requests. It passes the requests to php, mysql to process and provides the result. So php and mysql might consume the resources. So optimise them or try by reducing MaxRequestWorkers to limit the connections.
D KarthiKeyan