EctoSharding
A simple sharding library for Ecto.
Documentation can be viewed on hexdocs.
Installation
defp deps do
[
{:ecto_sharding, "~> 0.0.5"}
]
end
Usage
Configuration
Configure your app’s
Ecto.Repo
This configuration will be used when a not-sharded schema is being queried.
config :my_app, MyApp.Repo, adapter: Ecto.Adapters.MySQL, username: System.get_env("MYSQL_USERNAME"), password: System.get_env("MYSQL_PASSWORD"), database: System.get_env("MYSQL_DATABASE"), hostname: System.get_env("MYSQL_HOST"), pool_size: 15
Configure
EctoSharding
otp_app
needs to be set soEctoSharding
knows how to builds the repos for each shard.config :ecto_sharding, EctoSharding, otp_app: :my_app
If you know your shard information at compile time, you can also add that.
config :ecto_sharding, EctoSharding, otp_app: :my_app, shards: %{ "shard_1" => [ adapter: Ecto.Adapters.MySQL, username: System.get_env("MYSQL_USERNAME"), password: System.get_env("MYSQL_PASSWORD"), database: "my_db_shard_1", hostname: "10.0.0.1", pool_size: 15 ], "shard_2" => [ adapter: Ecto.Adapters.MySQL, username: System.get_env("MYSQL_USERNAME"), password: System.get_env("MYSQL_PASSWORD"), database: "my_db_shard_2", hostname: "10.0.0.2", pool_size: 15 ] }
Start
EctoSharding
as a supervised processWhen the supervisor starts up, it will expect all of its configuration to be there, so make sure any config is set before
start_link
is called.supervisor(EctoSharding, [])
use EctoSharding.Repo
instead ofEcto.Repo
In any repos you have defined in your app, use
EctoSharding.Repo
instead:use EctoSharding.Repo, otp_app: :my_app
use EctoSharding.Schema
instead ofEcto.Schema
The schema is where most of the magic happens. This is where you can declare a particular schema as sharded or not. Schemas will default to sharded.
A sharded schema
defmodule MyApp.User do use EctoSharding.Schema, sharded: true # default schema "users" do field :name, :string # ... end end
A not-sharded schema
defmodule MyApp.Account do use EctoSharding.Schema, sharded: false schema "accounts" do field :name, :string # ... end end
Querying
Setting the current shard
EctoSharding
uses a shard registry, backed by GenServer
to store information
about which shard we currently want to use and how to talk to that shard. This
means that you need to set the current shard in your application before you can
issue a query to the sharded database.
Setting the shard is as simple as
EctoSharding.current_shard("shard_1")
Take a plug
based web application for example. This is what a plug
that sets
the current shard might look like:
defmodule MyApp.ShardContext do
@behaviour Plug
import Plug.Conn
def init(opts), do: opts
def call(conn, _) do
account = conn.assigns.account
EctoSharding.current_shard(account.shard_id)
conn
end
end
Executing a query
Once the current shard has been set, we can query our repo just like normal and it will take care of using the correct repo for the schema involved in the query.
import Ecto.Query
MyApp.User
|> where(name: "Jane Doe")
|> limit(1)
|> MyApp.Repo