들어가며
레디스는 Stateliss의 특성을 가지므로 휘발성이 존재한다. 잘못하면 저장해둔 데이터가 다 날아가버리는 불상사가 생길 수 있
다. 그래서 이를 방지하기 위해 master-slave 관계를 가진 서버를 추가로 미리 만들어 놓는다.
개인 프로젝트를 진행하면서 레디스 서버 장애를 대비하기 위해 Replication 방식을 도입했다. 오늘은 스프링 부트를 통해 어떻게 적용을 했고, 테스트 결과에 대해 포스팅하려고 한다.
적용 방법
docker-compose.yml
우선 master 레디스 서버 1개, replica 서버 2개를 도커로 띄웠다. 기존에는 1개의 서버만 동작했으나 총 3개로 늘어났다.
여기서 주의해야하는 부분은 slave 서버 컨테이너의 command 이다.
command: redis-server --slaveof product_redis_master 6379
해당 컨테이너가 마스터 서버(컨테이너 이름: product_redis_master, 포트: 6379)의 slave를 담당한다는 것을 이렇게 표기해주는 것이다.
RedisConfig
@ConfigurationProperties를 사용하면 외부 설정 파일(application.properties, application.yml)에 정의된 설정 값을 POJO(Plain Old Java Object) 클래스로 바인딩할 수 있다.
RedisConnectionFactory를 빈으로 등록해주는 코드에서도 master-slave 모두 설정을 추가해줘야한다.
여기서 ReadForm.REPLICA_PREFERED를 살펴보면,
Redis 클라이언트의 읽기 동작을 설정하는 옵션으로, 이를 사용하면 Redis 클라이언트는 먼저 복제 노드(Replica)에서 데이터를 읽으려 시도한다. 복제 노드에서 데이터를 읽을 수 없는 경우에만 마스터 노드에서 데이터를 읽는다.
이렇게 레디스 master-slave 설정이 끝났다. 이제 Read/Write 결과를 살펴보자.
결과
Read Test
상품을 등록하면 master, slave 2개 전부 재고가 저장된다.
10개의 상품 주문 후에 다시 확인해봤을 때 모두 10개씩 감소했음을 알 수 있다.
Write Test
master에서 데이터를 추가하면 slave에도 자동으로 데이터가 추가된다.
만약 slave에 데이터를 추가하려고 하면 에러가 발생한다.
마치며
레디스 복제를 실제로 구현해보고 테스트까지 진행해보았다. 이제 마스터 서버의 데이터가 손실되어도 복제된 서버의 백업 데이터를 활용할 수 있어서 데이터 안전성을 높일 수 있다. 또한 slave 서버를 통해 읽기 요청을 할 수 있어 maste 서버에 부하를 줄일 수 있다.
사실 마스터 서버가 종료되면 슬레이브 서버가 자동으로 대체될 것으로 기대했으나 실제로는 마스터 서버가 종료되고 레디스에 접근 시도하니 500에러가 발생했다. 찾아보니 레디스의 Sentinel을 활용해야한다고 한다. 이는 모니터링을 통해 마스터, 슬레이브 상태를 지속적으로 체크하며, 마스터에 장애가 발생하면 자동으로 새로운 마스터 서버를 뽑아내어 자동 장애 조치가 가능하게 되는 것이다. 이를 적용해보려고 시도했으나 아직 문제를 해결하지 못했다. 다음 글에서는 이를 꼭 해결해서 글을 작성할 수 있도록 하겠다!!
댓글