Stuart-

There was a discussion we had a year ago about possibly changing the design
of how proxies worked. I believe it is something that can be done entirely
in charm space if people want to give it a try. You can certainly think
about it and whether it works better for you or not.

In our current model, you relate Postgres (provides DB) to a PostgresProxy
(provides and requires DB)  and then you relate the Application (requires
DB) to the PostgresProxy.
In the GUI graph you see:
postgres --- proxy --- application

However, TCP level proxies can really proxy any protocol, and don't really
care whether it is DB or not.

A different model that doesn't require HAProxy to grow all of
mysql/pgsql/http/everything provides and requires would be that we use a
"tcpproxy" protocol.
In which case, Postgres (provides DB and optionally requires TCPProxy), and
HAProxy (provides TCPProxy) and Application (requires DB) connects directly
to Postgres.
When Postgres is connected to an HAProxy on the TCPProxy connection, it
then rewrites its own private address to be that of the proxy.
So in the GUI graph, you see

 postgres --- application
  |
 haproxy

The actual flow of *data* is application <=> haproxy <=> postgres.

That would let you have a single HAProxy charm that knows how to proxy
anything on TCP, and the TCPProxy relation is defined to include enough
detail so that Postgres would know what to change its private address to
and haproxy knows enough information to know what ports it needs to expose
and what port in needs to forward that data to.

I don't know quite how that would work with postgres masters vs postgres
slaves, but it does mean that postgres charm is involved in its own
proxying (it knows when it is being proxied, and changes its behavior
accordingly).

I haven't quite worked through how all that interacts with your proposal
that not all units of postgresql are equal. Nor how it interacts with the
Azure model of only giving out one IP address for all the units of postgres.

John
=:->


On Mon, Jun 16, 2014 at 8:00 AM, Andrew Wilkins <
andrew.wilk...@canonical.com> wrote:

> On Fri, Jun 13, 2014 at 9:38 PM, Stuart Bishop <
> stuart.bis...@canonical.com> wrote:
>
>> 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.
>>
>
> I don't know anything much about PostgreSQL or its failover mechanisms,
> but this seems like an appropriate thing to do in general.
>
> Bear in mind that Azure ties together load balancing and service
> availability, so users of Azure will today have the issue you've described.
> The Azure provider will automatically distribute all units of a service to
> the same availability set, which means they all have a single public IP
> which load balances across the units that expose a common port.
>
>
>> 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.bis...@canonical.com>
>>
>> --
>> Juju mailing list
>> Juju@lists.ubuntu.com
>> Modify settings or unsubscribe at:
>> https://lists.ubuntu.com/mailman/listinfo/juju
>>
>
>
> --
> Juju mailing list
> Juju@lists.ubuntu.com
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/juju
>
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju

Reply via email to