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


Reply via email to