{"id":152,"date":"2015-02-02T14:31:01","date_gmt":"2015-02-02T03:31:01","guid":{"rendered":"https:\/\/icicimov.com\/blog\/?p=152"},"modified":"2017-01-02T15:40:03","modified_gmt":"2017-01-02T04:40:03","slug":"server-side-php-caching-in-joomla-with-repcached","status":"publish","type":"post","link":"https:\/\/icicimov.com\/blog\/?p=152","title":{"rendered":"Server side PHP caching in Joomla! with Repcached"},"content":{"rendered":"<p>Caching provides significant performance speed up since reading data from the memory is much faster then reading it from the database or disk, especially if it resides on a different server. In our case they are on the same one but still in memory caching can provide some speed gains. Since our setup is fully HA we need to reflect this on to the caching as well, meaning data like PHP sessions needs to be cached on both nodes. One pretty simple solution is <code>Repcached<\/code>, which is nothing else but clustered <code>Memcached<\/code> daemon. On both nodes we do:<\/p>\n<pre><code>$ sudo aptitude install libevent1-dev\n$ sudo aptitude build-dep memcached\n$ wget memcached-1.2.8-repcached-2.2.1.tar.gz\n$ tar -xzvf memcached-1.2.8-repcached-2.2.1.tar.gz\n$ cd memcached-1.2.8-repcached-2.2.1\n$ .\/configure --enable-replication\n$ make &amp;&amp; sudo make install\n<\/code><\/pre>\n<p>which installs repcached in \/usr\/local\/bin\/memcached. Now we can start the service on both nodes:<\/p>\n<pre><code>root@ip-172-31-119-7:~# \/usr\/local\/bin\/memcached -m 128 -p 11211 -u memcache -X 11212 -x 172.31.19.153 -v\nreplication: connect (peer=172.31.19.153:11212)\nreplication: marugoto copying\nreplication: close\nreplication: listen\nreplication: accept\n\nroot@ip-172-31-119-53:~# \/usr\/local\/bin\/memcached -m 128 -p 11211 -u memcache -X 11212 -x 172.31.19.17 -v\nreplication: connect (peer=172.31.19.17:11212)\nreplication: marugoto copying\nreplication: start\n<\/code><\/pre>\n<p>and confirm they connect to each other and are ready for replication. The repcached listens on tcp port 11211 on the local node and accepts connections from its peer on tcp port 11212. To confirm the replication working we store some value on server 1 and read it on server 2:<\/p>\n<pre><code>root@ip-172-31-119-7:~# telnet 127.0.0.1 11211\nTrying 127.0.0.1...\nConnected to 127.0.0.1.\nEscape character is '^]'.\nset foo 0 0 3\nbar\nSTORED\n\nroot@ip-172-31-119-53:~# telnet 127.0.0.1 11211\nTrying 127.0.0.1...\nConnected to 127.0.0.1.\nEscape character is '^]'.\nget foo\nVALUE foo 0 3\nbar\nEND\n<\/code><\/pre>\n<p>and also the other way around:<\/p>\n<pre><code>root@ip-172-31-119-53:~# telnet 127.0.0.1 11211\nTrying 127.0.0.1...\nConnected to 127.0.0.1.\nEscape character is '^]'.\nset hello 0 0 5\nworld\nSTORED\n\nroot@ip-172-31-119-7:~# telnet 127.0.0.1 11211\nTrying 127.0.0.1...\nConnected to 127.0.0.1.\nEscape character is '^]'.\nget hello\nVALUE hello 0 5\nworld\nEND\n<\/code><\/pre>\n<p>Now we need to install and enable the memcache extension in PHP so we can utilize the cache:<\/p>\n<pre><code>$ sudo aptitude install php5-memcache php5-memcached\n$ sudo php5enmod memcache\n$ sudo php5enmod memcached\n<\/code><\/pre>\n<p>and configure it in <code>\/etc\/php5\/cgi\/php.ini<\/code> file by replacing:<\/p>\n<pre><code>session.save_handler = files\nsession.save_path = \"\/var\/www\/html\/tmp\"\n<\/code><\/pre>\n<p>with:<\/p>\n<pre><code>session.save_handler = memcache\nsession.save_handler = memcached\nsession.save_path = \"tcp:\/\/172.31.19.17:11211?persistent=1,tcp:\/\/172.31.19.153:11211?persistent=1\"\n<\/code><\/pre>\n<p>and reload apache on both nodes:<\/p>\n<pre><code>$ sudo service apache2 reload\n<\/code><\/pre>\n<p>As we can notice I already had PHP caching set to file system path <code>\/var\/www\/html\/tmp<\/code>, meaning caching on the shared file system, which is also an option for having a shared cache.<\/p>\n<p>Now we can enable the Joomla! built in <code>System Page Cache<\/code> plugin and the Module&#8217;s Cache under <code>Global Configuration --&gt; System<\/code>, by choosing the <code>Conservative Caching<\/code> option and <code>Memcached<\/code> as <code>Cache Handler<\/code>. After some time we will see some cached entries:<\/p>\n<pre><code>root@ip-172-31-119-7:\/var\/www\/html$ echo 'stats cachedump 3 10' | nc 0 11211\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-page-f411954e67e8df28227048b4ef13e318_lock [1 b; 1424136491 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-sh404sef_analytics_auth-068044fa245bc3e910a7df006eef5e64_lock [1 b; 1424091909 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-page-4af3ac7e45e5a5a85f3f2bb065da4e5f_lock [1 b; 1424079984 s]\nEND\n<\/code><\/pre>\n<p>in this case some page cache and cache from the <code>sh404SEF<\/code> Joomla! module. And if we check the values of the keys stored in slab 3 on the other server:<\/p>\n<pre><code>root@ip-172-31-119-53:~# echo 'stats cachedump 3 10' | nc 0 11211\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-page-f411954e67e8df28227048b4ef13e318_lock [1 b; 1424136491 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-sh404sef_analytics_auth-068044fa245bc3e910a7df006eef5e64_lock [1 b; 1424091909 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-page-4af3ac7e45e5a5a85f3f2bb065da4e5f_lock [1 b; 1424079984 s]\nEND\n<\/code><\/pre>\n<p>we will see they are identical, another confirmation the replication is working. And if we check slab 11 for example:<\/p>\n<pre><code>stats cachedump 11 100\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-mod_menu-769fa07cdfd70c7344d4827fdaddb672 [742 b; 1424664176 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-com_languages-150645621128f97f4134a1707ca9cc6c [814 b; 1424664159 s]\nITEM memc.sess.key.tpbetjdd03k0e4ju4vm30hl974 [975 b; 1424662910 s]\nITEM memc.sess.key.74fk4ufueaa17nvbhvutbg6sq1 [975 b; 1424662910 s]\nITEM memc.sess.key.p5m69ggh6j6f750di77m2d0oo0 [975 b; 1424662909 s]\nITEM memc.sess.key.beop5c8cclp2s2vq50kfuvtkp4 [923 b; 1424662907 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-mod_custom-6899858c5696c07d9e22ad099741eb11 [923 b; 1424657022 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-mod_menu-e3ab9c649c1884e99f65638867a4ccaa [742 b; 1424657022 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-mod_menu-05c788ee4b344a4d5a61f2adfbeffac4 [883 b; 1424657020 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-_system-a7be9b9967636d025387c33e073c5b05 [760 b; 1424657015 s]\nITEM ee9b6e4d56e7aaf7b015608a4ffd4465-cache-mod_breadcrumbs-78272508895bfe648dc479c8c1d49475 [720 b; 1424655525 s]\n...\n<\/code><\/pre>\n<p>we can see here caching from some other modules and some cached PHP sessions too (the memc.sess.key.* items).<\/p>\n<p>If we ever want to clear the cache we run:<\/p>\n<pre><code>$ echo 'flush_all' | nc localhost 11211\nOK\n<\/code><\/pre>\n<p>on both servers. Some other useful commands:<\/p>\n<pre><code>$ echo 'stats' | nc 0 11211\n$ echo 'stats items' | nc 0 11211\n$ echo 'stats slabs' | nc 0 11211\n$ echo 'stats sizes' | nc 0 11211\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Caching provides significant performance speed up since reading data from the memory is much faster then reading it from the database or disk, especially if it resides on a different server. In our case they are on the same one&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-152","post","type-post","status-publish","format-standard","hentry","category-server"],"_links":{"self":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=152"}],"version-history":[{"count":5,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions"}],"predecessor-version":[{"id":157,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions\/157"}],"wp:attachment":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}