a small talk on getting big

50
A Small Talk on Getting Big. Scaling a Rails App & all that Jazz.

Upload: britt

Post on 07-Dec-2014

23.959 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: A Small Talk on Getting Big

A Small Talk on Getting Big.Scaling a Rails App & all that Jazz.

Page 2: A Small Talk on Getting Big

Good Dog Picture.

Page 3: A Small Talk on Getting Big

Medium Dog.

Page 4: A Small Talk on Getting Big

Bad Dog Picture.

Page 5: A Small Talk on Getting Big

How did this Happen?

Page 6: A Small Talk on Getting Big

Mongrel Picture.

Page 7: A Small Talk on Getting Big

Too Much Time in the Application.Too Much Time in the Database.

Page 8: A Small Talk on Getting Big

A Really Cool Trick

class ApplicationController < ActionController:Baseinclude ResponseManagementAdditionsafter_filter :show_runtimes

around_filter { |controller, action| controller.total_runtime = Benchmark.measure(&action).real }

end

Page 9: A Small Talk on Getting Big

A Really Cool Trick

module ResponseManagementAdditions def show_runtimes return if response.headers['Status'] == '304 Not Modified' || !(response.body && response.body.respond_to?(:sub!))

db_runtime = ((0 + (@db_rt_before_render || 0) + (@db_rt_after_render || 0)) * 1000).truncate rendering_runtime = ((@rendering_runtime || 0) * 1000).truncate total_runtime = ((@total_runtime || 0) * 1000).truncate

response.body.gsub!(/<\/body><\/html>$/, "<!-- served to you through a copper wire by #{HOSTNAME} at #{Time.now.to_s(:short)} in #{total_runtime} ms (d #{db_runtime} / r #{rendering_runtime}). thank you, come again. -->\n</body></html>") endend

Page 10: A Small Talk on Getting Big

Two Ways People Design Sites.

Over-architect.Under-architect.

Page 11: A Small Talk on Getting Big

Move Fast. Scale Quickly.

Page 12: A Small Talk on Getting Big

Too Much Time in the Application.

Page 13: A Small Talk on Getting Big

Abstract Long Running Processesto Daemons.

Page 14: A Small Talk on Getting Big

An Ugly but Amazingly Simple QueuingSystem.

Page 15: A Small Talk on Getting Big

class FooDaemon < TwitterDaemon::Base before_startup :set_fugly_dist_idx

def process unprocessed_content do |c| increment_counter(:total) # Do work ...

break unless running? end end

...

Page 16: A Small Talk on Getting Big

...

def unprocessed_content(&block) loop do content = ContentModel.pending_content("substring(truncate(id,0),-2,1) = #{@fugly_dist_idx}") messages.each { |message| yield message } sleep 1 if messages.nil? || messages.empty? end end

def set_fugly_dist_idx @fugly_dist_idx = ARGV.find { |v| v.match(/[0-9]/) } raise "You need to specify a dist idx between 0 and 9." unless @fugly_dist_idx @fugly_dist_idx = @fugly_dist_idx.to_i endend

Page 17: A Small Talk on Getting Big

A Better Queuing System.

Page 18: A Small Talk on Getting Big

Starling.

Page 19: A Small Talk on Getting Big

Distributed Queuing.Transactional Playback.

Fast.Simple.

Speaks Memcache's Language.100% Pure Ruby.

Page 20: A Small Talk on Getting Big

Not Open Source.

Page 21: A Small Talk on Getting Big

(yet ...)

Page 22: A Small Talk on Getting Big

Too Much Time in the Database.

Page 23: A Small Talk on Getting Big

The Basics. Database 101.(I shouldn't need this slide in here.)

Page 24: A Small Talk on Getting Big

Index everything you will query on.Avoid complex joins.

Use joint indices when you must join tables.Avoid scanning large sets of data.

Page 25: A Small Talk on Getting Big

Cache.

Page 26: A Small Talk on Getting Big

Cache.

Page 27: A Small Talk on Getting Big

Cache.

Page 28: A Small Talk on Getting Big

CACHE!

Page 29: A Small Talk on Getting Big

But How?That Sounds Hard.

Page 30: A Small Talk on Getting Big

Turns Out it Isn't.

Page 31: A Small Talk on Getting Big

Serialize, Denormalize.

Page 32: A Small Talk on Getting Big

class User < ActiveRecord::Base serialize :following_ids def following_ids # this accessor is overwritten because we want to lazily set the # friends_ids column, rather than running a gigantic slow migration. RAILS_DEFAULT_LOGGER.debug "loading following_ids" ids = read_attribute(:following_ids) if ids.nil? || !ids.kind_of?(Array) ids = connection.select_values("SELECT DISTINCT followed_user_id FROM followed_users WHERE user_id = #{self.id}").map(&:to_i).compact update_attribute(:following_ids, ids) end ids end

...

Page 33: A Small Talk on Getting Big

def following_ids_add(the_id) ids = self.following_ids.dup ids << the_id write_attribute(:following_ids, ids) end

def following_ids_delete(the_id) ids = self.following_ids.dup ids.delete(the_id) write_attribute(:following_ids, ids) end

end # End Class

Page 34: A Small Talk on Getting Big

Oh yeah, and Cheat.(It's ok!)

Page 35: A Small Talk on Getting Big

Thing about your application.How can you cheat and get away

with it?

Page 36: A Small Talk on Getting Big

Is your data delivered in real time?Is your data static content?

How do users interact?

Page 37: A Small Talk on Getting Big

Interestingness.(Little things that don't deserve other space.)

Page 38: A Small Talk on Getting Big

It's OK to use Monit to kill processesif they get too big.

Page 39: A Small Talk on Getting Big

Ensure you can deploy frequently.

Page 40: A Small Talk on Getting Big

Ensure you can roll back easily.

Page 41: A Small Talk on Getting Big

Scale where it matters.

Page 42: A Small Talk on Getting Big

Some code is ugly. It's OK.(who needs a hug?)

Page 43: A Small Talk on Getting Big

Ensure your users can give feedbackeasily.

Page 44: A Small Talk on Getting Big

Use the Community.

Page 45: A Small Talk on Getting Big

Make an API.(Scale your Developer-base.)

Page 46: A Small Talk on Getting Big

We run on Edge (but with Piston).

Page 47: A Small Talk on Getting Big

A Cool Trick. Gems in Vendor.

Rails::Initializer.run do |config|

# Load Gems from the /vendor/gems folder first, if they exist. config.load_paths += Dir["#{RAILS_ROOT}/vendor/gems/**"].map do |dir| File.directory?(lib = "#{dir}/lib") ? lib : dir end

...

Page 48: A Small Talk on Getting Big

Personal Pet Peeve.

It's 2007. Every spammer has your email address. Put it on your goddamn webpage so people can

get ahold of you about interesting things.

Page 49: A Small Talk on Getting Big

Questions?

Page 50: A Small Talk on Getting Big

Britt Selvitelle

IM & [email protected]