You need to understand the clear distinction between these two products to understand how to use them.
- APC is both an OPCode Cache and Fast Backend
- Memcache is just a Fast Backend
Using APC as an OPCode Cache
Simply install the module on your server
pecl install apc
And enable it in your php.ini
echo "extension=apc.so" >> /usr/lib/local/php.ini (RedHat/Centos)
echo "extension=apc.so" >> /etc/php5/conf.d/20apc.ini (Debian)
You then enable and fine-tune the runtime configuration to suit, eg.
apc.enabled
apc.shm_segments
apc.shm_size
apc.optimization
apc.num_files_hint
apc.user_entries_hint
apc.ttl
apc.user_ttl
...
Then restart PHP/Apache
/etc/init.d/httpd restart (RedHat/Centos)
/etc/init.d/apache2 restart (Debian)
After that, there is nothing else to do. Confirm APC is enabled with a quick phpinfo()
- but otherwise, at this point, the OPCode cache portion of APC is active.
Nothing needs to be configured on Magento's side.
Using APC as a Fast Backend
You need to add the following to your ./app/etc/local.xml
<global>
...
<cache>
<backend>apc</backend>
<prefix>mystore_</prefix>
</cache>
...
</global>
Then flush your existing store caches. To verify it is working, load a page in the front-end and the ./var/cache
directory should remain empty.
Using Memcache as a Fast Backend
You'll need to install Memcache as a PHP extension, and install the respective Memcache Daemon (Memcached) on your server.
pecl install memcache
And enable it in your php.ini
echo "extension=memcache.so" >> /usr/lib/local/php.ini (RedHat/Centos)
echo "extension=memcache.so" >> /etc/php5/conf.d/20memcache.ini (Debian)
/etc/init.d/httpd restart (RedHat/Centos)
/etc/init.d/apache2 restart (Debian)
Then install Memcached on the server. For RH/Centos, adjust the URL to suit your release version and CPU architecture.
rpm -Uhv http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
yum --enablerepo=rpmforge install memcached
apt-get install memcached (Debian)
Then modify Magento to use Memcache as a fast backend, change the socket path to a TCP/IP connection to suit.
<cache>
<slow_backend>database</slow_backend>
<fast_backend>memcached</fast_backend>
<fast_backend_options>
<servers>
<server>
<host>unix:///tmp/memcached.sock</host>
<port>0</port>
<persistent>0</persistent>
</server>
</servers>
</fast_backend_options>
<backend>memcached</backend>
<memcached>
<servers>
<server>
<host>unix:///tmp/memcached.sock</host>
<port>0</port>
<persistent>0</persistent>
</server>
</servers>
</cache>
The caveats of Memcache and tagging - what is it storing
Memcache only supports a single level of key-value relationships, so it cannot store the Magento cache tags (that are used to flush cache data independently). As a result, you either need to specify a slow_backend
to maintain the cache content tag relationship, or don't define one at all.
If you define a slow_backend
, you run the risk of the cache tags growing so large that performance is negated; there is also the inherent problem that you cannot scale across multiple servers if each server is maintaining their own cache tags.
So when using Memcache, the better approach (with the caveat you cannot flush caches independently), is to not bother using the slow_backend
.
In which case, we suggest removing <slow_backend>database</slow_backend>
and replacing it with:
<slow_backend>Memcached</slow_backend>
<slow_backend_options>
<servers>
<server>
<host>unix:///tmp/memcached.sock</host>
<port>0</port>
<persistent>0</persistent>
</server>
</servers>
</slow_backend_options>
This will break/disable the 2nd level of caching (and prevent tag storage), but still allow the performance of Memcache.
Which to use
If its a single server deployment - there's no harm just using APC for everything.
If its a distributed set-up - then you'll need to use Memcache as the fast backend (so that all machines can access the common store).
More concerning is that if your hosting provider can't tell you the right set up to use, you are certainly with the wrong host.
Attributions: sonassi.com, php.net, repoforge.org
There are two difficult things in computer science:
- Naming things
- Cache invalidation.
Hole punching falls into category #2 :)
General
The best approach is to start at the lower points of the stack and optimize up to the frontend of Magento.
Database and Filesystem
Should always be the first areas to focus on. Because. I/O.
MyTop is a handy Linux based perl script that will mimic the Linux 'top' command and give you insight on the state of your MySQL instance(s).
Htop is a more robust top, The strace feature can help determine ins/outs of a process to find potential bottlenecks.
Iotop is another tool to consider for monitoring I/O.
Other handy utility scripts like mysqltuner.pl and mysql tunning primer can offer insight into your MySQL runtime variables and offer advice to help. Keep in mind these are meant to be guides as the best approach is always an evaluation of requirements and tuning based on known data gathered. Blindly doing so can cause more damage at times than good. And prematurely running these without at least 24 hours of mysql runtime variables may offer bad advice.
Keep in mind Percona, MariaDB and standard MySQL should work with all of the above. Favoring Percona as a MySQL fork, since Magento is so heavy on InnoDB and XtraDB offers many tools and enhancements to the db engine.
Apache or Nginx
Still using Apache as it has served many others well, myself included. I have used and configured Nginx as well. While it does offer some advantages there is a learning curve. While the two are both popular options, it does offer some advantages over Apache, one would be a smaller memory footprint. However a slim downed Apache running PHP-FPM will have a similar memory footprint.
Case in point:
Since this article was about performance, I should point out that one
of the easiest ways to help apache get out of its own way is to not
use .htaccess files. Put what you'd put there in your Directory
stanzas, set AllowOverride to "None" and you end up not asking apache
to traverse the whole document path to figure out if it needs to pay
attention to .htaccess or not. This is a basic, simple tuning hint
that many people seem to miss.
To help facilitate this check out:
Utilizing a CDN to help take the ease off of either will help obviously but will have added benefit on frontend optimization since most end users browsers will be able to connect to both servers with the same number of connection limits. This also frees up Apache from not having to jump through checks and such just to serve up a simple static image. Lighthttpd is an option if you want to run a static web server just for content besides a CDN.
PHP
PHP-FPM and APC. Use them, strip out any unneeded or unrequired PHP modules not needed for Magento.
Magento codebase
AOE_TemplateHints is great to determine if your blocks are caching properly:
AOE_Profiler is good for profiling, be sure and enable its DB layer profiling (in a local/dev environment obviously). This in conjunction with the mytop tool mentioned previously makes finding bad behaving SQL an easier task.
3rd Party modules & Custom code
Some very good best practices for optimization from Magento themselves is a good read, and to keep in mind when reviewing 3rd party modules before using them. (there are lots of bad behaving ones IMO).
A tool Magniffer from Magento ECG will help easily identify bad behaving code based on the PDF provided above. It is symfony/php-parser based however but installable via composer.
Varnish
As an advocate of Varnish being the author was a FreeBSD kernel dev, it offers some crazy sub second load times. However if you even have some of the slightest differences in your templates that isn't out of box, you will spend time configuring varnish / magento to holepunch the content you need. Most I've seen will simply AJAX'ify the needed items uncached from Varnish.
There are a number of Magento modules to help facilitate this hole punching and caching:
Ultimately this should be at the last end of your optimization journey, and MAY require some customization to get things right.
Magento CE FPC
So far the best CE FPC I have found is: Lesti::FPC
it is a very well put together (all observer based) open-source and free FPC for Community.
At the end of the day use your own testing and judgement.
Some further reading:
Best Answer
I investigated even more and I think I finally solved the issue. So what can you do to analyse such an issue?
In order to have a good idea when the cache becomes too large and if the problem is really the cache size, add a cronjob which calls the following script e.g. each 15 minutes:
Then you can analyse the contents of
/html/cache_log
to see how the cache size develops, when your page becomes too slow and if the root cause is really the cache.Analyse your cache files. Therefore, it is quite helpful to write all cache files into a log file with e.g.:
Have a look at this file and the file names within. What kind of cache files are there? Is there anything suspicious? In my case, there were a whole lot of cache files containing
AMSHOPBY
in their file name - a reference to the Amasty Improved Navigation (Amasty_Shopby
) extension. It was creating a whole lot of cache files. Some of them looked quite weird to me. Disabling the Amasty Improved Navigation cache solved the problem instantly. I contacted their support with a detailed description and the support was really good. The caching strategy was quickly completely overhauled and is now much better. They promised to integrate the patch in the next version of the extension, so every version > 2.8.3 should be fine.Good luck in finding the root cause for your big cache!