CACHING
MEMCACHED vs. REDIS vs. FILESYSTEM
Brown Bag Session
Rafi Adnan
Faisal Islam
What is caching in web
application?
Web application caching is the process of storing dynamically generated
data for reuse and leaving data closer to the end user.
How Caching Works
Traditional Data Query
(Without Cache)
Query
Get Rows From Return Rows to
Database Application
Cached Data Query
Query
Data
Return Row to
In
Yes Application
Cache
No
Insert Rows
Get Rows Into
From Database Cache
Cache
Database Storage
Why we use?
➔ Better performance
◆ System loads faster/better responsiveness
➔ Better scalability
◆ Limit bottlenecks in a system
➔ Better robustness
◆ Can support more load
When to use?
Don’t be premature
Profile your application to find operations
that consume significant CPU time and/or
memory
Caching
Terminology
[ Cache Hit ] [ Backing store ]
when requested data is contained in the cache persist cached data on disk
[ Cache Miss ] [ Cache Scavenging ]
when requested not in the cached, has to be deleting items from the cache when
recomputed or fetched from original storage memory is scarce
[ Cache Key ] [ Local Cache ]
unique identifier for a data item in the cache caching data on clients rather than on
servers
[ Expiration ]
item expires at a specific date (absolute), [ Distributed Cache ]
specifies how long after an item was last extension of the traditional concept
accessed that is expires (sliding) of cache that may span multiple
servers
Advantages
❖ Speed up application
❖ Less Resources Used
❖ Reuse content
Disadvantages
❖ Stale Data
❖ Overhead
❖ Complexity
Type Of Caching
❑ Client Caching
- browser caches URLs for future uses
- Mozilla Firefox, Google Chrome
❑ Proxy Caching
- proxy server caches most requested URLs
- Varnish ( reverse proxy )
- CDN ( forward proxy )
❑ Server-side Caching
- server side cache reduces load on server
- File System Cache
- In-Memory Cache (MemCached, Redis)
File Cache
A file of data on a local hard drive. When
downloaded data are temporarily stored on the
user's local disk or on a local network disk, it speeds
up retrieval the next time the user wants that same
data (Web page, graphic, etc.) from the Internet or
other remote source.
In-Memory means
We are Bound By RAM
MemCached
Memcached is an in-memory key-
value store for small chunks of
arbitrary data (strings, objects) from
results of database calls, API calls, or
page rendering.
Redis
Redis is an open source, advanced key-
value store. It is often referred to as a
"data structure server" since keys can
contain strings, hashes, lists, sets and
sorted sets.
How to use?
[ File System Caching ] [ In-Memory Caching ]
➔ It works without any ➔ Need to install and configure
additional server. Most of the cache server
CMS by default use file cache ➔ Need client library to access
without any configurations. cache
➔ Most of the popular
framework has very good
built-in or third-party library.
In-Memory Cache ( Server - Client )
Installing memcached server (ubuntu): Installing redis server (ubuntu):
sudo apt-get install memcached sudo apt-get install redis-server
Installing memcached client(ubuntu): Redis client 3rd-party packages:
PHP : PHP :
Predis , phpredis
sudo apt-get install php5-
memcached Ruby on Rails :
redis-rb, em-hiredis, redic
Ruby on Rails :
Python :
Popular gem called Dalli redis-py, txredisapi, brukva
([Link]
) ([Link]
MemCached
➔ Dead Simple & Battle Tested
➔ Fast
➔ Non-Blocking get()/set()
➔ Multi-Threaded
➔ Consistent Hashing
Code Example - Memcached
$memCached = new Memcached();
Client
//connect with memcached server
$memCached->addServer('[Link]', '11211');
Server Addr
const INT_EXPIRATION_TIME_IN_SECONDS = 2;
//Set cache
Port
$memCached->set('key_1', 'serialize data',
INT_EXPIRATION_TIME_IN_SECONDS);
//get cache Output :
//if call unique_key after 2 seconds it will return false
$uniqueKeyValue = $memCached->get('key_1');
var_export($uniqueKeyValue);
'serialize data'
Code Example - Memcached
$memCached = new Memcached();
//connect with memcached server
$memCached->addServer('[Link]', '11211');
//consider our data set below
$employeeId = 1000;
$employeeData = array(
'name' => 'Rafi Adnan',
'designation' => 'Software Engineer',
Output :
'joining_date' => '2014-09-15'
);
$memCached->set($employeeId, json_encode($employeeData));
// Returns employee details as json {
$employeeDetail = $memCached->get($employeeId); "name":"Rafi Adnan",
"designation":"Software Engineer",
var_export($employeeDetail);
"joining_date":"2014-09-15"
}
What if I don't want
all the data?
➔ What if I just want the name?
➔ 64 bytes for the object vs 16 bytes for just the name?
➔ 4X network traffic
➔ More work for the application
Redis: Data Types
➔ Strings ( just like Memcached )
➔ Lists
➔ Sets
➔ Sorted Sets
➔ Hashes
Redis : Lists
➔ Stored in sorted order
➔ Can push/pop
➔ Fast head/tail access
➔ Index access
Code Example - Redis : Lists
$redisClient = new Predis\Client();
$redisClient->lpush('employees', 'Faisal'); array (
$redisClient->lpush('employees', 'Rafi'); 0 => 'Rafi',
$arrEmployeeList = $redisClient->lrange('employees', 0, -1);
1 => 'Faisal',
var_export($arrEmployeeList); )
$redisClient->rpush('employees', 'Akhtar');
$arrEmployeeList = $redisClient->lrange('employees', 0, -1);
var_export($arrEmployeeList);
array (
0 => 'Rafi',
1 => 'Faisal',
2 => 'Akhtar',
)
Redis : Sets
➔ Unordered collections of strings
➔ Unique ( no repeated members )
➔ diff, intersect, merge
Code Example - Redis : Sets
$redisClient = new Predis\Client();
$redisClient->sadd('employees', 'Rafi Adnan');
$redisClient->sadd('employees', 'Saeed Ahmed');
$redisClient->sadd('employees', 'Faisal Islam');
$redisClient->sadd('formerEmployees', 'Saeed Ahmed');
$currentEmployees =
$redisClient->sdiff('employees', 'formerEmployees');
var_export($currentEmployees); array (
0 => 'Rafi Adnan',
1 => 'Faisal Islam',
)
Code Example - Redis : Hashes
$redisClient = new Predis\Client();
$redisClient->hset('employees', 'teamCount', 10);
$redisClient->hset('employees', 'rubyTeam', 9); ‘10’ - string
$redisClient->hset('employees', 'phpTeam', 1);
$teamCount = $redisClient->hget('employees', 'teamCount');
var_export($teamCount);
$teamStatus = $redisClient->hgetall('employees');
var_export($teamStatus);
array (
'teamCount' => '10',
'rubyTeam' => '9',
'phpTeam' => '1',
)
Redis: The Bad
➔ Single-Threaded
➔ Limited client support for consistent hashing
➔ Significant overhead for persistence
➔ Not widely deployed
Memcached vs. Redis
Memcached Redis
(multi) get ✔ ✔
(multi) set ✔ ✔
increment/decrement ✔ ✔
delete ✔ ✔
expiration ✔ ✔
range queries ✔
data types ✔
persistence - ✔
multi-threaded ✔
replication - ✔
Die;
Questions, comments...