PHP: fastcgi
- Why:
Fastcgi is optimized to run php-code in a efficient way
fastcgi
Of course every time your php code is loaded it must be compiled before running it (this happens automatically)
To improve this I use eaccelerator
(this will cache the compiled scripts)
(WARNING if you replace some php scripts you should clean-out the cache to prevent core-dumps)
(a +70% boost is possible)
Also a nice reason to switch to mod_fcgi is that you can limit the workers only for php and let apache handle the flat files (like jpg, gif ...)
Apache: Worker
- Why:
Apache-mpm-prefork is good but not good enough
With prefork mode you need to much memory for 1 active connection,
(so when someone is using a 28k line could block 1 connection for a long time and is a wast of memory use)
Apache-mpm-worker is much better in using memory coz it is shared
1 process can handle many active requests using threads
The good thing about this is that you share the memory and you don't need to load it every time(or many times)
Apache: mod_disk_cache
- Why:
There are 2 great way,s of caching with apache
Disk cache and Memory cache
You should think memory cache is the best way, But I don't think so
Cache is something that can grow
Memory cache is gone @ restart
Cleanup memory cache = restart
Cleanup disk cache = just remove what is old (with htcacheclean)
I now memory is much faster then disk, but do the following test
time cat 2M-file > /dev/null
real 0m0.198s
user 0m0.004s
sys 0m0.008s
time cat 2M-file > /dev/null
real 0m0.008s
user 0m0.000s
sys 0m0.004s
As you can see the second time the file just comes from the memory
So the system-disk cache is used to speed-up this cache
(and it is as fast as mod_mem_cache)
Drupal:
Drupal is heavy in php scripts
To boost Drupal you can add many CPU cores but that is the brute force way (and costs ...)
The other way is caching(you should think)
That is right if you have anonymous users on your site
When only 10% is authenticated you should split-up the anonymous users against the others
and you will have a great boost for 90% of your traffic (cache)(and its worth doing that)
But when 90% is authenticated, it is not a good idea
Then you should use only the build-in cache of Drupal
(that give a great boost in speed)
So now my config for a default Drupal site (using the xen guest, 2cpu 3Ghz and 512MB memory)
Apache-mpm-worker
KeepAlive On
MaxKeepAliveRequests 50
KeepAliveTimeout 5
I use keepAlive but set a limit to it (so it will not take all your resources)
StartServers 4
MaxClients 400
MinSpareThreads 200
MaxSpareThreads 250
ThreadsPerChild 50
MaxRequestsPerChild 100000
With 4 servers(processes) as default I think it is enough
The ThreadsPerChild can be bigger (depending of your traffic)
The MaxRequestsPerChild Must be calculated to your needs
I mostly guess that this count has been reached on 1 day
(this is just to prevent memory-leaks)(when reached the process will be killed and a new will respawn)
SocketPath /var/lib/apache2/fcgid/sock
IPCConnectTimeout 20
IPCCommTimeout 20
OutputBufferSize 0
#MaxRequestsPerProcess 10000
IdleTimeout 360
BusyTimeout 60
IdleScanInterval 30
BusyScanInterval 100
ZombieScanInterval 13
ProcessLifetime 3600
MaxProcessCount 40
DefaultMaxClassProcessCount 40
This counters depends of your setup and are not all necessary
The imported one is MaxProcessCount and DefaultMaxClassProcessCount
With those you can limit the count of processes
(every process will take a lot of memory so you need to calculate that you don't take to much memory)
(take in mind that you need also memory free for your disk cache)
Caching:
CacheDirLevels 2
CacheDirLength 1
CacheRoot /var/cache/apache2/mod_disk_cache
CacheEnable disk /images/
CacheEnable disk /sites/
Here you can specify what directory's you should cache
You can take all if you wish "CacheEnable disk /"
(Apache is reading the http headers to decide what to include into the cache)
RequestHeader unset Cache-Control early
Unset the RequestHeader for Cache-Control!
This wil ignore the cachecontrol from the clients
If you push F5 in firefox it will send a "max-age=0" in the header
This will force to drop you cache and request a update
Of course this is what you will prevent if you try to cache for performance
SuexecUserGroup mario mario
For security reasons the fcgi will be started as user "mario"
(you must chmod mario:mario /var/www/site/ so that fcgi has rights to use your php scripts)
AddHandler fcgid-script .php
Options +ExecCGI
FCGIWrapper /var/www/php5-cgi .php
AllowOverride all
Order allow,deny
Allow from all
Here I specify that .php must be handled by a external tool (fcgi)
cat /var/www/php5-cgi
#!/bin/sh
exec /usr/bin/php5-cgi "$@"
/var/www/php5-cgi must be owned by the user and group of SuexecUserGroup
(just to let it executed by this user)
Conclusion
With those configurations you can speed-up your php to the max of your hardware
Apache can handle more requests than using prefork(coz of memory)
static files will be cached (this helps a lot, a jpg of 5k without cache 300requests/sec, with cache 3000request/sec)
requesting the frontpage(php) was default 15rqst/sec, after implementing this I had 220rqst/sec
If you really need the power for thousands of users you can even let the fcgi running on other servers to spread the CPU usage
Proxy-ing is not a good idea with Drupal, (well if you only have anonymous users)
The only thing it does is giving a extra latency coz it always must forward the request to the backend.