Skip to content
Jay OConnor edited this page Jan 7, 2015 · 10 revisions

Sharding

Octopus allows you to do Database Sharding. This means you could send some queries to specific shards, or pick one shard, and use it as the default database for your application.

Code Examples:

Sending a query to a specific shard:

# This will create a new user in "canada" shard
User.using(:canada).create!(:name => 'oi')

The Api also allows dynamically change the shard:

# This will create a new user in "canada" shard
User.using(:canada).using(:master).using(:canada).create!(:name => 'oi')

You could also pass a block to #using method, and #using method will send all queries inside the block to a specific shard:

# This will create a new user and a new client in "canada" shard
Octopus.using(:canada) do
  User.create(:name => "User")
  Client.create(:name => "Client")
end

the using method is also available for User instances:

class User < ActiveRecord::Base
  def awesome_queries
    Octopus.using(:canada) do
      User.create(:name => "teste")
      Dog.create(:name => "Xpto")
    end
  end
end

# This will create a new user and a new dog in the canada shard:
u = User.new
u.awesome_queries()

The shard could also be specify in the ActionController or Any subclass. All requests from that controller will be executed in the selected shard.

class ApplicationController < ActionController::Base
  around_filter :select_shard      

  def select_shard(&block)
    Octopus.using(current_user.country, &block)
  end
end

If you need dynamic shards using shards configuration saved in database, you can create a initializer containing something as this example:

begin
  shards = {:my_shards => {}}
  Shard.find(:all).each do |shard|
    shards[:my_shards][shard.database] = {:host => shard.host, :adapter => shard.adapter, :database => shard.database, :username => shard.username, :password => shard.password, :port => shard.port}
  end

  Octopus.setup do |config|
    config.environments = [:production, :staging]
    config.shards = shards
  end

rescue ActiveRecord::StatementInvalid => e
  puts e
end

Now you can use all shards saved in your database, without declare one by one in shards.yml, and you have a group named ‘my_shards’ can be used in migrations

Clone this wiki locally