MUC - Moodle Universal Cache

Post on 17-Jan-2017

500 views 0 download

transcript

MUCMoodle Universal Cache

Tim Hunt

Introduction

What is a cacheA place to keep data that would take time to re-compute

A cache stores values identified by a keyE.g. list of activities in a course, stored by course id

Caches may get purged at any timeCannot store real data there, just derived values for performance

Why have a cache system?Developers want to do stuff with data, not re-implement caching

Want to be able to use different back-end storesDisc, Memcache, REDIS, …cachestore_ is a plugin type

Admins should control which data goes in which store

Cache performanceTypical call to cache::get For a typical page• 0.5 ms data fetched from Memcache

150• 0.05 ms data in static acceleration

700

For comparison: typical DB query• 3 ms

40

Using caches

Typical use$cache = cache::make('core', 'string');$strings = $cache->get($component);

if ($strings === false) { $strings = load_strings($component); $cache->set($component, $strings);}

Defining your cacheIn db/caches.php in your plugin. E.g. from lib/db/caches.php$definitions = array( // Used to store processed lang files. // Keys used are revision, lang and component of the string file. // Static acceleration size is based on student access of the site. 'string' => array( 'mode' => cache_store::MODE_APPLICATION, 'simplekeys' => true, 'simpledata' => true, 'staticacceleration' => true, // Metadata helps cache 'staticaccelerationsize' => 30, // system handle the data 'canuselocalstore' => true, // efficiently. ),);

$string['cachedef_string'] = 'Language string cache';

Types of cacheApplication – Data that applies throughout Moodle

E.g. list of activities in each course / language strings

Session – Data that is relevant while a user is logged inE.g. list of all course categories this user can access

Request – Data within the handling of one requestE.g. list of temporary tables

Clearing the cache

$cache = cache::make('core', 'questiondata');$cache->delete($questionid);

cache::make('core', 'questiondata')->purge();

Recommended: just clear out what has changed

Dangerous

Also not recommended: time-to-live in cache definition

Bulk actions$cache->get_many(['key1', 'key2']);// ['key1' => 'value1', 'key2' => 'value2']

$cache->set_many( ['key1' => 'value1', 'key2' => 'value2']);

$cache->delete_many(['key1', 'key2']);

Advanced use: data source

Data source: why?Avoids the normal

“is this in the cache? Yes: good; No, re-compute”

Tell the cache where to get the data if it is not yet stored

Data source: definition$definitions = array( // Cache for question definitions. This is used by the question // bank class. Users probably do not need to know about this cache. // They will just call question_bank::load_question. 'questiondata' => array( 'mode' => cache_store::MODE_APPLICATION, 'simplekeys' => true, // The id of the question is used. 'requiredataguarantee' => false, 'datasource' => 'question_finder', 'datasourcefile' => 'question/engine/bank.php', ),)

class question_finder implements cache_data_source { public static function get_instance_for_cache(cache_definition $definition) { return self::get_instance(); // Singleton pattern. } public function load_for_cache($questionid) { global $DB; $questiondata = $DB->get_record_sql('SELECT q.*, qc.contextid FROM {question} q JOIN {question_categories} qc ON q.category = qc.id WHERE q.id = :id', array('id' => $questionid), MUST_EXIST); get_question_options($questiondata); return $questiondata; }}

Data source: use$cache = cache::make('core', 'questiondata');$cache->get($questionid);

Data source: implementationpublic function get($key, $strictness = IGNORE_MISSING) { // ... $result = $this->store->get($key); // ...

if ($result === false) { if ($this->loader !== false) { $result = $this->loader->get($key); } else { if ($this->datasource !== false) { $result = $this->datasource->load_for_cache($key); } } }

// ...}

Cache administration

Cache administrationE.g. https://learn2acct.open.ac.uk/cache/admin.php

Cache administration: continued

Cache administration:continued

Cache administration: continued

Issues

Memcache purgingMUC lets you store many different caches in one backend

cache::purge(); should just clear one of those caches

With Memcache, cache::purge() wipes all cachesThis is one of the reasons the VLE crashed in October

Moodle 3.2 now has REDIS cache store in coreWe should consider switching

Complex keysMUC tries to support keys that are not just ints or strings

However this hurts performance – best not to use it

This probably applies to other advanced MUC featuresCaching is about performanceSimple is good

Automated testsMUC caches are automatically cleared between each unit test or Behat test

Useful linkshttps://docs.moodle.org/dev/Cache_API

https://docs.moodle.org/dev/Cache_API_-_Quick_reference

cache/README.md in the code

https://docs.moodle.org/dev/The_Moodle_Universal_Cache_(MUC)