Backward compatibility: deploying without downtime

VilniusPHP 0x38

What's Backward compatibility?!

BC context

  • Libraries, semantic versioning (v2.3.13) Libraries, semantic versioning (v2.3.13)
  • APIs (/rest/v1/resources) APIs (/rest/v1/resources)
  • Code and database, cache, etc

I'll be talking about...

  • Deploying
  • Common pitfalls
  • Cache pitfalls
  • Database pitfalls

Marius BalĨytis

  • In 2016 - over a million transfers
  • Many systems with critical infrastructure
  • Customers all over the world
  • Lots of requests each second
  • Over 25 programmers (and counting)
  • Lots of deployments each day

Deployment

?

Demo! (deployment)

See first commits in deployment-playground repository

Cache versioning

Situation

  • Parse file from xml
  • Save into cache (APCu, Memcached, etc)
  • Use in PHP
  • Example - Doctrine config, routing, etc.

Demo! (cache)

See later commits in deployment-playground repository

Cache: summary

  • Resetting cache is risky
  • Use prefixes for each release
  • Warm up cache before switching release if possible
  • APCu - problematic

Database migrations

Situation

  • We have transfers with money field
  • Format: "100 EUR"
  • We want to make several columns: 100, EUR

Demo! (DB)

See last commits in deployment-playground repository

First: prepare

  • Add new columns, do not remove old ones
  • Always insert both old and new values (handle rollback)
  • Support both new and old columns - this will be needed later

Second: migrate to new functionality

  • Make old column nullable
  • Migrate data from old to new columns
  • Only use new columns in code
  • We can rollback as new columns are handled by previous release

Third: cleanup!

  • Remove old column
  • Make new columns not nullable

Let's summarize!

  • Race conditions sucks!
  • Think about deployments
  • Think about rollbacks