SlideShare ist ein Scribd-Unternehmen logo
1 von 41
Downloaden Sie, um offline zu lesen
Scaling Rails with
                      memcached
                    One Rubyist’s Guide to Hazardous Hits




                                                            1
memcached is your best friend and your worst enemy.
Who is this kid?
                                 CNET Networks


       PHP Developer                                  Rails Developer
        ๏   GameSpot                                  ๏ Chowhound

        ๏   TV.com                                     ๏   Chow.com
        ๏   MP3.com



                                                                                               2
- I work for CNET Networks in San Francisco.
- I used to do PHP for www.gamespot.com, www.tv.com, and www.mp3.com.
- GameSpot is one of the two biggest gaming sites on the web, the other being IGN. They are
pretty evenly matched.
- I now work full time as a Rails developer on www.chowhound.com and www.chow.com (launching
September 15th, 2006).
GameSpot
                ๏   30 million page views per day
                ๏   50 million++ during E3 (mid-May)
                    ๏   [ 3000 req/s ]
                ๏   ~70 app servers
                ๏   Netscalers
                ๏   ~15 database servers
                ๏   php4, apache 2, mysql 5

                                                                                                     3
E3 was a press event held yearly, 2006 being the final year. During this year’s E3 the Sony,
Microsoft, and Nintendo press conferences were streamed live by GameSpot. We had the exclusive
on the Sony and Nintendo conferences, with both companies’ domains pointing to our webcast as it
was happening. Massive traffic, everything went crazy. We had about 100 app servers for E3, all in
the red during peak times.

Imagine millions of teenage boys constantly hitting refresh.

Typical setup: request hits Netscaler (load balancer), Netscaler decides which app server gets the
request. Use gzip compression to save bandwidth (but had to turn it off due to load for peaks at
E3).
memcached.



                                4
memcached helps.
memcached
             • Distributed, in-memory data store
             • Created by and for LiveJournal
             • Scales
             • Fast. C. Non-blocking IO. O(1)
             • Digg, Facebook, Wikipedia, GameSpot
             • 43things, Mog, Chowhound

                                                                                                  5
-   Distributed: multiple servers storing data in RAM, transparent to your app.
-   Data is spread amongst servers, not duplicated.
-   LiveJournal had bad growing pains -- needed a solution.
-   Problem with databases: you can distribute reads but everyone needs to write (which blocks)
-   Scales -- drop in a new memcached daemon and you’re good to go.
-   Lots of big sites use it successfully
Like a DRb’d {}

                 • CACHE = MemCache.new(options)
                 • CACHE.get(:key)
                 • CACHE.set(:key, data, ttl)
                 • CACHE.delete(:key)


                                                                                                     6
- Very simple to use
- Conceptually a hash
- Time to live is expiration of key. You can set to 30 days in the future or pick a denitive time
Like a DRb’d {}

          • memcached ‘bucket’ (server) is decided
               based on requested key
          • memcache-client uses Marshal to store data
          • Can’t cache metaclassy things or procs
          • Run daemons on your app servers. Low
               CPU overhead.



                                                                            7
- memcache-client Ruby API decides which memcached server stores your key
Like a DRb’d {}
                                        ( sort of )


                                     • Not enumerable
                                     • Not a database



                                                               8
-   Hash keys are not maintained
-   This makes it faster
-   Not a database: things only kept in RAM, not persistent.
-   Restart your server, lose your data. That’s ok.
The Pattern

           • Check cache for key
           • If key exists, return the stored bytes
           • If key doesn’t exist, find bytes
           • Save bytes
           • Return bytes

                                                                                                   9
- We don’t really have to worry about this if we use a good library.
- “find bytes” can be a database query or any sort of intensive data lookup -- something we don’t
want to do on every request and therefor cache.
In other words...
                          def get_cache(key)
                           data = CACHE.get(key)

                            return data unless data.nil?

                           data = nd(key)
                           CACHE.set(key, data, self.ttl)
                           return data
                          end


                                                                                   10
Simple example. Assume `find’ will return what we want to cache. Can be anything.
In other words...
                              def get_cache(key)
                               data = CACHE.get(key)

                                return data unless data.nil?

                               data = nd(key)
                               CACHE.set(key, data, self.ttl)
                               return data
                              end


                                                                                                11
-   What if we want to cache nil? We will query the database every time the key is requested.
-   If you have 4 million rows that’s not something you want.
-   Cache false instead of nil.
-   This and other things you need to watch for.
What about MySQL query cache?



                 • memcached is for data.
                 • You can cache anything.
                 • Generated PNG’s, HTML, processed
                     objects, etc.




                                                      12
Forget the query cache.
Are you sure you need it?




                                  13
You might not.
It’s Not “Better” Than SQL

           • memcached is slower than SELECT on
               localhost for small sites / datasets
           • memcached will not help if you can’t keep up
               with the requests
           • None of the big guys started with
               memcached.



                                                                                             14
- Not going to speedup your blog. Going to slow it down.
- You need good hardware and a good setup before you can think about memcached
 - multi server setup, load balancing, master / slave databases
- Facebook, Slashdot, Digg didn’t start with memcached. They added it when they needed it.
Don’t Worry About It

             • Write your app and tests first
             • Get everything working smoothly
             • Keep a few days open to spend on caching
              • ^^ Near The End


                                                                                              15
-   Don’t let memcached get in the way
-   Don’t do premature optimization
-   Write good code, but dont GUESS where the problems are going to be. Test and see.
-   Your app needs to be able to run well without caching. Caching is an aid, not a crutch.
-   If you want to test your caching code use a hash-based mock.
-   acts_as_cached has one in test/xtures/
Don’t Worry About It

                 • Identify slow queries
                  • MySQL slow query log
                 • Hardware is the real secret sauce
                 • memcached is not a magic wand


                                                                        16
- Find out what’s really holding you back, the big bottlenecks
- Use the QueryTrace plugin to see where your queries are coming from
Where it Shines


             • Huge database, millions of rows
             • Huge traffic, millions of hits
             • Huge both, millions of everything


                                                                                   17
-   Even a few row select can be slow on a massive database
-   If your query does a lesort on a big dataset, forget it
-   Set your cache based on a unique id
-   Maybe your database isn’t massive but is getting completely hammered. Cache.
Yeah, but I’m about to
               launch Web 9.0




                                     18
- COUNT ME IN!!!
Hook Me Up
           • Download and compile from danga.com
           • OSXers: libevent and Hodel’s hacks
           • $ sudo gem install memcache-client
           • $ memcached -vv


                                                                                           19
- Danga are the LiveJournal guys
- Won’t work well on osx without Hodel’s hacks
- Install the Robot Coop’s memcache-client
- Start daemon in interactive mode, watch what’s going on.
- Setup a MemCache.new instance, hit .set and .get, watch what happens in your memcached
daemon
Options
       • Fragment Cache Store
        • http://rubyforge.org/projects/mcache-fragment/
       • Session Store
          •   config.action_controller.session_store = :mem_cache_store

       • Models ( DB Queries )
        • CachedModel

                                                                         20
- Fragment cache store plugin supports time based expirations
- Lots of stuff written about setting up session store
- CachedModel is what 43things wrote and uses.
CachedModel
           • Overwrites find() to pull from cache
           • Works on single objects only
           • Doesn’t play well with multi-object queries
                on gets or updates
           • Makes you inherit
           • Nice and simple
           • Clears cache keys on update()
                                                                 21
- You don’t have to worry about caching: does it for you
- Doesn’t work on find(:all) or complex queries (:include, etc)
acts_as_cached

               • Rails plugin
               • Allows you to store any Ruby object in
                   memcached
               • Gives you more than enough rope...


                                                                    22
-   Used on Chowhound and Chow
-   Gives us flexibility
-   Still have to do things by hand, but helps ease the pain
-   Puts the caching in your face. Think about what you’re doing.
What To Cache

• Slow Queries
• Page fragments
 •   (We don’t cache fragments on Chowhound)

• Processor intensive computations


                                               23
What To Cache

          class StoriesController < ApplicationController

             def show
              @story = Story.get_cache(params[:id])
             end

          end



                                                                               24
- Simple single row get
- We like get_cache because you are always aware of what is and isn’t cached
Issues

             • Keeping cache data fresh
              • Editors want to see their changes now!
             • Caching associations
             • Pagination / Big Collections


                                                                           25
-   Chowhound is a forum site, Chow is an editorial content site
-   Everyone wants to see their changes immediately
-   Mix that with lots of pagination and big collections
-   How the hell?
-   We want to cache associations because we want to use Rails’ niceness
-   But we don’t have to keep reimplementing the same patterns
Keep Cache Fresh

                    class Story < ActiveRecord::Base
                      acts_as_cached

                     def after_save
                       expire_cache(id)
                     end
                    end



                                                                                 26
- Simplest example.
- acts_as_cached doesn’t handle auto-deletion of keys for you like CachedModel
- Don’t forget to after_destroy, too!
Keep Cache Fresh

                 class Story < ActiveRecord::Base
                   acts_as_cached :include => :author
                   belongs_to :author

                  def after_save
                    expire_cache(id)
                  end
                 end


                                                                                                      27
- acts_as_cache can be passed a hash which is passed straight to nd()
- In this case, Story.get_cache(20) calls Story.nd(20, :include => :author)
- Caches the author along with the story
- If the author is updated, the story’s associated cached author is STALE
- If you have 20 stories all with 1 author, you have 20 redundant copies of that same author in the
cache
- RAM is cheap but you need to think this sort of thing through
Keep Cache Fresh
                   class Author < ActiveRecord::Base
                     acts_as_cached
                     has_many :stories

                    def after_save
                      expire_cache(id)
                      stories.each do |story|
                        story.expire_cache
                      end
                    end
                   end
                                                                   28
- Stories’ author associations are now always up to date
- Pattern can be powerful when dealing with complex associations
Why?


           • Keeping track of keys is hard
           • Sweepers / Observers get complicated fast
           • Maintains integrity with script/console, rake,
                and migrations




                                                              29
- CachedModel does it for you, which is nice
- We want to cache associations
Alternative
               class Story < ActiveRecord::Base
                 acts_as_cached
                 belongs_to :author

                    def author
                     Author.get_cache(author_id)
                    end

                def after_save
                  expire_cache(id)
                end
               end
                                                                                       30
-   Lots of cache hits -- unless you use an in-process cache
-   Everything always up to date
-   Best for simple associations
-   Great if your authors table is in another database -- you can’t do a join anyway
Versioning!
                      class Story < ActiveRecord::Base
                        acts_as_cached :version => 5

                       def after_save
                         expire_cache(id)
                       end
                      end



                                                                                    31
-   What if you run a migration and update your Story model, then need to deploy?
-   All stories in cached are not only stale but broken
-   Mismatch between cached attributes and new attributes
-   You may have run into this with sessions
-   Update the version, acts_as_cached helps you out here
-   Keys are normally stored as ENVIRONMENT:CLASS:ID
-   So app-development:Story:20
-   :version => 5 makes Story’s keys: app-development:Story:v5:20
-   Instantly invalidate all currently cached, older versions.
List Objects


            • Pagination is tricky
            • Who controls it? Controller? Model?
            • How do you keep pagination fresh?


                                                                                                   32
- Pagination helpers are way out the window
- It makes sense to think of list objects as data structures (models), not active record objects
- They’re just simple data structures we want to arbitrarily cache
class BlogPostList
   acts_as_cached

    PAGES = 5
    PER_PAGE = 30

    def self.nd(page = 0)
      BlogPost.nd(:all, :limit => PER_PAGE, :offset => page * PER_PAGE)
    end

   def self.get_cache(page = 0)
     if page < PAGES
        super(page)
     else
        nd(page)
     end
   end
 end

                                                                                              33
- Create class, give it a nd, overwrite its get_cache
- Pages 6 - innity are not cached. Do they get any traffic? Probably not. Check your logs.
- Pages 1 - 5 are cached.
class BlogPostList
       acts_as_cached

       PAGES = 5
       PER_PAGE = 30

       def self.expire_list_cache
        0.upto(PAGES) do |page|
         expire_cache(page)
        end
       end
     end




                                     34
- Now it’s easy to expire
- Put this in BlogPost.after_save:
 def after_save
   BlogPostList.expire_list_cache
 end
List Objects


             • Not just for pagination
             • Use it in your sidebar, footer, RSS, API, etc...
             • Reuse the caches you have


                                                                  35
-   List objects can be reused
-   Again, just data structures
-   Don’t bloat models with tons of caching code
-   Do post-processing if you need to
Clear All
          class ApplicationController < ActionController::Base
            before_lter :check_cache_skip

           def check_cache_skip
            returning true do
              Object.skip_cache_gets = params[:skip_cache] ? true : false
            end
           end
          end


              http://www.bigsite.com/index?skip_cache=1

                                                                                    36
-   Resets every cache key on that page load
-   Skips the get() so nd() is called and result is saved to cache then returned
-   Good for debugging caching code
-   Is what’s in my cache what I really want? Is all the clearing working?
Caveats
             • 1 meg per key limit
             • Disable caching in unit tests, or use a mock
             • No whitespace in key names!
             • Don’t save ‘nil’
             • Monitor your cache. memcached is fickle
             • Weird behavior? Restart.

                                                                                               37
-   Dont go overboard caching - 1 meg limit
-   acts_as_cached handles some of this: no whitespace in names, nils are converted to false
-   memcached has a tendency to return corrupt data after tons of use. Restart liberally.
-   Don’t try to keep memcached up forever. Bad mojo.
Monitoring
 $ sudo gem install memcache-client-stats
 $ ruby script/console
 >> require ‘memcache_client_stats’
 => true
 >> CACHE.stats(:key => 'bytes')
 => {quot;localhost:11211quot;=>quot;271349quot;,
      quot;localhost:11212quot;=>quot;62729quot;}
 >> CACHE.stats(:type => 'items')
 {quot;localhost:11211quot;=>
   {quot;items:18:agequot;=>quot;6497quot;, quot;items:18:numberquot;=>quot;1quot;, ... }}

                                                                                           38
- Great gem
- Spend some time learning what everything means
- Watch all your servers in one place -- build a page which aggregates and displays this
information
- It’d be nice if this was integrated into capistrano somehow...
  (I’ll get back to you on that)
Monitoring

           • Cacti
            • http://cacti.net/
           • memcached template
            • http://dealnews.com/developers/cacti/
                   memcached.html



                                                                 39
- Haven’t used it but it gets recommended on the mailing list.
Resources
•   memcached site
    • http://www.danga.com/memcached/
•   memcached mailing list
    • http://lists.danga.com/pipermail/memcached/
•   topfunky’s post
    • http://rubyurl.com/sbE
•   Robot Coop
    • http://dev.robotcoop.com/
•   The Adventures of Scaling
    • http://rubyurl.com/vK7
•   Sessions N Such (memcached sessions)
    • http://errtheblog.com/post/24

                                                    40
Questions? Thanks!
      Chris Wanstrath
      chris@ozmm.org

         Err the Blog
    http://errtheblog.com

      www.chow.com
    www.chowhound.com

        2006-09-12
                            41

Weitere ähnliche Inhalte

Was ist angesagt?

Memcache basics on google app engine
Memcache basics on google app engineMemcache basics on google app engine
Memcache basics on google app engineIdo Green
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and ConfigsScott Taylor
 
Architecting for Change: QCONNYC 2012
Architecting for Change: QCONNYC 2012Architecting for Change: QCONNYC 2012
Architecting for Change: QCONNYC 2012Kellan
 
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...Ontico
 
Percona Toolkit for Effective MySQL Administration
Percona Toolkit for Effective MySQL AdministrationPercona Toolkit for Effective MySQL Administration
Percona Toolkit for Effective MySQL AdministrationMydbops
 
Indexierung mit MySQL
Indexierung mit MySQLIndexierung mit MySQL
Indexierung mit MySQLFromDual GmbH
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统yiditushe
 
Apache hadoop 2_installation
Apache hadoop 2_installationApache hadoop 2_installation
Apache hadoop 2_installationsushantbit04
 
Building Scalable Websites with Perl
Building Scalable Websites with PerlBuilding Scalable Websites with Perl
Building Scalable Websites with PerlPerrin Harkins
 
Replication and Replica Sets
Replication and Replica SetsReplication and Replica Sets
Replication and Replica SetsMongoDB
 
Introduction to performance tuning perl web applications
Introduction to performance tuning perl web applicationsIntroduction to performance tuning perl web applications
Introduction to performance tuning perl web applicationsPerrin Harkins
 
High Availability Server with DRBD in linux
High Availability Server with DRBD in linuxHigh Availability Server with DRBD in linux
High Availability Server with DRBD in linuxAli Rachman
 
Mobile & Desktop Cache 2.0: How To Create A Scriptable Cache
Mobile & Desktop Cache 2.0: How To Create A Scriptable CacheMobile & Desktop Cache 2.0: How To Create A Scriptable Cache
Mobile & Desktop Cache 2.0: How To Create A Scriptable CacheBlaze Software Inc.
 
Engage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionEngage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionWebtrends
 
Redis深入浅出
Redis深入浅出Redis深入浅出
Redis深入浅出iammutex
 
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...PavelKonotopov
 
HBase本輪読会資料(11章)
HBase本輪読会資料(11章)HBase本輪読会資料(11章)
HBase本輪読会資料(11章)moai kids
 

Was ist angesagt? (19)

Memcache basics on google app engine
Memcache basics on google app engineMemcache basics on google app engine
Memcache basics on google app engine
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and Configs
 
Architecting for Change: QCONNYC 2012
Architecting for Change: QCONNYC 2012Architecting for Change: QCONNYC 2012
Architecting for Change: QCONNYC 2012
 
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...
Как Web-акселератор акселерирует ваш сайт / Александр Крижановский (Tempesta ...
 
Percona Toolkit for Effective MySQL Administration
Percona Toolkit for Effective MySQL AdministrationPercona Toolkit for Effective MySQL Administration
Percona Toolkit for Effective MySQL Administration
 
Indexierung mit MySQL
Indexierung mit MySQLIndexierung mit MySQL
Indexierung mit MySQL
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统
 
Apache hadoop 2_installation
Apache hadoop 2_installationApache hadoop 2_installation
Apache hadoop 2_installation
 
Php go vrooom!
Php go vrooom!Php go vrooom!
Php go vrooom!
 
Building Scalable Websites with Perl
Building Scalable Websites with PerlBuilding Scalable Websites with Perl
Building Scalable Websites with Perl
 
Replication and Replica Sets
Replication and Replica SetsReplication and Replica Sets
Replication and Replica Sets
 
Introduction to performance tuning perl web applications
Introduction to performance tuning perl web applicationsIntroduction to performance tuning perl web applications
Introduction to performance tuning perl web applications
 
High Availability Server with DRBD in linux
High Availability Server with DRBD in linuxHigh Availability Server with DRBD in linux
High Availability Server with DRBD in linux
 
Mobile & Desktop Cache 2.0: How To Create A Scriptable Cache
Mobile & Desktop Cache 2.0: How To Create A Scriptable CacheMobile & Desktop Cache 2.0: How To Create A Scriptable Cache
Mobile & Desktop Cache 2.0: How To Create A Scriptable Cache
 
Engage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionEngage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data Collection
 
Redis深入浅出
Redis深入浅出Redis深入浅出
Redis深入浅出
 
Web::Scraper
Web::ScraperWeb::Scraper
Web::Scraper
 
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
Building the Enterprise infrastructure with PostgreSQL as the basis for stori...
 
HBase本輪読会資料(11章)
HBase本輪読会資料(11章)HBase本輪読会資料(11章)
HBase本輪読会資料(11章)
 

Andere mochten auch

Programmable Matter with Modular Robots
Programmable Matter with Modular RobotsProgrammable Matter with Modular Robots
Programmable Matter with Modular Robotselliando dias
 
A Brief Tour of Responsability Driven Design
A Brief Tour of Responsability Driven DesignA Brief Tour of Responsability Driven Design
A Brief Tour of Responsability Driven Designelliando dias
 
Gerenciamento de Projetos OO
Gerenciamento de Projetos OOGerenciamento de Projetos OO
Gerenciamento de Projetos OOelliando dias
 
Scrum in five minutes
Scrum in five minutesScrum in five minutes
Scrum in five minuteselliando dias
 
HTML5: The New html for the web
HTML5: The New html for the webHTML5: The New html for the web
HTML5: The New html for the webelliando dias
 
Assembling wall panels with robotic technologies
Assembling wall panels with robotic technologiesAssembling wall panels with robotic technologies
Assembling wall panels with robotic technologieselliando dias
 
Algoritmo Genetico
Algoritmo GeneticoAlgoritmo Genetico
Algoritmo Geneticoelliando dias
 
How to Design Frameworks
How to Design FrameworksHow to Design Frameworks
How to Design Frameworkselliando dias
 
How To Build A Better Arduino
How To Build A Better ArduinoHow To Build A Better Arduino
How To Build A Better ArduinoAlastairDSilva
 
Model-Driven Software Development
Model-Driven Software DevelopmentModel-Driven Software Development
Model-Driven Software Developmentelliando dias
 
Interfaces de UsuĂĄrio UbĂ­quas - UUI
Interfaces de UsuĂĄrio UbĂ­quas - UUIInterfaces de UsuĂĄrio UbĂ­quas - UUI
Interfaces de UsuĂĄrio UbĂ­quas - UUIelliando dias
 
hardware de um sistema de computação
hardware de um sistema de computaçãohardware de um sistema de computação
hardware de um sistema de computaçãoelliando dias
 
Enabling White-Box Reuse in a Pure Composition Language
Enabling White-Box Reuse in a Pure Composition LanguageEnabling White-Box Reuse in a Pure Composition Language
Enabling White-Box Reuse in a Pure Composition Languageelliando dias
 
Representação de Números
Representação de NúmerosRepresentação de Números
Representação de Númeroselliando dias
 
Linguagens de Transformação de Modelos
Linguagens de Transformação de ModelosLinguagens de Transformação de Modelos
Linguagens de Transformação de Modeloselliando dias
 
RobĂłtica MĂłvel
RobĂłtica MĂłvelRobĂłtica MĂłvel
RobĂłtica MĂłvelelliando dias
 
UML-Based Web Engineering
UML-Based Web EngineeringUML-Based Web Engineering
UML-Based Web Engineeringelliando dias
 
Gerenciamento de Projeto para Desenvolvimento de Sistema
Gerenciamento de Projeto para Desenvolvimento de SistemaGerenciamento de Projeto para Desenvolvimento de Sistema
Gerenciamento de Projeto para Desenvolvimento de Sistemaelliando dias
 
Banco De Dados BĂĄsico
Banco De Dados BĂĄsicoBanco De Dados BĂĄsico
Banco De Dados BĂĄsicoelliando dias
 

Andere mochten auch (20)

Programmable Matter with Modular Robots
Programmable Matter with Modular RobotsProgrammable Matter with Modular Robots
Programmable Matter with Modular Robots
 
Acme Total
Acme TotalAcme Total
Acme Total
 
A Brief Tour of Responsability Driven Design
A Brief Tour of Responsability Driven DesignA Brief Tour of Responsability Driven Design
A Brief Tour of Responsability Driven Design
 
Gerenciamento de Projetos OO
Gerenciamento de Projetos OOGerenciamento de Projetos OO
Gerenciamento de Projetos OO
 
Scrum in five minutes
Scrum in five minutesScrum in five minutes
Scrum in five minutes
 
HTML5: The New html for the web
HTML5: The New html for the webHTML5: The New html for the web
HTML5: The New html for the web
 
Assembling wall panels with robotic technologies
Assembling wall panels with robotic technologiesAssembling wall panels with robotic technologies
Assembling wall panels with robotic technologies
 
Algoritmo Genetico
Algoritmo GeneticoAlgoritmo Genetico
Algoritmo Genetico
 
How to Design Frameworks
How to Design FrameworksHow to Design Frameworks
How to Design Frameworks
 
How To Build A Better Arduino
How To Build A Better ArduinoHow To Build A Better Arduino
How To Build A Better Arduino
 
Model-Driven Software Development
Model-Driven Software DevelopmentModel-Driven Software Development
Model-Driven Software Development
 
Interfaces de UsuĂĄrio UbĂ­quas - UUI
Interfaces de UsuĂĄrio UbĂ­quas - UUIInterfaces de UsuĂĄrio UbĂ­quas - UUI
Interfaces de UsuĂĄrio UbĂ­quas - UUI
 
hardware de um sistema de computação
hardware de um sistema de computaçãohardware de um sistema de computação
hardware de um sistema de computação
 
Enabling White-Box Reuse in a Pure Composition Language
Enabling White-Box Reuse in a Pure Composition LanguageEnabling White-Box Reuse in a Pure Composition Language
Enabling White-Box Reuse in a Pure Composition Language
 
Representação de Números
Representação de NúmerosRepresentação de Números
Representação de Números
 
Linguagens de Transformação de Modelos
Linguagens de Transformação de ModelosLinguagens de Transformação de Modelos
Linguagens de Transformação de Modelos
 
RobĂłtica MĂłvel
RobĂłtica MĂłvelRobĂłtica MĂłvel
RobĂłtica MĂłvel
 
UML-Based Web Engineering
UML-Based Web EngineeringUML-Based Web Engineering
UML-Based Web Engineering
 
Gerenciamento de Projeto para Desenvolvimento de Sistema
Gerenciamento de Projeto para Desenvolvimento de SistemaGerenciamento de Projeto para Desenvolvimento de Sistema
Gerenciamento de Projeto para Desenvolvimento de Sistema
 
Banco De Dados BĂĄsico
Banco De Dados BĂĄsicoBanco De Dados BĂĄsico
Banco De Dados BĂĄsico
 

Ähnlich wie Scaling Rails with memcached

Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)err
 
Make Your Life Easier With Maatkit
Make Your Life Easier With MaatkitMake Your Life Easier With Maatkit
Make Your Life Easier With MaatkitMySQLConference
 
The Native NDB Engine for Memcached
The Native NDB Engine for MemcachedThe Native NDB Engine for Memcached
The Native NDB Engine for MemcachedJohn David Duncan
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalabilityWim Godden
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Wim Godden
 
All The Little Pieces
All The Little PiecesAll The Little Pieces
All The Little PiecesAndrei Zmievski
 
phptek13 - Caching and tuning fun tutorial
phptek13 - Caching and tuning fun tutorialphptek13 - Caching and tuning fun tutorial
phptek13 - Caching and tuning fun tutorialWim Godden
 
Rails Conf Europe 2007 Notes
Rails Conf  Europe 2007  NotesRails Conf  Europe 2007  Notes
Rails Conf Europe 2007 NotesRoss Lawley
 
Caching and tuning fun for high scalability @ phpBenelux 2011
Caching and tuning fun for high scalability @ phpBenelux 2011Caching and tuning fun for high scalability @ phpBenelux 2011
Caching and tuning fun for high scalability @ phpBenelux 2011Wim Godden
 
Perl Memory Use 201207 (OUTDATED, see 201209 )
Perl Memory Use 201207 (OUTDATED, see 201209 )Perl Memory Use 201207 (OUTDATED, see 201209 )
Perl Memory Use 201207 (OUTDATED, see 201209 )Tim Bunce
 
WiredTiger In-Memory vs WiredTiger B-Tree
WiredTiger In-Memory vs WiredTiger B-TreeWiredTiger In-Memory vs WiredTiger B-Tree
WiredTiger In-Memory vs WiredTiger B-TreeSveta Smirnova
 
10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in production10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in productionParis Data Engineers !
 
Zend Server Data Caching
Zend Server Data CachingZend Server Data Caching
Zend Server Data CachingEl Taller Web
 
Linux-HA with Pacemaker
Linux-HA with PacemakerLinux-HA with Pacemaker
Linux-HA with PacemakerKris Buytaert
 
Performance Whack-a-Mole Tutorial (pgCon 2009)
Performance Whack-a-Mole Tutorial (pgCon 2009) Performance Whack-a-Mole Tutorial (pgCon 2009)
Performance Whack-a-Mole Tutorial (pgCon 2009) PostgreSQL Experts, Inc.
 
Caching and tuning fun for high scalability @ FOSDEM 2012
Caching and tuning fun for high scalability @ FOSDEM 2012Caching and tuning fun for high scalability @ FOSDEM 2012
Caching and tuning fun for high scalability @ FOSDEM 2012Wim Godden
 
Caching Data For Performance
Caching Data For PerformanceCaching Data For Performance
Caching Data For PerformanceDave Ross
 
Big Data Anti-Patterns: Lessons From the Front LIne
Big Data Anti-Patterns: Lessons From the Front LIneBig Data Anti-Patterns: Lessons From the Front LIne
Big Data Anti-Patterns: Lessons From the Front LIneDouglas Moore
 

Ähnlich wie Scaling Rails with memcached (20)

Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)
 
Make Your Life Easier With Maatkit
Make Your Life Easier With MaatkitMake Your Life Easier With Maatkit
Make Your Life Easier With Maatkit
 
The Native NDB Engine for Memcached
The Native NDB Engine for MemcachedThe Native NDB Engine for Memcached
The Native NDB Engine for Memcached
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011
 
All The Little Pieces
All The Little PiecesAll The Little Pieces
All The Little Pieces
 
phptek13 - Caching and tuning fun tutorial
phptek13 - Caching and tuning fun tutorialphptek13 - Caching and tuning fun tutorial
phptek13 - Caching and tuning fun tutorial
 
Rails Conf Europe 2007 Notes
Rails Conf  Europe 2007  NotesRails Conf  Europe 2007  Notes
Rails Conf Europe 2007 Notes
 
Surge2012
Surge2012Surge2012
Surge2012
 
Caching and tuning fun for high scalability @ phpBenelux 2011
Caching and tuning fun for high scalability @ phpBenelux 2011Caching and tuning fun for high scalability @ phpBenelux 2011
Caching and tuning fun for high scalability @ phpBenelux 2011
 
Perl Memory Use 201207 (OUTDATED, see 201209 )
Perl Memory Use 201207 (OUTDATED, see 201209 )Perl Memory Use 201207 (OUTDATED, see 201209 )
Perl Memory Use 201207 (OUTDATED, see 201209 )
 
WiredTiger In-Memory vs WiredTiger B-Tree
WiredTiger In-Memory vs WiredTiger B-TreeWiredTiger In-Memory vs WiredTiger B-Tree
WiredTiger In-Memory vs WiredTiger B-Tree
 
10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in production10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in production
 
Zend Server Data Caching
Zend Server Data CachingZend Server Data Caching
Zend Server Data Caching
 
Linux-HA with Pacemaker
Linux-HA with PacemakerLinux-HA with Pacemaker
Linux-HA with Pacemaker
 
Performance Whack-a-Mole Tutorial (pgCon 2009)
Performance Whack-a-Mole Tutorial (pgCon 2009) Performance Whack-a-Mole Tutorial (pgCon 2009)
Performance Whack-a-Mole Tutorial (pgCon 2009)
 
Caching and tuning fun for high scalability @ FOSDEM 2012
Caching and tuning fun for high scalability @ FOSDEM 2012Caching and tuning fun for high scalability @ FOSDEM 2012
Caching and tuning fun for high scalability @ FOSDEM 2012
 
Big data nyu
Big data nyuBig data nyu
Big data nyu
 
Caching Data For Performance
Caching Data For PerformanceCaching Data For Performance
Caching Data For Performance
 
Big Data Anti-Patterns: Lessons From the Front LIne
Big Data Anti-Patterns: Lessons From the Front LIneBig Data Anti-Patterns: Lessons From the Front LIne
Big Data Anti-Patterns: Lessons From the Front LIne
 

Mehr von elliando dias

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slideselliando dias
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScriptelliando dias
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structureselliando dias
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de containerelliando dias
 
Geometria Projetiva
Geometria ProjetivaGeometria Projetiva
Geometria Projetivaelliando dias
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agilityelliando dias
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Librarieselliando dias
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!elliando dias
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Webelliando dias
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduinoelliando dias
 
Minicurso arduino
Minicurso arduinoMinicurso arduino
Minicurso arduinoelliando dias
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorceryelliando dias
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Designelliando dias
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makeselliando dias
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojureelliando dias
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.elliando dias
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebookelliando dias
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Studyelliando dias
 

Mehr von elliando dias (20)

Clojurescript slides
Clojurescript slidesClojurescript slides
Clojurescript slides
 
Why you should be excited about ClojureScript
Why you should be excited about ClojureScriptWhy you should be excited about ClojureScript
Why you should be excited about ClojureScript
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structures
 
Nomenclatura e peças de container
Nomenclatura  e peças de containerNomenclatura  e peças de container
Nomenclatura e peças de container
 
Geometria Projetiva
Geometria ProjetivaGeometria Projetiva
Geometria Projetiva
 
Polyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better AgilityPolyglot and Poly-paradigm Programming for Better Agility
Polyglot and Poly-paradigm Programming for Better Agility
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
 
How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!How to Make an Eight Bit Computer and Save the World!
How to Make an Eight Bit Computer and Save the World!
 
Ragel talk
Ragel talkRagel talk
Ragel talk
 
A Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the WebA Practical Guide to Connecting Hardware to the Web
A Practical Guide to Connecting Hardware to the Web
 
Introdução ao Arduino
Introdução ao ArduinoIntrodução ao Arduino
Introdução ao Arduino
 
Minicurso arduino
Minicurso arduinoMinicurso arduino
Minicurso arduino
 
Incanter Data Sorcery
Incanter Data SorceryIncanter Data Sorcery
Incanter Data Sorcery
 
Rango
RangoRango
Rango
 
Fab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine DesignFab.in.a.box - Fab Academy: Machine Design
Fab.in.a.box - Fab Academy: Machine Design
 
The Digital Revolution: Machines that makes
The Digital Revolution: Machines that makesThe Digital Revolution: Machines that makes
The Digital Revolution: Machines that makes
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.Hadoop - Simple. Scalable.
Hadoop - Simple. Scalable.
 
Hadoop and Hive Development at Facebook
Hadoop and Hive Development at FacebookHadoop and Hive Development at Facebook
Hadoop and Hive Development at Facebook
 
Multi-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case StudyMulti-core Parallelization in Clojure - a Case Study
Multi-core Parallelization in Clojure - a Case Study
 

KĂźrzlich hochgeladen

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel AraĂşjo
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 

KĂźrzlich hochgeladen (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 

Scaling Rails with memcached

  • 1. Scaling Rails with memcached One Rubyist’s Guide to Hazardous Hits 1 memcached is your best friend and your worst enemy.
  • 2. Who is this kid? CNET Networks PHP Developer Rails Developer ๏ GameSpot ๏ Chowhound ๏ TV.com ๏ Chow.com ๏ MP3.com 2 - I work for CNET Networks in San Francisco. - I used to do PHP for www.gamespot.com, www.tv.com, and www.mp3.com. - GameSpot is one of the two biggest gaming sites on the web, the other being IGN. They are pretty evenly matched. - I now work full time as a Rails developer on www.chowhound.com and www.chow.com (launching September 15th, 2006).
  • 3. GameSpot ๏ 30 million page views per day ๏ 50 million++ during E3 (mid-May) ๏ [ 3000 req/s ] ๏ ~70 app servers ๏ Netscalers ๏ ~15 database servers ๏ php4, apache 2, mysql 5 3 E3 was a press event held yearly, 2006 being the nal year. During this year’s E3 the Sony, Microsoft, and Nintendo press conferences were streamed live by GameSpot. We had the exclusive on the Sony and Nintendo conferences, with both companies’ domains pointing to our webcast as it was happening. Massive traffic, everything went crazy. We had about 100 app servers for E3, all in the red during peak times. Imagine millions of teenage boys constantly hitting refresh. Typical setup: request hits Netscaler (load balancer), Netscaler decides which app server gets the request. Use gzip compression to save bandwidth (but had to turn it off due to load for peaks at E3).
  • 4. memcached. 4 memcached helps.
  • 5. memcached • Distributed, in-memory data store • Created by and for LiveJournal • Scales • Fast. C. Non-blocking IO. O(1) • Digg, Facebook, Wikipedia, GameSpot • 43things, Mog, Chowhound 5 - Distributed: multiple servers storing data in RAM, transparent to your app. - Data is spread amongst servers, not duplicated. - LiveJournal had bad growing pains -- needed a solution. - Problem with databases: you can distribute reads but everyone needs to write (which blocks) - Scales -- drop in a new memcached daemon and you’re good to go. - Lots of big sites use it successfully
  • 6. Like a DRb’d {} • CACHE = MemCache.new(options) • CACHE.get(:key) • CACHE.set(:key, data, ttl) • CACHE.delete(:key) 6 - Very simple to use - Conceptually a hash - Time to live is expiration of key. You can set to 30 days in the future or pick a denitive time
  • 7. Like a DRb’d {} • memcached ‘bucket’ (server) is decided based on requested key • memcache-client uses Marshal to store data • Can’t cache metaclassy things or procs • Run daemons on your app servers. Low CPU overhead. 7 - memcache-client Ruby API decides which memcached server stores your key
  • 8. Like a DRb’d {} ( sort of ) • Not enumerable • Not a database 8 - Hash keys are not maintained - This makes it faster - Not a database: things only kept in RAM, not persistent. - Restart your server, lose your data. That’s ok.
  • 9. The Pattern • Check cache for key • If key exists, return the stored bytes • If key doesn’t exist, nd bytes • Save bytes • Return bytes 9 - We don’t really have to worry about this if we use a good library. - “find bytes” can be a database query or any sort of intensive data lookup -- something we don’t want to do on every request and therefor cache.
  • 10. In other words... def get_cache(key) data = CACHE.get(key) return data unless data.nil? data = nd(key) CACHE.set(key, data, self.ttl) return data end 10 Simple example. Assume `nd’ will return what we want to cache. Can be anything.
  • 11. In other words... def get_cache(key) data = CACHE.get(key) return data unless data.nil? data = nd(key) CACHE.set(key, data, self.ttl) return data end 11 - What if we want to cache nil? We will query the database every time the key is requested. - If you have 4 million rows that’s not something you want. - Cache false instead of nil. - This and other things you need to watch for.
  • 12. What about MySQL query cache? • memcached is for data. • You can cache anything. • Generated PNG’s, HTML, processed objects, etc. 12 Forget the query cache.
  • 13. Are you sure you need it? 13 You might not.
  • 14. It’s Not “Better” Than SQL • memcached is slower than SELECT on localhost for small sites / datasets • memcached will not help if you can’t keep up with the requests • None of the big guys started with memcached. 14 - Not going to speedup your blog. Going to slow it down. - You need good hardware and a good setup before you can think about memcached - multi server setup, load balancing, master / slave databases - Facebook, Slashdot, Digg didn’t start with memcached. They added it when they needed it.
  • 15. Don’t Worry About It • Write your app and tests rst • Get everything working smoothly • Keep a few days open to spend on caching • ^^ Near The End 15 - Don’t let memcached get in the way - Don’t do premature optimization - Write good code, but dont GUESS where the problems are going to be. Test and see. - Your app needs to be able to run well without caching. Caching is an aid, not a crutch. - If you want to test your caching code use a hash-based mock. - acts_as_cached has one in test/xtures/
  • 16. Don’t Worry About It • Identify slow queries • MySQL slow query log • Hardware is the real secret sauce • memcached is not a magic wand 16 - Find out what’s really holding you back, the big bottlenecks - Use the QueryTrace plugin to see where your queries are coming from
  • 17. Where it Shines • Huge database, millions of rows • Huge trafc, millions of hits • Huge both, millions of everything 17 - Even a few row select can be slow on a massive database - If your query does a lesort on a big dataset, forget it - Set your cache based on a unique id - Maybe your database isn’t massive but is getting completely hammered. Cache.
  • 18. Yeah, but I’m about to launch Web 9.0 18 - COUNT ME IN!!!
  • 19. Hook Me Up • Download and compile from danga.com • OSXers: libevent and Hodel’s hacks • $ sudo gem install memcache-client • $ memcached -vv 19 - Danga are the LiveJournal guys - Won’t work well on osx without Hodel’s hacks - Install the Robot Coop’s memcache-client - Start daemon in interactive mode, watch what’s going on. - Setup a MemCache.new instance, hit .set and .get, watch what happens in your memcached daemon
  • 20. Options • Fragment Cache Store • http://rubyforge.org/projects/mcache-fragment/ • Session Store • cong.action_controller.session_store = :mem_cache_store • Models ( DB Queries ) • CachedModel 20 - Fragment cache store plugin supports time based expirations - Lots of stuff written about setting up session store - CachedModel is what 43things wrote and uses.
  • 21. CachedModel • Overwrites nd() to pull from cache • Works on single objects only • Doesn’t play well with multi-object queries on gets or updates • Makes you inherit • Nice and simple • Clears cache keys on update() 21 - You don’t have to worry about caching: does it for you - Doesn’t work on nd(:all) or complex queries (:include, etc)
  • 22. acts_as_cached • Rails plugin • Allows you to store any Ruby object in memcached • Gives you more than enough rope... 22 - Used on Chowhound and Chow - Gives us flexibility - Still have to do things by hand, but helps ease the pain - Puts the caching in your face. Think about what you’re doing.
  • 23. What To Cache • Slow Queries • Page fragments • (We don’t cache fragments on Chowhound) • Processor intensive computations 23
  • 24. What To Cache class StoriesController < ApplicationController def show @story = Story.get_cache(params[:id]) end end 24 - Simple single row get - We like get_cache because you are always aware of what is and isn’t cached
  • 25. Issues • Keeping cache data fresh • Editors want to see their changes now! • Caching associations • Pagination / Big Collections 25 - Chowhound is a forum site, Chow is an editorial content site - Everyone wants to see their changes immediately - Mix that with lots of pagination and big collections - How the hell? - We want to cache associations because we want to use Rails’ niceness - But we don’t have to keep reimplementing the same patterns
  • 26. Keep Cache Fresh class Story < ActiveRecord::Base acts_as_cached def after_save expire_cache(id) end end 26 - Simplest example. - acts_as_cached doesn’t handle auto-deletion of keys for you like CachedModel - Don’t forget to after_destroy, too!
  • 27. Keep Cache Fresh class Story < ActiveRecord::Base acts_as_cached :include => :author belongs_to :author def after_save expire_cache(id) end end 27 - acts_as_cache can be passed a hash which is passed straight to nd() - In this case, Story.get_cache(20) calls Story.nd(20, :include => :author) - Caches the author along with the story - If the author is updated, the story’s associated cached author is STALE - If you have 20 stories all with 1 author, you have 20 redundant copies of that same author in the cache - RAM is cheap but you need to think this sort of thing through
  • 28. Keep Cache Fresh class Author < ActiveRecord::Base acts_as_cached has_many :stories def after_save expire_cache(id) stories.each do |story| story.expire_cache end end end 28 - Stories’ author associations are now always up to date - Pattern can be powerful when dealing with complex associations
  • 29. Why? • Keeping track of keys is hard • Sweepers / Observers get complicated fast • Maintains integrity with script/console, rake, and migrations 29 - CachedModel does it for you, which is nice - We want to cache associations
  • 30. Alternative class Story < ActiveRecord::Base acts_as_cached belongs_to :author def author Author.get_cache(author_id) end def after_save expire_cache(id) end end 30 - Lots of cache hits -- unless you use an in-process cache - Everything always up to date - Best for simple associations - Great if your authors table is in another database -- you can’t do a join anyway
  • 31. Versioning! class Story < ActiveRecord::Base acts_as_cached :version => 5 def after_save expire_cache(id) end end 31 - What if you run a migration and update your Story model, then need to deploy? - All stories in cached are not only stale but broken - Mismatch between cached attributes and new attributes - You may have run into this with sessions - Update the version, acts_as_cached helps you out here - Keys are normally stored as ENVIRONMENT:CLASS:ID - So app-development:Story:20 - :version => 5 makes Story’s keys: app-development:Story:v5:20 - Instantly invalidate all currently cached, older versions.
  • 32. List Objects • Pagination is tricky • Who controls it? Controller? Model? • How do you keep pagination fresh? 32 - Pagination helpers are way out the window - It makes sense to think of list objects as data structures (models), not active record objects - They’re just simple data structures we want to arbitrarily cache
  • 33. class BlogPostList acts_as_cached PAGES = 5 PER_PAGE = 30 def self.nd(page = 0) BlogPost.nd(:all, :limit => PER_PAGE, :offset => page * PER_PAGE) end def self.get_cache(page = 0) if page < PAGES super(page) else nd(page) end end end 33 - Create class, give it a nd, overwrite its get_cache - Pages 6 - innity are not cached. Do they get any traffic? Probably not. Check your logs. - Pages 1 - 5 are cached.
  • 34. class BlogPostList acts_as_cached PAGES = 5 PER_PAGE = 30 def self.expire_list_cache 0.upto(PAGES) do |page| expire_cache(page) end end end 34 - Now it’s easy to expire - Put this in BlogPost.after_save: def after_save BlogPostList.expire_list_cache end
  • 35. List Objects • Not just for pagination • Use it in your sidebar, footer, RSS, API, etc... • Reuse the caches you have 35 - List objects can be reused - Again, just data structures - Don’t bloat models with tons of caching code - Do post-processing if you need to
  • 36. Clear All class ApplicationController < ActionController::Base before_lter :check_cache_skip def check_cache_skip returning true do Object.skip_cache_gets = params[:skip_cache] ? true : false end end end http://www.bigsite.com/index?skip_cache=1 36 - Resets every cache key on that page load - Skips the get() so nd() is called and result is saved to cache then returned - Good for debugging caching code - Is what’s in my cache what I really want? Is all the clearing working?
  • 37. Caveats • 1 meg per key limit • Disable caching in unit tests, or use a mock • No whitespace in key names! • Don’t save ‘nil’ • Monitor your cache. memcached is ckle • Weird behavior? Restart. 37 - Dont go overboard caching - 1 meg limit - acts_as_cached handles some of this: no whitespace in names, nils are converted to false - memcached has a tendency to return corrupt data after tons of use. Restart liberally. - Don’t try to keep memcached up forever. Bad mojo.
  • 38. Monitoring $ sudo gem install memcache-client-stats $ ruby script/console >> require ‘memcache_client_stats’ => true >> CACHE.stats(:key => 'bytes') => {quot;localhost:11211quot;=>quot;271349quot;, quot;localhost:11212quot;=>quot;62729quot;} >> CACHE.stats(:type => 'items') {quot;localhost:11211quot;=> {quot;items:18:agequot;=>quot;6497quot;, quot;items:18:numberquot;=>quot;1quot;, ... }} 38 - Great gem - Spend some time learning what everything means - Watch all your servers in one place -- build a page which aggregates and displays this information - It’d be nice if this was integrated into capistrano somehow... (I’ll get back to you on that)
  • 39. Monitoring • Cacti • http://cacti.net/ • memcached template • http://dealnews.com/developers/cacti/ memcached.html 39 - Haven’t used it but it gets recommended on the mailing list.
  • 40. Resources • memcached site • http://www.danga.com/memcached/ • memcached mailing list • http://lists.danga.com/pipermail/memcached/ • topfunky’s post • http://rubyurl.com/sbE • Robot Coop • http://dev.robotcoop.com/ • The Adventures of Scaling • http://rubyurl.com/vK7 • Sessions N Such (memcached sessions) • http://errtheblog.com/post/24 40
  • 41. Questions? Thanks! Chris Wanstrath chris@ozmm.org Err the Blog http://errtheblog.com www.chow.com www.chowhound.com 2006-09-12 41