proxies and multiplexing

Stuart Bishop stuart.bishop at canonical.com
Fri Jun 13 13:38:33 UTC 2014


Hi.

I'm having some trouble fitting proxy services, such as load
balancers, caches, connection pools etc. into the juju world view.

I feel that a proxy should seamlessly drop into an existing relation,
emulating the server from the clients perspective and emulating the
client from the server's perspective. This would seem easy, just
creating a new service that implements the exposed  interfaces. The
proxy does its thing and connects connections from the client units to
the backend units.

This all works fine, except when not all units of the backend are
equal. Without the proxy, the client is responsible for selecting the
backend unit it needs to talk to. Perhaps it needs to talk to a
particular storage shard. Perhaps it needs to talk to a master.
Perhaps it needs to select a quorum of backends. With a proxy, the
client units are no longer aware of the number of actual backend units
or their role in the service. Each unit in the proxy service has only
once face it can present to a client unit. It has no way of fronting
for several backend units, unless they are all identical and it
doesn't matter how the proxy routes the client connections.

Perhaps to avoid this situation, a service should provide a separate
interface for each type of unit. So for example, the PostgreSQL charm
would define separate 'db-master' and 'db-standby' interfaces, and a
client service wanting to use both the master for writes and standby
servers for reads would need to open two relations. This would allow
the pgbouncer charm to be dropped in, emulating both of the interfaces
and load balancing queries to the correct type of backend unit. This
seems cleanest, although changing the interface this radically is
going to break things.

Perhaps all units in a service should be equal. I chose not to do this
in the PostgreSQL charm to allow easy failover, with surviving units
examining each other and choosing the best replacement master.

Perhaps a unit could create some sort of virtual unit in the relation,
so it can present multiple variants of the interface. Even if it
worked, I suspect the added confusion would not be worth it.

What would be the best and most future proof method of going forward?
I think I'm going to need to rework my base interfaces to be proxy
friendly, deprecating the existing db interface and adding db-master
and db-standby interfaces (db-admin can remain, as all the operations
requiring a superuser will require the master). A single unit in a
PostgreSQL service will present connection details on the db-master
relations. All-but-one units will present their connection details on
the db-standby relations.


-- 
Stuart Bishop <stuart.bishop at canonical.com>



More information about the Juju mailing list