SlideShare une entreprise Scribd logo
1  sur  147
Télécharger pour lire hors ligne
zero     deploys
downtime   for Rails
                                           photo by Chris
             http://www.flickr.com/people/chrisinplymouth/
class ApparentlyHarmlessMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end
end
class CompletelySafeMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end

  def self.down
    add_column :users, :notes, :text
  end
end
class CompletelySafeMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end

  def self.down
    add_column :users, :notes, :text
  end
end
PGError: ERROR: column "notes" does not exist
INSERT INTO users(email, password, ..., notes)
Zero downtime?




Challenge accepted
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Hot compatibility


• Run concurrent versions of your
  application
• That are compatible between each other
Hot compatibility


  v1         v2
Hot compatibility


      v1                   v2

writes to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                              v1’                      v2

writes to `notes`            stop writing to `notes`    drop column `notes`


               class User
                 def self.columns
                   super.reject { |c| c.name == "notes" }
                 end
               end
Self dependency
Self dependency
user loads form
Self dependency
new form is deployed
Self dependency
              user submits the form



 POST /login
 username=bill@microsoft.com&password=q1w2e3
Self dependency
            server blows up
Self dependency
• Make controllers compatible:
Self dependency
• Make controllers compatible:
  class AuthController < ApplicationController

    protected

    def filtered_params
      params.dup.tap do |p|
        p.merge!(:email => p.delete(:username))
      end
    end
  end
Assets - Rails 2

                          Server 1


GET /dashboard

200


GET /stylesheets/all.js

200
Assets - Rails 2

                          Server 1   Server 2


GET /dashboard

200


GET /stylesheets/all.js

404
Assets - Rails 2


• https://github.com/ddollar/asset-resource
Asset pipeline - Rails 3

                                    v1


  GET /dashboard

  200


  GET /assets/application-{v1}.js

  200
Asset pipeline - Rails 3

                                    v1   v2


  GET /dashboard

  200


  GET /assets/application-{v1}.js

  404
Asset pipeline - Rails 3
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
• We’re still in need of tooling to help
  cleaning up old assets
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
• We’re still in need of tooling to help
  cleaning up old assets
  rake assets:clean:outdated
Migration strategies
Migration strategies
• Read-only models
Migration strategies
• Read-only models

   class Role < ActiveRecord::Base
     def readonly?
       true
     end
   end
Migration strategies
• Read-only models
• Ignore cached columns
Migration strategies
• Read-only models
• Ignore cached columns
   class User
     def self.columns
       super.reject { |c| c.name == "notes" }
     end
   end
Migration strategies
• Read-only models
• Ignore cached columns
• Know your database
Migration strategies
• Read-only models
• Ignore cached columns
• Know your database
 • Beware of O(n) db locks!
MyISAM
MyISAM
InnoDB
InnoDB
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
InnoDB
1. Create a new table with the same structure
2. Apply changes to new table
3. Copy data over
4. Acquire lock on original table
5. Sync new/updated/deleted rows
6. Swap tables
7. Release lock
InnoDB
1. Create a new table with the same structure
2. Apply changes to new table
3. Copy data over
4. Acquire lock on original table
5. Sync new/updated/deleted rows
6. Swap tables
7. Release lock
InnoDB
https://github.com/freels/table_migrator
InnoDB
https://github.com/freels/table_migrator

class AddStuffToMyBigTable < TableMigration

  migrates :users

  change_table do |t|
    t.integer :foo, :null => false, :default => 0
    t.string :bar
    t.index   :foo, :name => 'index_for_foo'
  end
end
InnoDB
https://github.com/freels/table_migrator
• Requires acts_as_paranoid
• Pretty old/stale codebase
  • Check forks for Rails 3 compatibility
Postgres
• Table locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
• O(n) locks on:
            constant time if you avoid default
                 values and constraints


 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
•   O(n) locks on:           constant time


    • Adding, updating or removing columns
    • Adding or removing indexes
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
   can be done without any locking
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
                  constant time
Postgres
• Adding fields with defaults
Postgres
• Adding fields with defaults

         before_save :assign_defaults

         def assign_defaults
           self.admin ||= false
         end
Postgres
• Adding fields with defaults
• Create indexes concurrently
Postgres
   • Adding fields with defaults
   • Create indexes concurrently
CREATE INDEX CONCURRENTLY users_email_index ON users(email);
Postgres
• Adding fields with defaults
• Create indexes concurrently
 • Outside a transaction!
Postgres
       • Adding fields with defaults
       • Create indexes concurrently
        • Outside a transaction!
class AddIndexToUsers < ActiveRecord::Migration
  def self.up
    return if indexes("users").map(&:name).include?("users_email_index")
    add_index :users, :email, :name => "users_email_index"
  end

  def self.down
    remove_index :users, :name => "users_email_index"
  end
end
What about renaming?

        v1                 v2

  reads and writes   reads and writes
      to `foo`           to `bar`
What about renaming?

      v1                v1’               v1’’               v2

reads and writes   add column `bar`   populate `bar`   reads and writes
    to `foo`               +          where needed         to `bar`
                   reads from `foo`
                    writes to both
                    `foo` and `bar`
What about renaming?

       v2              v2’               v3

 reads and writes   ignore `foo`   drop column `foo`
     to `bar`
NoSQL
NoSQL

• Schema migrations / O(n) locks are just
  part of hot compatibility
NoSQL

• Schema migrations / O(n) locks are just
  part of hot compatibility
• You still need to put effort into data
  migration
Workflow
Workflow


• Make sure pull requests are addressing
  hot compatibility
Workflow


• Make sure pull requests are addressing
  hot compatibility
• Work after code is merged
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Production
Production

• Run multiple server processes
Production

• Run multiple server processes
• Cycle them individually, or in batches
Production

• Run multiple server processes
• Cycle them individually, or in batches
 • Watch out for capacity!
Production

• Run multiple server processes
• Cycle them individually, or in batches
 • Watch out for capacity!
• Cycle them gracefully
Cycling techniques

• Above the stack
• Within the stack
• Platform
Above the stack


• Use your favorite web server
• Setup a load balancer above them, route
  around servers that are cycling
Above the stack
• PROTIP: default setup won’t work
• Configure load balancer to poll for your
  application health:
  class HealthController < ApplicationController
    def index
      if File.exists?(Rails.root.join("MAINTENANCE"))
        render :text => "Forget me!", :status => 503
      else
        render :text => "I'm alive!"
      end
    end
  end
Cycling + Load balancer
                 Server   Load balancer


 touch MAINTENANCE


       bounce servers     remove server from rotation
   rm MAINTENANCE

new servers come online

                           add server to rotation
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
HAProxy
      tell HAProxy where to check for the health

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                       do not let your web server queue requests
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                             tell HAProxy to run the health check specified above
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                                             every 2s
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                              stop routing to it once the health check failed once
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                                       and bring it back once it worked once
ELB

$ elb-configure-healthcheck MyLoadBalancer 
    --target "HTTP:5000/health" 
    --interval 2 
    --unhealthy-threshold 1 
    --healthy-threshold 1
Above the stack
Above the stack
•   Minimal impact
Above the stack
•   Minimal impact

•   Extended availability
    comes for free
Above the stack
•   Minimal impact          •   Complicated setup

•   Extended availability
    comes for free
Above the stack
•   Minimal impact          •   Complicated setup

•   Extended availability   •   Another component you
    comes for free              have to track and maintain
Within the stack
Within the stack
Unicorn


• Replaces your web server
• Bounces gracefully
Unicorn
63480   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
$ kill -USR2 63480

63480   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
$ kill -USR2 63480

63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
$ kill -QUIT 63480

63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
$ kill -QUIT 63480

63521   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
63521   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Within the stack
Within the stack
•   Easy to setup and deploy
Within the stack
•   Easy to setup and deploy

•   Optimal performance to
    cycle the server
Within the stack
•   Easy to setup and deploy   •   Changes your application
                                   stack
•   Optimal performance to
    cycle the server
Within the stack
•   Easy to setup and deploy   •   Changes your application
                                   stack
•   Optimal performance to
    cycle the server           •   Doesn’t address availability
                                   issues
Platform
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku

$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku

$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     starting for 1s   bundle exec thin start -p $PORT
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     starting for 5s   bundle exec thin start -p $PORT
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 1s         bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ heroku labs:enable preboot

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
web.1     starting for 5s   bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
web.1     up for 1s         bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 5s         bundle exec thin start -p $PORT
Heroku
• Migrations
Heroku
• Migrations
  $ git push pre-production master
  $ heroku run rake db:migrate --remote pre-production
  $ git push production master
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Future
Future

• Asset pipeline
Future

• Asset pipeline
• Mysql tooling
Future

• Asset pipeline
• Mysql tooling
• Can Rails help making the development of
  hot compatible applications easier?
Future

• Asset pipeline
• Mysql tooling
• Can Rails help making the development of
  hot compatible applications easier?
• Can databases?
Future
Future


• Hot compatibility beyond zero downtime
  deploys
Conclusion
Conclusion

• Zero downtime is a pain in the ass
Conclusion

• Zero downtime is a pain in the ass
• Hot compatibility to the rescue
Conclusion

• Zero downtime is a pain in the ass
• Hot compatibility to the rescue
• Make sure your production env is ready
Thank you!
http://pedro.heroku.com

        @ped

Contenu connexe

Tendances

Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSShekhar Gulati
 
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015Matt Raible
 
Puppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedInYevgeniy Brikman
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Matt Raible
 
How to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onHow to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onAtlassian
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)ColdFusionConference
 
Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Matt Raible
 
Capacity Management for Web Operations
Capacity Management for Web OperationsCapacity Management for Web Operations
Capacity Management for Web OperationsJohn Allspaw
 
Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Pavel Kaminsky
 
BDD in Java using Cucumber
BDD in Java using CucumberBDD in Java using Cucumber
BDD in Java using Cucumberslavkurochkin
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksAddy Osmani
 
Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Matt Raible
 
Continuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixContinuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixAtlassian
 
Continuous deployment-at-flipkart
Continuous deployment-at-flipkartContinuous deployment-at-flipkart
Continuous deployment-at-flipkartPankaj Kaushal
 
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Dave Olsen
 

Tendances (20)

Node.js vs Play Framework
Node.js vs Play FrameworkNode.js vs Play Framework
Node.js vs Play Framework
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJS
 
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
 
Rebooting a Cloud
Rebooting a CloudRebooting a Cloud
Rebooting a Cloud
 
Puppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet Release Workflows at Jive Software
Puppet Release Workflows at Jive Software
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedIn
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
How to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onHow to Build a Better JIRA Add-on
How to Build a Better JIRA Add-on
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)
 
Cache is King
Cache is KingCache is King
Cache is King
 
Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015
 
Capacity Management for Web Operations
Capacity Management for Web OperationsCapacity Management for Web Operations
Capacity Management for Web Operations
 
Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments
 
BDD in Java using Cucumber
BDD in Java using CucumberBDD in Java using Cucumber
BDD in Java using Cucumber
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & Tricks
 
Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013
 
Continuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixContinuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at Netflix
 
Continuous deployment-at-flipkart
Continuous deployment-at-flipkartContinuous deployment-at-flipkart
Continuous deployment-at-flipkart
 
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
 

En vedette

Continuous delivery for databases
Continuous delivery for databasesContinuous delivery for databases
Continuous delivery for databasesDevOpsGroup
 
LSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemLSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemMario Juric
 
Integrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideIntegrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideYu Tao Zhang
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeMichael May
 
Automate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopAutomate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopRed Gate Software
 
Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with DjangoRoger Barnes
 
Fault Tolerance with Kubernetes
Fault Tolerance with KubernetesFault Tolerance with Kubernetes
Fault Tolerance with KubernetesAditya Patawari
 
How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1Thoughtworks
 
Tricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationTricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationSimon Willison
 
Scalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosScalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosOlivier Paugam
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentRobert Treat
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsAndrei Solntsev
 
Docker - Sysmana 2014
Docker - Sysmana 2014Docker - Sysmana 2014
Docker - Sysmana 2014quaip
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentChristopher Read
 
Machine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksMachine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksNicolas Le Roux
 
Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Olivier Chapelle
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBrendan Gregg
 

En vedette (20)

Continuous delivery for databases
Continuous delivery for databasesContinuous delivery for databases
Continuous delivery for databases
 
Database compatibility
Database compatibilityDatabase compatibility
Database compatibility
 
How To Avoid Database Migration Hell
How To Avoid Database Migration HellHow To Avoid Database Migration Hell
How To Avoid Database Migration Hell
 
LSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemLSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing System
 
Integrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideIntegrate UFT with Jenkins Guide
Integrate UFT with Jenkins Guide
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the Edge
 
Automate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopAutomate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City Workshop
 
Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with Django
 
Fault Tolerance with Kubernetes
Fault Tolerance with KubernetesFault Tolerance with Kubernetes
Fault Tolerance with Kubernetes
 
How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1
 
Tricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationTricks & challenges developing a large Django application
Tricks & challenges developing a large Django application
 
Scalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosScalable Eventing Over Apache Mesos
Scalable Eventing Over Apache Mesos
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps Environment
 
Hadoop summit-ams-2014-04-03
Hadoop summit-ams-2014-04-03Hadoop summit-ams-2014-04-03
Hadoop summit-ams-2014-04-03
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOps
 
Docker - Sysmana 2014
Docker - Sysmana 2014Docker - Sysmana 2014
Docker - Sysmana 2014
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous Deployment
 
Machine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksMachine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris Datageeks
 
Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame Graphs
 

Similaire à Zero downtime deploys for Rails apps

Version control with subversion
Version control with subversionVersion control with subversion
Version control with subversionxprayc
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database DeploymentsMike Willbanks
 
Kubernetes Workshop
Kubernetes WorkshopKubernetes Workshop
Kubernetes Workshoploodse
 
9th docker meetup 2016.07.13
9th docker meetup 2016.07.139th docker meetup 2016.07.13
9th docker meetup 2016.07.13Amrita Prasad
 
Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Michael Dimmitt
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Bostonbenbrowning
 
Docker for Dummies
Docker for DummiesDocker for Dummies
Docker for DummiesRoel Hartman
 
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructureFrom Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructurePerforce
 
Elixir Programming Language 101
Elixir Programming Language 101Elixir Programming Language 101
Elixir Programming Language 101Around25
 
Serverless: A love hate relationship
Serverless: A love hate relationshipServerless: A love hate relationship
Serverless: A love hate relationshipJürgen Brüder
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011Bachkoutou Toutou
 
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...Simplilearn
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side SwiftChad Moone
 
Version Control With Subversion
Version Control With SubversionVersion Control With Subversion
Version Control With SubversionSamnang Chhun
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Nilesh Panchal
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureQAware GmbH
 

Similaire à Zero downtime deploys for Rails apps (20)

Version control with subversion
Version control with subversionVersion control with subversion
Version control with subversion
 
Versioning for Developers
Versioning for DevelopersVersioning for Developers
Versioning for Developers
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database Deployments
 
Kubernetes Workshop
Kubernetes WorkshopKubernetes Workshop
Kubernetes Workshop
 
9th docker meetup 2016.07.13
9th docker meetup 2016.07.139th docker meetup 2016.07.13
9th docker meetup 2016.07.13
 
Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
 
Docker for Dummies
Docker for DummiesDocker for Dummies
Docker for Dummies
 
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructureFrom Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
 
Elixir Programming Language 101
Elixir Programming Language 101Elixir Programming Language 101
Elixir Programming Language 101
 
Serverless: A love hate relationship
Serverless: A love hate relationshipServerless: A love hate relationship
Serverless: A love hate relationship
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side Swift
 
Version Control With Subversion
Version Control With SubversionVersion Control With Subversion
Version Control With Subversion
 
TorqueBox
TorqueBoxTorqueBox
TorqueBox
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
 
VS Debugging Tricks
VS Debugging TricksVS Debugging Tricks
VS Debugging Tricks
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventure
 

Dernier

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 

Dernier (20)

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 

Zero downtime deploys for Rails apps

  • 1. zero deploys downtime for Rails photo by Chris http://www.flickr.com/people/chrisinplymouth/
  • 2. class ApparentlyHarmlessMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end end
  • 3. class CompletelySafeMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end   def self.down     add_column :users, :notes, :text   end end
  • 4. class CompletelySafeMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end   def self.down     add_column :users, :notes, :text   end end
  • 5. PGError: ERROR: column "notes" does not exist
  • 6. INSERT INTO users(email, password, ..., notes)
  • 7.
  • 8.
  • 9.
  • 11. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 12.
  • 13. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 14. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 15. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 16. Hot compatibility • Run concurrent versions of your application • That are compatible between each other
  • 18. Hot compatibility v1 v2 writes to `notes` drop column `notes`
  • 19. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 20. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 21. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 22. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 23. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes` class User   def self.columns     super.reject { |c| c.name == "notes" }   end end
  • 27. Self dependency user submits the form POST /login username=bill@microsoft.com&password=q1w2e3
  • 28. Self dependency server blows up
  • 29. Self dependency • Make controllers compatible:
  • 30. Self dependency • Make controllers compatible: class AuthController < ApplicationController   protected   def filtered_params     params.dup.tap do |p|       p.merge!(:email => p.delete(:username))     end   end end
  • 31. Assets - Rails 2 Server 1 GET /dashboard 200 GET /stylesheets/all.js 200
  • 32. Assets - Rails 2 Server 1 Server 2 GET /dashboard 200 GET /stylesheets/all.js 404
  • 33. Assets - Rails 2 • https://github.com/ddollar/asset-resource
  • 34. Asset pipeline - Rails 3 v1 GET /dashboard 200 GET /assets/application-{v1}.js 200
  • 35. Asset pipeline - Rails 3 v1 v2 GET /dashboard 200 GET /assets/application-{v1}.js 404
  • 36. Asset pipeline - Rails 3
  • 37. Asset pipeline - Rails 3 • When updating assets, keep the existing version around
  • 38. Asset pipeline - Rails 3 • When updating assets, keep the existing version around • We’re still in need of tooling to help cleaning up old assets
  • 39. Asset pipeline - Rails 3 • When updating assets, keep the existing version around • We’re still in need of tooling to help cleaning up old assets rake assets:clean:outdated
  • 42. Migration strategies • Read-only models class Role < ActiveRecord::Base   def readonly?     true   end end
  • 43. Migration strategies • Read-only models • Ignore cached columns
  • 44. Migration strategies • Read-only models • Ignore cached columns class User   def self.columns     super.reject { |c| c.name == "notes" }   end end
  • 45. Migration strategies • Read-only models • Ignore cached columns • Know your database
  • 46. Migration strategies • Read-only models • Ignore cached columns • Know your database • Beware of O(n) db locks!
  • 50. InnoDB • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 51. InnoDB 1. Create a new table with the same structure 2. Apply changes to new table 3. Copy data over 4. Acquire lock on original table 5. Sync new/updated/deleted rows 6. Swap tables 7. Release lock
  • 52. InnoDB 1. Create a new table with the same structure 2. Apply changes to new table 3. Copy data over 4. Acquire lock on original table 5. Sync new/updated/deleted rows 6. Swap tables 7. Release lock
  • 54. InnoDB https://github.com/freels/table_migrator class AddStuffToMyBigTable < TableMigration   migrates :users   change_table do |t|     t.integer :foo, :null => false, :default => 0     t.string :bar     t.index :foo, :name => 'index_for_foo'   end end
  • 55. InnoDB https://github.com/freels/table_migrator • Requires acts_as_paranoid • Pretty old/stale codebase • Check forks for Rails 3 compatibility
  • 56. Postgres • Table locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 57. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 58. Postgres • O(n) locks on: constant time if you avoid default values and constraints • Adding, updating or removing columns • Adding or removing indexes
  • 59. Postgres • O(n) locks on: constant time • Adding, updating or removing columns • Adding or removing indexes
  • 60. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes can be done without any locking
  • 61. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes constant time
  • 63. Postgres • Adding fields with defaults before_save :assign_defaults def assign_defaults   self.admin ||= false end
  • 64. Postgres • Adding fields with defaults • Create indexes concurrently
  • 65. Postgres • Adding fields with defaults • Create indexes concurrently CREATE INDEX CONCURRENTLY users_email_index ON users(email);
  • 66. Postgres • Adding fields with defaults • Create indexes concurrently • Outside a transaction!
  • 67. Postgres • Adding fields with defaults • Create indexes concurrently • Outside a transaction! class AddIndexToUsers < ActiveRecord::Migration   def self.up     return if indexes("users").map(&:name).include?("users_email_index")     add_index :users, :email, :name => "users_email_index"   end   def self.down     remove_index :users, :name => "users_email_index"   end end
  • 68. What about renaming? v1 v2 reads and writes reads and writes to `foo` to `bar`
  • 69. What about renaming? v1 v1’ v1’’ v2 reads and writes add column `bar` populate `bar` reads and writes to `foo` + where needed to `bar` reads from `foo` writes to both `foo` and `bar`
  • 70. What about renaming? v2 v2’ v3 reads and writes ignore `foo` drop column `foo` to `bar`
  • 71. NoSQL
  • 72. NoSQL • Schema migrations / O(n) locks are just part of hot compatibility
  • 73. NoSQL • Schema migrations / O(n) locks are just part of hot compatibility • You still need to put effort into data migration
  • 75. Workflow • Make sure pull requests are addressing hot compatibility
  • 76. Workflow • Make sure pull requests are addressing hot compatibility • Work after code is merged
  • 77. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 78. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 79. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 80. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 81. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 82. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 84. Production • Run multiple server processes
  • 85. Production • Run multiple server processes • Cycle them individually, or in batches
  • 86. Production • Run multiple server processes • Cycle them individually, or in batches • Watch out for capacity!
  • 87. Production • Run multiple server processes • Cycle them individually, or in batches • Watch out for capacity! • Cycle them gracefully
  • 88. Cycling techniques • Above the stack • Within the stack • Platform
  • 89. Above the stack • Use your favorite web server • Setup a load balancer above them, route around servers that are cycling
  • 90. Above the stack • PROTIP: default setup won’t work • Configure load balancer to poll for your application health: class HealthController < ApplicationController   def index     if File.exists?(Rails.root.join("MAINTENANCE"))       render :text => "Forget me!", :status => 503     else       render :text => "I'm alive!"     end   end end
  • 91. Cycling + Load balancer Server Load balancer touch MAINTENANCE bounce servers remove server from rotation rm MAINTENANCE new servers come online add server to rotation
  • 92. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
  • 93. HAProxy tell HAProxy where to check for the health option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
  • 94. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 do not let your web server queue requests
  • 95. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 tell HAProxy to run the health check specified above
  • 96. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 every 2s
  • 97. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 stop routing to it once the health check failed once
  • 98. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 and bring it back once it worked once
  • 99. ELB $ elb-configure-healthcheck MyLoadBalancer --target "HTTP:5000/health" --interval 2 --unhealthy-threshold 1 --healthy-threshold 1
  • 101. Above the stack • Minimal impact
  • 102. Above the stack • Minimal impact • Extended availability comes for free
  • 103. Above the stack • Minimal impact • Complicated setup • Extended availability comes for free
  • 104. Above the stack • Minimal impact • Complicated setup • Extended availability • Another component you comes for free have to track and maintain
  • 107. Unicorn • Replaces your web server • Bounces gracefully
  • 108. Unicorn 63480 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 109. Unicorn $ kill -USR2 63480 63480 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 110. Unicorn $ kill -USR2 63480 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 111. Unicorn 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 112. Unicorn $ kill -QUIT 63480 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 113. Unicorn $ kill -QUIT 63480 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 114. Unicorn 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 116. Within the stack • Easy to setup and deploy
  • 117. Within the stack • Easy to setup and deploy • Optimal performance to cycle the server
  • 118. Within the stack • Easy to setup and deploy • Changes your application stack • Optimal performance to cycle the server
  • 119. Within the stack • Easy to setup and deploy • Changes your application stack • Optimal performance to cycle the server • Doesn’t address availability issues
  • 121. Heroku Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 122. Heroku $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 123. Heroku $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 starting for 1s bundle exec thin start -p $PORT
  • 124. Heroku Process State Command ------- --------------- ------------------------------- web.1 starting for 5s bundle exec thin start -p $PORT
  • 125. Heroku Process State Command ------- --------------- ------------------------------- web.1 up for 1s bundle exec thin start -p $PORT
  • 126. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 127. Heroku BETA $ heroku labs:enable preboot Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 128. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 129. Heroku BETA $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 130. Heroku BETA $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT web.1 starting for 5s bundle exec thin start -p $PORT
  • 131. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT web.1 up for 1s bundle exec thin start -p $PORT
  • 132. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 5s bundle exec thin start -p $PORT
  • 134. Heroku • Migrations $ git push pre-production master $ heroku run rake db:migrate --remote pre-production $ git push production master
  • 135. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 136. Future
  • 139. Future • Asset pipeline • Mysql tooling • Can Rails help making the development of hot compatible applications easier?
  • 140. Future • Asset pipeline • Mysql tooling • Can Rails help making the development of hot compatible applications easier? • Can databases?
  • 141. Future
  • 142. Future • Hot compatibility beyond zero downtime deploys
  • 144. Conclusion • Zero downtime is a pain in the ass
  • 145. Conclusion • Zero downtime is a pain in the ass • Hot compatibility to the rescue
  • 146. Conclusion • Zero downtime is a pain in the ass • Hot compatibility to the rescue • Make sure your production env is ready