카테고리 없음

단일 장애 지점 (SPOF) 문제와 해결책

딤섬뮨 2024. 2. 25. 21:46
728x90

1. 백엔드 개발에서의 SPOF

고가용성을 확보하기 위한 아키텍처 설계 (hudi.blog)

 

단일 장애 지점(Single Point Of Failure) 은 시스템이나 네트워크의 한 부분이 고장 났을 때 시스템의 가동이 멈추는 현상을 말한다. 이런 지점은 시스템의 취약점으로 작용하고 이를 해결하지 못하면 전체 시스템이 마비될 수 있다.

 

가장 흔한 예로는 데이터베이스 서버, 핵심 네트워크 스위치, 애플리케이션 서버가 하나만 존재할 때 발생한다.

이런 중요한 구성 요소가 장애를 일으키면 서비스가 정지되는 위험이있다.

 

예를 들어 모든 웹 트래픽을 단일 서버가 처리하는 경우나, 모든 데이터를 한 개의 데이터베이스 서버에 저장하는 경우가 있다. 코드 레벨에서도 발생할 수 있다. 특정 서비스나 라이브러리에 과도하게 의존하는 코드는 그 서비스나 라이브러리가 실패했을 때 전체 애플리케이션의 기능에 심각한 문제를 일으킬 수 있다.

 

해결 방안으로는 다양한 계층의 해결 방안이 있다.(네트워크 계층, 소프트웨어, 하드웨어 등등) 그중 소프트웨어를 우선적으로 알아보자

 

2.  코드 레벨  SPOF

문제 :  과도한 의존성의 문제

 특정 외부 서비스나 API에 의존할 경우, 애플리케이션의 중요 기능이 중단될 위험이 있다. 특히 결체 처리나 사용자 인증과 같은 핵심 기능을 담당하는 외부서비스에 이런 위험이 크다

 

해결 방안 

외부 서비스에 대한 타임 아웃 호출에 대한 타임 아웃 설정을 하거나, 서킷 브레이커 패턴을 사용해서 서비스 장애 시 자동으로 대체 서비스로 전환되도록 구상한다. 이는 장애 발생 시 즉시 대응할 수 있게 해 준다. 또한 한 서비스만에 만 의존하는 대신 여러 서비스 제공자를 사용함으로써 의존성을 분산시킨다.

 

2 - (1) 서킷 브레이커 패턴?

 

다른 서비스에 장애가 발생하였는데도 계속 요청을 주어 장애 복구를 힘들게 만드는 상황을 방지하고자, 

장애가 발생한 서비스를 탐지하고 요청을 보내지 않도록 차단하는 것.

즉, 실패할 수 있는 작업을 계속 시도하지 않도록 방지한다

 

만약 계속 장애가 나는 서비스를 요청하면 타임아웃만큼 대기시간이 생기고 스레드와 메모리 등 CPU의 자원을 점유하여 결국 시스템 리소스를 부족하게 만들어 장애를 유발할 수 있다.

 

Java 진영의 서킷 브레이커 라이브러리로는 Resilence4J라는 것이 대표적이다.

 

3. 단일 데이터베이스의 SPOF

문제 : 하나의 데이터베이스에 의존하게 되면 서버 장애 시 데이터 처리가 중단되고 전체 시스템에 영향을 준다.

 

해결 방안

여러 해결책이 있는데 대표적으로 레플리케이션, 샤딩 , 클러스터링이 있다.

 

3 - (1) 데이터베이스 레플리케이션?

데이터를 여러 서버에 복제하는 것이다. 이를 통해 만약 주 데이터 서버에 문제가 발생해도 복제된 다른 서버에서 동일한 데이터로 서비스를 계속 제공할 수 있다. 이는 시스템의 가용성을 크게 향상한다.

 

기준이 되는 서버를 마스터 서버라고 하고, 마스터 서버와 동일한 내용을 갖는 서버를 리플리카(슬레이브) 라고 한다.

[동작]

1. 마스터 노드에 쓰기 트랜잭션이 실행되고

2. 마스터 노드는 데이터를 저장하고, 트랜잭션에 대한 로그를 파일에 기록한다.

3. 리플리카 노드의 IO 스레드는 마스터 노드의 로그 파일을 파일(Reply Log)에 복사한다

4. 리플리카 노드의 SQL 스레드는 파일을 한 줄씩 읽으며 데이터를 저장한다.

 

 

[백업이랑 차이가 뭔데?]

 

백업은 주기적인 시간으로 이루어지기에 장애가 발생한 시간과 마지막 백업 시간의 사이에 생긴 데이터를 소실할 수 있다.

 

마스터 서버가 죽는다면, 리플리카 서버를 승격시키면 되기에 SPOF가 나도 대처할 수 있다.

더 나아가 리플리카 서버와 마스터 서버 별로 특정 읽기 / 외의 작업을 나눠서 처리하면 데이터베이스의  부하를 더 줄일 수 있다.

 

하지만, 노드들 간의 데이터 동기화가 보장되지 않아 일관성이 없을 수도 있다.

 

3 - (2) 샤딩?

대용량 데이터 베이스를 더 작은 관리하기 쉬운 파티션(여러 개의 DB서버)으로 나누는 것이다.

각 파티션에서 데이터 처리 부하를 분산시키면 전체 시스템의 성능과 확장성이 향상된다.

 

어떻게 나뉘는지가 중요한 포인트이다.

 

모듈러 샤딩 : PK를 모듈러 연산한 결과로 DB 라우팅

레인지 샤딩 : PK의 범위 기준으로 DB라우팅

디렉터리 샤딩 : 별도의 조회 테이블(해당 PK가 어디 저장됨)을 사용해서 샤딩

 

근데, 이건 나뉜 각 DB 서버에 대한 SPOF는 여전히 존재해 보인다.

 

3 - (3) 클러스터링?

클러스터링은 여러 개의 DB를 수평적인 구조로 구축하는 방식이다.

주로 해당 방안을 사용한다.

1. 1개의 노드에 쓰기 트랜잭션 수행, Commit 수행

2. 디스크에 옮기기 전에 다른 노드로 데이터 복제 요청

3. 다른 노드에서 수락했다는 신호를 보내고 디스크에 쓰기를 시작

4. 다른 노드로부터 신호를 받으면 실제 디스크에 저장

 

서로 노드 간의 동기화가 되었다는 신호를 주고받아 일관성 있는 데이터를 저장할 수 있다. 하지만 이 과정 때문에 쓰기 성능은 느려짐. 하나의 서버가 죽었다면, 다른 서버를 활성화시켜 문제에 대응할 수 있지만, 하나의 서버는 이슈가 생길 때까지 아무 일도 하지 않아서 비용적인 측면에서 낭비일 수도 있다.

 

 

4. 서버 SPOF

문제 : 하나의 서버에 의존하게 되면 서버 장애 시 서비스 제공이 어렵다.

 

해결 방법 

 

 

Web Server

서버 1대가 아닌, 단순하게 물리적 서버를 여러 개 띄워서 1번 서버에서 장애 발생 시, 2번 서버가 처리를 진행하는 등 로드밸런서를 함께 이용하여 서버에 향하는 요청을 관리해 준다

WAS

개발자가 작성한 코드에 의해 애플리케이션에 문제가 발생할 수 있다(Out Of Memory) 이럴 땐 똑같이 애플리케이션을 n개 띄워서 부하를 분산시킨다. ex.Nginx에서는 로드 밸런싱을 지원한다.

 

 

 

 

[출처]

고가용성을 확보하기 위한 아키텍처 설계 (hudi.blog)

'replication'의 검색결과 - MangKyu's Diary (tistory.com)

[디자인패턴] 서킷 브레이커 패턴(Circuit Breaker Pattern)의 필요성 및 동작 원리 - MangKyu's Diary (tistory.com)

단일 장애 지점(SPOF)이란? — 개발자의 서랍 (tistory.com)

728x90