Slide 1

Slide 1 text

FAST Adjunct Professor: Richard Schneeman @schneems

Slide 2

Slide 2 text

Hello

Slide 3

Slide 3 text

$ whoami schneems

Slide 4

Slide 4 text

Mechanical Engineer

Slide 5

Slide 5 text

I Code

Slide 6

Slide 6 text

Sextant Gem

Slide 7

Slide 7 text

Wicked ‘ ‘ Gem

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Adjunct Professor

Slide 10

Slide 10 text

Good News Everyone!

Slide 11

Slide 11 text

I <3 Tacos

Slide 12

Slide 12 text

Speed Vs Throughput

Slide 13

Slide 13 text

Speed

Slide 14

Slide 14 text

Throughput

Slide 15

Slide 15 text

Both Are Important

Slide 16

Slide 16 text

2 common Patterns

Slide 17

Slide 17 text

Optimize & Cache for speed

Slide 18

Slide 18 text

Optimization: Search for slow

Slide 19

Slide 19 text

Optimization: Make it fast

Slide 20

Slide 20 text

Caching: Search for expensive

Slide 21

Slide 21 text

Caching: Make it cheap

Slide 22

Slide 22 text

Add capacity for throughput

Slide 23

Slide 23 text

Speed helps throughput

Slide 24

Slide 24 text

Speed First

Slide 25

Slide 25 text

Client Side vs Server Side

Slide 26

Slide 26 text

Page Load Cycle } Server Side

Slide 27

Slide 27 text

Back End Speed

Slide 28

Slide 28 text

Measure

Slide 29

Slide 29 text

Potential Causes of slow

Slide 30

Slide 30 text

Inefficient Code

Slide 31

Slide 31 text

Slow IO (database)

Slide 32

Slide 32 text

Maybe it’s the language

Slide 33

Slide 33 text

Tweak GC

Slide 34

Slide 34 text

How do we find our problem?

Slide 35

Slide 35 text

Look for N+1 Queries

Slide 36

Slide 36 text

Use Logs

Slide 37

Slide 37 text

Problem @products = Product.all # ... <% @products.each do |product| %>
  • <%= product.name %>
  • $<%= product.price %>
  • <%= product.user.name %>
  • ...

    Slide 38

    Slide 38 text

    Problem

    Slide 39

    Slide 39 text

    Fix With Eager Loading

    Slide 40

    Slide 40 text

    Solved @products = Product.includes(:user).all # ... <% @products.each do |product| %>
  • <%= product.name %>
  • $<%= product.price %>
  • <%= product.user.name %>
  • ...

    Slide 41

    Slide 41 text

    Solved

    Slide 42

    Slide 42 text

    Look for Queries not Using an index

    Slide 43

    Slide 43 text

    Use Logs

    Slide 44

    Slide 44 text

    config/production.rb config. active_record. auto_explain_threshold_in_seconds = 1

    Slide 45

    Slide 45 text

    Add Indexes

    Slide 46

    Slide 46 text

    Use A Monitoring Software

    Slide 47

    Slide 47 text

    New Relic

    Slide 48

    Slide 48 text

    Scout etc.

    Slide 49

    Slide 49 text

    Cache Expensive Queries

    Slide 50

    Slide 50 text

    Expensive Query Benchmark.measure do User.some_expensive_query end.real => 20s

    Slide 51

    Slide 51 text

    Use Memcache & Rails.cache

    Slide 52

    Slide 52 text

    Cache Query Benchmark.measure do Rails.cache.fetch(“cache_key”) do User.some_expensive_query end end.real => 20.5s Slower first time

    Slide 53

    Slide 53 text

    Cache Query Benchmark.measure do Rails.cache.fetch(“cache_key”) do User.some_expensive_query end end.real => 0.00001s Crazy fast after that

    Slide 54

    Slide 54 text

    Naming things & cache invalidation

    Slide 55

    Slide 55 text

    Method Cacheable gem

    Slide 56

    Slide 56 text

    Cache Query User.cache.some_expensive_query => 20.5s Slower first time

    Slide 57

    Slide 57 text

    Cache Query User.cache.some_expensive_query => 0.00001s Crazy fast after that

    Slide 58

    Slide 58 text

    Throughput

    Slide 59

    Slide 59 text

    Compounding Traffic writes on. Wikipedia

    Slide 60

    Slide 60 text

    Compounding Traffic edits on. Wikipedia

    Slide 61

    Slide 61 text

    View Caching

    Slide 62

    Slide 62 text

    Never worked well for me

    Slide 63

    Slide 63 text

    View Fragment Caching

    Slide 64

    Slide 64 text

    Nested View Fragment Caching

    Slide 65

    Slide 65 text

    cache_digests gem

    Slide 66

    Slide 66 text

    Split up Web/ Workers/ Datastores

    Slide 67

    Slide 67 text

    Web Runs Ruby code & handles requests

    Slide 68

    Slide 68 text

    Datastores run separately

    Slide 69

    Slide 69 text

    Workers handle non request processing

    Slide 70

    Slide 70 text

    Workers: Run resque, send email, etc.

    Slide 71

    Slide 71 text

    I ran out of capacity, now what?

    Slide 72

    Slide 72 text

    Scale UP

    Slide 73

    Slide 73 text

    No content

    Slide 74

    Slide 74 text

    Scale OUT

    Slide 75

    Slide 75 text

    No content

    Slide 76

    Slide 76 text

    Scaling up is Easy but limited

    Slide 77

    Slide 77 text

    Scaling out is hard but unlimited

    Slide 78

    Slide 78 text

    Ephemeral Web Machines

    Slide 79

    Slide 79 text

    Heroku $ heroku ps:scale web=4

    Slide 80

    Slide 80 text

    Amazon (AWS) Provision instances & use chef or other tools to install proper software, and then connect to a load balancer

    Slide 81

    Slide 81 text

    Code Code Code Code Code

    Slide 82

    Slide 82 text

    Don’t store state on server

    Slide 83

    Slide 83 text

    Store in database

    Slide 84

    Slide 84 text

    Session

    Slide 85

    Slide 85 text

    S3 etc.

    Slide 86

    Slide 86 text

    Workers: Headless data crunchers

    Slide 87

    Slide 87 text

    Workers run: Resque

    Slide 88

    Slide 88 text

    How do we scale data storage?

    Slide 89

    Slide 89 text

    Master DB Slave DB Slave DB Slave DB Slave DB Write Copy Read Master/Slave

    Slide 90

    Slide 90 text

    Users in USA Read Sharding Write Users in Europe Users in Asia Users in Africa

    Slide 91

    Slide 91 text

    cannot join against sharded data

    Slide 92

    Slide 92 text

    Facebook shards mysql

    Slide 93

    Slide 93 text

    Instagram shards postgresql

    Slide 94

    Slide 94 text

    postgresql better than mysql IMHO

    Slide 95

    Slide 95 text

    NoSQL

    Slide 96

    Slide 96 text

    Not a magic bullet

    Slide 97

    Slide 97 text

    Key Value Example > redis = Redis.new > redis.set(“foo”, “bar”)

    Slide 98

    Slide 98 text

    Key Value Example > redis = Redis.new > redis.set(“foo”, “bar”) > redis.get(“foo”)

    Slide 99

    Slide 99 text

    Key Value Example > redis = Redis.new > redis.set(“foo”, “bar”) > redis.get(“foo”) => “bar”

    Slide 100

    Slide 100 text

    Every datastore will punch you in the face “ -Adam Keys

    Slide 101

    Slide 101 text

    Key/Value Stores

    Slide 102

    Slide 102 text

    Shard on Key

    Slide 103

    Slide 103 text

    Consistent Hashing

    Slide 104

    Slide 104 text

    Memcache Distributed B C A

    Slide 105

    Slide 105 text

    Memcache Distributed B C A Easily add more nodes D

    Slide 106

    Slide 106 text

    CAP Theorem

    Slide 107

    Slide 107 text

    Pick Two: Consistency Availability Partition- Tolerance

    Slide 108

    Slide 108 text

    Riak Distributed B C A Eventual Consistency D Data In Copied To Extra Nodes ... Eventually

    Slide 109

    Slide 109 text

    RIAK has configurable CAP

    Slide 110

    Slide 110 text

    Client Side Speed

    Slide 111

    Slide 111 text

    Page Load Cycle } Client Side

    Slide 112

    Slide 112 text

    Front End Assets

    Slide 113

    Slide 113 text

    Loading Assets: Slow

    Slide 114

    Slide 114 text

    Decrease Size

    Slide 115

    Slide 115 text

    GZIP

    Slide 116

    Slide 116 text

    CDN

    Slide 117

    Slide 117 text

    Speed = Distance/ Time

    Slide 118

    Slide 118 text

    Distance Matters

    Slide 119

    Slide 119 text

    Shorter Distance = faster

    Slide 120

    Slide 120 text

    Your Server User

    Slide 121

    Slide 121 text

    No content

    Slide 122

    Slide 122 text

    What if We could...

    Slide 123

    Slide 123 text

    No content

    Slide 124

    Slide 124 text

    CDN

    Slide 125

    Slide 125 text

    CDN Content Distribution Network

    Slide 126

    Slide 126 text

    CDN CDN CDN

    Slide 127

    Slide 127 text

    CDN Serves Images CSS Javascript

    Slide 128

    Slide 128 text

    Akamai Cloudfront

    Slide 129

    Slide 129 text

    config/production.rb config.action_controller.asset_host = ENV["cloudfront_url"]

    Slide 130

    Slide 130 text

    Browser Caching

    Slide 131

    Slide 131 text

    Load on: First Request

    Slide 132

    Slide 132 text

    Store it

    Slide 133

    Slide 133 text

    Use local copy on future requests

    Slide 134

    Slide 134 text

    Expires Headers

    Slide 135

    Slide 135 text

    config/production.rb config.static_cache_control = "public, max-age=2592000"

    Slide 136

    Slide 136 text

    Wait, what happens if we make changes?

    Slide 137

    Slide 137 text

    Turn on Rails Asset fingerprints

    Slide 138

    Slide 138 text

    config/production.rb config.assets.digest = true

    Slide 139

    Slide 139 text

    HASH a file to take it’s “fingerprint”

    Slide 140

    Slide 140 text

    MD5 is an algorithm to fingerprint files

    Slide 141

    Slide 141 text

    headers.css 908e25f4bf641868d86 83022a5b62f54 Run MD5 on this: Produces this:

    Slide 142

    Slide 142 text

    When file changes, so does fingerprint

    Slide 143

    Slide 143 text

    headers.css headers- 908e25f4bf641868d86 83022a5b62f54.css File w/o fingerprint File with fingerprint:

    Slide 144

    Slide 144 text

    Measure to Optimize

    Slide 145

    Slide 145 text

    Use YSlow

    Slide 146

    Slide 146 text

    No content

    Slide 147

    Slide 147 text

    Compress Assets

    Slide 148

    Slide 148 text

    Serve Using CDN

    Slide 149

    Slide 149 text

    Async Script Loading

    Slide 150

    Slide 150 text

    Slide 151

    Slide 151 text

    Slide 152

    Slide 152 text

    defer guarantees order

    Slide 153

    Slide 153 text

    defer has IE support

    Slide 154

    Slide 154 text

    Don’t block page parsing

    Slide 155

    Slide 155 text

    Measure Everything

    Slide 156

    Slide 156 text

    Scale out with more machines

    Slide 157

    Slide 157 text

    Speed up your datastore or add caching

    Slide 158

    Slide 158 text

    (jobs.heroku.com)

    Slide 159

    Slide 159 text

    No content

    Slide 160

    Slide 160 text

    Questions?