ø dowtime migrations - rubyconf 2015

ø dowtime migrations - rubyconf 2015

Migrações em zero downtime com ruby.

Nesta apresentação mostro um pouco do mindset na RD para o rollout de novas features ou migrações sem downtime.

93b1c03b74dff7a41060d41a2da750ce?s=128

Jônatas Davi Paganini

September 12, 2015
Tweet

Transcript

  1. ø downtime Jônatas Davi Paganini jonatas jonatasdp

  2. 8 dev teams

  3. 10 deploys / day

  4. RD Station

  5. +2m mail / day

  6. +700 external services integrations

  7. +N callbacks

  8. Availability is REQUIRED

  9. 99,9% 99,5% 99,0% 98,6% 98,0% 97,0% 99,99% 00:43:00 03:36:00 07:12:00

    10:00:00 14:24:00 21:36:00 00:04:32 Availability
  10. 99.999???

  11. availability = ( total_time - timeout / total_time ) *

    100
  12. ø downtime

  13. mindset

  14. NO schedule maintenance

  15. avoid: all || nothing

  16. build reversible things

  17. build incremental migrations

  18. RubyConf 2012

  19. compatible versions

  20. http://shipit.resultadosdigitais.com.br/blog/ migrando-com-zero-downtime talk is <cheap>!

  21. show me the code!!!

  22. Migration add_column :people, :full_name, :string

  23. Update data Person.all.each do |person| person.full_name = "#{person.first_name} #{person.last_name}" person.save

    end
  24. 350 million updates!!!

  25. WTF time?!

  26. Let’s improve it! Person.all.each do |person| person.full_name = "#{person.first_name} #{person.last_name}"

    person.save end
  27. Select RIGHT attributes!

  28. Update 0.1 Person.select("id,first_name,last_name").each do |person| person.full_name = "#{person.first_name} #{person.last_name}" person.save

    end
  29. update_attribute instead of save

  30. Update 0.2 Person.select("id,first_name,last_name").each do |person| person.update_attribute "full_name", "#{person.first_name} #{person.last_name}" end

  31. find in batches

  32. avoid transaction overhead

  33. Update 0.3 Person.select("id,first_name,last_name").find_in_batches do |people| People.transaction do people.each do |person|

    person.update_attribute "full_name", "#{person.first_name} #{person.last_name}" end end end
  34. FAILURE resilient

  35. Update 0.4 Person.where(full_name: nil).select("id,first_name,last_name").find_in_batches do |people| People.transaction do people.each do

    |person| person.update_attribute "full_name", "#{person.first_name} #{person.last_name}" end end end
  36. explore connection pool

  37. Update 0.5 update_sql = "UPDATE people set full_name =" Person.where(full_name:

    nil).select("id,first_name,last_name").find_in_batches do |people| People.transaction do people.each(ActiveRecord::Base.connection_config[:pool]) do |person| ActiveRecord::Base.connection_pool.with_connection do |conn| set_full_name = conn.quote("#{person.first_name} #{person.last_name}") conn.execute("#{update_sql} #{set_full_name} where id = #{person.id} ") end end end end
  38. model hook

  39. Model class Person < ActiveRecord::Base before_save :update_full_name def update_full_name self.full_name

    = "#{first_name} #{last_name}" end end
  40. rollout control

  41. Rollout class Rollout def enabled?(feature, context) redis.sismember(feature, context) rescue Redis::BaseError

    false end def enable(feature, context) redis.sadd(feature) end def disable(feature, context) redis.srem(feature) end private def redis Redis::Namespace.new("rollout", redis: $redis) end end
  42. rollout use

  43. if: before_save :update_full_name, if: -> { Rollout.enabled? "started_migration", "global" }

  44. deploy steps

  45. smoothly steps

  46. PR #1 add new column

  47. PR #2 write old & new columns

  48. PR #3 migrate data

  49. PR #4 read from new column

  50. PR #5 remove old column

  51. PR #6 remove rollout code, cache

  52. Conclusion

  53. Embrace migrations • smoothly • incremental • safe • resilient

  54. Avoid migrations • all || nothing • ! roll outable

    features
  55. REFERENCES blog.codeship.com/rails-migrations-zero-downtime/ shipit.resultadosdigitais.com.br/blog/migrando-com-zero-downtime/ confreaks.tv/videos/railsconf2012-zero-downtime-deploys-for-rails-apps

  56. ?

  57. Thanks! jonatas jonatasdp ideia.me shipit.resultadosdigitais.com.br