Magento – Improving Speed with APC and Memcached

backendcachece-1.7.0.2full-page-cacheperformance

We have studied many forums and don't know the answer to the following. We have both APC and Memcache installed on our servers. We are not sure what the correct and best config is.

My question

What are/is the best settings for running Magento using both Memcache + APC at the same time? (Or is this not smart at all)

Background research

Here Memcache and APC are advised as fast and slow cache (but no disk). Sounds like this only works when you have enough RAM (and sure about it)

And this article is about Memcache or APC – and we have both

And here it states that Memcache only really works when you also have a slow backend defined

And I think this article is saying the same

This is my ISP's solution for local.xml

<cache>
  <backend>apc</backend>
  <prefix>sitenamehere__</prefix>
</cache>
<cache>
  <backend>memcached</backend>
  <memcached>
    <servers>
      <server>
        <host><![CDATA[127.0.0.1]]></host>
        <port><![CDATA[11211]]></port>
        <persistent><![CDATA[1]]></persistent>
      </server>
    </servers>
    <compression><![CDATA[0]]></compression>
    <cache_dir><![CDATA[]]></cache_dir>
    <hashed_directory_level><![CDATA[]]></hashed_directory_level>
    <hashed_directory_umask><![CDATA[]]></hashed_directory_umask>
    <file_name_prefix><![CDATA[]]></file_name_prefix>
  </memcached>
</cache>

Situation

Shared hosting
Brim FPC installed: http://ecommerce.brimllc.com/full-page-cache-magento.html
(this FPC also has a scaleable file cache to make it more complex)

Best Answer

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