High Performance Rails

High Performance Rails

6f8e101c016fa7ebbe58e693dbd86b7d?s=128

Issei Naruta

May 31, 2013
Tweet

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