On Fri, Feb 12, 2016 at 12:54:53PM -0800, Florin Andrei wrote:
> I have a couple HAproxy instances in front of several webservers. The
> HAproxies are receiving traffic from an ELB upstream. All HAproxies are
> identical.
>
> I want to load balance and make sessions sticky based on the contents of
> a request header. In a nutshell, all requests with the same header value
> must go to, and stick to, the same backend server.
>
> A configuration I'm thinking of (but I'm not 100% sure it's correct)
> might look like this:
>
> backend be_http
> mode http
> balance hdr(X-Forwarded-For)
> hash-type consistent
> stick on hdr(X-Forwarded-For)
> server s1 x.x.x.x1:8080 check
> server s2 x.x.x.x2:8080 check
> server s3 x.x.x.x3:8080 check
> server s4 x.x.x.x4:8080 check
>
> But here's my question. I have not one, but two HAproxy instances. Are
> they going to compute the hash the same way? In other words, for the
> same value of that header, is haproxy1 going to send the sessions to the
> same backend server as haproxy2?
The hash is absolutely determinist and that's mandatory for situations
like yours to work. It's also what ensures reloads continue to distribute
the traffic similarly. What you need to keep in mind however is that the
hash depends on the number of servers in the farm. The operation is a 32-bit
hash on the input data, divided by the number of available servers, and the
remainder determines the server which will get the request.
So when a server goes up or down, you may have a short time during which
both LBs will hash differently (eg: one second if your checks run every
second).
There are two things you can do to improve the situation :
- use "hash-type consistent" to change the hash algorithm. It will
ensure that instead of doing a modulo and redistributing all the
load, the traffic targetting dead servers will be redistributed
to the remaining ones. However you need to be aware that the
traffic is less fair between servers when using consistent hashing,
you need to expect differences of +/- 10-20% between the most loaded
one and the least loaded one.
- declare a peers section and reference it in your stick table so
that each time a connection is sent to a server on one LB, the
information is sent to the neighbour that will do its best to
respect this choice, or if it needs to rebalance it (dead server),
will inform back about the change.
Willy