대규모 시스템 도입
- 인터넷에서는 수백만 명의 사용자가 동시에 접속하고 상호작용할 수 있는 시스템을 구축해야 하는 상황이 자주 발생한다.
- 이러한 시스템은 단순히 많은 사용자를 처리하는 것뿐만 아니라, 안정성과 신뢰성을 유지하면서 고성능을 제공해야 한다.
- 기능에 대한 테스트를 통해 애플리케이션이 정상적으로 동작하는것을 확인하는 것은 당연한 것이다.
- 성능 테스트를 통해 내가 만든 애플리케이션의 성능을 측정하여 애플리케이션이 실제 환경에서 어떻게 동작하는지 미리 검증하고, 신뢰성 있는 시스템을 구축해야 한다.
동시 접속자와 초당 요청량(TPS)
시스템을 사용할 사용자 수를 파악하는 것이 중요하다. 시스템 모니터링을 통해 하루에 몇 명의 사용자가 접속하는지 알 수 있다.
그러나 단순히 하루 접속량을 파악하는 것만으로는 충분하지 않고, 동시 접속자 수를 알아야 한다.
TPS (TPS, Transactions Per Second)
TPS란?
TPS (Transactions Per Second)는 초당 처리되는 트랜잭션의 수를 말한다.
TPS는 시스템이 얼마나 많은 요청을 동시에 처리할 수 있는지를 나타내며, 시스템의 처리 능력을 가늠할 수 있게 해준다.
시스템은 초당 요청량(TPS)을 견딜 수 있어야 한다. 이를 위해서는 초당 접속자 요청량이 가장 많은 시간대를 파악해야 한다.
요청량이 가장 많은 시간대에 초당 요청량이 1000건이라면, 시스템이 견딜 수 있는 최대 부하는 초당 1500건 정도로 설계하는 것이 여유로울 것이다. 이로 인해 예기치 않은 트래픽 증가로 인한 오류를 막을 수 있다.
요청 종류에 따른 개발
데이터 제공 및 저장에서 가장 많은 시간을 소모하는 부분은 DB에서 데이터를 조회하거나 쓰는 것이다.
이에 따라, 데이터의 조회가 빈번한지, 쓰기 및 업데이트가 빈번한지 파악하고 알맞은 전략을 수립하는 것이 중요할 것이다.
읽기 요청 최적화
캐시 사용
모든 사용자가 같은 데이터를 요청하는 경우(개인화된 데이터가 아님), DB의 데이터를 캐시에 저장하면 요청에 대한 응답 속도를 개선할 수 있다.
또한, DB의 부하를 줄일 수 있다. 이는 네트워크 지연을 최소화하고 사용자 경험을 향상시키는 길로 이어진다.
하지만 캐시를 사용한다고 해서 무작정 좋은 것만은 아니다.
캐시의 데이터와 DB의 데이터가 일치하지 않는 경우, 데이터 일관성 문제가 발생할 수 있다.
이에 따라 적절한 캐싱 전략을 수립하여 시스템의 효율성을 극대화해야 한다.
또한, 데이터 소실의 위험을 줄이기 위해 데이터의 유효성을 지속적으로 검증하고, 데이터가 손실되지 않았는지 확인해야 한다.
💡 레디스 캐시 사용할 때 조심해햐할 점
- 무한 로딩이 된다면 모든 요청이 막힌다.
→ 무한 로딩을 방지하기 위해 Connection Time Out 제한 시간을 반드시 설정할 것!- 레디스에 필요한 정보만을 담는 것이 아니라 객체 자체를 직렬화해서 전체를 담는다면, 용량 초과 현상이 발생할 수도 있다. 이렇게 되면 레디스가 죽어버린다.
→ 꼭 필요한 정보만 캐싱하자.
데이터베이스 인덱싱
데이터베이스 인덱싱으로 조회 성능을 크게 향상시킬 수 있다. 인덱스를 사용하면 데이터베이스는 데이터를 빠르게 검색할 수 있다. 올바르게 설계된 인덱스는 읽기 성능을 최적화하고 쿼리 응답 시간을 줄인다. 다만, 인덱스가 너무 많으면 쓰기 성능이 저하될 수 있다는 점을 염두해야 한다.
데이터베이스 샤딩
데이터베이스를 여러 샤드로 분할하여 각각의 샤드가 독립적으로 쿼리를 처리하도록 하는 방법이다. 이를 통해 단일 데이터베이스에 대한 부하를 분산시킬 수 있으며, 읽기 요청에 대한 응답 속도를 향상시킬 수 있다.
예를 들어 테이블 파티셔닝(Table Partitioning)이 있다. 이는 기본적인 형태의 샤딩으로, 데이터베이스 단에서 데이터를 분할한다.
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT,
order_date DATE,
amount DECIMAL
) PARTITION BY RANGE (order_date);
CREATE TABLE orders_01 PARTITION OF orders FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE orders_02 PARTITION OF orders FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
PARTITION BY RANGE (order_date)
테이블을 order_date 열을 기준으로 범위 파티셔닝(Range Partitioning)한다.
데이터가 order_date 값에 따라 여러 파티션으로 나뉘어 저장된다.
orders_01 PARTITION OF orders: orders 테이블의 첫 번째 파티션인 orders_01 테이블을 생성한다. 이 파티션은 orders 테이블의 일부로 동작한다.
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'): 2024-01-01부터 2024-02-01까지의 order_date 값을 가지는 데이터가 이 파티션에 저장된다. 여기서 TO의 값(2024-02-01)은 포함되지 않으며, 2024-01-01부터 2024-01-31까지의 데이터만 이 파티션에 저장된다.
읽기 전용 데이터베이스
읽기 전용 데이터베이스는 주로 읽기 요청을 처리하는 데이터베이스로 데이터를 주기적으로 동기화하여 최신 상태를 유지하면서 읽기 요청을 처리한다.
쿼리 최적화
쿼리 최적화는 SQL 쿼리를 효율적으로 작성하여 데이터베이스의 읽기 성능을 향상시키는 방법이다. 예를 들어, 불필요한 조인을 줄이고, 필요한 컬럼만 선택하며, 적절한 조건을 사용하는 것이 중요하다.
쓰기 요청 최적화
DB에서 데이터를 생성할 때(쓰기) 가장 많은 시간을 소요한다.
비동기 처리
쓰기 요청을 비동기 방식으로 처리하면 DB에 직접 접근하지 않고도 빠르게 응답을 반환할 수 있다.
비동기 처리는 특히 높은 트래픽을 처리할 때 유용하다.
예를 들어 메시지를 바로 DB에 쓰지 않고, 큐에 넣어 나중에 처리하는 방법이 있다.
이를 통해 애플리케이션은 요청을 빠르게 처리할 수 있으며, 사용자는 요청을 보낸 후 즉시 응답을 받기 때문에, 사용자 경험이 향상된다.
다만, 비동기 처리 시 데이터 소실이나 오류를 방지하기 위해 큐에 데이터를 넣을 때 적절한 검증을 수행하고,
큐에 쌓인 데이터를 지속적으로 모니터링하여 실패한 요청을 재시도할 수 있는 메커니즘을 마련해야 한다.
또한, 데이터의 순서를 보장하고, 중복 처리를 방지하기 위한 고유 식별자(ID)를 사용해야 한다.
배치 처리
실시간으로 처리할 필요가 없는 쓰기 요청은 배치를 통해 한꺼번에 처리할 수 있다.
예를 들어 일정 시간마다 큐에 쌓인 메시지를 DB에 쓰는 방법이 있다.
또한, 매일 자정에 하루 동안 수집된 로그 데이터를 한 번에 DB에 저장하는 방식으로 사용할 수 있다.
이를 통해 실시간 처리의 부담을 줄이고, 시스템 자원을 효율적으로 사용할 수 있다.
배치 처리 시에도 데이터 소실을 방지하기 위해 배치 작업 중 오류가 발생한 경우 이를 기록하고,
재시도할 수 있는 메커니즘을 마련해야 한다.
즉, 배치 작업의 상태를 모니터링하고, 배치 작업이 완료되었는지 확인하는 프로세스가 필요하다.
분산 DB
단일 DB로 모든 쓰기 요청을 처리하기 어렵다면, 분산 DB를 사용하여 부하를 분산시킬 수 있다.
예를 들어 여러 개의 DB 인스턴스를 사용하여 각 인스턴스가 특정 사용자 그룹의 데이터를 처리하도록 할 수 있다.
분산 DB는 데이터를 여러 개의 노드에 분산 저장하여 고가용성과 확장성을 제공한다.
또한, 샤딩(Sharding) 기법을 통해 데이터베이스를 수평으로 분할하여 각 샤드가 독립적으로 쓰기 작업을 처리하도록 할 수 있다.
이를 통해 단일 노드의 부하를 줄이고, 시스템의 전체 성능을 향상시킬 수 있다.
🌟 분산 DB 사용 시 데이터 일관성을 유지하기 위해 트랜잭션 관리와 데이터 동기화에 신경 써야 한다.
데이터 일관성 유지
❗ 대규모 시스템에서는 데이터 일관성을 유지하는 것이 중요하다. 이를 위해 분산 트랜잭션, 이벤트 소싱, CQRS(Command Query Responsibility Segregation) 패턴 등의 기법을 사용할 수 있다.
분산 트랜잭션
- 분산 트랜잭션은 여러 개의 독립된 시스템이나 데이터베이스에서 동시에 일어나는 트랜잭션을 일관되게 관리하는 방법이다.
- 단일 트랜잭션이 여러 시스템에 걸쳐 발생할 때, 모든 시스템이 해당 트랜잭션을 성공적으로 완료하거나, 모든 시스템이 트랜잭션을 실패로 처리하도록(Roll Back) 보장한다. 이를 통해 데이터의 일관성을 유지할 수 있다.
- 분산 트랜잭션이 필요한 이유는 MSA에서 여러 서비스가 독립적으로 운영되기 때문이다.
트랜잭션(Transaction)
데이터베이스의 상태를 변환하는 작업의 단위로, ACID(원자성, 일관성, 고립성, 지속성) 속성을 보장한다.
- 원자성 (Atomicity): 트랜잭션의 작업들이 모두 성공하거나 모두 실패하여, 부분적인 작업 수행이 없는 것을 보장한다.
- 일관성 (Consistency): 트랜잭션이 완료된 후에도 데이터베이스는 모든 무결성 제약 조건을 유지한다.
- 격리성 (Isolation): 동시에 실행되는 트랜잭션이 서로 간섭하지 않도록 보장한다.
- 지속성 (Durability): 트랜잭션이 성공적으로 완료된 후의 결과는 시스템 장애가 발생해도 영구적으로 유지된다.
분산 트랜잭션(Distributed Transaction)
여러 분산된 데이터 소스에 걸쳐 트랜잭션을 수행하는 작업이다.
마이크로서비스나 여러 데이터베이스에서 데이터를 동시에 업데이트하는 경우가 이에 해당한다.
- 2PC (Two-Phase Commit)준비 단계(Prepare Phase): 각 참여 노드는 트랜잭션 준비 상태를 확인하고, 준비 완료를 마스터 노드에 알린다.
- 커밋 단계(Commit Phase): 마스터 노드는 모든 참여 노드가 준비되었음을 확인하고, 트랜잭션을 커밋하도록 지시한다. 만약 준비가 완료되지 않은 노드가 있다면 트랜잭션을 롤백한다.
- 분산 트랜잭션을 관리하는 프로토콜로, 준비(Prepare) 단계와 커밋(Commit) 단계로 나누어 트랜잭션을 처리한다. (마스터 노드가 필요)
❗ 이 방법은 하나의 서비스가 장애가 있는 경우나 각각의 서비스에 동시에 Rocking이 걸리게 되면 성능의 문제가 발생하기 때문에 비효율적이다.
- 사가 패턴(Saga Pattern)각 서비스의 로컬 트랜잭션을 순차적으로 처리한다. 각 로컬 트랜잭션은 DB를 업데이트하고, 다음 로컬 트랜잭션을 트리거하는 이벤트(메시지)를 게시한다. 트랜잭션 실패 시 보상 트랜잭션을 실행하여 상태를 차례대로 롤백한다.
- Ex) 트랜잭션을 여러 서비스(단계)로 나누어 처리하며, 각 서비스(단계)에서 독립적으로 커밋된다.
- (1) 주문 생성 단계: 주문 서비스에서 사용자가 주문을 생성
- (2) 결제 처리 단계: 결제 서비스에서 주문 결제를 처리
- (3) 재고 감소 단계: 재고 서비스에서 주문된 상품의 재고를 감소
- (1) → (2) → (3) 순으로 각각의 트랜잭션을 수행하고 각각 커밋하며, 한 단계의 트랜잭션이 성공하면 다음 단계로 넘어가고, 실패하면 이전 단계에서 수행된 작업을 취소한다.
- (1) 트랜잭션 수행 및 성공 → (1) 커밋 → (1)에서 (2)의 트랜잭션 트리거 → (2) 트랜잭션 수행 및 성공 → (2) 커밋 → (2)에서 (3)의 트랜잭션 트리거 → (3) 트랜잭션 수행 및 실패 → (2) 보상 트랜잭션 수행 → (1) 보상 트랜잭션 수행
❗ SAGA 패턴에는 크게 두 가지 방식이 있다. 이는 다음에 정리하도록 하자.
분산 트랜잭션의 장단점
———장점———
데이터 일관성 보장
분산된 여러 데이터 소스에 걸쳐 일관된 데이터 상태를 유지할 수 있다. 모든 트랜잭션이 성공적으로 완료되거나 모두 실패하도록 보장한다.
확장성
분산 트랜잭션을 통해 여러 시스템이 독립적으로 동작하면서도, 필요한 경우 협력하여 일관된 상태를 유지할 수 있다. 이를 통해 시스템의 확장성을 높일 수 있다.
신뢰성
트랜잭션의 ACID 속성을 분산 환경에서도 유지할 수 있어 시스템의 신뢰성을 높인다. 데이터 무결성과 일관성을 유지할 수 있다.
———단점———
복잡성 증가
여러 시스템 간의 트랜잭션을 동기화하고 데이터 일관성을 유지하는 것은 복잡하다.
성능 저하
2PC와 같은 프로토콜을 사용할 경우, 트랜잭션의 준비와 커밋 단계에서 지연이 발생할 수 있다. 이는 시스템의 성능을 저하시킬 수 있다.
네트워크 오버헤드
여러 시스템 간의 통신이 필요하므로 네트워크 오버헤드가 증가할 수 있다. 이는 트랜잭션 처리 속도 저하를 일으킨다.
복구의 어려움
분산 트랜잭션 실패 시, 모든 시스템에서 일관된 상태로 롤백하는 것이 쉽지 않다. 특히, 부분적으로 실패한 트랜잭션을 처리하는 데 어려움이 있을 수 있다.
이벤트 소싱(Event Sourcing)
이벤트 소싱은 데이터 상태 변화를 이벤트로 기록하고, 해당 이벤트들을 순차적으로 재생하여 현재 상태를 파악한다.
전통적인 데이터 저장 방식과 달리, 이벤트 소싱에서는 데이터 변경 자체가 아닌 변경 이벤트를 저장한다.
이러한 방식은 특히 복잡한 비즈니스 로직을 다루는 시스템에서 데이터 일관성과 추적 가능성을 높인다.
하지만 복잡성이 증가하므로, 시스템 요구사항에 따라 신중하게 적용해야 한다.
이벤트(Event)
데이터의 상태 변화를 나타내는 기록.
예를 들어, "주문 생성", "결제 완료", "주문 취소" 등이 이벤트가 될 수 있다.
이벤트 스토어(Event Store)
이벤트를 순서대로 저장하는 저장소.
이벤트의 불변성과 순차성을 보장한다.
애그리게이트(Aggregate)
관련된 이벤트를 모아 현재 상태를 재현할 수 있는 엔티티.
Aggregate는 도메인 모델의 일부분으로, 이벤트를 적용하여 상태를 변화시킨다.
커맨드(Command)
Aggregate에 특정 동작을 지시하는 명령.
커맨드는 이벤트를 생성하는 트리거 역할을 한다.
프로젝션(Projection)
이벤트를 읽기 모델로 변환하여 조회 성능을 최적화하는 방식.
이벤트를 기반으로 읽기 전용 데이터베이스를 업데이트한다.
이벤트 소싱의 장단점
———장점———
데이터 변경 이력 추적
모든 상태 변화를 이벤트로 기록하므로, 데이터 변경 이력을 완벽하게 추적할 수 있다.
모니터링과 디버깅에 유용하다.
복구 및 재생
이벤트를 재생하여 시스템의 현재 상태를 복구할 수 있다.
데이터 손실이나 시스템 장애 시 유용하다.
———단점———
복잡성 증가
시스템 설계와 구현의 복잡성이 증가한다.
이벤트 모델링과 이벤트 스토어 관리가 필요하다.
읽기 성능
이벤트를 재생하여 현재 상태를 계산해야 하므로, 읽기 성능이 저하될 수 있다.
이를 위해 프로젝션과 CQRS를 활용할 수 있다.
CQRS(Command & Query Responsibility Segregation)
CQRS는 명령(Commnad)과 조회(Query)의 책임을 분리하는 소프트웨어 디자인 패턴
읽기 작업과 쓰기 작업을 서로 다른 모델로 분리하여, 각 작업에 최적화된 구조를 사용할 수 있도록 한다.
이를 통해 시스템의 성능, 확장성, 유지보수성을 향상시키는 데 도움이 된다.
명령(Command) - CUD
데이터를 변경 작업, 데이터베이스에 대한 쓰기 작업을 수행한다.
명령 모델은 데이터의 상태 변경을 담당한다.
조회(Query) - R
데이터를 조회하는 작업, 데이터베이스에 대한 읽기 작업을 수행한다.
조회 모델은 읽기 전용 데이터베이스 또는 캐시를 사용하여 빠른 응답을 제공한다.
CQRS의 장단점
———장점———
성능 향상
읽기와 쓰기를 분리하여 각 작업에 최적화된 데이터 저장소와 인프라를 사용할 수 있다.
확장성
읽기와 쓰기를 독립적으로 확장할 수 있다. 예를 들어, 읽기 요청이 많은 경우 조회 모델을 수평으로 확장하여 부하를 분산시킬 수 있다.
유지보수성
비즈니스 로직이 명령 모델에 집중되므로, 복잡한 상태 변경 로직을 관리하기 쉽다. 또한, 읽기 모델은 단순화되어 유지보수하기 용이하다.
———단점———
복잡성 증가
시스템 설계와 구현의 복잡성이 증가한다. 명령 모델과 조회 모델을 각각 설계하고 관리해야 한다.
데이터 동기화
명령 모델과 조회 모델 간의 데이터 동기화가 필요하다.
모니터링과 로깅
- 대규모 시스템에서 모니터링과 로깅은 시스템의 안정성과 성능을 유지하는 데 반드시 필요하다.
- 이를 통해 시스템의 상태를 실시간으로 파악하고, 문제 발생 시 신속하게 대응할 수 있다.
다음 세 가지 측면에서 장점을 갖는다.
- 시스템 안정성 유지
- 성능 최적화
- 문제 예방 및 대응
모니터링
애플리케이션, DB, 캐시 등 각 컴포넌트의 성능을 모니터링한다.
Prometheus, Grafana 같은 툴을 사용할 수 있다.
시스템의 주요 지표(TPS, 응답 시간, 에러율 등)를 모니터링하고, 이상 징후를 감지하면 알림을 받을 수 있다.
모니터링을 통해 시스템의 상태를 실시간으로 파악하고, 문제 발생 시 빠르게 대응할 수 있다.
또한, 모니터링 데이터를 기반으로 시스템의 성능을 분석하고, 최적화할 수 있다.
실시간 상태 파악
모니터링 도구를 통해 시스템의 주요 지표를 실시간으로 확인할 수 있다. 이를 통해 시스템의 현재 상태를 파악하고, 이상 징후를 빠르게 감지할 수 있다.
자동 알림 및 신속한 대응
특정 임계치를 초과하는 경우 자동으로 알림을 받을 수 있어, 잠재적인 문제를 조기에 발견하고 대응할 수 있다.
성능 분석 및 최적화
모니터링 데이터를 기반으로 시스템의 성능을 분석하고 최적화 할 수 있다. 예를 들어, 특정 시간대에 트래픽이 급증하는 경우 해당 시간대에 자원을 추가로 할당할 수 있다. 또한 시스템의 병목 지점을 파악하고, 이를 최적화하여 전체 성능을 향상시킬 수 있다.
로깅
애플리케이션의 주요 이벤트를 로깅하여 문제 발생 시 원인을 추적할 수 있다.
로그는 Elasticsearch, Logstash, Kibana(ELK 스택) 등을 사용하여 수집, 저장, 분석할 수 있다.
이를 통해 시스템의 상태를 파악하고, 문제를 해결할 수 있다.
로깅은 시스템의 모든 중요한 이벤트를 기록하므로, 문제 발생 시 정확한 원인을 파악할 수 있다.
이벤트 추적
로깅을 통해 시스템에서 발생하는 모든 중요한 이벤트를 기록한다. 이는 문제가 발생했을 때 원인을 추적하고 분석하는 데 도움이 된다. 또한, 같은 문제가 다시 발생하지 않도록 예방할 수 있다.
디버깅 및 오류 해결
로그를 분석하여 오류의 원인을 파악하고, 이를 기반으로 문제를 해결할 수 있다.
패턴 분석 및 최적화
로그 데이터를 분석하여 사용자의 행동 패턴이나 시스템의 성능 패턴을 이해할 수 있다. 이를 통해 시스템을 더 효율적으로 운영할 수 있다. 또한, 시스템의 성능 저하 원인을 찾아내고, 지속적인 최적화를 진행할 수 있다.
법적 및 규제 요구 사항 준수
로그 데이터를 보관하고 분석하는 것이 법적 및 규제 요구 사항을 준수하는 데 필수적이다.
테스트와 배포
시스템이 정상적으로 동작하는지 확인(테스트)해야 한다.
테스트
단위 테스트(Unit Test)
- 시스템의 개별 구성 요소를 테스트하여 각 부분이 예상대로 동작하는지 확인한다.
- JUnit, TestNG와 같은 도구를 사용하여 자동화된 단위 테스트를 작성하고 실행한다.
- 단위 테스트는 개발 초기 단계에서 발생할 수 있는 결함을 조기에 발견하고 수정하는 데 유용하다.
통합 테스트(Integration Test)
- 여러 모듈이 함께 동작하는지 테스트합니다. 모듈들이 올바르게 상호작용하는지를 검증한다.
- Spring Boot에서는 @SpringBootTest 어노테이션을 사용하여 통합 테스트를 작성할 수 있다.
부하 테스트(Load Test)
- 시스템이 높은 트래픽 상황에서도 안정적으로 동작하는지를 테스트합니다.
- Apache JMeter와 같은 도구를 사용하여 다양한 부하 시나리오를 설정하고 테스트를 수행합니다.
- 부하 테스트를 통해 시스템의 성능 한계를 파악하고, 병목 지점을 찾아 최적화할 수 있습니다.
회귀 테스트(Regression Test)
- 새로운 코드 변경(새로운 기능 추가 등)이 기존 기능에 영향을 미치지 않는지 확인한다.
- 회귀 테스트는 지속적인 코드 변경에도 시스템의 안정성을 유지하는 데 중요하다.
사용자 수용 테스트(UAT, User Acceptance Test)
- 실제 사용자 환경에서 시스템을 테스트하여, 사용자가 요구하는 기능이 모두 제대로 동작하는지 확인한다.
- 사용자 피드백을 반영하여 시스템을 최종 조정하고, 배포를 준비한다.
배포
지속적인 통합(CI, Continuous Integration)
- 개발자가 변경한 코드를 자동으로 빌드하고 테스트하여, 코드 변경 시점에서 발생할 수 있는 문제를 조기에 발견하고 해결할 수 있다.
- Jenkins, GitLab CI, Travis CI와 같은 도구를 사용하여 CI 파이프라인을 설정한다.
- CI는 코드 통합을 빠르고 효율적으로 수행하여 개발 주기를 단축시키고, 코드 품질을 높인다.
지속적인 배포(CD, Continuous Deployment)
- CI 파이프라인을 통해 검증된 코드를 자동으로 프로덕션 환경에 배포한다.
- Argo CD와 같은 도구를 사용하여 CD 파이프라인을 설정한다.
- CD는 코드 변경 사항을 빠르고 안전하게 프로덕션 환경에 적용하여, 새로운 기능을 사용자에게 신속하게 제공할 수 있다.
Canary 배포
- 새로운 버전을 전체 시스템에 배포하기 전에, 일부 사용자에게만 배포하여 문제가 없는지 확인한다.
- 문제가 발생할 경우 빠르게 이전 버전으로 롤백할 수 있다.
- Canary 배포는 리스크를 최소화하면서 새로운 기능을 단계적으로 도입할 수 있는 방법이다.
블루-그린 배포(Blue-Green Deployment)
- 두 개의 환경(블루와 그린)을 사용하여 하나는 현재 운영 중인 환경이고, 다른 하나는 새로운 버전을 배포하는 환경으로 사용한다.
- 새로운 버전을 그린 환경에 배포한 후, 모든 트래픽을 그린 환경으로 전환한다. 문제가 발생하면 블루 환경으로 빠르게 롤백할 수 있다.
- 블루-그린 배포는 무중단 배포를 가능하게 하며, 배포 실패 시 신속한 복구가 가능하다.
롤링 배포(Rolling Deployment) → 쿠버네티스
- 새로운 버전을 점진적으로 배포하여, 각 서버를 순차적으로 업데이트한다.
- 시스템 가동 시간을 유지하면서 점진적으로 새로운 버전을 도입할 수 있다.
- 롤링 배포는 대규모 시스템에서 무중단 배포를 구현하는 데 유용하다.
대규모 시스템을 설계하는 데 필요한 기본적인 개념들을 탑재했다.
개념을 알았으니 적용하면서 이해도를 높여보자.
'Backend' 카테고리의 다른 글
| 어플리케이션 성능 테스트 - JMeter (0) | 2024.08.30 |
|---|---|
| RabbitMQ로 SAGA 패턴 구현 (0) | 2024.08.30 |
| Prometheus & Grafana & Loki 모니터링 (0) | 2024.08.20 |
| Kafka 기본 개념 및 연동 실험 (0) | 2024.08.19 |
| RabbitMQ 기본 개념 및 실습 (0) | 2024.08.19 |