Hello,
I would like to seek your advice on what else that I need to do in order to speed up Drupal site. Its really slow for logged in users . The only thing that is good now is Boost , which also has some problems on its own that i worked around.
My site is on a dedicated server on HostGator. Here's what I have so far:
Installed Boost - running ok for anonymous users. Problems with the login block being visible after logging out. I solved this (almost) by ajaxifying the login block (i just wrote my custom code)
Installed AuthCache and XCache - no noticeable speed gains for logged in users . Authcache refuse to cache pages with Views error.
Removed AuthCache, uninstalled XCache.
Installed mod_deflate and APC. Still slow.
As for the database config, i increase the query cache size, hacked views module to include a SQL_CACHE to every SELECT query.
Im running out of tricks so to speak. The site is getting nearly launched and I would really like to make the experience of the logged in users in a acceptable speed.
Here's the server spec:
Intel Xeon 3470+ (Quad Core)
8 GB DDR3 Memory
2 X 500 GB Hard Drives
10 TB Bandwidth
5 Dedicated IPs
Thanks in advance. I hope you can help me.
Ryan
Comments
It sounds like you're not
It sounds like you're not using Varnish Cache?
Are most of your visitors anonymous?
Have you also looked into MySQL alternatives like MariaDB or PerconaDB?
I would also look into tuning your MySQL:
https://github.com/rackerhacker/MySQLTuner-perl
These are just a few suggestions.
My users are mostly
My users are mostly authenticated. Im also trying to follow the recommendation the mysql tuning primer.
It sounds like you are just
It sounds like you are just randomly applying performance tuning techniques but you don't really know what you problem is yet. Figure out what the problem is, then apply the most appropriate fix. Randomly applying performance techniques will only multiply your problems.
--
Dave Hansen-Lange
Director of Technical Strategy, Advomatic.com
Pronouns: he/him/his
Agreed 1000%. Check to make
Agreed 1000%. Check to make sure your DB is the actual problem. Using query logging from the Devel module helps with this. Also make sure that APC is actually running. There is a file called apc.php that comes with APC. Put that where you can access it via a web browser and look to see if things are actually being cached.
HollyIT - Grab the Netbeans Drupal Development Tool at GitHub.
I have to agree I am just
I have to agree I am just trying things out randomly. APC is running, I can see it when I run phpinfo(); . A while ago I disabled dblog and it speed up a bit.
How can I profile my website ? I already have xdebug installed but the output points to call_user_func_array which is being called multiple times.
I also tried to output the devel query info - I saw that "SHOW TABLES" is called very often that's why I hacked the core mysqli.inc. What I did was I set a static variable and assigned the output of SHOW TABLES in a static array.
Here's my apc config : http://pastie.org/3180234
32MB may not be enough
32MB may not be enough memory. Install apc.php and check your "Cache full count".
Given that module list, 32mb
Given that module list, 32mb is no where near enough. I would say more like 128mb. But the only real way to tell is looking at apc.php.
HollyIT - Grab the Netbeans Drupal Development Tool at GitHub.
The problem
Isn't the problem that Drupal executes approximately 300 sql queries per authenticated page request? No amount of mysql optimisation is going to get around that.
The only solution that I've found is Authcache which delivers easy, instant, massive performance increase.
It sounds like you are
It sounds like you are putting a band-aid over a gaping wound. I've never had a D6 or D7 site have 300 queries on a page. If you can figure out how to fix that problem, then you will fix things everywhere. Whereas with Authcache there will still occasional cache misses.
--
Dave Hansen-Lange
Director of Technical Strategy, Advomatic.com
Pronouns: he/him/his
Question about modules
Hi Ryan,
+1 on the checking APC config.
Also, which/how many modules do you have installed and do you have tons of data? The specific module mix can be a factor.
-Darrell
Drupal StackExchange
I only have 12,000+ data (8K
I only have 12,000+ data (8K nodes , 3K user records) . As for the modules : http://pastie.org/pastes/3180216/text
APC et al
Another +1 to check apc.php first of all.
If it doesn't help, and you need to dig deeper, you can run xhprof. It will show you more precisely what is your bottleneck.
If you ever figure out what
If you ever figure out what the problem was, please don't forget to come back to this thread and let us know. I, for one, am intensely curious as to how you managed to make a site run slow on that kind of hardware when it hasn't even launched yet.
The Boise Drupal Guy!
Agree
Yes, hardware is impressive, so slowness is strange
I think one factor is that
I think one factor is that the resources above are shared between three websites - one running ruby on rails, the other two on PHP (KohanaPHP and Drupal). Plus the server also hosts a sphinx daemon which is being queried by 7 external websites.
Ruby on rails is a resource hog (using mongrel) . I am converting that site to Drupal pretty soon! The other PHP site built with KohanaPHP serves as the backend for the Ruby on Rails website and thus their DB is shared.
Edit : Its good that KohanaPHP supports APC cache. I also increased the apc.shm_size to 256MB. What's about apc.slam_defense?
Just a quick question. I'm
I leave slam_defense at the default. Shouldn't be a big deal unless you restart php often and/or have many thousands of files.
Just a couple quick questions.
I'm assuming Apache2, but worker or prefork?
What version of APC?
Why the complex filters? I see no apc.cache_by_default so I can assume it's at the default of 1, "on"? Which means that your + filters are extraneous and only the -admin is doing anything.
I've never had a Drupal php file go over 1M (though boost is right about 950k and views3 admin.inc is 812k) but I do apc.max_file_size=2M to be safe.
APC Version 3.1.9 PHP Version
APC Version 3.1.9
PHP Version 5.2.17 running as FCGI
I set apc.shm_size to 256MB mainly because the site im configuring isn't the sole site that use APC. As I've mentioned, KohanaPHP also has the option to use APC for caching, luckily. I use APC for the other site mainly for storing search-objects found by sphinx.
I'm interested to know what the optimal setting for TTL and slam defense. I dont reset php often but i might have thousands of cached objects for sphinx search results.
I've managed to bring the page execution time to 400ms for authenticated users with APC enabled. I didn't get much results with xcache. Also setting apc.stat to 0 speed things up a bit.
Boost is still running for anonymous users. Can APC handle anonymous traffic too?
Thanks a lot for your advice about APC . Im still observing and checking if the site needs more, then I may have to throw in memcache.
FCGI is where your problem
FCGI is where your problem is. It can't share cache across processes. I would suggest going to mod_php and then try APC for opcode and Drupal's object cache. You'll probably see a big improvement. I run mod_php + APC on one client's site with almost the exact same specs as your server. The module load is a little lighter, but not much, plus Drupal is running 5 sites on it. Our average response time for logged in users is about 500ms. That's with over 50,000 nodes, 40,000 users and 2 million+ comments. We even had one period where we got over 60,000 page views in one hour and the server load never went above 3.
HollyIT - Grab the Netbeans Drupal Development Tool at GitHub.
Jamie types faster than
Jamie types faster than me.
You can go back to apache-prefork + mod_php but that introduces other issues with memory management.
I could suggest nginx+php-fpm or apache-worker + php-fpm, either of which would give you the memory advantages of light processes for non-php requests, but then you'd need to upgrade to php 5.3 and the possibility that some rare community module might need a patch for 5.3 compatibility. This scares some people away, though it shouldn't.
Sorry to open a new can of worms on you.
Your response time is
Your response time is impressive. I'm going to request to scrap FCGI in favor of mod_php.
Edit : I saw this email from HostGator support when I requested to install APC and dump XCache :
"We wanted to check with you before installing APC. APC requires that your php handler be set to FCGI, or DSO (we recommend FCGI). You are currently using php as suPHP. Also, please note that when using APC, ioncube and zend optimizer will have to be disabled for php."
Hello, My shared hosting is
Hello,
My shared hosting is using PHP as "Server API : CGI/FastCGI" and allows APC with 64M.
And when I check apc.php, all seems ok :
Cache full count : 0
Fragmentation : 0%
All php files seem to be stored permanently and there the APC memory doesn't seem to be flushed and rebuilt after each process.
Maybe my hosting configuration allows using APC with CGI/FastCGI?
400ms sounds pretty good.
400ms sounds pretty good. Nice work.
apc.stat does give a boost, but you have to remember to clear the cache or restart php every time you update a module. The day you forget is the day some change in a module will start giving your visitors a white screen of death. Been there.
The fact that you're using apache2 worker and php through fcgi makes me question whether you're actually getting the benefit of apc at all. Unfortunately, I'm not an expert on configuration issues of apache2 worker, since I personally use nginx+php-fpm. Since you're using php 5.2.xx I'm going to assume that you're not using php-fpm.
Probably most of us assumed incorrectly that you use apache-prefork with mod_php which works beautifully with apc. But if you're using apache-worker, like it sounds that you are, you don't get the benefit of one apc cache being shared among all processes. Apache-worker has all sorts of other advantages.
I'd like other folks to chime in on this, but I can direct you to two good articles. One is by the highly respected Drupal house 2bits: http://2bits.com/articles/apache-fcgid-acceptable-performance-and-better... where Khalid concludes: "Although we have not dug too deep into it, we have found is that APC is not shared among the processes. And because the php-cgi processes are killed and new ones spawned, the persistence of APC's user/data cache cannot be relied upon. This is not important for most users, but if you are using things like the Drupal cache router module or the performance logging module, this will impact you."
And that brings up another point. You list cacherouter among your modules, but you don't say you're using memcached. So you could possibly be using the APC user cache, but most folks prefer memcached for cache use.
2ms sounds even better ?
I'm currently generating pages for logged in users in less than 2 ms.
Strangely, the Drupal community seems entirely disinterested ...
I'm interested. We have a
I'm interested. We have a development group that uses over 500 modules and eat over 200M of RAM per request. Exec's say throw hardware at the problem ... well, we've thrown all we can at it.
Ye gods! How can you
Ye gods! How can you possibly be using that many modules?
You had me at "2 ms" ;) Care
You had me at "2 ms" ;)
Care to do a bit of a mini-writeup?
Regarding APC and anonymous
Regarding APC and anonymous users, sorry if this gets basic since you're talking about using sphinx you seem to be a sophisticated user, but other folks might not know this stuff.
APC can act as an opcode cache (or any opcode cache, e.g. xcache, eaccelerator) storing a machine language compiled copy of your php script code in memory so that the next time that same php routine is called, it doesn't have to compile on the fly again. This is a way to address the slow speed of non-compiled scripting languages such php and is usually a huge boost.
If however, fcgid is generating a new process each time, which is does by default, then you're just wasting processing power and time generating an apc cache of the code just to have that process die shortly after. There's no persistent, shared memory copy of the compiled code used by all php processes.
If you're using Boost you're talking about serving a static Boost file (or using a reverse proxy like Varnish, nginx, etc.) which keeps its own copy of a generated page separate from php. So in that case you're taking php out of the equation and so an opcode cache doesn't help serving anonymous traffic except each time the page changes and is generated anew.
Then there's the other issue of apc/memcached/cacherouter. Drupal generates all sort of cached content, including variable, theme files, views, and also full pages if you're using Drupal built-in full page caching. With Boost installed you usually have built in full page caching off. The default is to store all that cache data in the mysql database. However, since it's really just simple key-value pairs, and doesn't need any advanced relational database features, that stuff can be offloaded to a simple and fast key-value store such as memcached, APC "user" cache which is different than opcode cache, redis, etc.
Since this takes all sorts of cache set and get functions away from mysql this can produce a speed improvement with logged-in users.
So you have cacherouter installed, and you might have it configured to use APC as that "user" cache. Again, completely different than using APC as an opcode cache. Or you might not have configured cacherouter with the special lines in settings.php to make it work with APC as a "user" or "data" cache.
Going back to FCGI from mod_php
So we switched from FCGI to mod_php to better exploit APC. Now my biggest problem is apache runs as 'nobody' while all my scriptsand directories are owned by the account I login with via SSH. With Apache as nobody drupal can't create directories and i had to change permissions to 777 which I really don't like.
Do you have any workaround for this 'nobody' user issue? Im afraid I'll have to ask HG to go back to FCGI, observe the performance and then decide.
Thank you for all your help so far. I learned a lot from you guys!
You could start here
You could start here http://www.practicalweb.co.uk/blog/11/05/31/drupal-files-directory-permi... and roll your own from there.
Full Fat Things ( http://fullfatthings.com ), my Drupal consultancy that makes sites fast.
You set the user and group
You set the user and group Apache runs under in httpd.conf. Best thing is to have Apache run under its own user/group, then make the directories group writable and put yourself in that group so you have access to the file system.
EDIT: Oh and make your web files owner/group your apache user/group.
HollyIT - Grab the Netbeans Drupal Development Tool at GitHub.
Before switching to mod_php,
Before switching to mod_php, all our Drupal files, including contributed and custom modules have 'myusername:myusername' as user and group respectively. When switch to mod_php, it runs as nobody so it can't write to the existing site/default/files directory owned by myusername.
But I think apache can still run my php files because it's permissions are set to 444. I tried editing :
r--r--r myuser myuser template.php
and it was still picked up and processed by apache. I think i just need to set the ownership of sites/default/files to nobody user so that it can still upload the files.
Thanks. Im staying with mod_php.
Might be a really bad module?
Try to run tests that you can measure. E.g. https://github.com/luckow/DrupalSiege (I haven't pulled latests D7 updates on this script yet, see the repo I forked from).
Then disable one module at a time and see if there's a big difference somewhere.
Need to attention on some basic things
Followings things can be done for enhance the performance of site.
These are the basic steps to resolve the issue in site and also many thing can be done in order to enhance the performance of site.
Thanks,
Tech Musings
A couple websites to check out...
Try checking out these sites I've found them useful!
https://developers.google.com/pagespeed/
http://developer.yahoo.com/performance/rules.html
Steps to take after pressflow/cachegrind
Once you have a cachegrind of your site and have switched over to pressflow; checkout the wiki on for patches that improve performance even more: http://groups.drupal.org/node/187209
The first 3 patches are a no brainier; the rest are highly dependent on your setup; some may help performance, some may hurt performance. cache grind is there to help you figure out what core patches work best for you. First 3 patches (the no brainiers):
Cache module_implements()
Optimize element_children()
_menu_link_translate() might avoid calling _menu_load_objects() (if using views module)
Note that APC could give you
Note that APC could give you worse times if you don't give it enough memory; this is because of fragmentation. Just make sure via apc.php that you always have some free memory left after regular use and fragmentation is very low (in our site we always run at "0% fragmentation" according to apc.php)
Interesting. How can I make
Interesting. How can I make sure that fragmentation stays nearest 0%?
Just use the apc.php file and
Just use the apc.php file and monitor your memory usage for a few days. Make sure you always have a little bit of free memory in APC and not using it all up.
HollyIT - Grab the Netbeans Drupal Development Tool at GitHub.
Give it enough memory
Giving APC enough memory appears to prevent fragmentation. There is a nice article about APC here: http://xerosphere.net/optimizing-apc-for-drupal
--
Perttu Ehn
Adjust apc.max_file_size
On a related note, some module files are larger than the apc.max_file_size default of 1M and will be left out of the APC file cache unless this is bumped up a bit.
Drupal / APC returns garbage data
I've been having these problems for 3 days now. I enabled the watchdog to log any errors in my site. I saw an error,copied the link address, logged out and viewed the said page as anonymous and it displayed garbage data. When I clear APC cache it went ok again. Any more ideas?
Disabled Cache Router
I've disabled Cache Router and every problem went away. Fragmentation never hit 1%.
I would suggest persisting
I would suggest persisting with Authcache. (It's the only way I've found so far of getting decent (excellent in fact) performance for authenticated Drupal users.
I ported the Authcache module from D6 to D7 and in the process reduced my page generation times from ~950ms with 1 concurrent user down to about ~0.8 ms with 125 concurrent users.
I've published some benchmarks here.
http://groups.drupal.org/node/206138
Note: You need to be using either FileCache or MemCache along with AuthCache otherwise you will only get a very modest speed increase. However, once it's working your site will fly :)