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

Vroom, Ruby Vroom

kowsik
August 11, 2012

Vroom, Ruby Vroom

My big-oh take on performance, web scale, capacity planning and sizing. These slides also address key relationships between concurrency, hit-rate and average response time in web apps.

kowsik

August 11, 2012
Tweet

Other Decks in Technology

Transcript

  1. about me former CTO @mudynamics now CTO @blitz_io rubyist since

    2006 led a team to build a 250K LoC commercial, non- web-app codebase
  2. @mudynamics commercial fuzzer on steroids first version in C++ second

    version was ruby bindings over C++ VALUE pointers and rb_scan_args() rb_gc_mark() and rb_gc_start() third version was pure ruby with C ext profit!
  3. fuzzing methodical fault injection into http, spdy, soap, json, xml,

    you name it automated -ve rspec hdd - hacker driven development broke/hacked a lot of things printers, browsers, web apps, voip gateways, video servers, IM servers speed of execution was super important
  4. ruby clean and beautiful, outside and inside <3 principle of

    least surprise extensions in C almost like writing ruby rb_raise, rb_call, etc 1.8.7 interpreter “purer” than 1.9.2 the VM complexifies the code paths harder to do code walkthroughs
  5. languages are neither slow or fast interpreter implementation trade-offs matter

    optimizations and gotchas comes down to “big oh”
  6. big oh you prolly seen O(1), O(logn), O(n), O(n2) things

    that make you go doh when you get it majority of performance issues poor choice of data structures algorithms capped speed of light => don’t blame rails that it’s slow
  7. big-oh in figs 0 10 20 30 40 1 3

    5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 O(1) O(logn) O(n) O(n^2)
  8. gem install t command line twitter - very cool, but...

    in --version 0.6.2 `time t` => 1.34s oh really, but why?
  9. hacking t vi bin/t line #4 p $LOADED_FEATURES.size; exit 1

    `t` => 433 Hmm, lots of dependencies, but still ruby -e ‘p $LOADED_FEATURES.class’ => Array
  10. load.c#rb_feature_p features = get_loaded_features(); for (i = 0; i <

    RARRAY_LEN(features); ++i) { v = RARRAY_PTR(features)[i]; f = StringValuePtr(v); if ((n = RSTRING_LEN(v)) < len) continue; if (strncmp(f, feature, len) != 0) {
  11. $LOADED_FEATURES .0s 7.5s 15.0s 22.5s 30.0s 1 10 100 1000

    10000 100000 1000000 $LOADED_FEATURES
  12. rails startup time gem install rails rails new foobar vi

    config/routes.rb p $LOADED_FEATURES.size => 784 watch this as you build a real app
  13. @blitz_io polyglot distributed app that makes load testing a fun

    sport capacity planning, sizing, scalability questions sinatra, jQuery, backbone.js, couchdb, redis & C++ recently experimenting with dynamodb running on all 7 regions of AWS so you can say => send me 10K users from singapore integrations with new relic, copper egg & scoutapp
  14. early days no redis just yet before filter for cookie

    -> session before do @account = @db.get session[:id] end couchdb gets hammered for static assets doh!
  15. self ddos first architecture filtered _changes with couchdb 10’s of

    engines worldwide huge self-ddos on each sprint/rush couchdb engines
  16. ddos mitigation switch to redis for queuing, couchdb for persistence

    BRPOPLPUSH is atomic, O(1) and light-weight completed jobs move from redis to couchdb dropped UI response time from ~750ms to < 20ms
  17. ObjectSpace Number of objects and GC hiccups Big Oh remember?

    github.com/kowsik/vroom vroom-blitz.herokuapp.com /gc /gc_count Explicit GC every 10 seconds
  18. Concurrency vs Hit-rate hit-rate is number of requests/second not the

    same as average response time! concurrency is number of open sockets aka simultaneous users single threaded sinatra has a concurrency of one!
  19. hit-rate vroom-ruby.herokuapp.com/sync?delay=1000 get '/sync' do delay = params[:delay].to_i rescue 0

    sleep(delay/1000.0) unless delay.zero? "#{delay} ms" end expect hit-rate of 1/second and average response time of 1 second blitz => -p 1-1:60
  20. let’s make it async async behaves like a load-balanced cluster

    aget '/async' do delay = params[:delay].to_i rescue 0 EM.add_timer(delay/1000.0) do body "#{delay} ms" end end each request still takes 1 second but you gain concurrency because of multiplexing => hit-rate is no longer 1/second
  21. connection pools vroom-ruby.herokuapp.com/pool?delay=1000 uses a thread pool size of 10

    8 lane highway becoming 1 lane leading to congestion only observable at concurrencies > pool size blitz => -p 1-10:10,10-10:10,10-50:10,50-50:60
  22. redis in @blitz_io engine registration write-through cache job scheduling API

    throttling but redis is a data structure server big oh with all its might
  23. redis doh’s Lists - LINDEX, LINSERT, LREM => O(n) Sets

    - SDIFF, SDIFFSTORE, SUNION, SUNIONSTORE => O(n) Sets - SINTER, SINTERSTORE => O(n*m)
  24. wrapping up performance is a fun sport slowness usually has

    reasons check data-structures check algorithms just takes some experience to spot the problems and it’s not always rails