$30 off During Our Annual Pro Sale. View Details »

High Performance Rails

High Performance Rails

Issei Naruta

May 31, 2013
Tweet

More Decks by Issei Naruta

Other Decks in Programming

Transcript

  1. )JHI 1FSGPSNBODF 3BJMT Issei Naruta RubyKaigi 2013 (long edition)

  2. *TTFJ/BSVUB VP of DevOps at COOKPAD Inc. @mirakui Image delivering

    && site performance improvement
  3. “Speed up Rails”

  4. None
  5. COOKPAD is Japan’s top recipe site allowing visitors to upload

    and search through original, user- created recipes. 20 million UU/month 1.38 million recipes *Jan 2013
  6. $00,1"% • AWS • Rails 3.2 • Ruby 2.0.0

  7. 4J[FPG 0VS3BJMT"QQ • 1003 models • 236 controllers • 2871

    view templates • 1978 lines in routes.rb • 3383 assets in manifest.yml *26 May 2013
  8. NT

  9. 8IBUJTUIF lSFTQPOTFUJNFz

  10. Started GET "/articles/1" ... : Article Load (0.1ms) SELECT articles.*

    FROM ... : Rendered articles/show.html.erb within layouts/application (0.7ms) Completed 200 OK in 100ms (Views: 70.1ms | ActiveRecord: 10.0ms) 3FTQPOTFUJNFJO SBJMTMPH
  11. 3FTQPOTFUJNFJO SFTQPOTFIFBEFS X-Runtime: 0.123456

  12. routing before_filter after_filter rendering action Rails Rack "Completed" time X-Runtime

    )5513FRVFTU )5513FTQPOTF
  13. *T3BJMT4MPX

  14. http://www.techempower.com/benchmarks/ Rails (slow) Servlet (fast) 8FC'SBNFXPSL#FODINBSLT

  15. .BKPSQSFNJTFPG IJHIQFSGPSNBODF 3BJMTBQQT

  16. %PO`UQSPDFTT SVCZDPEF JGQPTTJCMF

  17. /HJOY 6OJDPSO QSPYZ CVGGFSJOH 3BJMT

  18. /HJOY 6OJDPSO serve static files

  19. /HJOY 6OJDPSO 7BSOJTI "QBDIF TUBUJDpMFT QBHFDBDIJOH QSPYZ CVGGFSJOH 3BJMT

  20. #SPXTFSTJEF $BDIJOH

  21. #SPXTFSTJEF $BDIJOH

  22. 6TJOHCSPXTFSTJEFDBDIJOH

  23. /FWFSVTFCSPXTFSTJEFDBDIJOH

  24. $POEJUJPOBM(&5

  25. 1st request 2nd request

  26. None
  27. GSFTI@XIFO • Set ETag and Last-Modified to response header •

    Return “304 Not Modified” if; •ETag == If-None-Match • Last-Modified <= If-Modified-Since • Skip rendering if 304 (fast!)
  28. is equal to

  29. FUBH\^ 3BJMT ETag is made of <!BSUJDMF DVSSFOU@VTFSJE>

  30. 3VCZ7FSTJPO

  31. 0VSSVCZIJTUPSZ • Sep 2012 • REE (Ruby Enterprise Edition) 1.8.7

    • Feb 2013 • MRI 1.9.3 • Apr 2013 • MRI 2.0.0
  32. 8IBU`T3&& • MRI 1.8.7 + “MBARI patch” • “100% compatible

    with MRI 1.8.7” • Copy-on-Write Friendly GC • tcmalloc
  33. REE 1.8.7 MRI 1.9.3 MRI 2.0.0 3FTQPOTFUJNF CZSVCZWFSTJPOT -100ms -20ms

  34. #FODINBSLT JOUIJTQSFTFOUBUJPOBSF 3VCZ 3BJMTSD

  35. 1FSGPSNBODF #PUUMFOFDLT JO3BJMT

  36. 0% 20% 40% 60% 80% 100% SQL Ruby 3FTQPOTFUJNF CSFBLEPXO

    SFDJQFTIPX DPPLQBEDPN
  37. 4MPXTUVGG *FYQFSJFODFE • ActiveRecord objects creation • Resolving routes

  38. "DUJWF3FDPSE`T PWFSIFBE "SUJDMFMBTU  UP@B "SUJDMF-PBE NT 4&-&$5ABSUJDMFTA '30.

  39. "DUJWF3FDPSE`T PWFSIFBE #FODINBSLNT\"SUJDMFMBTU  UP@B^ "SUJDMF-PBE NT 4&-&$5ABSUJDMFTA '30. 

    The query is fast enough but creating 100 AR objects is slow
  40. 3FTPMWJOHSPVUFT • Fat routes slow down url_for • e.g. link_to

    helper
  41. 4J[FPG 0VS3BJMT"QQ • 1003 models • 236 controllers • 2871

    view templates • 1978 lines in routes.rb • 3383 assets in manifest.yml *26 May 2013
  42. MJOL@UPIFMMP IFMMP@JOEFY@VSM MJOL@UPbIFMMP` DPOUSPMMFSbIFMMP` BDUJPObJOEFY` 8IJDIJTGBTUFS

  43. DPOpHSPVUFTSC HFUbIFMMPJOEFY` UPbIFMMPJOEFY` UJNFTEPcJc HFUlIFMMP\J^z UPbIFMMPJOEFY` FOE .BLFGBUSPVUFT

  44. MJOL@UPIFMMP IFMMP@JOEFY@VSM NT MJOL@UPbIFMMP` DPOUSPMMFSbIFMMP` BDUJPObJOEFY` NT 3FTVMU

  45. 4MPXSBDL NJEEMFXBSF w3BDL$BDIF • Caches response with Rails.cache • Default

    in Rails 3.2 • Not default in Rails 4
  46. $BDIJOH

  47. 'SBHNFOU$BDIF

  48. DBDIFEP USFOE@LFZXPSET FOE

  49. DBDIFEP controller action cache digest (Rails4) views/localhost:3000/hello/cache_test/3e9258928c27f4ffc5135520c3a976c5 %FGBVMUDBDIFLFZ

  50. DBDIFGSBHNFOUbLFZ`EP views/localhost:3000/hello/cache_test?fragment=key1 /3e9258928c27f4ffc5135520c3a976c5 fragment key 'SBHNFOUDBDIFLFZ

  51. DBDIFbLFZ`EP views/key1/116839051556390fb4d5b25362cfe6eb global key (MPCBMDBDIFLFZ

  52. DBDIF!BSUJDMFEP table name @article.cache_key (id, updated_at) views/articles/1-20130527190532189241000 /116839051556390fb4d5b25362cfe6eb "3DBDIFLFZ

  53. $BDIF%JHFTUT BLBl3VTTJBOEPMMDBDIJOHz

  54. projects documents comments 1 * 1 * has_many :documents has_many

    :comments belongs_to :document id updated_at id project_id updated_at id document_id updated_at belongs_to :documents
  55. projects/show.html.erb _document.html.erb _comment.html.erb DBDIFQSPKFDUEP DBDIFEPDVNFOUEP DBDIFDPNNFOUEP

  56. comment.update!

  57. projects/show.html.erb _document.html.erb _comment.html.erb DBDIFQSPKFDUEP DBDIFEPDVNFOUEP DBDIFDPNNFOUEP still old... 3BJMT ʜʜ

    LFZOPUDIBOHFE ʜʜ
  58. projects documents comments 1 * 1 * has_many :documents has_many

    :comments belongs_to :document, touch: true id updated_at id project_id updated_at id document_id updated_at belongs_to :documents, touch: true update
  59. projects/show.html.erb _document.html.erb _comment.html.erb DBDIFQSPKFDUEP DBDIFEPDVNFOUEP DBDIFDPNNFOUEP updated 3BJMT8BZ LFZDIBOHFE LFZDIFOHFE

    LFZDIBOHFE
  60. projects/show.html.erb _document.html.erb _comment.html.erb DBDIFQSPKFDUEP DBDIFEPDVNFOUEP DBDIFDPNNFOUEP updated 3BJMT8BZ LFZDIBOHFE .PEJGZpMF

    LFZDIBOHFE
  61. made of [id, updated_at] MD5 of the template file itself

    and all of its dependencies views/documents/1-20130527190532189241000 /116839051556390fb4d5b25362cfe6eb
  62. "DUJPO$BDIF

  63. caches_action :show, if: -> { !current_user.staff? }, cache_path: -> {

    custom_cache_path }, expires_in: 1.hour