SlideShare ist ein Scribd-Unternehmen logo
1 von 29
ENHANCE YOUR APDEX..
                     NATURALLY!
                      Proven methods to enhance your
                       Rails performance when trafic
                              increases X times

                                               Vlad ZLOTEANU
     #ParisRB                          Software Engineer - Dimelo
     March 6, 2002                                @vladzloteanu
Copyright Dimelo SA                                     www.dimelo.com
Be Warned!




                 Surprise coming up…
                 at the end of this talk! ;)



Copyright Dimelo SA                        www.dimelo.com
Dimelo


                      Software editor, SaaS platforms, social media CR

                      Frontend platforms
                         Collaborative platforms, ‘forum/SO-like’,
                         white-labeled, for big accounts (a kind of
                         GetSatisfaction / UserVoice for big accounts)
                      Backend product
                         SocialAPIs
                         kind of tweetdeck, but multiple channel,
                         designed for multiple users/teams

Copyright Dimelo SA                                          www.dimelo.com
Technical details (frontend product)


                      30+ average dynamic (Rails) req/s (web + api)
                         Peaks of 80 req/s
                      2M+ dynamic requests / day
                      700k+ unique visitors / day




Copyright Dimelo SA                                         www.dimelo.com
Tools


                      Load/Stress tests: AB, httperf, siege

                      Htop, iftop, mytop
                      passenger-status, passenger-memory-status

                      Mysql: EXPLAIN query, SHOW PROCESSLIST

                      Application logs
                      NewRelic

Copyright Dimelo SA                                           www.dimelo.com
Demo env


                      Rails 3.2
                      REE + Passenger + Apache (3 workers)
                      MySQL 5.5.x + InnoDB tables
                      OSX Lion - MBPro 2010 8GB RAM

    class Post < ActiveRecord::Base # 500K posts
      belongs_to :author
      has_and_belongs_to_many :categories
      # state -> [ moderation, published, answered ]
    …

    class Category < ActiveRecord::Base
      has_and_belongs_to_many :posts

Copyright Dimelo SA                                          www.dimelo.com
A. External services: timeouts [DEMO]

   # EventMachine app on port 8081

         operation = proc do
            sleep 2 # simulate a long running request
            resp.status = 200
            resp.content = "Hello World!"
          end

           EM.defer(operation, callback)


   # AggregatesController on main site (port 8080)

           uri = URI('http://127.0.0.1:8081’)
           http = Net::HTTP.new(uri.host, uri.port)

           @rss_feeds = http.get("/").body
Copyright Dimelo SA                                   www.dimelo.com
A. External services: timeouts

   Problem            Page depends on external resource (E.G.: RSS,
                      Twitter API, FB API, Auth servers, …)
                      External resource responds very slow, or
                      connection hangs
                      In ruby, Net::HTTP’s default timeout is 60s!
                      Ruby 1.8 – Timeout library is not reliable

 Solution             Move it to a BG request
                      Put timeouts EVERYWHERE!
                      Enable timeouts on API clients
                      Cache parts that involve external resources
Copyright Dimelo SA                                         www.dimelo.com
A. Internal services(2)

   Problem            Same conditions, but this time 2 services from
                      same server/application have calls each to other



   Solution           Same problems, but risk of deadlock!




Copyright Dimelo SA                                          www.dimelo.com
B. DB: Queries containing ‘OR’
                 conditions [Demo]
   # Request: list also my posts (current user’s posts),
   even if they are not published

   # Current index: on [state, created_at]

    @posts.where("state = :state OR author_id =
   :author_id",
         {:state => 'published',
          :author_id => params[:author_id]})




Copyright Dimelo SA                               www.dimelo.com
B. DB: Queries containing ‘OR’
                 conditions

   Problem            Queries containing “OR” conditions
                          EG: ‘visible_or_mine’ (status = published OR
                          author_id=42 )
                       .. will make index on [ a, b, c ] unusable on (a
                      OR condition) AND b AND c

   Solution           Don’t use it!
                      Cache the result
                      Put index only on sort column
                      On: (a OR cond) AND b AND c, put index on[b, c]
Copyright Dimelo SA                                           www.dimelo.com
C. Filtering on HABTM relations [Demo]

 # Request: Filter by one (or more) categories
 # Model
 @posts = @posts.joins(:categories).
            where(:categories =>
              {:id => params[:having_categories]})


 # OR: Create join model, use only one join

 # Model
 has_many :post_categorizations
 has_many :categories, :through => :post_categorizations

  # Controller
  @posts.joins(:post_categorizations).
                       where(:post_categorizations =>
                {:category_id =>
Copyright Dimelo SA params[:having_categories]})        www.dimelo.com
C. Filtering on HABTM relations

   Problem            Filtering on HABTM relations creates a double
                      join
                          .. which are (usually) expensive

   Solution           Rewrite double joins
                        Use intermediary model
                        Join on intermediary model




Copyright Dimelo SA                                         www.dimelo.com
D. DB: Pagination/count on large tables
                 [Demo]
   # Nothing fancy, just implement pagination

   # Controller
   @posts = @posts.paginate(
                :page => params[:page]).
            order('posts.created_at desc')


   # View
   <%= will_paginate @posts %>




Copyright Dimelo SA                             www.dimelo.com
D. DB: Pagination/count on large tables

   Problem            Count queries are expensive on large tables
                      Each time a pagination is displayed, a count
                      query is run
                      Displaying distant page (aka using a big OFFSET)
                      is very expensive

                      MyISAM: counts LOCK the TABLE!




Copyright Dimelo SA                                          www.dimelo.com
D. DB: Pagination/count on large tables
                 (2)


  Solution            Cache count result
                          .. and don’t display ‘last’ pages
                      Limit count
                          SELECT COUNT(*) FROM a_table WHERE some_conditions
                          
                          SELECT COUNT(*) FROM (SELECT 1 FROM a_table WHERE
                          some_conditions LIMIT x) t;
                  Drop the isolation: NOLOCK / READ
                 UNCOMMITED


Copyright Dimelo SA                                              www.dimelo.com
E. Fragment caching: Thundering herd

   # Let’s implement fragment caching, time-expired for
   displaying the previous page (no pagination
   optimisations were enabled)



   <% cache_key = ("posts::" +
            Digest::MD5.hexdigest(params.inspect))

         cache cache_key, :expires_in => 20.seconds do   %>
          <h1>Posts#index</h1>
   ….
   <% end %>




Copyright Dimelo SA                                 www.dimelo.com
E. Fragment caching: Thundering herd

   Problem            Using: fragment cache, time-expired
                      Cache for a resource-intensive page expires 
                      multiple processes try to recalculate the key
                      Effects: resource consumption peaks, passenger
                      worker pools starvation



                                                                       t

    Cache unavailable;             Cache
    Cache computation              validity

Copyright Dimelo SA                                        www.dimelo.com
E. Fragment caching: Thundering herd (2)




Copyright Dimelo SA                             www.dimelo.com
E. Fragment caching: Thundering herd (3)


                      Backgrounded calculation/sweeping is
                      hard/messy/buggy

   Solution
                      Before expiration time is reached (t - delta),
                      obtain a lock and trigger cache recalculation
                      The next processes won’t obtain the lock and
                      will serve the still-valid cache
                      Rails 2:
                      github.com/nel/atomic_mem_cache_store
                      Rails 3: Implemented.

Copyright Dimelo SA                                          www.dimelo.com
F. API and Web on same server

   Problem            API and Web don’t have complementary usage
                      patterns
                         Web slows down APIs, that should respond
                         fast
                         APIs are much more prone to peaks
                            Worker threads starvation

   Solution           Put API and WEB on different servers
                      Log/Throttle API calls


Copyright Dimelo SA                                          www.dimelo.com
G. API: dynamic queries

   Problem            REST APIs usually expose a proxy to your DB
                      Client can make any type of combination
                      available: filter + sort
                          And because they can, they will.

   Solution           Don’t give them too many options 
                      Use one db per client (prepare to shard per
                      client)
                          Will be able to: add custom indexes
                      Log/Throttle API calls
Copyright Dimelo SA                                         www.dimelo.com
H. Ruby GC: not adapted for Web
                 frameworks

   Problem            Ruby GC is not optimized for large web
                      frameworks
                      On medium Rails apps, ~50% of time can be
                      spent in GC

   Solution           Use REE or Ruby 1.9.3
                      Activate GC.stats & benchmark your app
                      Tweak GC params
                         trade memory for CPU
                         Previous conf: 40%+ speed for 20%+ memory
Copyright Dimelo SA                                       www.dimelo.com
I. Other recomandations

   Solution
                      Use MyISAM (on MySQL) unless you really need
                      transactions
                      Design your models thinking about sharding
                      (and shard the DB, when it becomes the
                      bottleneck)
                      Perf refactor: improve where it matters
                         Benchmark (before and after)
                      Btw.. Don’t make perf tests on OSX :P




Copyright Dimelo SA                                      www.dimelo.com
Copyright Dimelo SA   www.dimelo.com
Le Dimelo Contest revient !




             Coder un Middleware Rack
                        pour
       déterminer les urls accédées via Rack,
       calculer le nombre de visiteurs uniques,
       en temps réel, agrégé sur les 5 dernières
      minutes.


Copyright Dimelo SA                            www.dimelo.com
Le prix !




Copyright Dimelo SA          www.dimelo.com
Copyright Dimelo SA   www.dimelo.com
.end

                        Thank you!


                           ?

Copyright Dimelo SA                  www.dimelo.com

Weitere ähnliche Inhalte

Ähnlich wie Enhance you APDEX.. naturally!

Jeff Barr Amazon Services Cloud Computing
Jeff Barr Amazon Services Cloud ComputingJeff Barr Amazon Services Cloud Computing
Jeff Barr Amazon Services Cloud Computing
deimos
 
Systems Bioinformatics Workshop Keynote
Systems Bioinformatics Workshop KeynoteSystems Bioinformatics Workshop Keynote
Systems Bioinformatics Workshop Keynote
Deepak Singh
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01
Tony Frame
 

Ähnlich wie Enhance you APDEX.. naturally! (20)

Distributed-ness: Distributed computing & the clouds
Distributed-ness: Distributed computing & the cloudsDistributed-ness: Distributed computing & the clouds
Distributed-ness: Distributed computing & the clouds
 
Jeff Barr Amazon Services Cloud Computing
Jeff Barr Amazon Services Cloud ComputingJeff Barr Amazon Services Cloud Computing
Jeff Barr Amazon Services Cloud Computing
 
Systems Bioinformatics Workshop Keynote
Systems Bioinformatics Workshop KeynoteSystems Bioinformatics Workshop Keynote
Systems Bioinformatics Workshop Keynote
 
Cloud Talk
Cloud TalkCloud Talk
Cloud Talk
 
Microservices reativos usando a stack do Netflix na AWS
Microservices reativos usando a stack do Netflix na AWSMicroservices reativos usando a stack do Netflix na AWS
Microservices reativos usando a stack do Netflix na AWS
 
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.com
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.comRuby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.com
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.com
 
Clean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixClean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflix
 
Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
 
M/DB and M/DB:X
M/DB and M/DB:XM/DB and M/DB:X
M/DB and M/DB:X
 
Learning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersLearning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client Developers
 
Intro to mobile web application development
Intro to mobile web application developmentIntro to mobile web application development
Intro to mobile web application development
 
Accelerating Application Development with Amazon Aurora (DAT312-R2) - AWS re:...
Accelerating Application Development with Amazon Aurora (DAT312-R2) - AWS re:...Accelerating Application Development with Amazon Aurora (DAT312-R2) - AWS re:...
Accelerating Application Development with Amazon Aurora (DAT312-R2) - AWS re:...
 
Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01Googleappengineintro 110410190620-phpapp01
Googleappengineintro 110410190620-phpapp01
 
The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
The Best Practices and Hard Lessons Learned of Serverless Applications
The Best Practices and Hard Lessons Learned of Serverless ApplicationsThe Best Practices and Hard Lessons Learned of Serverless Applications
The Best Practices and Hard Lessons Learned of Serverless Applications
 
Scalability at GROU.PS
Scalability at GROU.PSScalability at GROU.PS
Scalability at GROU.PS
 
OrientDB the database for the web 1.1
OrientDB the database for the web 1.1OrientDB the database for the web 1.1
OrientDB the database for the web 1.1
 
Best Practices and Hard Lessons of Serverless- AWS Startup Day Toronto- Diego...
Best Practices and Hard Lessons of Serverless- AWS Startup Day Toronto- Diego...Best Practices and Hard Lessons of Serverless- AWS Startup Day Toronto- Diego...
Best Practices and Hard Lessons of Serverless- AWS Startup Day Toronto- Diego...
 
TorqueBox at DC:JBUG - November 2011
TorqueBox at DC:JBUG - November 2011TorqueBox at DC:JBUG - November 2011
TorqueBox at DC:JBUG - November 2011
 

Kürzlich hochgeladen

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Kürzlich hochgeladen (20)

MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 

Enhance you APDEX.. naturally!

  • 1. ENHANCE YOUR APDEX.. NATURALLY! Proven methods to enhance your Rails performance when trafic increases X times Vlad ZLOTEANU #ParisRB Software Engineer - Dimelo March 6, 2002 @vladzloteanu Copyright Dimelo SA www.dimelo.com
  • 2. Be Warned! Surprise coming up… at the end of this talk! ;) Copyright Dimelo SA www.dimelo.com
  • 3. Dimelo Software editor, SaaS platforms, social media CR Frontend platforms Collaborative platforms, ‘forum/SO-like’, white-labeled, for big accounts (a kind of GetSatisfaction / UserVoice for big accounts) Backend product SocialAPIs kind of tweetdeck, but multiple channel, designed for multiple users/teams Copyright Dimelo SA www.dimelo.com
  • 4. Technical details (frontend product) 30+ average dynamic (Rails) req/s (web + api) Peaks of 80 req/s 2M+ dynamic requests / day 700k+ unique visitors / day Copyright Dimelo SA www.dimelo.com
  • 5. Tools Load/Stress tests: AB, httperf, siege Htop, iftop, mytop passenger-status, passenger-memory-status Mysql: EXPLAIN query, SHOW PROCESSLIST Application logs NewRelic Copyright Dimelo SA www.dimelo.com
  • 6. Demo env Rails 3.2 REE + Passenger + Apache (3 workers) MySQL 5.5.x + InnoDB tables OSX Lion - MBPro 2010 8GB RAM class Post < ActiveRecord::Base # 500K posts belongs_to :author has_and_belongs_to_many :categories # state -> [ moderation, published, answered ] … class Category < ActiveRecord::Base has_and_belongs_to_many :posts Copyright Dimelo SA www.dimelo.com
  • 7. A. External services: timeouts [DEMO] # EventMachine app on port 8081 operation = proc do sleep 2 # simulate a long running request resp.status = 200 resp.content = "Hello World!" end EM.defer(operation, callback) # AggregatesController on main site (port 8080) uri = URI('http://127.0.0.1:8081’) http = Net::HTTP.new(uri.host, uri.port) @rss_feeds = http.get("/").body Copyright Dimelo SA www.dimelo.com
  • 8. A. External services: timeouts Problem Page depends on external resource (E.G.: RSS, Twitter API, FB API, Auth servers, …) External resource responds very slow, or connection hangs In ruby, Net::HTTP’s default timeout is 60s! Ruby 1.8 – Timeout library is not reliable Solution Move it to a BG request Put timeouts EVERYWHERE! Enable timeouts on API clients Cache parts that involve external resources Copyright Dimelo SA www.dimelo.com
  • 9. A. Internal services(2) Problem Same conditions, but this time 2 services from same server/application have calls each to other Solution Same problems, but risk of deadlock! Copyright Dimelo SA www.dimelo.com
  • 10. B. DB: Queries containing ‘OR’ conditions [Demo] # Request: list also my posts (current user’s posts), even if they are not published # Current index: on [state, created_at] @posts.where("state = :state OR author_id = :author_id", {:state => 'published', :author_id => params[:author_id]}) Copyright Dimelo SA www.dimelo.com
  • 11. B. DB: Queries containing ‘OR’ conditions Problem Queries containing “OR” conditions EG: ‘visible_or_mine’ (status = published OR author_id=42 ) .. will make index on [ a, b, c ] unusable on (a OR condition) AND b AND c Solution Don’t use it! Cache the result Put index only on sort column On: (a OR cond) AND b AND c, put index on[b, c] Copyright Dimelo SA www.dimelo.com
  • 12. C. Filtering on HABTM relations [Demo] # Request: Filter by one (or more) categories # Model @posts = @posts.joins(:categories). where(:categories => {:id => params[:having_categories]}) # OR: Create join model, use only one join # Model has_many :post_categorizations has_many :categories, :through => :post_categorizations # Controller @posts.joins(:post_categorizations). where(:post_categorizations => {:category_id => Copyright Dimelo SA params[:having_categories]}) www.dimelo.com
  • 13. C. Filtering on HABTM relations Problem Filtering on HABTM relations creates a double join .. which are (usually) expensive Solution Rewrite double joins Use intermediary model Join on intermediary model Copyright Dimelo SA www.dimelo.com
  • 14. D. DB: Pagination/count on large tables [Demo] # Nothing fancy, just implement pagination # Controller @posts = @posts.paginate( :page => params[:page]). order('posts.created_at desc') # View <%= will_paginate @posts %> Copyright Dimelo SA www.dimelo.com
  • 15. D. DB: Pagination/count on large tables Problem Count queries are expensive on large tables Each time a pagination is displayed, a count query is run Displaying distant page (aka using a big OFFSET) is very expensive MyISAM: counts LOCK the TABLE! Copyright Dimelo SA www.dimelo.com
  • 16. D. DB: Pagination/count on large tables (2) Solution Cache count result .. and don’t display ‘last’ pages Limit count SELECT COUNT(*) FROM a_table WHERE some_conditions  SELECT COUNT(*) FROM (SELECT 1 FROM a_table WHERE some_conditions LIMIT x) t; Drop the isolation: NOLOCK / READ UNCOMMITED Copyright Dimelo SA www.dimelo.com
  • 17. E. Fragment caching: Thundering herd # Let’s implement fragment caching, time-expired for displaying the previous page (no pagination optimisations were enabled) <% cache_key = ("posts::" + Digest::MD5.hexdigest(params.inspect)) cache cache_key, :expires_in => 20.seconds do %> <h1>Posts#index</h1> …. <% end %> Copyright Dimelo SA www.dimelo.com
  • 18. E. Fragment caching: Thundering herd Problem Using: fragment cache, time-expired Cache for a resource-intensive page expires  multiple processes try to recalculate the key Effects: resource consumption peaks, passenger worker pools starvation t Cache unavailable; Cache Cache computation validity Copyright Dimelo SA www.dimelo.com
  • 19. E. Fragment caching: Thundering herd (2) Copyright Dimelo SA www.dimelo.com
  • 20. E. Fragment caching: Thundering herd (3) Backgrounded calculation/sweeping is hard/messy/buggy Solution Before expiration time is reached (t - delta), obtain a lock and trigger cache recalculation The next processes won’t obtain the lock and will serve the still-valid cache Rails 2: github.com/nel/atomic_mem_cache_store Rails 3: Implemented. Copyright Dimelo SA www.dimelo.com
  • 21. F. API and Web on same server Problem API and Web don’t have complementary usage patterns Web slows down APIs, that should respond fast APIs are much more prone to peaks Worker threads starvation Solution Put API and WEB on different servers Log/Throttle API calls Copyright Dimelo SA www.dimelo.com
  • 22. G. API: dynamic queries Problem REST APIs usually expose a proxy to your DB Client can make any type of combination available: filter + sort And because they can, they will. Solution Don’t give them too many options  Use one db per client (prepare to shard per client) Will be able to: add custom indexes Log/Throttle API calls Copyright Dimelo SA www.dimelo.com
  • 23. H. Ruby GC: not adapted for Web frameworks Problem Ruby GC is not optimized for large web frameworks On medium Rails apps, ~50% of time can be spent in GC Solution Use REE or Ruby 1.9.3 Activate GC.stats & benchmark your app Tweak GC params trade memory for CPU Previous conf: 40%+ speed for 20%+ memory Copyright Dimelo SA www.dimelo.com
  • 24. I. Other recomandations Solution Use MyISAM (on MySQL) unless you really need transactions Design your models thinking about sharding (and shard the DB, when it becomes the bottleneck) Perf refactor: improve where it matters Benchmark (before and after) Btw.. Don’t make perf tests on OSX :P Copyright Dimelo SA www.dimelo.com
  • 25. Copyright Dimelo SA www.dimelo.com
  • 26. Le Dimelo Contest revient ! Coder un Middleware Rack pour déterminer les urls accédées via Rack, calculer le nombre de visiteurs uniques, en temps réel, agrégé sur les 5 dernières minutes. Copyright Dimelo SA www.dimelo.com
  • 27. Le prix ! Copyright Dimelo SA www.dimelo.com
  • 28. Copyright Dimelo SA www.dimelo.com
  • 29. .end Thank you! ? Copyright Dimelo SA www.dimelo.com

Hinweis der Redaktion

  1. Modalite super simple de avoir du downtime – garantie