Hi Konrad,
On Sun, Feb 05, 2012 at 10:32:23PM +0100, konrad rzentarzewski wrote:
> On Thu, Feb 02, 2012 at 01:44:57PM +0100, Baptiste wrote:
> > Hi,
> >
> > There is no way to do this.
> > Even using stick tables, since only entries from a table are
> > synchronized and not counters associated to each of them.
>
> given that instances get equal load there is no need for any state table
> as long as algorith is identical (the same applies to consistent
> hashing, you don't need to sync anything to get identical results as
> long as urls and backend ids are identical).
Agreed, this is unrelated.
> in this specific scenario this should be sufficient:
>
> use_backend app_50_percent if srv_is_up(cluster/other_haproxy)
> use_backend app_100_percent unless srv_is_up(cluster/other_haproxy)
>
> backend cluster
> server other_haproxy 1.2.3.4:80 check
>
> backend app_50_percent
> default-server maxconn 24
>
> backend app_100_percent
> default-server maxconn 48
Interesting. Initially I thought you wanted to share the maxconn between
multiple servers of the same farm (something I have in the roadmap and which
is not easy to implement if servers do not track themselves). But you're
interested in always running your servers at full load whatever the number
of running haproxy boxes in fact.
> a bit of hassle in configuration, though doable if you use configuration
> management software and templates... but if you do context swithing
> between almost gross of backends it came became a litle mess.
>
> the "clean way" to do that would be:
>
> throttle_backend 50% if srv_is_up(cluster/other_haproxy)
> default_backend just_an_app
OK I get it now. It cannot be done really that way because ACLs are
evaluated by request, we can't (and don't want to) change the backend's
weight per request but rather per check or per time unit. Ideally we
should find a way to declare an action on the result of a check.
Or maybe we could proceed differently. Imagine that we decide to share the
weights between multiple backends. Then we could define in each backend
the list of the other backends the weight has to be divided between. When
the backend is a "real" one with the same servers, it's easy to understand
that the weights and maxconns will be divided so that they don't overload
the same shared servers. And when the backend only hosts one server being
a check for the remote haproxy machine, the weights and maxconns would be
shared between them.
example 1: local case :
backend customer1
share-load customer2
server srv1 192.168.0.1:80 maxconn 100 check
server srv2 192.168.0.2:80 maxconn 100 check
backend customer2
# same farm as customer 1
share-load customer1
server srv1 192.168.0.1:80 maxconn 100 track customer1/srv1
server srv2 192.168.0.2:80 maxconn 100 track customer1/srv2
example 2: rmeote case :
backend app
# cut weights and maxconns in half if other haproxy is up
share-load haproxy-peer
server srv1 192.168.0.1:80 maxconn 100 check
server srv2 192.168.0.2:80 maxconn 100 check
backend haproxy-peer
server srv1 192.168.0.253:8000 check
One thing which is still difficult is to build the dependency chain and
to propagate state changes. We already have an internal event when all
servers in a backend are down, so probably we could rely on this to
change other backends' throttle value. Another method would be to be
able to define a groups of backends which share their throttle parameters
only at one place. But this would mean that the "haproxy-peer" above would
belong to multiple backends.
Thinking about it, there could be something completely different. For your
usage, we're really talking about haproxy peers. Maybe we could state that
a backend's weight directly depends on the number of peers that are up in
the "peers" section. The pre-requisite to share those weights would then be
to have a peers section. Maybe then we'd add a flag "active" to the peers
to indicate which ones are supposed to take traffic in parallel. Well, it
would not necessary be easy to handle active/passive scenarios.
I think this requires a bit more thinking. The elements we have right now :
- most people use 2 haproxy boxes, one active, one passive, so the load
should always be at 100% on both.
- some people use 2 active-active boxes, but at any time, any of
them might be offline (maintenance of failure). The load should be
at 50% each when they're all OK, or 100% when they don't see each other
- some people use up to 4 active-active boxes (I've been reported a
single large deployment around one hundred, but this is very specific
and does not count). In such a deployment, we can see that it works
just as above, but we don't have just 50% or 100%, but we have
100%/#boxes. Peers can make sense, but peers are not much suited to
monitor VIPs when only a VIP is switched. Health checks are more
appropriate.
- a large number of hosting providers have many backends pointing to the
same servers and would love to share the load between them. But there
it's a bit different as it's a matter of global maxconn for the servers
and not of backend throttling in fact, so maybe the two needs are totally
unrelated.
If anyone wants to bring some ideas on the table, you're welcome :-)
Cheers,
Willy