1. Multi-AZ를 사용하지 않으려 했던 이유

  • AWS RDS의 프리티어 T2 인스턴스를 사용 중이며, Multi-AZ는 T2에서 지원되지 않습니다.
  • Multi-AZ를 사용하려면 T3 이상 인스턴스로 업그레이드해야 하는데, 이는 추가 비용이 발생합니다.
  • 비용을 절감하기 위해 Spring에서 장애 복구 및 페일오버 로직을 직접 구현하는 방법을 고민하였습니다.


2. 시도했던 해결책과 발생한 문제들

(1) 프라이머리 장애 발생 시, 레플리카를 승격하고 기존 프라이머리를 다시 레플리카로 전환하는 방법

시도한 방법

  • 프라이머리가 장애 발생하면 리드 레플리카를 프라이머리로 승격
  • 기존 프라이머리가 복구되면 다시 리드 레플리카로 강등
  • Multi-AZ 없이도 자동 복구 시스템을 구축하여 운영 가능하도록 설정

발생한 문제

  • MySQL에서는 프라이머리 강등(Demotion)을 지원하지 않음
    • 프라이머리를 다시 레플리카로 만들 수 없기 때문에 의미 없음
    • 자바 코드에서 CHANGE MASTER TO 명령을 실행하면 강등 처리가 가능하지만, AWS RDS에서는 보안 정책으로 권한 제한을 하므로 실행할 수 없음.
    • Aurora MySQL을 사용할 경우 가능하지만 Aurora MySQL 사용 자체가 비용 발생(mysql.rds_set_external_master).
  • T2 인스턴스에서는 바이너리 로그(Binary Log)가 기본적으로 비활성화되어 있어 복제 설정이 어려움
    • 바이너리 로그를 활성화하여 복제하더라도 강등 기능이 없기 때문에 프라이머리만 사용하게 되어 실질적인 해결책이 되지 않음
    • 바이너리 로그를 활성화하면 I/O 성능이 저하될 가능성이 있어, 성능 저하 문제까지 발생할 수 있음
  • 프라이머리가 복구되더라도 자동으로 다시 레플리카가 될 수 없고, 수동으로 복제 설정을 다시 해야 함

결론

프라이머리를 다시 레플리카로 강등할 수 없는 한, 복제 설정을 유지하는 것이 의미가 없음.


(2) 프라이머리 장애 발생 시, 레플리카를 승격한 후 기존 프라이머리를 방치하는 방법

시도한 방법

  • 장애 발생 시 리드 레플리카를 프라이머리로 승격하여 운영을 지속
  • 기존 프라이머리가 복구되면 더 이상 사용하지 않고 방치
  • 운영자가 AWS에 직접 접속하여 수동으로 관리

발생한 문제

  • 장애가 발생할 때마다 새로운 프라이머리가 추가되면서 기존 프라이머리가 계속 방치됨
  • 시간이 지나면 운영 비용이 증가할 가능성이 높아짐
  • 레플리카가 승격된 후에도 자동으로 읽기 전용 처리가 되지 않으므로, 기존과 동일한 복제 구조를 유지하기 어려움

결론

기존 프라이머리를 방치하는 방식은 운영 부담이 크고, 시간이 지나면서 비용이 증가할 가능성이 높음.


(3) HikariCP를 활용한 장애 감지 및 엔드포인트 변경 방식

시도한 방법

  • HikariCP의 커넥션 풀링 기능을 활용하여 DB 상태를 감지
  • 프라이머리가 장애 발생하면 레플리카의 엔드포인트를 찾아 자동으로 변경

발생한 문제

  • 프라이머리 주소를 찾는 동안 쓰기 요청이 발생하면 데이터 불일치 가능성 존재
    • 새로운 프라이머리를 찾는 동안 기존 장애 난 프라이머리로 일부 트랜잭션이 전송될 수 있음
  • AWS RDS에서는 승격된 DB의 엔드포인트가 변경되지 않음
    • 예를 들어, replica-xxx라는 엔드포인트가 그대로 남아 있어 일관성이 떨어짐
  • T2 인스턴스에서는 프라이머리와 리드 레플리카를 재구성하는 과정에서 수동 설정이 필요함

결론

HikariCP를 활용하더라도 운영 환경에서 일관성을 유지하기 어려움.


(4) 상태 관리를 위해 Redis 등 외부 스토리지를 활용하는 방법

시도한 방법

  • Redis를 활용하여 현재 DB 상태(프라이머리, 레플리카 여부)를 저장
  • 애플리케이션이 매 요청마다 Redis를 조회하여 현재의 프라이머리를 판단

발생한 문제

  • 복잡도가 증가하며, Redis/Spring/MySQL 간 상태 동기화 관리 부담이 큼
  • 장애 발생 시 Redis의 상태도 신뢰할 수 없는 경우 발생 가능
    • 예를 들어, Redis 장애 시 DB 상태를 확인할 방법이 없음

결론

운영 부담이 증가하며, Redis와 같은 추가적인 방법을 활용해야 하므로 Multi-AZ를 사용하는 것보다 복잡도가 증가.


3. 최종 정리

  • MySQL 자체적으로 프라이머리 강등이 불가능하고, AWS RDS에서는 관련 명령어 실행도 제한되므로, Multi-AZ 없이 장애 복구 자동화를 구현하는 것은 현실적으로 어렵습니다.
  • 비용을 절감하기 위해 직접 구현하려 했지만, 운영 부담과 데이터 일관성을 유지하는 데 한계가 많았습니다.

결론적으로, Spring에서 장애 복구를 직접 처리하려는 접근 방식은 운영 부담이 크며, Multi-AZ가 가장 실용적인 해결책이라고 판단하였습니다.