Guide pour faire du master/replica surveillé par HAProxy

This commit is contained in:
jlecour 2022-10-20 17:03:24 +02:00
parent 656bc17ec5
commit b90350247e

View file

@ -423,6 +423,172 @@ Sentinel doit pouvoir ecrire dans son fichier de configuration :
chown redis: /etc/redis/sentinel.conf
~~~
## Load-balancing avec HAProxy
Il est possible d'avoir un master et plusieurs replica derrière un proxy/load-balancer HAProxy (sur `172.19.3.100` dans l'exemple).
~~~.haproxy
frontend fe_redis
mode tcp
option tcplog
bind 127.0.0.1:6379
default_backend be_redis
backend be_redis
mode tcp
balance first
default-server maxconn 1024 check agent-check agent-port 16379 agent-inter 1s
server srv1 172.20.3.200:6379
server srv2 172.20.3.201:6379
~~~
Sur les serveurs avec Redis (`172.19.3.200` et `172.19.3.201` dans notre exemple), il faut installer le paquet `xinetd` puis créer une configuration `/etc/xinetd.d/haproxy-agent-redis-role` :
~~~
service haproxy-agent-redis-role
{
socket_type = stream
bind = 172.19.3.200
port = 16379
protocol = tcp
wait = no
type = UNLISTED
user = root
server = /usr/share/scripts/haproxy-agent-redis-role.sh
log_on_failure += USERID
disable = no
only_from = 172.19.3.100
}
~~~
On active ce service dans `/etc/services` :
~~~
haproxy-agent-redis-role 16379/tcp
~~~
Puis on redémarre `xinetd` : `systemctl restart xinetd`
Enfin, on installe le script qui sert d'agent `/usr/share/scripts/haproxy-agent-redis-role.sh` :
~~~.bash
#!/bin/sh
set -u
config_var() {
variable=$1
file=$2
test -f "${file}" && grep -E "^${variable}\s+.+$" "${file}" | awk '{ print $2 }' | sed -e "s/^[\"']//" -e "s/[\"']$//"
}
get_role() {
host=$(config_var "bind" "${conf_file}")
port=$(config_var "port" "${conf_file}")
pass=$(config_var "requirepass" "${conf_file}")
if [ -n "${pass}" ]; then
export REDISCLI_AUTH="${pass}"
fi
cmd="${redis_cli_bin} -h ${host} -p ${port} INFO REPLICATION"
${cmd} 2>/dev/null | grep -Eo "role:\w+" | cut -d ':' -f2
}
get_status() {
systemctl is-active "${1}"
}
redis_cli_bin=$(command -v redis-cli)
if [ -z "${redis_cli_bin}" ]; then
printf "%s\n" "down # missing redis"
exit 1
fi
if [ $# -lt 1 ]; then
service="redis-server.service"
conf_file="/etc/redis/redis.conf"
else
service="redis-server@${1}.service"
conf_file="/etc/redis-${1}/redis.conf"
fi
if [ ! -r "${conf_file}" ]; then
printf "%s\n" "down # missing config"
exit 3
fi
status=$(get_status "${service}")
case "${status}" in
active)
printf "%s " "up"
;;
inactive)
printf "%s\n" "stopped # systemd:${status}"
exit 1
;;
failed)
printf "%s\n" "fail # systemd:${status}"
exit 1
;;
*)
printf "%s\n" "down # systemd:${status}"
exit 1
;;
esac
role=$(get_role "${conf_file}")
case "${role}" in
master)
printf "%s" "ready # role:master"
;;
slave)
printf "%s" "maint # role:slave"
;;
*)
printf "%s" "maint # role:unknown"
;;
esac
printf "\n"
exit 0
~~~
### Redis multi-instances
Ce script est compatible avec la présence de multiples instances de Redis.
Si on l'exécute avec un argument `foo` il cherchera une configuration `/etc/redis-foo/redis.conf` et un service systemd `redis-server@foo`.
Il faudra alors déclarer autant de services xinetd que d'instances à surveiller :
~~~
haproxy-agent-redis-role-foo 16380/tcp
haproxy-agent-redis-role-bar 16381/tcp
~~~
Et enfin, modifier les services pour ajouter le paramètre `server_args` :
~~~
service haproxy-agent-redis-role-foo
{
socket_type = stream
bind = 172.19.3.200
port = 16380
protocol = tcp
wait = no
type = UNLISTED
user = root
server = /usr/share/scripts/haproxy-agent-redis-role.sh
server_args = foo
log_on_failure += USERID
disable = no
only_from = 172.19.3.100
}
~~~
## Benchmarks