Intro to memcached
Intro to memcached
TO
MEMCACHED
Tags
memcached,
performance,
scalability, php,
mySQL, caching
techniques, #ikdoeict
jurriaanpersyn.com
lead web dev at Netlog
since 4 years
php + mysql +
frontend
working on Gatcha
For who?
talk for students
professional bachelor
ICT www.ikdoeict.be
Why this talk?
One of the first things
I’ve learnt at Netlog.
Using it every single
day.
Program
- About caching
- About memcached
- Examples
- Tips & tricks
- Toolsets and other
solutions
What is caching?
A copy of real data
with faster (and/or
cheaper) access
What is caching?
• storage cost
• typical stats:
• Browser cache
• DNS cache
• Content Delivery Networks (CDN)
• Proxy servers
• Application level
• full output caching
plugin)
(eg. Wordpress WP-Cache
• ...
Caches in the web stack (cont’d)
• Application level
• opcode cache (APC)
• query cache (MySQL)
• storing denormalized results in the
database
• object cache
• storing values in php objects/classes
Efficiency of caching?
• database access
• reading files
(in fact, any filesystem access)
• API calls
• Heavy computations
• XML
Where to cache on the server-side?
• key/value dictionary
About memcached (cont’d)
• It’s a server
• Client access over TCP or UDP
• Servers can run in pools
• eg. 3 servers with 64GB mem each give
you a single pool of 192GB storage for
caching
• Typical:
• user sessions (often)
• user data (often, shared)
• homepage data (eg. often, shared,
expensive)
What to store in memcache? (cont’d)
• Workflow:
• monitor application (query logs /
profiling)
• No redundancy / fail-over
• No replication (single item in cache lives on one
server only)
• pecl/memcache
• pecl/memcached
• newer, in beta, a couple more features
PHP Client Comparison
pecl/memcache pecl/memcached
First Release Date 2004-06-08 2009-01-29 (beta)
Actively Developed? Yes Yes
External Dependency None libmemcached
Features
Automatic Key Fixup Yes No
Append/Prepend No Yes
Automatic Serialzation2 Yes Yes
Binary Protocol No Optional
CAS No Yes
Compression Yes Yes
Communication Timeout Connect Only Various Options
Consistent Hashing Yes Yes
Delayed Get No Yes
Multi-Get Yes Yes
Session Support Yes Yes
Set/Get to a specific server No Yes
Stores Numerics Converted to Strings Yes
PHP Client functions
• Very easy
• Very fast
• But: all the dependencies ...
• language, css, template, logged in
user’s details, ...
<?php
$html = $cache->get('mypage');
if (!$html)
{
ob_start();
echo "<html>";
// all the fancy stuff goes here
echo "</html>";
$html = ob_get_contents();
ob_end_clean();
$cache->set('mypage', $html);
}
echo $html;
?>
Data caching
• on a lower level
• easier to find all dependencies
• ideal solution for offloading database
queries
function getUserData($UID)
{
$key = 'user_' . $UID;
$userData = $cache->get($key);
if (!$userData)
{
$queryResult = Database::query("SELECT * FROM USERS
WHERE uid = " . (int) $UID);
$userData = $queryResult->getRow();
$cache->set($userData);
}
return $userData;
}
?>
“There are only two
hard things in
Computer Science:
cache invalidation and
naming things.”
Phil Karlton
Invalidation
• Use:
• data that is fetched more then it’s
updated
• flooding checks
• output caching (eg. for RSS feeds)
• locks
<?php
function getUserData($UID)
{
$db = DB::getInstance();
$db->prepare("SELECT *
FROM USERS
WHERE uid = {UID}");
$db->assignInt('UID', $UID);
$db->execute();
return $db->getRow();
}
?>
<?php
function getUserData($UID)
{
$db = DB::getInstance();
$db->prepare("SELECT *
FROM USERS
WHERE uid = {UID}");
$db->assignInt('UID', $UID);
$db->setCacheTTL(0); // cache forever
$db->execute();
return $db->getRow();
}
?>
<?php
function getUserData($UID, $invalidateCache = false)
{
$db = DB::getInstance();
$db->prepare("SELECT *
FROM USERS
WHERE uid = {UID}");
$db->assignInt('UID', $UID);
$db->setCacheTTL(0); // cache forever
if ($invalidateCache)
{
return $db->invalidateCache();
}
$db->execute();
return $db->getRow();
}
?>
<?php
function updateUserData($UID, $data)
{
$db = DB::getInstance();
$db->prepare("UPDATE USERS
SET ...
WHERE uid = {UID}");
...
return $result;
}
?>
<?php
function getLastBlogPosts($UID, $start = 0,
$limit = 10, $invalidateCache = false)
{
$db = DB::getInstance();
$db->prepare("SELECT blogid
FROM BLOGS WHERE uid = {UID}
ORDER BY dateadd DESC LIMIT {start}, {limit}");
// invalidate caches
getLastBlogPosts($UID, 0, 10);
getLastBlogPosts($UID, 11, 20);
... // ???
return $result;
}
?>
<?php
function getLastBlogPosts($UID, $start = 0,
$limit = 10)
{
$cacheVersionNumber = CacheVersionNumbers::
get('lastblogsposts_' . $UID);
$db = DB::getInstance();
$db->prepare("SELECT blogid FROM ...");
...
$db->setCacheVersionNumber($cacheVersionNumber);
$db->setCacheTTL(0); // cache forever
$db->execute();
return $db->getResults();
}
?>
<?php
class CacheVersionNumbers
{
public static function get($name)
{
$result = $cache->get('cvn_' . $name);
if (!$result)
{
$result = microtime() . rand(0, 1000);
$cache->set('cvn_' . $name, $result);
}
return $result;
}
...
CacheVersionNumbers::bump('lastblogsposts_' . $UID);
return $result;
}
?>
Query Caching (cont’d)
c.commenter_uid AS uid
FROM COMMENTS c
WHERE c.postid = {postID}");
...
$comments = Users::addUserDetails($comments);
...
?>
<?php
...
public static function addUserDetails($array)
{
foreach($array as &$item)
{
$item = array_merge($item,
self::getUserData($item['uid']));
// assume high hit ratio
}
return $item;
}
...
?>
So?
• Pro’s:
• speed, duh.
• queries get simpler (better for your db)
• easier porting to key/value storage
solutions
• Cons:
• You’re relying on memcached to be up
and have good hit ratios
Multi-Get Optimisations
• Solution: multiget
• fetch multiple keys from memcached in
one single call
• xCache
• eAccelerator
• Zend optimizer
Last thought
Game tracking
Start game and end game calls results in accurate gameplay
tracking and allows us to show who is playing the game at any
given moment, compute popularity, target games.
High-scores
You push your high-score to our API, we do the hard work of
creating different types of leader boards and rankings.
Achievements
Pushing achievements reached in your game, just takes one API
call, no configuration needed.
Gatcha For Game Developers
Multiplayer Games
We run SmartFox servers that enable you to build real-time
multiplayer games, with e.g.. in game chat
coming:
How to integrate?
Flash Games
We offer wrapper for AS3 and AS2 games with full
implementation of our API
Unity3D Games
OpenSocial Games
Talk to the supported containers via the Gatcha OpenSocial
Extension
Other Games
Simple iframe implementation. PHP Client API available for the
Gatcha API
PHP Talents
Working on integrations and the gaming platform
Flash Developers
Working on Flash Games and the gaming platform
Design Artists
Designing games and integrations
jurriaan@netlog.com
Resources, a.o.:
• memcached & apc: http://www.slideshare.net/benramsey/
caching-with-memcached-and-apc
• speed comparison: http://dealnews.com/developers/
memcachedv2.html
• php client comparison: http://code.google.com/p/memcached/
wiki/PHPClientComparison
• cakephp-memcached: http://teknoid.wordpress.com/
2009/06/17/send-your-database-on-vacation-by-using-
cakephp-memcached/
• caching basics: http://www.slideshare.net/soplakanets/caching-
basics
• caching w php: http://www.slideshare.net/JustinCarmony/
effectice-caching-w-php-caching