Rails has powerful sharding features available right within ActiveRecord.
It is possible to define either vertical or horizontal shards
and use connected_to to switch between them.
When execution happens inside the method,
all database connections follow the configuration specified in the connected_to block.
To configure our shards, we use the config/database.yml file.
Here’s how ours looks.
development:
primary:
<<: *default
database: primary_database
primary_shard_two:
<<: *default
database: primary_shard_two
primary_shard_two_replica:
<<: *default
database: primary_shard_two
replica: trueThen we initiate the connection in ApplicationRecord.
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
connects_to shards: {
default: { writing: :primary, reading: :primary_replica },
shard_two: { writing: :primary_shard_two, reading: :primary_shard_two_replica }
}
endNote that primary
and primary_shard_two are not replicas of each other.
Rather, they are independent databases which share the same schema.
The primary_replica
and primary_shard_two_replica are replicas.
Before
Originally two parameters were required for a connected_to block – the name of the shard
and the role.
This was done to make it less syntactically confusing to use.
Let’s look at an example.
ActiveRecord::Base.connected_to(role: :reading, shard: :default) do
puts ActiveRecord::Base.connection_db_config.name
Blog.count
end
primary_replica
Blog Count (3.1ms) SELECT COUNT(*) FROM "blogs"
=> 3However, if we don’t specify the role parameter,
Rails throws an ArgumentError.
ActiveRecord::Base.connected_to(shard: :default) do
puts ActiveRecord::Base.connection_db_config.name
Blog.count
end
Traceback (most recent call last):
1: from (irb):1
ArgumentError (`connected_to` cannot accept a `shard` argument without a `role`.)After
Changes to this PR remove the need for role to be passed to every connected_to block.
This was done to prevent the need for a role parameter from being passed
when execution was only concerned with the shared.
It also paves the way for more complex multi-tenancy work to be done later on while also simplifying calls for applications
that don’t use roles,
rather only have writer shards.
