Showing posts with label Memcached. Show all posts
Showing posts with label Memcached. Show all posts

Wednesday, 23 October 2013

Simple Spring Memcached [ Memcached + Spring Caching ]

Introduction

Memcached is undoubtedly one of the most popular distributed caching system used across applications. Through his post I will try to make you understand on how to integrate memcache with a Spring enabled applications. Since Spring directly supports only Ehcache therefore we will use google's SSM (Simple Spring Memcache ) to use spring caching abstraction.

Getting started

1. Dependencies - For downloading SSM dependencies add following to your POM. 
 
  com.google.code.simple-spring-memcached
  spring-cache
  3.2.0
 
 
  com.google.code.simple-spring-memcached
  spymemcached-provider
  3.2.0
 
 

2. Enable Caching – To enable caching in your spring application add following to your spring memcached.xml.
<cache:annotation-driven/>

3. Configure Spring to enable Memcached based caching  – Add following to your application memcached.xml.
 
 
    
      
        
          
          
          
          
          
        
         
           // "applicationData1" is 1st cache Name for your code
          
          
          
          
        
         
           // "applicationData2" is 2nd cache Name for your code
          
          
          
          
        
        
    
  

 
  
  
   
  
  
   
    
   
  
  
   
    
   
      
      
  
  
   
     
 

  
    
  

  
    
  
 
** Note: You have to keep on adding "applicationData1", "applicationData2" ......."applicationData.....N" if you have N number of cache name for your application. 

Limitation: You are having common key for two different value as mentioned below.

@Cacheable(value = "applicationData1", key = #EmployeeId")
@Cacheable(value = "applicationData2", key = #EmployeeId")

In above scenario two  same key are trying to put some value therefore one key will overwrite the other key value and will lead to data corruption. To avoid this we have to make our key unique. This can be achieved by adding a string in-front of the key as done below. 

@Cacheable(value = "applicationData1", key = "'applicationData1'+#EmployeeId")
@Cacheable(value = "applicationData2", key = "'applicationData2'+#EmployeeId")


If you have no constraint about overwriting cache value then there is no need for making your key unique and everything can be put in single memcache. 
As stated earlier in my different post "phpMemCachedAdmin" is a great tool to Monitor And Debug Memcached Server [ http://kulshresht-gautam.blogspot.in/2013/08/how-to-monitor-and-debug-memcached.html ]. In the snap below you can see that the key and it's corresponding size. Expiration time for these keys are infinite which is clearly visible from snapshot below.














How to install memcache : I had explained it here: http://kulshresht-gautam.blogspot.in/2013/07/memcached-installation.html


References:
https://code.google.com/p/simple-spring-memcached/wiki/Getting_Started
https://code.google.com/p/simple-spring-memcached/wiki/UserGuide#Cache_zone

Wednesday, 7 August 2013

How to Monitor And Debug Memcached Server Using phpMemCachedAdmin


Download phpMemCachedAdmin tarball


#wget http://phpmemcacheadmin.googlecode.com/files/phpMemcachedAdmin-1.2.2-r262.tar.gz


Install phpMemCachedAdmin in `/var/www/html/memcached/` directory, create a folder memcached inside /var/ww/html/. Extract phpMemCachedAdmin.tar.gz and change permission for Memcache.php

# mkdir -p /var/www/html/memcached
# tar -xvzf phpMemcachedAdmin-1.2.2-r262.tar.gz -C /var/www/html/memcached/
# chmod a+rwx /var/www/html/memcached/Config/Memcache.php

Apache Configuration

Create a file "memcached.conf" inside /etc/httpd/conf.d and add below configuration in that file.

# cd /etc/httpd/conf.d
# vim memcached.conf

Add below configuration in memcached.conf

Listen 85
<VirtualHost *:85>
    ServerName   10.23.11.11
    UseCanonicalName Off
    ServerAdmin  "kulshresht@xyz.com"
    DocumentRoot "/var/www/html/memcached"
    CustomLog  /var/log/httpd/memcached-access_log common
    ErrorLog   /var/log/httpd/memcached-error_log
</VirtualHost>

P.S: You can use any port for phpAdmin , whichever is free for you. In mine case 80 and 81 were already used , therefore i had used 85.

Restart Apache: /etc/init.d/httpd restart
P.S: Do not forget to install php to see the UI interface -> [ sudo yum install php ]

Few snapshots are attached below for reference:












If you want to explore further on Memcache installation steps then go to below link:
http://kulshresht-gautam.blogspot.in/2013/07/memcached-installation.html


Wednesday, 10 July 2013

How to install Memcache from source code

How to install Memcache from source code


There are two ways to install memcache :
  1. From some repository (CentOS,RHEL etc). [e.g: yum install memcached]
  2. From source code –> I would prefer this method because sometimes the CentOS or RHEL repository   doesn't have the latest version . I had personally faced this issue.

To cross check and verify that memcahe is installed and running fine. Try below command:


#netstat -nap |grep LISTEN |grep 11211
(No info could be read for "-p": geteuid()=507 but you should be root.)
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      -
tcp        0      0 :::11211                    :::*                        LISTEN      -

Note: If you are installing using source code the Libevent would be required. Install that using Yum command. http://libevent.org/

As I write the latest Memcahed version is 1.4.15 . Pick up the latest version from below link: https://code.google.com/p/memcached/wiki/ReleaseNotes

Start memcahe from command prompt :
Command : nohup /usr/bin/memcached -p 11211 -u memcached -m 4096 -vv -I 10 &
Alternative way : /etc/init.d/memcached start/stop

It's preferred to install memcache in /opt/ directory, if you are installing memcache from source code. So that you don't overwrite other version of any other software running on the machine.


Steps to install memcache from source code:

# wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz
# wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
# tar -xzf memcached-1.4.15.tar.gz
# tar -xzf libevent-2.0.21-stable.tar.gz
# tar -xzf memcache-3.0.6.tgz

# cd libevent-2.0.21-stable [ you can get it from http://libevent.org/ ]
# ./configure --prefix=/usr --libdir=/usr/lib64
# make
# make install

# cd ..

# cd memcached-1.4.15
# ./configure --prefix=/usr --libdir=/usr/lib64
# make
# make install



Classes, sizes, and chunks are shown best by starting up memcached with -vv:

[kulshresht@server123 bin]$ ./memcached -vv
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       120 perslab    8738
slab class   3: chunk size       152 perslab    6898
slab class   4: chunk size       192 perslab    5461
slab class   5: chunk size       240 perslab    4369
slab class   6: chunk size       304 perslab    3449
slab class   7: chunk size       384 perslab    2730
slab class   8: chunk size       480 perslab    2184
slab class   9: chunk size       600 perslab    1747
slab class  10: chunk size       752 perslab    1394
slab class  11: chunk size       944 perslab    1110


Please feel free to drop me a mail if you are facing any issue(s) with installation.

If you want to explore further about how to monitor and debug memcache, please got to below link:
http://kulshresht-gautam.blogspot.in/2013/08/how-to-monitor-and-debug-memcached.html

References:


How to Integrate tomcat with memcahed for session clustering

Integrating tomcat with memcached for session clustering



It’s bit confusing there. Will make it simple for you.

Download below four jars to your tomcat lib folder:
     1)  memcached-session-manager-1.6.4.jar
     2)   memcached-session-manager-tc7-1.6.4.jar
     3)  spymemcached-2.8.12.jar
     4)  couchbase-client-1.1.4.jar

And add below configuration in your context.xml file located inside /conf folder of tomcat.

<!--    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />   -->  
     <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                 memcachedNodes="n1:web1.prod:11211,n2:web2.prod:11211"
                 failoverNodes="n2"
                 requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        />

Restart your application and you are done with your tomcat-memcache integration. Wasn’t it quiet simple :)....

Few things to remember:
Tomcat-1 (t1) will primarily store it's sessions in memcached-2 (m2) which is running on another machine (m2 is a regular node for t1). Only if m2 is not available, t1 will store it's sessions in memcached-1 (m1, m1 is the failoverNode for t1). With this configuration, sessions won't be lost when machine 1 (serving t1 and m1) crashes.

<t1>   <t2>
  . \ / .
  .  X  .
  . / \ .
<m1>   <m2>


The default strategy uses java serialization and is already provided by the memcached-session-manager jar.

SERVER_ERROR object too large for cache

SERVER_ERROR object too large for cache

> I get "SERVER_ERROR object too large for cache" when reading a large 
> value from memcached.

Solution: Start memcache with -I option.
/opt/bin/memcached -p 11211 -u memcached -m 4096 -vv -I 10 &

Now memcache provides Configurable maximum item size

Many people have asked for memcached to be able to store items larger than 1MB, while it's generally
recommended that one not do this, it is now supported on the commandline. A few enlightened folk have also asked for memcached to reduce the maximum item size. That is also an option.
The new -I parameter allows you to specify the maximum item size at runtime. It supports a unit postfix to allow for natural expression of item size.
Examples:
memcached -I 256k # Refuse items larger than 256k.
memcached -I 5m  # Allow objects up to 5MB

Memcached used as session replication/manager


What is memcache?

Memcache is an in-memory, distributed cache. The primary API for interacting with it are SET(key, value) and GET(key) operations. Memcache is essentially a hashmap (or dictionary) that is spread across multiple servers, where operations are still performed in constant time.
The most common usage of memcache is to cache expensive database queries and HTML renders such that these expensive operations don’t need to happen over and over again.
But in this post I would be focusing on how can we use memcache for session-replication.

How is memcache so fast?

Memcache is so fast for two reasons: the cache is entirely in-memory; and operations are performed in constant time. Memcache avoids writing any data to disk, which results in faster operations and no fault tolerance. If the server running memcache is restarted, the keys on that server will be lost, which is fine for the use case of memcache, as a temporal caching layer and not a definitive data store. The use of constant time operations is simply a deployment of all those good old tricks and tips for a computer science algorithms & data structures class. O(1) is a nice property to have.

Eviction, Expiration, and Memory Limits

Besides getting and setting keys, eviction and expiration are major components of memcache, too. When a key is SET in the cache, an expiration is set along with the key. Most memcache clients have a default expiration which can be optionally overwritten on a per-key basis.
Memcache doesn’t evict keys when their expiration time expires, as doing so isn’t possible while still guaranteeing O(1) operation times. Instead expiration is more of a way to say how long until a key should be considered stale. When a GET is performed, Memcache checks if the key’s expiration time is still valid before returning it.
A key is evicted from the cache when the total cache size has reached the limit. Most memcache implementations offer a least recently used (LRU) eviction policy, which evicts the key that was least recently used when a new key is added to the cache and the cache has reached its limit.
In general, the higher your cache limit, the fewer evictions you’ll have, and the higher your hit-rate will be, ultimately resulting in better performance and scalability.

Eviction meaning in simple terms: Removes items from the cache to free memory for new items.
Note: A key/value pair stored in memcached can get evicted prior to its expiry if there is still free space available?

Memcache allocates space in chuncks vs on-demand, and then stores items into the chunks and manages that memory manually. As a result, smaller items can "use" much larger pieces of memory than they would if space was allocated on a per-item basis.










To see stats from server side . A quick way to get memcache status
[kulshresht@web06 bin]$ echo stats | nc 172.16.0.52 11211 STAT pid 6274 STAT uptime 1807302 STAT time 1373449782 STAT version 1.4.15 STAT libevent 2.0.21-stable STAT pointer_size 64 STAT rusage_user 3916.447609 STAT rusage_system 7673.810403 STAT curr_connections 28 STAT total_connections 7126 STAT connection_structures 31 STAT reserved_fds 20 STAT cmd_get 60623944 STAT cmd_set 65457134 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 27331 STAT get_misses 60596613 STAT delete_misses 25500664 STAT delete_hits 224497 STAT incr_misses 0 STAT incr_hits 0 STAT decr_misses 0
.
.
.
.
[kulshresht@server1 bin]$ telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. stats STAT pid 6274 STAT uptime 1808371 STAT time 1373450851 STAT version 1.4.15 STAT libevent 2.0.21-stable STAT pointer_size 64 STAT rusage_user 3919.035216 STAT rusage_system 7677.627823 STAT curr_connections 28 STAT total_connections 7131 STAT connection_structures 31

To get the beautful UI for memcahe go to below URL:
https://code.google.com/p/phpmemcacheadmin/

It's worth noting that memcached uses it's own slab allocator instead of using standard malloc()/free() in order to be speed up memory management.

Memcached allocates memory in blocks of 1MB (by default), referred to as a slab. Slabs belong to a slab class, which is defined by the size of item that is stored in that slab.Lets say that we have two slab classes, a slab class of 1KB and the 2nd class at 2.25KB (the default growth factor in slab classes is 1.25 ). An item of 500bytes or anything less than 1KB would get put into slab of 1KB slab class and any item  >1KB and <2.25KB will go in 2nd slab of 2.25KB.

Memcahe will make slab on it's own depending on need and demand. Just keep in mind to give -I parameter at the time of memcache startup. Otherwise you will get "SERVER_ERROR object too large for cache" if cache exceeds the maximum slab size which is 1 MB by default.

memcached -I 10m  # Allow objects up to 10MB

For my application memcache made 52 slabs and max chunk size was of 10MB.

We can refuse items larger than particular size too. e.g: memcached -I 128k # Refuse items larger than 128k.

When an itme is stored then first there is a check to see which class it should fall into , based on it's size, and then memcached will check that class's stack to see if there are any empty spots available. If not, a new slab will be allocated to store the new item.

All this leads to one conclusion, that there is some tradeoff in unused memory. Not every item is going to be exactly the size defined by the slab class, or you could have just one item stored in a class for items of size 1k, meaning that 1MB is allocated just to store that 1k item. But these operations are very fast and very simple.