미션 크리티컬 애플리케이션은 고가용성을 필요로 합니다. 고가용성의 목표는 사용자에게 서비스나 자원에 대한 일관된 접근을 제공하면서 중단의 가능성을 최소화하는 것입니다. 자동 장애 조치(failover)는 고가용성을 달성하기 위해 사용되는 특정 메커니즘입니다. 이는 시스템 구성 요소(예: 서버, 네트워크, 데이터베이스)의 실패를 자동으로 감지하고 즉시 작업을 대기 중인 구성 요소로 전환하는 것을 포함하며 인간 개입 없이 이루어집니다. 이로 인해 내결함성이 향상됩니다.
MariaDB MaxScale는 고가용성을 위한 기능을 포함하는 데이터베이스 프록시입니다. 이 기사에서는 Java와 Svelte로 구현된 온라인 스토어 시뮬레이터 애플리케이션으로 어떻게 시도할 수 있는지 보여드리겠습니다.
아키텍처
다음 다이어그램은 데모 애플리케이션의 아키텍처를 보여줍니다:
A web application developed with JavaScript and the Svelte framework makes HTTP requests to a Java backend. The backend answers with server-sent events that the frontend uses to update the user interface on the browser.
백엔드는 스프링 부트로 구현되어 MariaDB 데이터베이스 클러스터에 R2DBC(반응형)를 사용하여 연결됩니다. 백엔드 로직은 간단히 말해 온라인 스토어 데이터베이스에 대한 읽기와 쓰기를 시뮬레이션합니다. 시뮬레이션은 매개변수화되어 있으며 사용자는 다음을 조정할 수 있습니다:
- 분당 제품 방문 횟수: 데이터베이스에 대한 분당 읽기 횟수.
- 분당 주문 수: 데이터베이스에 대한 분당 쓰기 횟수.
- 상품 당 주문량: 쓰기 확장.
- 밀리초 단위 타임아웃: 데이터베이스에 요청이 실패로 간주되기까지 몇 초.
데이터베이스 클러스터는 데이터베이스 프록시인 MaxScale를 통해 앞단에서 관리됩니다. 이 프록시는 클러스터를 Java 백엔드에 단일 논리적 데이터베이스처럼 보이게 합니다. MaxScale는 읽기/쓰기 분리를 수행하여(쓰기는 기본 MariaDB 서버로, 읽기는 복제본으로 전송) 그리고 구성 가능한 알고리즘을 사용하여 복제본 서버 간에 읽기 부하를 균등하게 분산합니다. 데이터는 자동으로 복제되어 기본 서버에서 복제 데이터베이스 서버로 전송됩니다.
Docker 이미지 소스에서 빌드
I have prepared custom Docker images for every component in the simulator. You can either build the images from the source (optional) or use the already built and published images from Docker Hub. If you decide to build the images yourself, you can find the source code on GitHub:
- MariaDB 배포: MaxScale를 통한 복제 MariaDB 토폴로지를 쉽게 배포할 수 있는 사용자 지정 이미지입니다. 프로덕션에서 사용하지 마세요! 이 이미지들은 데모 애플리케이션에만 적합합니다. 프로덕션 배포를 위해 공식 MariaDB Docker 이미지를 사용하세요.
- 백엔드 애플리케이션: 데이터베이스 클러스터에 연결하는 백엔드 애플리케이션입니다.
- 프론트엔드 애플리케이션: 백엔드에 시뮬레이션 구성 요청을 보내고 시뮬레이션 결과를 표시하기 위해 이벤트를 받는 프론트엔드 애플리케이션입니다.
각 저장소에는 사용자 정의 Docker 이미지를 빌드하는 데 사용할 수 있는 Dockerfiles가 있습니다. 예를 들어, 백엔드 애플리케이션 이미지를 빌드하려면 다음을 실행하세요:
docker build --tag alejandrodu/online-store-simulator-java-backend .
시뮬레이션 실행
모든 서비스는 다음 Docker Compose 파일(docker-compose.yml
)을 사용하여 시작할 수 있습니다:
version: "3.9"
services:
server-1:
container_name: server-1
image: alejandrodu/mariadb
ports:
- "3306:3306"
environment:
- MARIADB_CREATE_DATABASE=demo
- MARIADB_CREATE_USER=user:Password123!
- MARIADB_CREATE_REPLICATION_USER=replication_user:ReplicationPassword123!
- MARIADB_CREATE_MAXSCALE_USER=maxscale_user:MaxScalePassword123!
server-2:
container_name: server-2
image: alejandrodu/mariadb
ports:
- "3307:3306"
environment:
- MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306
server-3:
container_name: server-3
image: alejandrodu/mariadb
ports:
- "3308:3306"
environment:
- MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306
maxscale:
container_name: maxscale
image: alejandrodu/mariadb-maxscale
command: --admin_host 0.0.0.0 --admin_secure_gui false
ports:
- "4000:4000"
- "8989:8989"
- "27017:27017"
environment:
- MAXSCALE_USER=maxscale_user:MaxScalePassword123!
- MARIADB_HOST_1=server-1 3306
- MARIADB_HOST_2=server-2 3306
- MARIADB_HOST_3=server-3 3306
healthcheck:
test: ["CMD", "maxctrl", "list", "servers"]
interval: 5s
timeout: 10s
retries: 5
java-backend:
container_name: java-backend
image: alejandrodu/online-store-simulator-java-backend
ports:
- "8080:8080"
environment:
- spring.r2dbc.url=r2dbc:mariadb://maxscale:4000/demo
- spring.r2dbc.username=user
- spring.r2dbc.password=Password123!
- spring.liquibase.url=jdbc:mariadb://maxscale:4000/demo
- spring.liquibase.user=user
- spring.liquibase.password=Password123!
depends_on:
maxscale:
condition: service_healthy
svelte-frontend:
container_name: svelte-fronted
image: alejandrodu/online-store-simulator-svelte-frontend
ports:
- "5173:80"
environment:
- BACKEND_URL=http://java-backend:8080
Docker Compose 파일이 있는 디렉토리로 이동하여 다음과 같이 따로 서비스를 시작하세요:
docker compose up -d
MaxScale 구성
시뮬레이션을 시작하기 전에 트랜잭션 재생을 위한 MaxScale를 구성하세요. 또한 시뮬레이션을 더 흥미롭게 만들기 위해 타임아웃을 조정하세요.
http://localhost:8989/로 이동하여 UI에 로그인하세요:
- 사용자 이름:
admin
- 비밀번호:
mariadb
MariaDB 클러스터 상태를 보여주는 대시보드가 나타납니다.

주 서버(server-1)와 두 개의 복제본(server-2 및 server-3)이 있습니다. 복제는 server-1(주)에서 server-2 및 server-3(복제본)으로 이미 구성되어 있습니다. 모든 서버가 실행 중이어야 합니다.
mdb_monitor를 클릭한 다음 연필 아이콘을 클릭하여 매개변수 편집을 활성화하세요. 다음 매개변수를 설정하세요:
auto_failover
(true
): 이 설정은 자동 장애 조치(failover)를 활성화합니다. MariaDB 서버가 다운되면 MaxScale이 복제본 서버를 선택하고 새 주 서버로 재구성하여 쓰기 작업을 계속할 수 있게 합니다.auto_rejoin
(true
): 이 설정은 복구된 서버의 자동 재가입을 활성화합니다. 실패한 서버가 다시 올라오면 MaxScale이 이를 감지하고 사용 가능한 복제본 서버로 구성합니다.failcount
(1
): 서버가 다운되어 장애 조치(failover) 프로세스를 활성화하기 위해 필요한 모니터(서버 상태를 확인하는 MaxScale의 구성 요소) 반복 횟수를 설정합니다. 이 값을1
로 설정하여 실패 후 즉시 장애 조치(failover)가 시작되도록 합니다.backend_connect_timeout
(1000
): 모니터 연결에 대한 연결 타임아웃입니다. 이 데모를 위해 낮은 값(1초)을 설정하여 장애 조치(failover)를 빠르게 활성화합니다.backend_read_timeout
(1000
): 모니터링 연결에 대한 읽기 타임아웃.backend_write_timeout
(1000
): 모니터링 연결에 대한 쓰기 타임아웃.master_failure_timeout
(1000
): 주 실패 타임아웃.monitor_interval
(1000
): 서버가 얼마나 자주 모니터링되는지.
경고: 이 값들은 이 데모에 적합하지만 프로덕션 환경에서는 아마도 최선이 아닐 가능성이 큽니다!
매개변수가 설정되면 편집 완료를 클릭하고 확인을 클릭하십시오.
또한 트랜잭션 재생을 활성화해야 합니다. 이는 서버에서 SQL 문이 라우팅된 직후 다운된 서버에서 실패한 비행 중인 트랜잭션을 자동으로 재실행합니다. 이는 실패 사례와 트랜잭션 재시도를 코딩할 필요가 없으므로 소프트웨어 개발자에게 유용한 기능입니다.
메인 메뉴에서 대시보드를 클릭한 다음 서버 목록에서 쿼리_라우터_서비스 링크 중 하나를 클릭합니다. 매개변수를 다음과 같이 편집하십시오.
transaction_replay
(true
): 실패한 트랜잭션의 자동 재시도를 활성화합니다.transaction_replay_retry_on_deadlock
(true
): 이전과 동일한 경우 교착 상태가 발생합니다.transaction_replay_retry_on_mismatch
(true
): 이전과 동일한 경우 체크섬 불일치가 발생합니다.
매개변수가 설정되면 편집 완료를 클릭하고 확인을 클릭하십시오.
시뮬레이션 시작
모든 설정이 완료되었으므로 시뮬레이션을 시작할 수 있습니다. http://localhost:5173/로 이동하여 다음 매개변수를 구성하십시오(이름은 자명하기를 바랍니다):
- 분당 제품 방문 횟수:
6000
- 분당 주문 수:
60
- 타임아웃(밀리초):
8000
그러나 시뮬레이션을 시작하기 전에 온라인 스토어용 제품을 생성해야 합니다. 데이터 | 제품 생성…을 클릭하세요. 기본값을 그대로 두고 생성을 클릭하십시오. 데이터베이스에 제품이 생성됨에 따라 UI가 업데이트되는 것을 볼 수 있어야 합니다.
이제 마침내 시작을 클릭하여 시뮬레이션을 시작할 수 있습니다.

서버 장애 시뮬레이션
이 시점에서 기본 서버가 쓰기(주문)을 처리하고 있습니다. 그 서버를 중지하면 어떻게 될까요? 명령 줄에서 실행하십시오:
docker stop server-1
여러 요인에 따라 시뮬레이터에서 “실망한 방문자” 또는 “놓친 기회”가 몇 가지 발생할 수 있습니다. 아니면 전혀 없을 수도 있습니다! MaxScale 덕분에 제품 방문(읽기)과 주문(쓰기)이 계속됩니다. 자동 장애 조치(failover)가 없으면 모든 것을 수동으로 재구성해야 하므로 오프라인 시간이 더 길어지고 많은 방문자와 기회를 놓치게 됩니다!
장애 서버 시작:
docker start server-1
MaxScale 대시보드 (http://localhost:8989/)로 이동하여 서버-1이 이제 정상적인 복제본인지 확인하십시오.
수동으로 전환을 수행하여 서버-1을 다시 기본 서버로 만들 수 있습니다. mdb_monitor를 클릭한 다음 MASTER 섹션에 마우스를 올리세요. 연필 아이콘을 클릭하고 서버-1을 선택하세요. 교체를 클릭하고 대시보드에서 새로운 기본 서버가 서버-1인지 다시 확인하세요.
결론
자동 장애 조치(failover)는 고가용성 시스템의 한 구성요소일 뿐입니다. MaxScale와 같은 데이터베이스 프록시를 사용하여 자동 장애 조치를 설정할 수 있지만, 로드밸런싱, 쿼리 라우팅, 트랜잭션 재시도, 토폴로지 격리 등 다른 구성요소들도 사용할 수 있습니다. 문서를 여기서 확인하세요.
Source:
https://dzone.com/articles/high-availability-and-resiliency-in-databases