부제 : Redis Master Node -> Slave Node 변경됨 해결
데이터 캐싱을 위하여 인메모리 기반인 Redis 저장소를 선택하였다.
배포를 위해 클라우드 서버에 Docker로 Redis를 띄우고 문제가 발생했다. (메모리 문제로 redis:alpine 사용, 큰 차이 X)
개발 단계에선 로컬 Redis를 사용하였기 때문에 문제가 없었다..
문제 상황
실제 배포한지 1~2주 때부터 해당 에러가 발생함
error in execution; nested exception is io.lettuce.core.redisreadonlyexception: readonly you can't write against a read only replica.
해당 오류는 Lettuce Redis 클라이언트가 읽기 전용 레플리카에 쓰기 작업을 시도하여 발생하는 문제
근데 분명 단일 노드로 Redis를 구성했었는데..?
해결 시도
1. redis-cli 접속후 slave-read-only no 설정 (실패)
slave-read-only no
이 설정 명령어를 실행하면 당장에 작동은 되지만 slave 상태의 노드에 write 권한을 준것이기 때문에 근본적인 원인이 해결된 것은 아니다.
또한 Spring 에서 설정해준 TTL(Time To Live) 도 적용되지 않았다.
-> 해당 이슈는 Master 와 전체 동기화(Full Resynchronization) 시 입력된 데이터는 모두 날아가기 때문
2. redis-cli 접속후 slaveof no one 설정 (실패)
slaveof no one
위의 명령어는 Slave 상태인 노드를 Master 노드로 전환해주는 설정이다.
해당 명령어를 실행한 직후에 cli 에서 role 을 입력해 확인해보면 Master 노드로 바뀐 상태를 확인가능하다.
이로써 해결되는가 싶었지만... (한번에 되는 법이 없지!)
모종의 이유로 Slave 노드로 계속 변경되었다 ㅜ
연결되어있는 마스터 노드 주소를 확인하니 터무니 없는 주소가 나와 당황스러웠다.
변경되는 이유 추측
- redis.conf 설정 파일 문제
- Docker network 문제
3. redis.conf 설정 파일 직접 설정 (실패)
redis 설정 파일에 --slaveof, --replicaof 같이 명시적으로 해당 구문이 있으면 변경될 수도 있다 한다.
전까진 따로 설정 파일을 주입해주지 않고 default 로 사용했기 때문에 redis.conf 파일을 직접 작성하였다.
# Redis 설정 파일 (redis.conf)
# daemonize yes로 하면 구동되지 않음
daemonize no
# protected-mode no로 설정
protected-mode no
# 포트 설정
port 6379
# 바인딩 주소 설정
bind 0.0.0.0
해당 파일을 보면 --slaveof, --replicaof 구문이 존재하지 않는다.
도커 컨테이너 실행 명령
docker run -d -p 6379:6379 --name [컨테이너 이름] -v /etc/redis/redis.conf:/etc/redis/redis.conf redis:alpine redis-server /etc/redis/redis.conf
이또한 Slave 로 바뀌는 현상 발생 !!!
4. 독립된 docker network 구성 (실패)
계속되는 오류 현상에 다른 방식으로 접근하게 된다.
도커 컨테이너 run 명렁을 아무 옵션없이 실행하면 기본적으로 docker bridge 네트워크에 연결된다.
필자의 서버엔 기존의 다른 redis server 가 존재했기 때문에 독립된 환경에서 구성해보기로 하였다.
Docker Nework 생성
docker network create redis-net
도커 컨테이너 실행 명령(add docker network)
docker run -d -p 6379:6379 --name [컨테이너 이름] --network redis-net -v /etc/redis/redis2.conf:/etc/redis/redis.conf redis:alpine redis-server /etc/redis/redis.conf
그렇다 이또한 실패 !
5. docker-compose 를 통한 Redis Master-Slave 구축 (성공)
Master-Slave 구조를 구성했다는 것은 기존의 고집하던 단일 Master 노드를 버렸다는 것.
Redis Master-Slave 구조란 ?
- 하나의 master에 다수의 slave가 붙을 수 있음
- Master는 Read-Write mode로 동작
- Slave는 Read-Only mode로 동작
바뀐 구조
docker-compose.yml 파일 구성
version: "3"
networks:
default:
external:
name: redis-net #docker network 설정
services:
redis:
container_name: [master node 이름]
image: redis:alpine
ports:
- [master node port]:6379
redis-slave-1:
container_name: [slave node1 이름]
image: redis:alpine
command: redis-server --slaveof redis 6379 #slave node 설정
ports:
- [slave node1 port]:6379
depends_on:
- redis #slave node 설정
redis-slave-2:
container_name: [slave node2 이름]
image: redis:alpine
command: redis-server --slaveof redis 6379 #slave node 설정
ports:
- [slave node2 port]:6379
depends_on:
- redis #slave node 설정
docker-compose 실행 명령어
# 여러 컨테이너를 백그라운드로 시작
docker-compose up -d
결과
Master 노드에 데이터를 넣을시 Slave 1, 2도 동기화되어 데이터가 존재한다.
Master 노드
Slave 1 노드
Slave 2 노드
1개의 Master 노드, 2개의 Slave 노드를 구성하여서 해당 문제를 해결하였다.
이번 문제를 해결하며 Redis 와 많이 친해졌다...ㅎㅎ (단일 master 노드 발상은 ^^)
추후 고가용성을 위하여 Redis Sentinel or Cluster 구축해보는 것도 좋을듯하다.
'Server & Infra' 카테고리의 다른 글
[Docker] Ubuntu에 Docker로 웹서비스 구축하기 (0) | 2023.11.29 |
---|---|
[JMeter] Apache JMeter를 이용한 간단한 성능 테스트 (1) | 2023.02.26 |