Upgrade to Pro — share decks privately, control downloads, hide ads and more …

High Performance Rails (long edition)

High Performance Rails (long edition)

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

    View Slide

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

    View Slide

  3. “Speed up Rails”

    View Slide

  4. View Slide

  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

    View Slide

  6. $00,1"%
    • AWS
    • Rails 3.2
    • Ruby 2.0.0

    View Slide

  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

    View Slide

  8. NT

    View Slide

  9. 8IBUJTUIF
    lSFTQPOTFUJNFz

    View Slide

  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

    View Slide

  11. 3FTQPOTFUJNFJO
    SFTQPOTFIFBEFS
    X-Runtime: 0.123456

    View Slide

  12. routing
    before_filter
    after_filter
    rendering
    action
    Rails
    Rack
    "Completed" time
    X-Runtime
    )5513FRVFTU
    )5513FTQPOTF

    View Slide

  13. *T3BJMT4MPX

    View Slide

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

    View Slide

  15. .BKPSQSFNJTFPG
    IJHIQFSGPSNBODF
    3BJMTBQQT

    View Slide

  16. %PO`UQSPDFTT
    SVCZDPEF
    JGQPTTJCMF

    View Slide

  17. /HJOY
    6OJDPSO
    QSPYZ
    CVGGFSJOH
    3BJMT

    View Slide

  18. /HJOY
    6OJDPSO
    serve
    static files

    View Slide

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

    View Slide

  20. #SPXTFSTJEF
    $BDIJOH

    View Slide

  21. #SPXTFSTJEF
    $BDIJOH

    View Slide

  22. 6TJOHCSPXTFSTJEFDBDIJOH

    View Slide

  23. /FWFSVTFCSPXTFSTJEFDBDIJOH

    View Slide

  24. $POEJUJPOBM(&5

    View Slide

  25. 1st request
    2nd request

    View Slide

  26. View Slide

  27. [email protected]
    • 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!)

    View Slide

  28. is equal to

    View Slide

  29. FUBH\^
    3BJMT

    ETag is made of

    View Slide

  30. 3VCZ7FSTJPO

    View Slide

  31. 0VSSVCZIJTUPSZ
    • Sep 2012
    • REE (Ruby Enterprise Edition) 1.8.7
    • Feb 2013
    • MRI 1.9.3
    • Apr 2013
    • MRI 2.0.0

    View Slide

  32. 8IBU`T3&&
    • MRI 1.8.7 + “MBARI patch”
    • “100% compatible with MRI 1.8.7”
    • Copy-on-Write Friendly GC
    • tcmalloc

    View Slide

  33. REE 1.8.7 MRI 1.9.3 MRI 2.0.0
    3FTQPOTFUJNF
    CZSVCZWFSTJPOT
    -100ms
    -20ms

    View Slide

  34. #FODINBSLT
    JOUIJTQSFTFOUBUJPOBSF
    3VCZ
    3BJMTSD

    View Slide

  35. 1FSGPSNBODF
    #PUUMFOFDLT
    JO3BJMT

    View Slide

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

    View Slide

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

    View Slide

  38. "DUJWF3FDPSE`T
    PWFSIFBE
    "SUJDMFMBTU
    [email protected]
    "SUJDMF-PBE NT
    4&-&$5ABSUJDMFTA'30.

    View Slide

  39. "DUJWF3FDPSE`T
    PWFSIFBE
    #FODINBSLNT\"SUJDMFMBTU
    [email protected]^
    "SUJDMF-PBE NT
    4&-&$5ABSUJDMFTA'30.

    The query is fast enough but
    creating 100 AR objects is slow

    View Slide

  40. 3FTPMWJOHSPVUFT
    • Fat routes slow down url_for
    • e.g. link_to helper

    View Slide

  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

    View Slide

  42. [email protected] [email protected]@VSM
    [email protected]` DPOUSPMMFSbIFMMP` BDUJPObJOEFY`
    8IJDIJTGBTUFS

    View Slide

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

    View Slide

  44. [email protected] [email protected]@VSM
    NT
    [email protected]` DPOUSPMMFSbIFMMP` BDUJPObJOEFY`
    NT
    3FTVMU

    View Slide

  45. 4MPXSBDL
    NJEEMFXBSF
    w3BDL$BDIF
    • Caches response with Rails.cache
    • Default in Rails 3.2
    • Not default in Rails 4

    View Slide

  46. $BDIJOH

    View Slide

  47. 'SBHNFOU$BDIF

    View Slide

  48. DBDIFEP
    [email protected]
    FOE

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  53. $BDIF%JHFTUT
    BLBl3VTTJBOEPMMDBDIJOHz

    View Slide

  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

    View Slide

  55. projects/show.html.erb
    _document.html.erb
    _comment.html.erb
    DBDIFQSPKFDUEP
    DBDIFEPDVNFOUEP
    DBDIFDPNNFOUEP

    View Slide

  56. comment.update!

    View Slide

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

    View Slide

  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

    View Slide

  59. projects/show.html.erb
    _document.html.erb
    _comment.html.erb
    DBDIFQSPKFDUEP
    DBDIFEPDVNFOUEP
    DBDIFDPNNFOUEP
    updated
    3BJMT8BZ
    LFZDIBOHFE
    LFZDIFOHFE
    LFZDIBOHFE

    View Slide

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

    View Slide

  61. made of [id, updated_at]
    MD5 of the template file itself
    and all of its dependencies
    views/documents/1-20130527190532189241000
    /116839051556390fb4d5b25362cfe6eb

    View Slide

  62. "DUJPO$BDIF

    View Slide

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

    View Slide

  64. expires_in
    Sweeper
    expires_in
    expires_in
    expires_in
    Sweeper
    Sweeper
    Sweeper
    Sweeper
    Sweeper
    Sweeper
    expires_in
    expires_in
    expires_in
    Sweeper

    View Slide

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

    View Slide

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

    View Slide

  67. 5FNQMBUF
    &OHJOFT

    View Slide

  68. FSC
    IBNM
    TMJN
    )PX3BJMTSFOEFS
    UFNQMBUFT

    View Slide

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

    View Slide

  70. &3# FSVCJT

    View Slide

  71. 4MJN

    View Slide

  72. )BNM

    View Slide

  73. View Slide

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

    View Slide

  75. #FODINBSL
    UJNFTEP
    [email protected]@TUSJOH
    FOE
    ERB (erubis)
    Haml
    Slim

    View Slide

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

    View Slide

  77. 6OJDPSOXJUI
    ($EJTBCMF

    View Slide

  78. )5513FRVFTUT
    time

    View Slide

  79. 6OJDPSO%FGBVMU
    GC

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  83. 1SPpMJOH

    View Slide

  84. SVCZQSPG

    View Slide

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

    View Slide

  86. "DUJWF4VQQPSU#FODINBSLBCMF
    3BJMTPSMBUFS

    <% benchmark "Process data files" do %>
    <%= expensive_files_operation %>
    <% end %>
    # production.log
    Process data files (123.45ms)

    View Slide

  87. 'JHIUJOHBHBJOTU
    TMPXRVFSJFT

    View Slide

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

    View Slide

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

    View Slide

  90. "SQSPYZFYBNQMF

    View Slide

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

    View Slide

  92. "DUJWF3FDPSE
    %#"EBQUFS
    "SQSPYZ qVFOUE .POHP%#
    -PHHJOHTMPXRVFSJFT
    VTJOH"SQSPYZ

    View Slide

  93. View Slide

  94. $PODMVTJPO

    View Slide

  95. 5SBEFPGG
    JOQFSGPSNBODFUVOJOH

    View Slide

  96. %FWFMPQFST
    6TFST 4FSWFST

    View Slide

  97. 13

    View Slide

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

    View Slide

  99. 13

    View Slide

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

    View Slide

  101. 5IBOLZPVGPS
    MJTUFOJOH

    View Slide