프로젝트를 진행하며 클라우드 환경에서 Redis를 사용했습니다.
이 글에서는 이 과정에서 겪었던 문제들과 해결 방법에 대해서 작성했습니다.
Redis가 갑작스럽게 종료되면 세션과 다양한 정보가 손실될 수 있습니다. 이러한 문제를 해결하기 위해 클러스터를 사용하여 고가용성(HA)를 구성하는 것이 좋다고 판단되었습니다.
세션 정보를 관리하던 Redis가 갑작스럽게 종료되어 Session 정보가 초기화된다면 어떨까요?
100만 명의 유저가 현재 접속 중이다가 모두 로그아웃이 된다고 칩시다.
그럼 서버가 복구되었을 때 100만 명이 기다렸다는 듯이 한 번에 서버에 접속하게 되고, 100만 명의 트래픽을 받을 준비가 되어 있지 않은 서버라면 2차 장애로 이어질 수도 있을 것입니다.
그래서 기존에 사용하던 단일 노드 Redis를 클러스터 모드로 변경해보자는 목표를 세웠고, Docker를 이용해서 전환 작업을 진행 했습니다.
로컬 환경과 (Ncloud) 클라우드 환경 둘 다 테스트를 하면서 진행했습니다. 클러스터 모드를 구성하는 과정에서부터 문제가 발생했습니다.
Docker 내부에서 Redis 클러스터를 브릿지로 관리했습니다.
따라서 외부에서 접속하기 위해서는 public ip를 이용해서 각 노드 별로 주어진 포트를 이용해서 접속을 해야 했습니다.
클라우드 VM 내부에서는 접속이 원활하게 잘 되었습니다.
ping도 서버에서 Docker로 잘 작동했습니다.
외부/내부에서 redis-cli도 잘 작동했습니다.
그런데 Spring Boot 혹은 Redis Insight와 같은 툴에서 Redis 클러스터 클라이언트를 사용하는 곳에서는 제대로 접속이 되지 않았습니다.
Docker 브릿지 네트워크
노드 IP 설정
VM 내부/외부에서는 Redis CLI로 접속이 가능했지만, 외부에서는 Redis Insight와 같은 도구나 Spring Boot에서 접속할 수 없었습니다.
이 문제의 원인은 Redis 클러스터의 클라이언트가 접속할 때 모든 Redis의 url을 가져오는데 이때 내부적으로 사용되는 브릿지 IP를 사용하기 때문이었습니다.
이를 해결하기 위해 Redis 설정파일에 아래와 같은 옵션을 추가하여 외부 IP로 접근이 가능하도록 변경해야 합니다.
#redis.conf
cluster-announce-ip: public-ip
cluster-announce-port: port
cluster-announce-bus-port: redis-bus-port ex)17001
또한, 클러스터를 구성할 때 public IP를 사용해야 하므로, Ncloud, AWS, GCP, Azure 등의 환경에서도 해당포트의 방화벽 규칙을 추가해야 정상적으로 작동합니다.
이러한 변경 사항을 적용한 후, Redis 클러스터의 외부 접속 문제가 해결되었습니다. Spring Boot와 Redis Insight와 같은 도구에서도 정상적으로 클러스터에 접속할 수 있게 되었습니다.
결론적으로, Docker Redis 클러스터 외부 접속 트러블 슈팅을 진행하면서 다음과 같은 사항들을 확인하고 수정해야 합니다.
위의 사항들을 차례대로 확인하고 수정하면, Docker Redis 클러스터 외부 접속 문제를 해결할 수 있습니다. 이를 통해 고가용성이 보장되는 Redis 클러스터를 구축하고 관리할 수 있게 되어 프로젝트의 안정성과 성능을 높일 수 있습니다.
출처 : https://stackoverflow.com/questions/57158537/can-not-connect-springboot-to-redis-cluster-on-docker
http://redisgate.kr/redis/cluster/cluster_start.php