Cache is King!(Or How I Learned To Stop Worryingand Love the RAM)
Cache is King• What is Memcaching?• How Does it Work?• Setup Overview.• How To Namespace the Right Way.• Avoiding Cache Rushing.• What Should I Cache?Agenda
Cache is King• a big ol hash table• RAM not disc• alleviates database (and other io) loads tospeed up load times• stores data objects as key->value pairs• open source (BSD license)• distributedWhat is Memcaching?
Cache is King• A database• Redundant• Locking• A backup• Highly available• Limitless in size• Namespaced (more later)What Memcaching is NOT?
Cache is King• 2 hashes• client hashes key against server list to findserver• client then sends request to server• server does hash key lookup against slabs ofkeys• Serve returns objectHow Does it Work?
Cache is King• When setting a value you can avoid the 250byte limit imposed for keys by md5-hashingthem.• If your max page size is 1MB are you limited to1 MB size chunks? Kinda – but there iscompression available.• You can increase or decrease page size and/orgrowth factor, but there is a performance hit.Storage
Cache is King• Default minimum chunk size is 48 bytes• Default growth factor is 1.25• 48 bytes required for storage overhead• Each slab is a 1mb page containing same sizechunks• Non-contiguous – there is space wastedChunks and Slabs and Growth Factors
Cache is King• Need to store a 1001 byte piece (953 + 48).• Multiply by growth factor until chunk size isgreater than 1001 bytes88 x 1.25^11 = 1025• Look for the slab of 1025 byte pieces.• Create a new slab if it does not exist• Store the value in a chunk (note 24 bytes wasted)• 250 byte limit to key (so use md5 to set and get)Example
Cache is King• There is no room left for our 1025-byte chunkAND we have initialized enough slabs alreadyto fill the memcached space – what now?• LRU (least recently used) within 1025b slabs• LRU is not global.• Evict the LRU 1025-byte chunkEviction
Cache is King• Memcached is not language specific• Memcached runs as a service on the OS• PHP has a library to connect to it• Grab an API (or write your own) to wrap thefunctionality in PHP for your needs.In Practice
Cache is KinggetaddreplacedeleteWhat functions do I need to wrap?
Cache is King•NOT natively supported•BUT completely do-ableNamespaces
Cache is King• Do not store an array of keys as arepresentation of a namespace.• Does not scale well• You MUST iterate through all in orderto expire namespaceNamespaces the Wrong Way
Cache is King• Requires at least 1 additional round trip tothe hash table (using namespace, key andvalue)– store a key->value pair of namespace and key– then store a key->value pair of key and value• Assign an ID for a namespace (or retrievethe existing one if it already exists)Namespaces the Right Way
Cache is King• Setting involves:– Get namespace->id (generate and set with no expire ifnew namespace)– Set key->id (no expire)– then set the key->value (with expire)• Getting involves:– Get id by namespace (namespace->id)– if not exists then “miss”– If success then get the key->id– key->value (may still “miss”)Namespaces the Right Way
Cache is King• Deleting (expiring) involves:– “increment” value of namespace->id– Since we have stored the data as COMPRESSEDrather than INT it will invalidate this chunk– Now simply trying to get something by key andnamespace will “miss” because the first get fornamespace fails– Note the subsequent key->value pairs are notdeleted – they merely become inaccessible, willturn LRU and eventually get evicted.Namespaces the Right Way
Cache is King• 2 process (A and B) want the same thing that is expired• A "misses" so it goes off to get it from the database• B then "misses" so it also goes off to get it (A isnt done)• A and B are both hitting the DB for the same thing• A and B both intend to "replace" to cache when they return• If you are doing millions of page hits a day = big troubles!• NOT optimal! - indeed can be a bottleneck on commonand/or expensive valuesCache Rush
Cache is King• Store your value as an array or object with a "real" expireincluded, then cache with extra time added on.• The item will be retrieved regardless cuz you stored it withextra time• A can add time to the internal expiry and do a cachereplace before going to process data• B checks cache - hey its not expired (‘cuz A added time!)• A comes back and does another replace with– new data– new internal expiry– new cache expiryCache Rush Solution
Cache is King• start with low-hanging fruit– Big Static Html pages– objects that change seldom (long expiry dates –more likely to update before expired)– objects that change more often (careful withexpiration dates now – much more important)What Should I Cache?
Cache is King• Now the big stuff– dynamic html (i.e. with user content) cached asstatic with placeholders for dynamic content– Static html fragments cached short term for thedynamic content– finally - user specific data that is expensive, butused often (store as fragments or objects thenreplace placeholders in cached html)What Should I Cache?
Cache is King• David Engel• firstname.lastname@example.org• http://winnipegphp.com• http://www.meetup.com/Winnipeg-PHP/• http://www.linkedin.com/groups/PHP-Winnipeg-3874131Closing