Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

“Speed up Rails”

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

4J[FPG 0VS3BJMT"QQ • 1003 models • 236 controllers • 2871 view templates • 1978 lines in routes.rb • 3383 assets in manifest.yml *26 May 2013

Slide 8

Slide 8 text

NT

Slide 9

Slide 9 text

8IBUJTUIF lSFTQPOTFUJNFz

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

3FTQPOTFUJNFJO SFTQPOTFIFBEFS X-Runtime: 0.123456

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

*T3BJMT4MPX

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

.BKPSQSFNJTFPG IJHIQFSGPSNBODF 3BJMTBQQT

Slide 16

Slide 16 text

%PO`UQSPDFTT SVCZDPEF JGQPTTJCMF

Slide 17

Slide 17 text

/HJOY 6OJDPSO QSPYZ CVGGFSJOH 3BJMT

Slide 18

Slide 18 text

/HJOY 6OJDPSO serve static files

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

#SPXTFSTJEF $BDIJOH

Slide 21

Slide 21 text

#SPXTFSTJEF $BDIJOH

Slide 22

Slide 22 text

6TJOHCSPXTFSTJEFDBDIJOH

Slide 23

Slide 23 text

/FWFSVTFCSPXTFSTJEFDBDIJOH

Slide 24

Slide 24 text

$POEJUJPOBM(&5

Slide 25

Slide 25 text

1st request 2nd request

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

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!)

Slide 28

Slide 28 text

is equal to

Slide 29

Slide 29 text

FUBH\^ 3BJMT ETag is made of

Slide 30

Slide 30 text

3VCZ7FSTJPO

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

#FODINBSLT JOUIJTQSFTFOUBUJPOBSF 3VCZ 3BJMTSD

Slide 35

Slide 35 text

1FSGPSNBODF #PUUMFOFDLT JO3BJMT

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

4MPXTUVGG *FYQFSJFODFE • ActiveRecord objects creation • Resolving routes

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

"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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

4J[FPG 0VS3BJMT"QQ • 1003 models • 236 controllers • 2871 view templates • 1978 lines in routes.rb • 3383 assets in manifest.yml *26 May 2013

Slide 42

Slide 42 text

MJOL@UPIFMMP IFMMP@JOEFY@VSM MJOL@UPbIFMMP` DPOUSPMMFSbIFMMP` BDUJPObJOEFY` 8IJDIJTGBTUFS

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

$BDIJOH

Slide 47

Slide 47 text

'SBHNFOU$BDIF

Slide 48

Slide 48 text

DBDIFEP USFOE@LFZXPSET FOE

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

$BDIF%JHFTUT BLBl3VTTJBOEPMMDBDIJOHz

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

comment.update!

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

"DUJPO$BDIF

Slide 63

Slide 63 text

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