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

The road to a Multi-Tenant Rails App

The road to a Multi-Tenant Rails App

At the beginning of the world there was a Rails app, built to solve a specific problem and it happens to be a single tenant app. In another SAAS world, with a freemium model, most of the tenants that signs up (after finding you on Google) are 'kinda lazy’, and don’t really use the app, and don't do anything other than signup. There will be, however, a few special users out there waiting for your app. They also found you on Google, signs up, logins on a daily basis, use it, and use it. Importantly, these special users had allocated the same amount of resources as the ‘kinda lazy’ ones.
To scale in the scenario describe requires a change in approach: Special tenants get Special treatment, while ‘kinda lazy’ tenants get default treatment (and shared resources).
In this talk I will describe a few options that are available for this problem.

Helio Cola

June 11, 2015
Tweet

More Decks by Helio Cola

Other Decks in Programming

Transcript

  1. The road to Multi-Tenant Helio Rodrigues Senior SW Engineer Mobile

    Posse www.mobileposse.com
  2. Thank you, first! ❖ To all DCRUG organizers ❖ To

    all ARUG organizers ❖ To all NOVARUG organizers You all provide an awesome service to science, technology, and all of us!
  3. Also: thanks to you ❖ Quote from Ken Collins (https://github.com/metaskills)

  4. about.me ❖ 15+ years developing Software ❖ ~10 years developing

    C/C++ in Solaris environment ❖ ~5/6 years since I found happiness ❖ ~4 years of full time happiness ❖ helio.cola@gmail.com - @hacrods ❖ I am extremely shy!
  5. Where I work! ❖ Full-time job: www.mobileposse.com ❖ Latest product:

    www.appenvoy.com ❖ Part-time job: You will hear about it one day!
  6. Agenda ❖ How we usually get to a multi tenant

    problem ❖ The problem ❖ Possible solutions & tradeoffs ❖ Core changes ❖ Delayed Jobs ❖ Database migrations ❖ Tenant migration ❖ Questions & Close up
  7. How we get there You go and build it: ❖

    A rails app with a handful of delayed job tasks with MongoDB ❖ User management & CanCan(can) with System, Admin, and Editor roles ❖ Gems: Oauth2, doorkeeper, delayed_job, mustache, devise, foreman, fog, carrierwave, aws-core-sdk, parallel, newrelic_rpm, and gravtastic ❖ Create a JSON/REST API with swagger docs ❖ The signup process (via CMS) ✤ User signup trigger a chef/knife/recipe/stuff that does a lot of things including ✴ Open a AWS Route53 for my_user.user.myapp.com ✴ Install your rails app on /home/deployer/my_user on the WebServers + AppServers ✴ Configure nginx/passenger ✴ Start all rails apps ✦ db:seed will setup the MongoDB with initial user, password and a few other things ✴ Start delayed job workers
  8. tenant1 Web Servers App Servers tenant1 tenant1 Mongo ReplicaSet tenant2

    tenant2 tenant2
  9. The Single Tenant Problem ❖ Way too many resources allocated

    for non-active users ❖ Can’t fit too many users in a single landlord ❖ Users need to be deleted to open space for new users
  10. tenant1 Web Servers App Servers tenant2 tenant3 tenant4 tenant5 tenant1

    tenant2 tenant3 tenant4 tenant5 tenant1 tenant2 tenant3 tenant4 tenant5 Mongo ReplicaSet
  11. Agenda ❖ How we usually get to a multi tenant

    problem ❖ The problem ❖ Possible solutions & tradeoffs ❖ Core changes ❖ Delayed Jobs ❖ Database migrations ❖ Tenant migration ❖ Questions & Close up
  12. The Solution: ❖ Let’s GO Multi-Tenant Web Servers App Servers

    Mongo ReplicaSet tenant1 tenant2 tenant3 tenant4 tenant5 Landlord1 Landlord2 tenant1 tenant2 tenant3 tenant4 tenant5 Landlord1 Landlord2
  13. Types of Multi-tenant apps: ✴ One database for all customers

    ✴ One database per customer ✴ One collection per partner ✴ Reference: https://docs.compose.io/use-cases/multi- tenant.html
  14. Agenda ❖ How we usually get to a multi tenant

    problem ❖ The problem ❖ Possible solutions & tradeoffs ❖ Core changes ❖ Delayed Jobs ❖ Database migrations ❖ Tenant migration ❖ Questions & Close up
  15. Core changes ✤ Database switch before reaches your app controllers

    ✤ Delayed jobs outside the tenant database ✤ Database migration per LandLord and rake tasks per tenant ✤ Signup/Delete a new tenant is now a feature the app needs to support ✤ Migrate tenant between landlords
  16. Database switch References ✦ https://groups.google.com/forum/#!msg/ mongoid/eNenGVmfG48/cWuHFLAjVK0J

  17. Database switch References ✦ https://groups.google.com/forum/#!msg/ mongoid/eNenGVmfG48/cWuHFLAjVK0J class MongoidDbSwitcher def initialize(app)

    @app = app end def call(env) response = @app.call(env) response[2] = ::Rack::BodyProxy.new(response[2]) do ::Mongoid.override_database("school_one_#{env['SERVER_NAME']}") end response end end config.middleware.insert_before Warden::Manager, MongoidDbSwitcher
  18. Database switch: appartment gem require 'rack/request' require 'apartment/tenant' require 'apartment/deprecation'

    module Apartment module Elevators # Provides a rack based tenant switching solution based on request # class Generic def initialize(app, processor = nil) @app = app @processor = processor || parse_method end def call(env) request = Rack::Request.new(env) database = @processor.call(request) Apartment::Tenant.switch! database if database @app.call(env) end def parse_database_name(request) deprecation_warning parse_tenant_name(request) end def parse_tenant_name(request) raise "Override" end def parse_method if self.class.instance_methods(false).include? :parse_database_name deprecation_warning method(:parse_database_name) else method(:parse_tenant_name) end end def deprecation_warning Apartment::Deprecation.warn "[DEPRECATED::Apartment] Use #parse_tenant_name instead of #parse_database_name -> #{self.class.name}" end end end end
  19. Database switch: appartment gem

  20. Database switch: appartment gem

  21. Agenda ❖ How we usually get to a multi tenant

    problem ❖ The problem ❖ Possible solutions & tradeoffs ❖ Core changes ❖ Delayed Jobs ❖ Database migrations ❖ Tenant migration ❖ Questions & Close up
  22. Delayed jobs Delayed jobs outside the tenant database ❖ The

    delayed jobs are created in the landlord’s DB but do things on the tenant’s DB
  23. Agenda ❖ How we usually get to a multi tenant

    problem ❖ The problem ❖ Possible solutions & tradeoffs ❖ Core changes ❖ Delayed Jobs ❖ Database migrations ❖ Tenant migration ❖ Questions & Close up
  24. Database migrations Database migration and rake tasks on a per

    tenant/ landlord basis ❖ Keep the rails way ❖ Migration run for all tenants for a given LandLord ❖ Rake tasks run for a subset (one, two, or all)
  25. Signup/Delete ❖ Signup/Delete a new tenant is now a feature

    the app needs to support ❖ Tenant is white listed in each landlord and only those are answered by the landlord
  26. Moving tenants Multi instances with different purpose ✤ Default: all

    signups from the public website ✤ Bleeding Edge: latest and greatest features ✤ Stable: mature version, bug free ✤ Custom clients
  27. References ✦ http://mongoid.org/en/mongoid/docs/persistence.html#custom ✦ https://groups.google.com/forum/#!msg/mongoid/Rp64Tvjwtbk/dNVa92opzeIJ ✦ https://groups.google.com/forum/#!msg/mongoid/eNenGVmfG48/cWuHFLAjVK0J ✦ https://docs.compose.io/use-cases/multi-tenant.html ✦

    https://github.com/influitive/apartment
  28. Before we go ✴ http://db-engines.com/en/ranking ✴ Google: db engines ranking

    Questions?