Slide 1

Slide 1 text

DYNAMIC DATA CACHE LONE STAR PHP 2014 https://joind.in/10824

Slide 2

Slide 2 text

EFFECTIVE CACHE

Slide 3

Slide 3 text

DATA REUSABILITY

Slide 4

Slide 4 text

DISTANCE TO DATA

Slide 5

Slide 5 text

BASIC QUICK WEB FORUM

Slide 6

Slide 6 text

THE DATA LOOKUPS Get Recent Posts Get User By ID

Slide 7

Slide 7 text

CACHE THE OUTPUT. EASY SOLUTION? MESSY SOLUTION.

Slide 8

Slide 8 text

WHY CACHING STATIC OUTPUT SUCKS Potentially hundreds of static HTML files on the web server.  But, static serving is fast!  Yes… yes it is… sometimes… Have to wrap every single app output with cache collecting and storage. May even have to refactor the app depending on how output is sent out. (lots of echos everywhere vs a template, etc, whatever)  But WordPress has a plugin for that!  Good for you.

Slide 9

Slide 9 text

AND IS THERE A POINT? (TO RENDER OUTPUT CACHE)

Slide 10

Slide 10 text

9 OUT OF 10 TIMES IT AIN’T YOUR WEBSERVER BEING SLOW

Slide 11

Slide 11 text

HOLD UP, I’M SORTING. LOL.

Slide 12

Slide 12 text

SO_CLOSE_TO_YOU_RIGHT_NOW.MP3

Slide 13

Slide 13 text

DATA CACHING STYLES

Slide 14

Slide 14 text

TYPE 1: CACHE RAW DATA

Slide 15

Slide 15 text

CACHE RAW DATA if cache exists return cached data else query database fetch data result cache data return data

Slide 16

Slide 16 text

CACHE RAW DATA PRO Typically smaller memory footprint. Abstracts the cache at a very high level that is easy to intercept. Interception being key. You could integrity test it against the database, if you wanted. CON Still requires PHP to parse data and create your objects for each requested object.

Slide 17

Slide 17 text

TYPE 2: CACHE DATA OBJECTS

Slide 18

Slide 18 text

CACHE DATA OBJECTS if cache exists return cached object else query database fetch result build object from data cache object return object

Slide 19

Slide 19 text

CACHE DATA OBJECTS PRO Objects are brought back just as you left them. Objects don‘t need to construct again. Just inflate. CON Requires deeper integration with the code platform depending on application structure. May require architecture changes – this style works much nicer with Factory style building. If an object is changed, such as a property renamed, all the cached versions will be broke. A forced flush!

Slide 20

Slide 20 text

ACTUAL DATA CACHES

Slide 21

Slide 21 text

APPCACHE

Slide 22

Slide 22 text

APPCACHE Local to the application instance/hit/request. Great for storing objects which tend to be small and reused multiple times an application, such as users objects. Installation: None. It’s an application design feature. Overly Simple Example: Cache::$Data = array( ‘user-1’ => User Object { ‘ID’=>1, ‘Name’=‘Bob’ }, ‘user-117’ => User Object { ‘ID’=>117, ‘Name’=‘John’ } );

Slide 23

Slide 23 text

MEMCACHE

Slide 24

Slide 24 text

MEMCACHE Local to the application cluster/network. We use it the same as the Appcache, only it magically persists across page hits or requests. Memcache is a server for key=>value storage. It allows you to build a pool of servers working together to create one giant cache. Servers can be added and dropped as needed. http://memcached.org/ It can be accessed with PHP via the Memcache extension. http://www.php.net/memcache (note, PHP has memcache and memcacheD… without the D is the preferred, updated, and up to date version. However, the preferred server daemon does have the D.)

Slide 25

Slide 25 text

MEMCACHE Server Installation: apt-get install memcached service memcached start Client Installation apt-get install php5-memcache

Slide 26

Slide 26 text

CACHE INTERFACE

Slide 27

Slide 27 text

CACHE INTERFACE: APP AND MEM Here we have the constructor for this Cache interface class. Because of how we want it to work, ideally our application would only create one instance of this class to be globally accessed by anything in the app. Also known as a singleton. That is what the static property and Create method is for. At application start we call Cache::Create(); and will be able to access it via Cache::$Main. If you have a global instance manager (Nether\Stash) you would not need the statics.

Slide 28

Slide 28 text

CACHE INTERFACE: STORE INTO CACHE In Appcache we can store data as is, because Objects are Passed-By- Reference by default, and other values are only Copy-On-Write, this is a very efficient storage for data that probably won’t change by the end of the application hit. To store into Memcache however we must flatten or serialize the data before sending it to the Memcache server. This will allow Memcache to store flat data it does not care what it is at all. Cache::$Main->Set(‘test’,’bob’);

Slide 29

Slide 29 text

SERIALIZED DATA O:13:"Nether\Object":1:{s:5:"Hello";s:5:"World";} object(Nether\Object) { ["Hello"] => string(5) "World“ }

Slide 30

Slide 30 text

CACHE INTERFACE: FETCH FROM CACHE To fetch from Appcache we can grab the data right back as stored. To fetch from Memcache we have to reinflate or unseralize the data we originally stored there. $data = Cache::$Main->Get(‘test’);

Slide 31

Slide 31 text

CACHE INTERFACE: INVALIDATE CACHE When a data object changes, all the caches related to that object need to be flushed so that they can be recached with the updated version. This will tell the caches to forget the data stored, next time we fetch the data we will notice the cache is missing and repopulate it with fresh data. Cache::$Main->Drop(‘test’);

Slide 32

Slide 32 text

APPLYING THE CACHE INTERFACE

Slide 33

Slide 33 text

NOT CACHED VS CACHED

Slide 34

Slide 34 text

CACHE PROCESS: FIRST HIT, FIRST QUERY get_user(1); checking cache… i no has. i no has. checking database… lol, fools. i has it. ok now I has it. ok now i has it. here is user with id 1

Slide 35

Slide 35 text

CACHE PROCESS: FIRST HIT, SECOND QUERY get_user(1); checking cache… i has i has! here it is. here is user with id 1

Slide 36

Slide 36 text

CACHE PROCESS: SECOND HIT, FIRST QUERY get_user(1); checking cache… i no has. oh oh i has! here it is. now i has it. here is user with id 1

Slide 37

Slide 37 text

CACHE PROCESS: SECOND HIT, SECOND QUERY get_user(1); checking cache… i has i has! here it is. here is user with id 1

Slide 38

Slide 38 text

I’M BORED, YO.

Slide 39

Slide 39 text

DISKCACHE

Slide 40

Slide 40 text

DISKCACHE Local to the filesystem. Great for caching huge data sets that may take time for the server to turn out, like a list of all the users who wrote posts that had over 100 likes this month, data we would use to generate a “most popular submitter” type page. Scan post table, Join user table, Count post likes Where likes >= 100 Sort by likes A simple query, but after 1,000,000 posts could “be slow” and also could return a huge data set. Huge datasets like this could be too much bloat to have in App and Memcache. Installation: None. It’s an application design feature.

Slide 41

Slide 41 text

CACHE INTERFACE: DISKCACHE Diskcache is better suited for large data sets that do not change or are not accessed as often as other objects. You must also take into consideration file system security when implementing it.

Slide 42

Slide 42 text

PUTTING IT TOGETHER

Slide 43

Slide 43 text

ORIGINAL FORUM EXAMPLE

Slide 44

Slide 44 text

ORIGINAL FORUM EXAMPLE NOW WITH MORE CACHE

Slide 45

Slide 45 text

THE NEW FLOW Read the most recent posts. Iterate over each post, fetch the user associated. Render the page. If the most recent posts were not already cached, they are cached the first time they are fetched. If the user was not already cached, they are cached first time they are fetched as well. Next time this page is loaded: 100% of the request is served from cache without a single hit to the database.

Slide 46

Slide 46 text

HIT IT HARD, HIT IT OFTEN.

Slide 47

Slide 47 text

SOME THIRD PARTY STUFF… ONES YOU CAN BOLT ONTO ANYTHING. Doctrine Cache (App, APC, Disk, Memcache, MongoDB, Redis, …)  https://github.com/doctrine/cache Symfony 2 Cache (App, APC, Disk, Memcache, Redis, …)  https://github.com/illuminate/cache Nether Cache (App, Memcache, Disk)  https://github.com/netherphp/cache

Slide 48

Slide 48 text

EXAMPLE USING THIRD PARTY: NETHER This example uses the Nether Cache module to handle checking, populating, and invalidating of cache. All the third parties more or less work the same, just with different function names and whatnot. Pick the one that fits best in your framework, (e.g. already using Symfony2, use illuminate/cache)

Slide 49

Slide 49 text

OVERLY ENTHUSIASTIC CONSTRUCTION __construct($id); A Constructor. Constructors construct things. To build something, you must provide materials. Why would a constructor fetch and cache? It’s not __fetchachtor($id); Searching by Email or Username? Constructor expects an ID here. Why does an object need to know how to fetch an object?

Slide 50

Slide 50 text

FACTORY + OBJECT CACHE Constructor only contains logic to validate and construct the object given the building materials it was given. The finished Object is cached. GetByID knows that the cache contains complete objects. Static functions means objects don’t have public methods they don’t need. A user doesn’t need to know how to find itself by its Email when you already have found it.

Slide 51

Slide 51 text

FACTORY + DATA CACHE Constructor only contains logic to validate and construct the object given the building materials it was given. The original source data is cached. GetByID knows that the cache is really just a database row. Static functions means objects don’t have public methods they don’t need. A user doesn’t need to know how to find itself by its Email when you already have found it.

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

SECURING YOUR CACHE Shared hosting and Diskcache?  Encrypt cache before store.  Only store to a private directory that only the required applications have access to read.  Don’t cache in the public web directory. Memcached, MongoDB, Redis, or any other network accessed cache?  Cache servers should only be accessible by the private network only.  Firewalling, etc.  Encrypt if you want, technically not necessary if protected isolated network.

Slide 54

Slide 54 text

IT IS YOUR CACHE. IT SHOULD CRY IF YOU WANT IT TO.

Slide 55

Slide 55 text

CACHE. HIT IT HARD. HIT IT OFTEN. Bob Majdak Jr • @bobmajdakjr • [email protected] • This Talk: • https://joind.in/10824 • These Slides: • http://goo.gl/ReC4uy