1

I am running a Website that gets heavy usage at a particular time. I run apache 2.4 on an EC2 Ubuntu 16.04 server with 4 Core CPU and 16GB of RAM and 2GB Swap. Size of the average apache process is 35MB (approx). I have set up the KeepAlive value as ON and KeepAliveTimeout to a lower value of 5.

I am using MPM prefork and the configuration looks like:

<IfModule mpm_prefork_module>
        StartServers             5
        MinSpareServers          5
        MaxSpareServers          10
        ServerLimit              350
        MaxRequestWorkers        350
        MaxConnectionsPerChild   20000
</IfModule>

When the number of concurrent users increases, htop shows that all the 4 cores are 100% utilized, however, the RAM still shows only 1.5 or 2GB utilized, out of the available 15GB.

enter image description here

Why isn't more memory being utilized? Is it normal to have this kind of CPU usage? If the number of users increases from here, the server starts to return an HTTP 522 error.

Additional Information: The calculation used to get the values, were referenced from this tutorial and this answer on ServerFault

I found a single apache process taking up approximately 35MB of memory. I run a nodejs (for socketio) under PM2. MySQL is run from an RDS and is not on this server. Though, I have reduced some values as per the suggested calculations:

Available Memory - 14000MB 

(leaving the remaining RAM for other purposes)

Apache Process usage - 40MB
MaxRequestWorkers = 14000/40 = 350
StartServers 30% of MaxRequestWorkers

(should be 105, but I feel it is too high. Should I make it 105?)

MinSpareServers 5% of MaxRequestWorkers 

(should be 17)

MaxSpareServers 10% of MaxClients 

(Is it okay to have this value same as StartServers and as high as 105?)

ServerLimit = MaxRequestWorkers

Edit I modified the prefork configuration, using the suggested calculations:

<IfModule mpm_prefork_module>
        StartServers             105
        MinSpareServers          17
        MaxSpareServers          105
        ServerLimit              350
        MaxRequestWorkers        350
        MaxConnectionsPerChild   20000
</IfModule>

I ran a script that makes 2 API calls, imitating a user coming on board and doing some action 4 times. Running 20 of these scripts parallel, with new configurations still gave a high load average value: enter image description here

gentrobot
  • 169
  • 2
  • 10
  • 2
    If you're maxed out on CPU with a load average of 18.96, RAM's not your problem. Using more of it won't change the fact that you've hit a CPU bottleneck (barring stuff like caching or better indexes for SQL). – ceejayoz Oct 11 '17 at 20:59
  • 1
    Why such a low MaxSpareServers limit? it takes time to spin up those additional servers. You may be constantly starting and stopping processes, which will eat up CPU. Rather than doing that find out how many connections you might have during peak times and set the MaxSpareServers limit appropriately. *Also*, that may help explain why your memory usage is lower than expected. – Gene Oct 12 '17 at 03:13
  • @ceejayoz The load average, in peak hours at times, goes as highs as 70-80. Also, SQL indexes should not be a problem because MySQL runs from an RDS, not on this server. I do run a nodejs server via PM2. I'm refactoring my code and trying to find bottlenecks, was wondering if my Apache is set up properly or not. – gentrobot Oct 12 '17 at 04:55
  • @Gene I'm fairly new to Apache tuning. I followed this [tutorial](http://cloudinservice.com/tune-apache-performance-using-mpm-prefork-module/) and (this question)[https://serverfault.com/questions/644622/tuning-apache2-prefork-maxclients-serverlimit] to figure out the values for MaxServers and MaxRequestWorkers. I have updated the question to add information about calculations used. – gentrobot Oct 12 '17 at 05:21
  • Each apache process isn't actually using a full 35MB of memory. Some of that is shared memory, a significant portion of that. Bump up the min and max spare servers, restart apache, and see how much total memory is being used. Be sure to exclude buffers/cache when getting the total. – Gene Oct 12 '17 at 17:15
  • @Gene As per my edit above, I modified the prefork conf values. It started to cause even more load on CPU and server kept giving 502 timeout. Even after reducing the numbers and doing an apache restart, it still didn't solve immediately. I am refactoring my code a little and then will run tests for increased and normal maxserver values. Then I'll share the results. Thanks a lot for your help so far. Hope to get more insight, once I post the results. – gentrobot Oct 13 '17 at 07:35

0 Answers0