본문 바로가기

devops

[Redis] Redis Sentinel + HAproxy


Redis Sentinel


Redis Sentinel은 Redis 서버에 대한 상태를 감시하며, Redis Master와 Slave로 구성되어 있다.

Master에 장애가 발생할 경우 Slave를 Master로 자동으로 변경하여 FailOver에 대처한다.

 

Redis Master의 상태 체크는 다수결에 의해 결정이 되는데, 이를 위해 Redis Sentinel은 홀수로 구성이 되어야 한다.

 

Redis Sentinel 상태 체크 및 FailOver 과정

Redis Sentinel-1이 Redis Master가 응답이 없다고 Sentinel-2 / Sentinel-3에 알림 - SDown(Subjective Down)

Redis Sentinel-2/Sentien-3이 Redis Master와 응답에 성공했다면, 상태를 정상으로 판단.

만약, 응답에 실패했다면, Redis Master의 상태를 장애로 판단 - ODwon(Objective Down)

Redis Slave를 Redis Master로 변경

 

Redis Sentinel 구성


Redis Sentinel은 Redis가 실행 중인 서버에서 구성해도 되고, 독립적으로 구성해도 된다.

Redis가 실행 중인 서버에서 구성할 시, Redis Port와 다른 Port만 사용하면 된다.

주의할 점은, Sentinel을 홀수로 구성해야 원활한 FailOver 처리가 가능하다.

 

Redis + Sentinel Compose


Redis 및 Sentinel을 Docker로 실행시키기 위한 Compse 파일

version: '3.7'

services:
  redis_1:
    image: redis:6.2.3
    ports:
      - 6379
    volumes:
      - /volumes/redis_01:/data

  redis_2:
    image: redis:6.2.3
    command: redis-server --slaveof redis_1 6379
    ports:
      - 6379
    depends_on:
      - redis_1
    volumes:
      - /volumes/redis_02:/data

  redis_3:
    image: redis:6.2.3
    command: redis-server --slaveof redis_1 6379
    ports:
      - 6379
    depends_on:
      - redis_1
    volumes:
      - /volumes/redis_03:/data

  sentinel:
    build: ./sentinel/6.2.3-alpine
    depends_on:
      - redis_1
      - redis_2
      - redis_3
    environment:
      - SENTINEL_QUORUM=1
      - SENTINEL_DOWN_AFTER=5000
      - SENTINEL_FAILOVER=5000
      - MASTER_HOST=redis_1
    volumes: 
      - ./sentinel/6.2.3-alpine/sentinel_conf:/etc/redis

Sentinel 빌드를 위한 docker file

FROM redis:6.2.3-alpine

EXPOSE 26379

COPY sentinel-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/sentinel-entrypoint.sh

ENTRYPOINT ["sentinel-entrypoint.sh"]

CMD [ "redis-server", "/etc/redis/sentinel.conf", "--sentinel" ]

Sentinel 컨테이너가 실행될 때 사용될 설정 파일 생성

#!/bin/sh

mkdir -p /etc/redis

tee /etc/redis/sentinel.conf <<EOF
port 26379

dir /tmp

sentinel resolve-hostnames yes
sentinel monitor docker-cluster $MASTER_HOST 6379 $SENTINEL_QUORUM
sentinel down-after-milliseconds docker-cluster $SENTINEL_DOWN_AFTER
sentinel parallel-syncs docker-cluster 1
sentinel failover-timeout docker-cluster $SENTINEL_FAILOVER
EOF

chown redis:redis /etc/redis/sentinel.conf

exec "/usr/local/bin/docker-entrypoint.sh" "$@"

 

HAProxy


HAProxy는 소프트웨어 로드 밸런서로 L4 / L7의 기능 및 로드 밸런서를 제공한다.

앞서, Redis Sentinel을 통해 Redis Master에 장애가 발생하여 Slave가 새롭게 Master로 승격되는 FailOver기능을 적용시켰다. 하지만, Client의 경우 기존 장애가 발생한 Redis Master를 계속 참조하게 된다.

때문에 변경된 Redis Master로 Client가 다시 참조할 수 있도록 HAProxy를 구성하도록 한다.

 

HAProxy + Redis Compose


앞서 작성한 Redis + Sentinel Compose 스크립트에 HAProxy를 추가해준다.

version: '3.7'

services:
  redis_1:
    image: redis:6.2.3
    ports:
      - 6379
    volumes:
      - /volumes/redis_01:/data

  redis_2:
    image: redis:6.2.3
    command: redis-server --slaveof redis_1 6379
    ports:
      - 6379
    depends_on:
      - redis_1
    volumes:
      - /volumes/redis_02:/data

  redis_3:
    image: redis:6.2.3
    command: redis-server --slaveof redis_1 6379
    ports:
      - 6379
    depends_on:
      - redis_1
    volumes:
      - /volumes/redis_03:/data

  sentinel:
    build: ./sentinel/6.2.3-alpine
    depends_on:
      - redis_1
      - redis_2
      - redis_3
    environment:
      - SENTINEL_QUORUM=1
      - SENTINEL_DOWN_AFTER=5000
      - SENTINEL_FAILOVER=5000
      - MASTER_HOST=redis_1
    volumes: 
      - ./sentinel/6.2.3-alpine/sentinel_conf:/etc/redis

  proxy:
    build: ./haproxy/1.7
    depends_on:
      - redis_1
      - redis_2
      - redis_3
      - sentinel
    ports:
      - '9000:9000'
      - '6379:6379'
    environment:
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=password
      - REDIS_HOSTS=redis_1,redis_2,redis_3

HAProxy 빌드를 위한 Docker file

FROM haproxy:1.7

COPY haproxy-entrypoint.sh /

RUN chmod +x /haproxy-entrypoint.sh

EXPOSE 6379
EXPOSE 9000

ENTRYPOINT [ "/haproxy-entrypoint.sh" ]

CMD [ "haproxy", "-f", "/etc/haproxy/haproxy.cfg" ]

HAProxy 컨테이너가 실행될 때 사용될 설정 파일 생성

#!/bin/bash

set -ex

echo "=> Creating HAProxy Configuration Folder"
mkdir -p /etc/haproxy


echo "=> Writing HAProxy Configuration File"
tee /etc/haproxy/haproxy.cfg <<EOF
defaults
  mode tcp
  timeout connect 3s
  timeout server 6s
  timeout client 6s

listen stats
  mode http
  bind :9000
  stats enable
  stats hide-version
  stats realm Haproxy\ Statistics
  stats uri /haproxy_stats
  stats auth $ADMIN_USERNAME:$ADMIN_PASSWORD

frontend ft_redis
  mode tcp
  bind *:6379
  default_backend bk_redis

backend bk_redis
  mode tcp
  option tcplog
  option tcp-check
  #uncomment these lines if you have basic auth
  #tcp-check send AUTH\ yourpassword\r\n
  #tcp-check expect +OK
  tcp-check send PING\r\n
  tcp-check expect string +PONG
  tcp-check send info\ replication\r\n
  tcp-check expect string role:master
  tcp-check send QUIT\r\n
  tcp-check expect string +OK
EOF

echo "=> Adding Redis Nodes to Health Check"
COUNT=1

for i in $(echo $REDIS_HOSTS | sed "s/,/ /g")
do
    # call your procedure/other scripts here below
    echo "  server redis-backend-$COUNT $i:6379 maxconn 1024 check inter 1s" >> /etc/haproxy/haproxy.cfg
    COUNT=$((COUNT + 1))
done

echo "=> Starting HAProxy"
exec "/docker-entrypoint.sh" "$@"

 

'devops' 카테고리의 다른 글

Docker Swarm  (0) 2021.08.29
[Docker] Jenkins & fabric  (0) 2021.07.25
MQTT/AMQP  (0) 2021.06.18
Volatile / Lock  (0) 2021.06.17
ASP.Net Core에서 NSwag 사용하기  (0) 2021.02.14