From:
Co_Creating_Health
Views: 353
Comments: 0
Slow flow your way into wellness with Tai Chi's oldest, but tested methods in keeping you fit. Learn how you can benefit from this exercise.
Slide 1: CHI: Universal caching for Perl
Jonathan Swartz YAPC|10 2009 Pittsburgh, PA
Slide 2: What is CHI?
• Standard interface and implementation for
Perl caches - aka 'DBI for caching' performance and extendibility
• Inspired by Cache::Cache, but improves
Slide 3: Why do we need it?
• CPAN modules that need cache can simply
ask for a CHI handle single place
• Implement generic caching features in a • Make new cache backends trivial to create
Slide 4: Modules that just need "a cache"'
• Templating: HTML::Mason,
Template::Toolkit
• Web frameworks: Catalyst, CGI::Application • Sessions: CGI::Session, Apache::Session • ORMs: Data::ObjectDriver,
Rose::DB::Object
• Code processing: Perl::Tidy, Perl::Critic • Startup impaired: Class::MOP/Moose
Slide 5: Basic API
# Choose a driver # my $cache = CHI->new( driver => 'Memory' ); my $cache = CHI->new( driver => 'File', cache_root => '/path/to/root' ); my $cache = CHI->new( driver => 'FastMmap', root_dir => '/path/to/root', cache_size => '1k' ); # Get and set items # my $customer = $cache->get($name); if ( !defined $customer ) { $customer = get_customer_from_db($name); $cache->set( $name, $customer, "10 minutes" ); } $cache->remove($name);
Slide 6: Current CHI drivers
• • • • • • •
Memory - In-process memory File - Hierarchical, one file per entry FastMmap - Mmap'ed files Memcached DBI BerkeleyDB CacheCache - Any existing Cache::Cache driver
Slide 7: Driver skeleton
package CHI::Driver::MyDriver; use Moose; extends 'CHI::Driver'; has 'attr' => ( ... ); sub fetch { my ( $self, $key ) = @_; sub store { my ( $self, $key, $data ) = @_; sub remove { my ( $self, $key ) = @_; sub clear { my ($self) = @_; sub get_keys { my ($self) = @_; sub get_namespaces { my ($self) = @_;
Slide 8: Avoiding miss stampedes
• Problem: Many processes try to recompute
cache when it expires
• Solution 1: Probabilistic expiration
my $cache = CHI->new(..., expires_variance => 0.20);
• Solution 2: Busy locks
my $cache = CHI->new(..., busy_lock => '30 sec');
Slide 9: Recomputation latency
• • •
Problem: Client waits while data is recomputed Solution 1: Background recomputation Solution 2: Externally initiated recomputation
my $customer = $cache->compute( $name, sub { get_customer_from_db($name) }, "10 minutes" );
use LWP::Simple; foreach my $url (@common_urls) { # recompute_cache temporarily reduces expiration get("http://www.mysite.com/$url?recompute_cache=1"); }
Slide 10: Multilevel caches
• • •
Several caches can be chained together Example 1: L1 cache in front of memcached
my $cache = CHI->new( driver => 'Memcached', servers => [ "10.0.0.15:11211", ... ], l1_cache => { driver => 'Memory', max_size => '1MB' } );
Example 2: Mirror cache to migrate cache directories
my $cache = CHI->new( driver => 'File', root_dir => '/old/root' mirror_cache => { driver => 'File', root_dir => '/new/root' } );
Slide 11: To doand reporting • Cache statistics - collection
• • • •
Registry of storage types (like Rose::DB) with memoization Background recomputation Close performance gap between CHI and native Plugins for Catalyst, CGI::Session, etc.
Slide 12: Additional resources
• Download CHI from CPAN http://cpan.uwinnipeg.ca/dist/CHI • Search for drivers http://cpan.uwinnipeg.ca/search?query=CHI::Driver • Subscribe to perl-cache mailing list http://groups.google.com/group/perl-cache-discuss