본문 바로가기

리눅스

우분투 24.04에서 Redis 클러스터를 구성하고 HAProxy + Keepalived로 고가용성을 확보하는 방법

728x90
반응형

우분투 24.04에서 Redis 클러스터를 구성하고 HAProxy + Keepalived로 고가용성을 확보하는 방법

서버 구성 개요

서버 IP 주소 Redis 인스턴스 역할
VIP 192.168.0.100 - 클라이언트 접속용
node1 192.168.0.101 6381, 6382 Redis + HAProxy + Keepalived
node2 192.168.0.102 6381, 6382 Redis + HAProxy + Keepalived
node3 192.168.0.103 6381, 6382 Redis + HAProxy + Keepalived

필요 패키지 설치

sudo apt update
sudo apt install -y curl gnupg lsb-release

커널 튜닝(Redis 성능 최적화)

Swap 비활성화

sudo swapoff -a

(또는)

sudo sed -i.bak '/swap/s/^/#/' /etc/fstab

파일 디스크립터 증가

echo "redis soft nofile 65535" | sudo tee -a /etc/security/limits.conf
echo "redis hard nofile 65535" | sudo tee -a /etc/security/limits.conf

(또는)

cat <<EOF | sudo tee -a /etc/security/limits.conf > /dev/null

# Add parameter for WebServer
*               soft    nofile          65535
*               hard    nofile          65535
*               soft    nproc           unlimited
*               hard    nproc           unlimited
EOF

TCP 커널 파라미터

cat <<'EOF' | sudo tee -a /etc/sysctl.conf > /dev/null

### Redis 커널 파라미터
net.ipv4.tcp_max_syn_backlog = 8192

### HAProxy 커널 파라미터
net.ipv4.ip_local_port_range = 1024 65535

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15

### Keepalived 커널 파라미터
net.ipv4.ip_nonlocal_bind = 1

net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
EOF

sudo sysctl -p

TCP backlog 설정

echo "net.core.somaxconn = 65535" | sudo tee -a /etc/sysctl.conf

sudo sysctl -p

Overcommit Memory 설정

echo "vm.overcommit_memory=1" | sudo tee -a /etc/sysctl.conf

sudo sysctl -p

Transparent Huge Pages(THP) 비활성화

echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

(또는) rc.local 활성화

- 변군이글루 블로그 : 우분투 24.04에서 rc.local을 활성화하는 방법

cat <<EOF | sudo tee /etc/rc.local > /dev/null
#!/bin/bash

# Transparent Huge Pages 비활성화
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

exit 0
EOF
sudo chmod +x /etc/rc.local
cat <<EOF | sudo tee -a /lib/systemd/system/rc-local.service > /dev/null

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now rc-local.service

Redis 설치 및 클러스터 구성

Redis 설치

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update
sudo apt install -y redis-server
redis-server --version
Redis server v=8.2.3 sha=00000000:1 malloc=jemalloc-5.3.0 bits=64 build=8ef393086911f0f6
sudo systemctl disable --now redis-server

Redis 설정

sudo mkdir -pv /var/lib/redis/{6381,6382}
sudo chown redis:redis /var/lib/redis/6381
sudo chown redis:redis /var/lib/redis/6382

port 6381

sudo vim /etc/redis/redis6381.conf
# 네트워크 설정
bind 0.0.0.0
port 6381
daemonize yes
protected-mode no

# 보안 설정
requirepass yourStrongPassword
masterauth yourStrongPassword

# 파일 경로
dir /var/lib/redis/6381
pidfile /var/run/redis6381.pid
logfile "/var/log/redis/redis6381.log"

# 클러스터 설정
cluster-enabled yes
cluster-config-file nodes6381.conf
cluster-node-timeout 3000
더보기

---

cat <<'EOF' | sudo tee /etc/redis/redis6381.conf > /dev/null
# 네트워크 설정
bind 0.0.0.0
port 6381
daemonize yes
protected-mode no

# 보안 설정
requirepass yourStrongPassword
masterauth yourStrongPassword

# 파일 경로
dir /var/lib/redis/6381
pidfile /var/run/redis6381.pid
logfile "/var/log/redis/redis6381.log"

# 클러스터 설정
cluster-enabled yes
cluster-config-file nodes6381.conf
cluster-node-timeout 3000

# 지속성 (Persistence)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000

# 메모리 및 퍼포먼스
maxmemory-policy allkeys-lru
tcp-keepalive 60
timeout 0
tcp-backlog 511
hz 10

# 로그 레벨
loglevel notice

# 백그라운드 저장 실패 시 쓰기 중단 방지 (운영 환경 권장)
stop-writes-on-bgsave-error no

# RDB / AOF 병행 사용 시 안전 모드
rdbcompression yes
rdbchecksum yes
aof-use-rdb-preamble yes

# 기타
supervised no
EOF

---

port 6382

sudo vim /etc/redis/redis6382.conf
# 네트워크 설정
bind 0.0.0.0
port 6382
daemonize yes
protected-mode no

# 보안 설정
requirepass yourStrongPassword
masterauth yourStrongPassword

# 파일 경로
dir /var/lib/redis/6382
pidfile /var/run/redis6382.pid
logfile "/var/log/redis/redis6382.log"

# 클러스터 설정
cluster-enabled yes
cluster-config-file nodes6382.conf
cluster-node-timeout 3000
더보기

---

cat <<'EOF' | sudo tee /etc/redis/redis6382.conf > /dev/null
# 네트워크 설정
bind 0.0.0.0
port 6382
daemonize yes
protected-mode no

# 보안 설정
requirepass yourStrongPassword
masterauth yourStrongPassword

# 파일 경로
dir /var/lib/redis/6382
pidfile /var/run/redis6382.pid
logfile "/var/log/redis/redis6382.log"

# 클러스터 설정
cluster-enabled yes
cluster-config-file nodes6382.conf
cluster-node-timeout 3000

# 지속성 (Persistence)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000

# 메모리 및 퍼포먼스
maxmemory-policy allkeys-lru
tcp-keepalive 60
timeout 0
tcp-backlog 511
hz 10

# 로그 레벨
loglevel notice

# 백그라운드 저장 실패 시 쓰기 중단 방지 (운영 환경 권장)
stop-writes-on-bgsave-error no

# RDB / AOF 병행 사용 시 안전 모드
rdbcompression yes
rdbchecksum yes
aof-use-rdb-preamble yes

# 기타
supervised no
EOF

---

인스턴스별 디렉토리 생성 후 실행

redis-server /etc/redis/redis6381.conf
redis-server /etc/redis/redis6382.conf

인스턴스별 종료

redis-cli -p 6381 -a yourStrongPassword SHUTDOWN
redis-cli -p 6382 -a yourStrongPassword SHUTDOWN

redis-server 프로세스 종료

ps -ef | grep redis-server | grep -v grep | awk '{print $2}' | xargs sudo kill

Redis 비밀번호 저장

환경 변수(REDISCLI_AUTH) 사용(권장)

export REDISCLI_AUTH=yourStrongPassword
unset REDISCLI_AUTH

.redisclirc 파일 사용

  • root 계정 환경에서는 redis-cli가 이 파일을 무시하는 경우가 많음
echo "auth yourStrongPassword" > ~/.redisclirc
chmod 600 ~/.redisclirc

클러스터 생성

redis-cli --cluster create \
  192.168.0.101:6381 192.168.0.102:6381 192.168.0.103:6381 \
  192.168.0.101:6382 192.168.0.102:6382 192.168.0.103:6382 \
  --cluster-replicas 1
더보기

---

redis-cli --cluster create \
  192.168.0.101:6381 192.168.0.102:6381 192.168.0.103:6381 \
  192.168.0.101:6382 192.168.0.102:6382 192.168.0.103:6382 \
  --cluster-replicas 1 \
  -a yourStrongPassword

---

  • 마스터 3개, 슬레이브 3개 자동 배치

클러스터 상태 확인

redis-cli -c -p 6381 cluster info

노드 정보 확인

redis-cli -c -p 6381 cluster nodes

슬롯 분포 확인

redis-cli -c -p 6381 cluster slots
728x90

3. HAProxy 설치 및 설정

HAProxy 설치

sudo apt-get install -y --no-install-recommends software-properties-common
sudo add-apt-repository -y ppa:vbernat/haproxy-3.2
sudo apt install -y haproxy
haproxy -v
HAProxy version 3.2.7-1ppa1~noble 2025/10/25 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2030.
Known bugs: http://www.haproxy.org/bugs/bugs-3.2.7.html
Running on: Linux 6.8.0-87-generic #88-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 09:28:41 UTC 2025 x86_64
sudo systemctl enable --now haproxy

HAProxy 설정

sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg_$(date '+%Y%m%d-%H%M%S')
sudo vim /etc/haproxy/haproxy.cfg
# ===============================
# Redis Frontend
# ===============================
frontend redis_front
    bind *:6379
    mode tcp
    default_backend redis_cluster

# ===============================
# Redis Cluster Backend
# ===============================
backend redis_cluster
    mode tcp
    balance roundrobin
    option tcp-check

    # Redis 인증 포함 헬스 체크(정확한 순서와 구문)
    tcp-check connect
    tcp-check send AUTH\ yourStrongPassword\r\n\r\n
    tcp-check expect string OK
    tcp-check send PING\r\n\r\n
    tcp-check expect string PONG
    tcp-check send QUIT\r\n\r\n
    tcp-check expect string OK

    # Redis 노드 목록
    server node1-6381 192.168.0.101:6381 check inter 2s rise 2 fall 3
    server node1-6382 192.168.0.101:6382 check inter 2s rise 2 fall 3
    server node2-6381 192.168.0.102:6381 check inter 2s rise 2 fall 3
    server node2-6382 192.168.0.102:6382 check inter 2s rise 2 fall 3
    server node3-6381 192.168.0.103:6381 check inter 2s rise 2 fall 3
    server node3-6382 192.168.0.103:6382 check inter 2s rise 2 fall 3
더보기

---

cat <<'EOF' | sudo tee /etc/haproxy/haproxy.cfg > /dev/null
# ===============================
# HAProxy for Redis Cluster (Optimized)
# ===============================
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    maxconn 4096
    daemon
    user haproxy
    group haproxy

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    option  redispatch
    retries 3
    timeout connect 4s
    timeout server  30s
    timeout client  30s
    timeout check   10s    
    maxconn 2000

# ===============================
# Redis Frontend
# ===============================
frontend redis_front
    bind *:6379
    mode tcp
    default_backend redis_cluster

# ===============================
# Redis Cluster Backend
# ===============================
backend redis_cluster
    mode tcp
    balance roundrobin
    option tcp-check

    # Redis 인증 포함 헬스 체크(정확한 순서와 구문)
    tcp-check connect
    tcp-check send AUTH\ yourStrongPassword\r\n\r\n
    tcp-check expect string OK
    tcp-check send PING\r\n\r\n
    tcp-check expect string PONG
    tcp-check send QUIT\r\n\r\n
    tcp-check expect string OK

    # Redis 노드 목록
    server node1-6381 192.168.0.101:6381 check inter 2s rise 2 fall 3
    server node1-6382 192.168.0.101:6382 check inter 2s rise 2 fall 3
    server node2-6381 192.168.0.102:6381 check inter 2s rise 2 fall 3
    server node2-6382 192.168.0.102:6382 check inter 2s rise 2 fall 3
    server node3-6381 192.168.0.103:6381 check inter 2s rise 2 fall 3
    server node3-6382 192.168.0.103:6382 check inter 2s rise 2 fall 3

# ===============================
# Stats Dashboard (optional)
# ===============================
listen stats
    bind *:9999
    mode http
    stats enable
    stats hide-version
    stats uri /haproxy?stats
    stats refresh 10s
    stats auth admin:admin
    stats admin if TRUE
EOF

---

  • 클라이언트는 VIP:6379로 접속
  • HAProxy가 정상 Redis 노드로 트래픽 전달

문법 검사(설정 테스트)

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

rsyslog에서 로그 파일로 분리

cat <<'EOF' | sudo tee /etc/rsyslog.d/49-haproxy.conf > /dev/null
# HAProxy 로그 설정
if ($programname == 'haproxy') then /var/log/haproxy.log
& stop
EOF

rsyslog 재시작

sudo systemctl restart rsyslog

HAProxy 재시작

sudo systemctl restart haproxy

Redis Cluster 모드(192.168.0.101 6381 인스턴스)로 PING 체크

redis-cli -h 192.168.0.101 -p 6381 ping

HAProxy(Port 6379)로 PING 체크

redis-cli -h 192.168.0.101 -p 6379 ping

4. Keepalived 설치 및 VIP 구성

Keepalived 설치

sudo apt install -y keepalived
sudo cp /etc/keepalived/keepalived.conf.sample /etc/keepalived/keepalived.conf

Keepalived 설정

VIP 헬스체크 스크립트

cat <<'EOF' | sudo tee /usr/local/bin/chk_haproxy.sh > /dev/null
#!/bin/bash
if pidof haproxy > /dev/null; then
  exit 0
else
  exit 1
fi
EOF
chmod +x /usr/local/bin/chk_haproxy.sh

MASTER 설정

sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_$(date '+%Y%m%d-%H%M%S')
vim /etc/keepalived/keepalived.conf
더보기

---

cat <<'EOF' | sudo tee /etc/keepalived/keepalived.conf > /dev/null
global_defs {
    notification_email {
        admin@example.com
    }
    notification_email_from admin@example.com
    router_id LVS_DEVEL
    enable_script_security
    script_user root
}

vrrp_script chk_haproxy {
    script "/usr/local/bin/chk_haproxy.sh"
    interval 2
    weight 2
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.100
    }
    track_script {
        chk_haproxy
    }
}
EOF

---

vrrp_script chk_haproxy {
    script "/usr/bin/chk_haproxy.sh"
    interval 2
    weight 2
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    interface eth0
    state MASTER
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass redis_pass
    }
    virtual_ipaddress {
        192.168.0.100
    }
    track_script {
        chk_haproxy
    }
}
  • MASTER/BACKUP 설정은 서버마다 priority 조정
    • MASTER 101(높은 값일수록 더 높은 우선순위를 가짐)
    • BACKUP_1 100
    • BACKUP_2 99

BACKUP 설정

sudo sed -i.bak \
  -e 's/state MASTER/state BACKUP/' \
  -e 's/priority 101/priority 100/' \
  /etc/keepalived/keepalived.conf
sudo sed -i.bak \
  -e 's/state MASTER/state BACKUP/' \
  -e 's/priority 101/priority 99/' \
  /etc/keepalived/keepalived.conf
  • VIP는 HAProxy가 설치된 서버에만 존재

문법 검사(설정 테스트)

sudo keepalived -t

또는

sudo keepalived -t -f /etc/keepalived/keepalived.conf

Keepalived 재시작

sudo systemctl enable --now keepalived

VIP 확인

ip addr show enp0s3
$ ip addr show enp0s3 | grep "192.168.0.100"
    inet 192.168.0.100/32 scope global enp0s3

실제 동작 테스트

nc -zv -w 3 192.168.0.100 6379
redis-cli -h 192.168.0.100 -p 6379 ping
redis-cli -h 192.168.0.100 -p 6379 cluster nodes
redis-cli -h 192.168.0.100 -p 6379 -c set foo bar
redis-cli -h 192.168.0.100 -p 6379 -c get foo

 

참고URL

- 변군이글루 블로그 : Redis 제품 보안 업데이트 권고

- 변군이글루 블로그 : 우분투 24.04에서 최신 버전의 HAProxy를 설치하는 방법

- 변군이글루 블로그 : 우분투에서 Keepalived를 사용하여 고가용성(High Availability, HA)을 구성하는 방법

- Debian/Ubuntu HAProxy packages : https://haproxy.debian.net

 

728x90
반응형