I am tweaking my homepage for performance, currently it handles about 200 requests/second on 3.14.by which eats 6 SQL queries, and 20 req/second on 3.14.by/forum which is phpBB forum.
Strangely enough, numbers are about the same on some VPS and dedicated Atom 330 server.
Server software is the following: Apache2+mod_php prefork 4 childs (tried different numbers here), php5, APC, nginx, memcached for PHP sessions storage.
MySQL is configured to eat about 30% of available RAM (~150Mb on VPS, 700Mb on dedicated server)
This looks like there is a bottleneck somewhere not allowing me to go higher, any suggestions? (i.e. I know that doing less than 6 SQL's would make it faster, but this does not look like a limiting factor, as sqld eats no more than a few % in top due to cached queries)
Has anyone tested that kicking preforked apache2 and leaving just nginx+php is much faster?
Some more benchmarks
Small 40-byte static file: 1484 r/s via nginx+apache2, 2452 if we talk to apache2 directly.
Small "Hello world" php script: 458 r/s via ngin+apache2.
Update: It appears bottleneck is MySQL performance on cached data. Page with single SQL shows 354req/sec, with 6 SQL's - 180 req/sec. What do you think I can tweak here? (I can fork out 100-200Mb for MySQL)
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
default-character-set=cp1251
collation-server=cp1251_general_cs
skip-character-set-client-handshake
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
skip-external-locking
bind-address = 127.0.0.1
key_buffer = 16M
max_allowed_packet = 8M
thread_stack = 64K
thread_cache_size = 16
sort_buffer_size = 8M
read_buffer_size = 1M
myisam-recover = BACKUP
max_connections = 650
table_cache = 256
thread_concurrency = 10
query_cache_limit = 1M
query_cache_size = 16M
expire_logs_days = 10
max_binlog_size = 100M
[mysqldump]
quick
quote-names
max_allowed_packet = 8M
[mysql]
[isamchk]
key_buffer = 8M
!includedir /etc/mysql/conf.d/
Obviously, there is a lot you can try. Your best bet is chasing your logs for queries that don't use indexes (enable logs for those) and other non-optimized queries. I have compiled a huge list of performance related options over the years, so I've included a small subset here for your information - hopefully it helps. Here are some general notes for things you can try (if you haven't already):
MySQL
Apache
PHP
OS Tweaks
If the bottleneck is not CPU, then its IO - either network or disc. So.. you need to see how much IO is going on. I wouldn't have thought its the network (unless you're on a 10mbps half-duplex link, but its worth checking the switch in case auto-detect isn't doing its job right).
That leaves disk IO, which can be a big factor especially on VPSs. Use sar or iostat to have a look at the disks, then google how to find more details if your disk is being used heavily.
I would look into caching with either Nginx (memcached) or Varnish.
By the very least you should server static files with Nginx like SaveTheRbtz said.
As the server doesn't seem to be problem, maybe the load generator is. Try to run it on it on several machines.
It sounds to me like you might be hitting the maximum amount of connections Apache lets in. Take a look at your Apache configuration. Increasing server limit and max clients should help if you are not already bound by some other limit like I/O or memory. Look at the values present for mpm_prefork_module or mpm_worker_module and adjust accordingly to meet your needs.
Is this load generated by a tool or real-world loads?
You may want to check memcached. I've seen issues at high connection rates of it causing latency in the application.
If using a load generator, what do you get when hitting a small static page?
During the loads, you may want to check the network stack for TIME_WAIT conditions. Perhaps you are filling up your connection queue.
There's about a 100 more reasons and items you can look at but without more information, I'm just throwing out guesses at this point.
99% percent of the time issues like this will trace back to the database. Make sure your hitting indexes first of all. If that doesn't work, start caching everything that you can.
I recommend you to use (if possible) a connection pooler to keep the database connected to your web applications (no needs to reconnect at each requests). That can make an huge difference of speed.
Also, try to analyse all your queries with EXPLAIN (and why not profile your queries with SHOW PROFILE ?).