Does juju support 'named' interfaces?

Clint Byrum clint at
Tue Jun 26 06:41:58 UTC 2012

Excerpts from Sidnei da Silva's message of 2012-06-25 18:05:30 -0700:
> Hi there,
> For Ubuntu One (and, I assume, for a couple other services out there),
> we have named database shards that users are assigned to according to
> a mapping specified by yet-another database.
> So, in order to connect a service to those sharded databases, I need
> to require not just a single pgsql interface, but a finite set of
> 'named' pgsql instances which will be assigned to each shard.
> So to be more specific, when I do:
>   juju add-relation my-app my-deployed-shard0
> ...where 'my-app' requires multiple pgsql backends (shard[0-N]) and
> 'my-deployed-shard0' would *have* to be used as 'shard0' by 'my-app',
> how does one structure this?
> I can see someone working around this by forking the pgsql charm as
> 'pgsql-shard[0-N]' and each of those charms only providing the
> specific interface, and having the app require 'pgsql-shard[0-N]'
> instead of a generic 'pgsql' charm, but clearly this would cause an
> unnecessary interface explosion.
> Here's an example of what the actual config file for the application looks like:
> """
> defaults:
>     options:
>         isolation: repeatable-read
> shards:
>     new_user_shards: [shard0, shard1, shard2]
>     shard_ids: [shard0, shard1, shard2]
> stores:
>     storage:
>         host: storage.internal
>         database: storage
>     shard0:
>         host: shard0.internal
>         database: shard0
>     shard0-slave:
>         host: shard0-slave.internal
>         database: shard0
>     shard1:
>         host: shard1.internal
>         database: shard1
>     shard1-slave:
>         host: shard1-slave.internal
>         database: shard1
>     shard2:
>         host: shard2.internal
>         database: shard2
>     shard2-slave:
>         host: shard2-slave.internal
>         database: shard2
>     account:
>         host: account.internal
>         database: account
>     account2:
>         host: account2.internal
>         database: account
> """
> Thoughts?

I think this shouldn't be too challenging:

Some stipulations:
* both requires and provides can be satisfied/utilized multiple times.
* each established relationship has an ID. You will see it in the
  *-relation-* hooks as $JUJU_RELATION_ID. They can also be enumerated
  with `relation-ids`.
* Each unit of each service related to you will cause relation-joined
  and relation-changed hooks with a different $JUJU_UNIT_NAME.
* One can have multiple relations of the same interface type

Given that, I'd do this with the current pgsql charm:

* Require a separate relation name for the "mapping" database.
* Make the number of shards configurable. Default to -1 which means
  "1 per shard db server" shard names are just shard#
* mapping-relation-changed: assign all unassigned shards in all available
  shard dbs.
* shard-relation-changed: record shard db target in a list of available
  shard dbs.
* Use $JUJU_RELATION_ID+$JUJU_UNIT_NAME to uniquely name them.
* re-run mapping-relation-changed
* shard-relation-departed/broken: shard is funneled to an unused pool
  if possible, or somehow flagged as "dead" or "orphaned"
* config-changed basically just re-runs mapping-relation-changed

The important thing here is that by using JUJU_RELATION_ID for the shard
dbs, you can do this:

juju deploy pgsql --constraints mem=10G -n 2 shard-dbs
juju deploy pgsql --constraints mem=1G mapping-db
juju deploy myappserver -n 5
juju add-relation myappserver:mapping mapping-db
juju add-relation myappserver:shard shard-dbs

...and then when things start to grow out of hand:

juju add-unit shard-dbs -n 2

... and now the dataset grows so you need bigger servers:

juju set myappserver nshard=4
juju deploy pgsql --constraints mem=24G -n 4 big-shard-dbs
juju add-relation myappserver:shard big-shard-dbs
# The pool is now 8 instead of 4, but nshards still == 4
juju set myappserver nshards=4
# shard-dbs now migrated to big-shard-dbs:
juju remove-relation myappserver:shard shard-dbs

The only bummer about this is the poor visibility of the result of each
operation. Its tough to trust whats going on in the remove-relation when
it could mean your appserver is now down.

Note that this will work without anything special in pgsql.  add-unit,
for now, does not setup any kind of replication.. just starts up another

More information about the Juju mailing list