From b90350247e8429c147c4a6a984bc9c6ba9c57785 Mon Sep 17 00:00:00 2001 From: jlecour Date: Thu, 20 Oct 2022 17:03:24 +0200 Subject: [PATCH] =?UTF-8?q?Guide=20pour=20faire=20du=20master/replica=20su?= =?UTF-8?q?rveill=C3=A9=20par=20HAProxy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HowtoRedis.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/HowtoRedis.md b/HowtoRedis.md index cce9ac79..f81c9a85 100644 --- a/HowtoRedis.md +++ b/HowtoRedis.md @@ -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