High Performance Rails (long edition)

High Performance Rails (long edition)

Which I talked at Rubykaigi 2013 is: https://speakerdeck.com/mirakui/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
  64. expires_in Sweeper expires_in expires_in expires_in Sweeper Sweeper Sweeper Sweeper Sweeper

    Sweeper expires_in expires_in expires_in Sweeper
  65. Action Caching is not Rails 4 Way Use Russian-doll Caching

  66. action cache page cache sweeper actionpack-action_caching actionpack-page_caching rails-observers &YUSBDUFEBTHFNT GPS3BJMT

    3BJMT
  67. 5FNQMBUF &OHJOFT

  68. FSC IBNM TMJN )PX3BJMTSFOEFS UFNQMBUFT

  69. FSC IBNM TMJN 3VCZ )PX3BJMTSFOEFS UFNQMBUFT "DUJPO7JFX5FNQMBUFDPNQJMF BUpSTUUJNFPG SFOEFSJOHFBDIUFNQMBUFT

  70. &3# FSVCJT

  71. 4MJN

  72. )BNM

  73. SFOEFSbFSC@UFTU` @BQQ@WJFXT@IFMMP@FSC@UFTU@IUNM@FSC@@@ Calls

  74. Compiling time is not critical matter for Rails apps, but

    rendering time is.
  75. #FODINBSL UJNFTEP SFOEFS@UP@TUSJOH FOE ERB (erubis) Haml Slim

  76. 3FOEFSJOH5JNF ERB Haml Slim 1,032.49 ms 1,866.02 ms 1,689.26 ms

  77. 6OJDPSOXJUI ($EJTBCMF

  78. )5513FRVFTUT time

  79. 6OJDPSO%FGBVMU GC

  80. ($EJTBCMF GC.start GC.disable GC.disable

  81. # unicorn config after_fork do |server, worker| GC.disable end #

    config.ru require “unicorn/oob_gc” use Unicorn::OobGC, 10 Run GC each 10 requests
  82. # config.ru # Unicorn self-process killer require 'unicorn/worker_killer' # Max

    requests per worker use Unicorn::WorkerKiller::MaxRequests, 3072, 4096 # Max memory size (RSS) per worker use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2)) VOJDPSOXPSLFSLJMMFS IUUQTHJUIVCDPNL[LVOJDPSOXPSLFSLJMMFS
  83. 1SPpMJOH

  84. SVCZQSPG

  85. SVCZQSPG • Call-tree is too complex to profile Rails apps

  86. "DUJWF4VQQPSU#FODINBSLBCMF 3BJMTPSMBUFS <% benchmark "Process data files" do %> <%=

    expensive_files_operation %> <% end %> # production.log Process data files (123.45ms)
  87. 'JHIUJOHBHBJOTU TMPXRVFSJFT

  88. "SQSPYZ IUUQTHJUIVCDPNDPPLQBEBSQSPYZ "DUJWF3FDPSE %#"EBQUFS SELECT * FROM ... Query

  89. "SQSPYZ IUUQTHJUIVCDPNDPPLQBEBSQSPYZ "DUJWF3FDPSE %#"EBQUFS 1SPYZ 1SPYZ logging rewrite query

  90. "SQSPYZFYBNQMF

  91. "SQSPYZFYBNQMF "DUJWF3FDPSE %#"EBQUFS SELECT * FROM ... $PNNFOU"EEFS SELECT *

    FROM ... /*this_is_comment*/
  92. "DUJWF3FDPSE %#"EBQUFS "SQSPYZ qVFOUE .POHP%# -PHHJOHTMPXRVFSJFT VTJOH"SQSPYZ

  93. None
  94. $PODMVTJPO

  95. 5SBEFPGG JOQFSGPSNBODFUVOJOH

  96. %FWFMPQFST 6TFST 4FSWFST

  97. 13

  98. 8F`SFIJSJOH http://info.cookpad.com/jobs/ [en, ja]

  99. 13

  100. 5JNFUPIBDL HVZT http://info.cookpad.com/24contest4 http://info.cookpad.com/24contest4_en 24-hour hack-a-thon June 15 - 16

    [en] [ja]
  101. 5IBOLZPVGPS MJTUFOJOH