Hi Mark,

Le 15/02/2014 21:28, Mark Ruys a écrit :
Hi,

I've read the blog
http://blog.exceliance.fr/2014/01/17/emulating-activepassing-application-clustering-with-haproxy/
 which
describes how to prevent an automatic fail back in case of a a fail over
in a active/passive setting. This is important for us as we want to be
sure that MySQL replication is fully recovered before the failed master
gets active again.

It's confusing because the examples you provided are for HTTP servers and you're talking about MySQL replication. In many cases, you'll manage it differently. Well, I'll use HTTP too for my example but will try to describe a solution that works for mysql.

In a typically HAProxy setting (at least in our case), we have backend
servers serving a few IP-adresses (each SSL certificate needs its own IP
address). So the frontend binds to a few IP-addresses. But the stick
table can only hold a single dst IP-address. Shouldn't the size of stick
table be at least at big as the number of addresses the frontend binds to?

Then I have another problem. In some unfortunate scenarios the network
gets unreliable. So it could be the case that server s1 is unreachable
and automatic fail over to s2 occurs. This is sticky, so when s2 is
reachable again, no automatic fail back happens, just as we want. But
then s2 gets unreachable. In this case an automatic fail back will
start! This is against the prerequisite that a fail back should /only/
occur by manual intervention. So wouldn't it be safer to define the
backend like this:

backend bk_app
 stick-table type ip size 1 peers LB
 stick on dst
 server s1 10.0.0.1:80 check rise 9999999
 server s2 10.0.0.2:80 check backup

Then we've got 100 days time to review the situation and force a manual
fail back when I'm ready (by reloading the haproxy service).

I think that for such a critical scenario, it can be a good idea to split servers into 2 backends.

Example :
  backend active
    server s-active 10.0.0.1:80 check

  backend passive
    server s-passive 10.0.0.2:80

Then a frontend can elect the backend depending on the "active" backend state :
  frontend cluster :80
    acl PASSIVE nbsrv(active) eq 0
    use_backend passive if PASSIVE
    default_backend active

This will (almost) simulate the "backup" behaviour, without some features such as redispatch. But in a replication scenario, I prefer a connection error than a redispatch that will write to the wrong server.

Now, it's time to have a sticky cluster. For that :
1. Add 1 stick table in the "passive" backend,
2. Add a new condition in the frontend to check if there's an entry or not (this is where I introduce "always_true");
3. Peers are used to remember the states on reload
4. Also add a stats socket to allow a manual reset (switch back to the active server).

Example :
  global
    daemon
    pidfile /var/run/tmp/haproxy.pid
    stats socket /var/run/haproxy.sock

  peers LB
    peer LB1 10.0.0.98:1234
    peer LB2 10.0.0.99:1234

  defaults
    timeout client 20s
    timeout server 20s
    timeout connect 4s

  frontend cluster :80
    acl PASSIVE nbsrv(active) eq 0
    acl PASSIVE table_cnt(passive) gt 0
    use_backend passive if PASSIVE
    default_backend active

  backend active
    server s-active 10.0.0.1:80 check

  backend passive
    stick-table type integer size 1 peers LB
    stick on always_true
server s-passive 10.0.0.2:80 # is it necessary to check the passive one ?

From this example, the default backend will be the active one.
Once "s-active" is DOWN or an entry exists in the "passive" table, the "passive" backend will be used.

To switch back to the "active" backend :
# echo "clear table passive" | socat stdio /var/run/haproxy.sock


--
Cyril Bonté

Reply via email to