AWS 복원성 아키텍처

SangLog·2023년 9월 11일
1

복원성(resiliency)는 애플리케이션이 실패를 회피하거나 실패 발생 시 신속하게 회복 할 수 있는 능력을 말한다.

애플리케이션의 복원성이란 애플리케이션이 기대한 성능을 발휘하는 시간의 비율을 나타내는 가용성(availablity)의 또 다른 표현이다.

따라서 희망하는 가용성 수준을 결정한 뒤 비로소 AWS환경의 설계를 시작할 수 잇다.

가용성 계산하기

안정성은 가용성 지표를 통해 정량적으로 나타낼 수 있다.
가용성이란 애플리케이션이 기대한 성능을 발휘하는 시간의 비율을 의미한다.
보통 애플리케이션의 가용성에 대한 기대는 99% 이상으로 상당히 높은 편이다.

전통적인 애플리케이션/ 클라우드 네이티브 애플리케이션 가용성 차이

전통적인 애플리케이션의 가용성

기존의 Linux, Window에서 실행되는 애플리케이션을 의미한다.
그러한 시스템을 코드변경 없이 aws 환경으로 이식하는 경우를 전통적인 애플리케이션 차원으로 생각해볼 수 있다.

기본적으로 총가용성은 강한 의존성 관계에 속한 가용성의 곱으로 계산할 수 있다.
예를들어 ec2의 가용성은 90%이고 멀티 AZ 기반 RDS인스턴스 가용성은 99.95%이므로 둘의 곲은 89.955%가 된다.

이럴때 총 가용성을 높이기 위해서는 중복 구현 요소를 사용할 수 있다.
(ec2인스턴스를 서로다른 az에 세개로 구성 하는등)
이렇게 하면 중복구현 요소의 가용성은 100%에서 해당 인스턴스의 실패 비율을 차감하는 방식으로 계산한다
3개의 ec2로 구성하는 경우 아래와 같다.
100% - (10% 10% 10%) = 99.9%

클라우드 네이티브 애플리케이션의 가용성

AWS와 같은 특정 클라우드 플랫폼의 리소스를 활용하게 위해 만들어진 애플리케이션으로 Lambda 함수를 활용한 서버리스 애플리케이션도 이에 해당한다.

가용성을 높이려면 AZ여러곳에 ec2를 배치해서 ALB로 트래픽을 분산시키는 방법을 쓰면 된다.

여기서 리전도 나눠서 배치파면 가용성을 더 높혀줄 수 있다.

리소스 용량 제한 파악

클라우드 용량에는 제한이 잇다. AWS는 개별 사용자가 우연히 혹은 의도적으로라도 모든 클라우드 리소스를 고갈시키지 못하도록 하는 용량 제한을 적용하고 있다.
이를 통해서 다른 사용자의 리소스 사용권을 보장할 수 있다.

용량 제한은 서비스에 따라 다르며, 네트워크 처리용량, 초당 s3 put요청 횟수 등으로 다양하고 이들 중 일부는 AWS에 요청해 상향 조정할 수 있다.

AWS Trusted Advisor를 이용해 우리의 계정에 적용된 서비스 용량 제한을 확인 할 수 있으며, CloudWatch Alarms 설정에서 용량 제한선에 이르기 전에 경고 메시지를 보내도록 할 수 있다.

가용성 높이기

지금까지 이야기한 가용성은 AWS 서비스에만 국한된 것이었다. 하지만 실제 애플리케이션의 가용성 수준은 버그 발생, 메모리 누수 , 데이터베이스 오류 등으로 더욱 낮아질 수 있다.

가용성 최대화를 위한 최선의 방법

  • 서로 다른 AZ에 다수의 중소규모 인스턴스를 분산 배치 (하나의 대규모 인스턴스에서 웹 애플리케이션 호스팅 보다)
  • 적절한 시기에 실패한 인스턴스를 대체하는 새로운 인스턴스를 배포해야 한다.

EC2 Auto Scaling

EC2 auto scaling은 애플리케이션의 실패 상황에 대한 대응 및 신속한 복원을 위한 서비스로, 사용자가 지정한 수의 EC2인스턴스를 자동으로 프로비저닝 및 시작할 수 있도록 도우며, 수요 증가세에 맞춰 동적으로 인스턴스를 추가한다.
인스턴스 실패 또는 폐기 시 Auto Scaling이 자동으로 인스턴스를 대체한다.

EC2 Auto Scaling은 인스턴스를 자동으로 시작하기 위해 시작 환경설정 및 시작 템플릿을 사용하며, 기본적으로 설정된 파라미터에 따라 인스턴스를 구성하고, 인스턴스 시작시 관련 스크립트를 실행한다.

시작 환경설정

인스턴스를 수동으로 생성하려면 다양한 환경설정 파라미터를 작성해야한다. 시작 환경 설정(launch configuration)은 직접 인스턴스를 프로비저닝할 때 입력해야 하는 모든 정보를 포함한 문서라 할 수 있다.

사용자는 기존 EC2인스턴스를 이용해서 시작 환경설정을 생성 할 수 있으며, Auto Scaling에서 인스턴스 설정 내역을 복사항 후 필요한 내용만 수정하면 된다.

시작 환경설정은 EC2 Auto Scaling에서만 사용할 수 있다.
사용자가 수동으로 인스턴스를 생성할 떄는 시작 환경설정을 사용할 수 없다.
일당 시작 환경설정을 생성한 뒤에는 이를 수정할 수 없다.

시작 템플릿

시작 템플릿(launch templates)도 미리 설정한 파라미터 내용에 따라 인스턴스를 자동 생성할 수 있다. 하지만 시작 템플릿의용도가 시작 환경설정보다 훨씬 다양한다.

시작 템플릿은 Auto Scaling뿐만 아니라 개별 EC2인스턴스를 직접 생성할 떄도 사용할 수 있다.

시작 템플릿은 버전 속성을 가지기 떄문에 생성 후에도 변경이 가능하다.

Auto Scaling 그룹

Auto Scaling 그룹은 Auto Scaling 이 관리하는 EC2 인스턴스 그룹이다.
Auto Sacling 그룹 생성시 가장 먼저 인스턴스 생성을 위한 시작 환경설정 또는 시작 템플릿을 지정한다.
그후 Auto Sacling이 생성 및 유지할 인스턴스의 수를 아래와 같이 지정한다.

  • 최소용량 : Auto Scaling 이 성능을 유지하기 위해 지켜야 할 최소 인스턴스 수
  • 최대용량 : Auto Sacling 이 성능을 유지하기 위해 지켜야 할 최대 인스턴스 수를 의미한다. (이는 AWS가 계정당 부여하는 용량 제한과 관계가 있다)
  • 희망용량 : 희망 용량은 최소 및 최대용량 사이의 값으로 이를 설정안하면 Auto Scaling이 최소 용량에 맞춰 인스턴스를 생성한다.

Appication Load Balancer 타겟 그룹 설정

Auto Sacling 그룹에서 인스턴스로 전달되는 트래픽을 Application Load Balancer로 분산시키려는 경우 Auto Sacling 그룹 생성 시 ALB 타겟 그룹에 추가하면된다.

애플리케이션 인스턴스의 헬스 체크

Auto Sacling 그룹 생성후에는 자동으로 최소/희망 용량에 맞춰서 인스턴스의 수를 조절하며, 특정 인스턴스의 상태가 나빠질 경우 해당 요소를 폐기하고 새 인스턴스를 추가한다.

기본적으로 Auto Sacling은 EC2 헬스 체크 정보에 따라 인스턴스의 상태를 결정한다.

애플리케이션 로드 벨런서를 이용해서 인스턴스 트래픽을 분산시키는 경우 로드밸런서의 타겟 그룹에 대한 헬스 체크를 하도록 환경설정을 할 수 있고 200~499 까지의 HTTP 응답 코드가 포함되며 auto scaling 그룹이 인스턴스의 정상 작동 여부를 확인하도록 할 수 있다.

Auto Sacling 옵션

수동 스케일링

생성 이후 희망용량을 변경하면 Auto Scaling은 즉시 이를 반영해준다.
이렇게 수동으로도 인스턴스 수를 조절할 수 있다.

동적 스케일링 정책

EC2의 CPU , 메모리, 저장 공간 등의 리소스가 고갈되면 인스턴스가 자동으로 추가되도록 셋팅할 수 있다.

  • CPU 누적 활성화율
  • 타겟별 평균 요청횟수
  • 네트워크 평균 유입량
  • 네트워크 평균 유출량

이러한 네이티브 성능 지표 외에도 CloudWatch logs에서 성능 지표를 추출할 수 있는 매트릭스 필터를 사용할 수 있다.

동적 스케일링 정책은 정리하자면 아래와 같이 세가지로 볼 수 있다.

  1. 심플 스케일링 정책
    지표가 기준치를 초과하면 Auto Sacling이 희망 용량을 증가시킨다.
    chnageInCapacity : 지정된 수량만큼 용량을 증가시킨다.
    ExactCapacity : 현재 용량과 상관없이 지정된 수량에 맞춘다
    PercentchangeInCapacity : 현재 용량에 대한 비율로 수량을 증가
  1. 스텝 스케일링 정책
    기준치를 초과하는 성능 지표에 맞춰 신속하게 인스턴스를 추가할 수 있다.
    예를 들어 CPU활성화율 50% 증가시에는 2개 60% 도달시에는 4개 추가
  1. 타겟 추적 정책
    사용자가 지표와 목표 값을 선택하면 Auto Sacling이 CloudWatch Alarm 및 스케일링 정책을 생성하고 해당 지표의 목표 값에 맞춰 인스턴스의 수를 조정한다.
    타겟 추적 정책의 특징은 스케일 아웃은 물론 인스턴스의 수를 줄이는 스케일인 기능을 사용할 수 있다는 것이다.

예약작업

애플리케이션 워크로드 패턴이 예측 가능하면 용량을 선제적으로 조정해서 인스턴스 조정 가능.
예를들어 금요일에 사용량 많으면 평소에 2개 쓰다가 금요일에는 4개로 늘리는식으로.

데이터 백업과 복원

S3

One Zone IA를 제외한 S3의 모든 스토리지 클래스가 멀티 AZ에 객체를 분산 저장한다.

데이터 삭제 및 데이터 손상을 방지하려면 S3 버저닝 기능을 활성화 한다.
S3 버저닝 기능이 활성화 되면 저장 객체는 임의의 덮어쓰기나 실수에 의한 삭제로부터 안전해진다.

멀티 AZ의 실패 또는 리전의 실패로부터 데이터를 보호하기 위해 크로스 리전 복제 기능을 활성화해 하나의 리전은 소스 버킷으로 또 다른 리전은 데스티네이션 버킷으로 설정한다.

Elastic File System

EFS(Elastic File System)은 EC2 인스턴스와 온프레미스 서버 간의 파일 공유를 가능케 하는 관리형 NFS(Network File System)이다. EFS는 리전 내 멀티 AZ 환경에 데이터를 저장해 개별 AZ 실패 상황에 대비한다.

AWS Backup Service를 이용해 정해진 스케줄에 따라 EFS에 백업을 생성하도록 할 수 있다.

Elastic Block Storage

EBS는 리전 내 멀티 AZ 환경에 볼륨을 자동ㅇ로 복제해 개별 AZ 실패 상황에 대비하지만 데이터 변조 위험은 존재한다.

EBS 볼륨 백업의 가장 간단한 방법은 스냅샷을 생성하는 것이며, AWS는 S3에 EBS 스냅샷을 저장한다.

EBS 스냅샷은 직접 생성하거나 Amazon Data LifeCycle Manager를 이용해 일정 주기마다 자동으로 스냅샷을 생성하도록 할 수 있다.

데이터베이스의 복원성

데이터베이스의 데이터 보호 방안은 관계형 데이터베이스인지 비관계형데이터베이스인지 여부에 따라 달라진다.

자체 관계형 데이터베이스 서버를 실행하는경우 해당 데이터베이스 엔진에 내장된 백업 기능을 이용해 데이터베이스를 파일로 저장할 수 있다.

AWS RDS를 사용하는경우 간단하게 데이터베이스 스냅샷만 생성하면된다.
스냅샷으로 데이터베이스를 복원하는 작업에는 몇분이 소요되며 복원 후 새로운 데이터베이스 인스턴스가 생성된다.

복원성을 높이기 위해서 멀티 AZ환경에 데이터베이스를 배포할 수 있으며, 하나의 AZ에는 기본 인스턴스, 다른 AZ에는 대기 인스턴스를 둘 수 있따.

DynamoDB는 멀티 AZ환경에 테이블을 저장하며 개별 AZ실패 상황에서도 저지연성, 고성능의 NoSQL 데이터베이스 서비스를 제공할 수 있다.

DynamoDB 글로벌 테이블을 사용해 멀티 리전에 테이블을 복제하면 복원성을 더욱 높일 수 있다. 또한 DynamoDB 테이블의 기준시점 복구를 설정해 자동으로 백업을 생성하도록 할 수 있다.

복원성 네트워크 생성하기

모든 AWS리소스는 네트워크에 의존하므로 네트워크를 적절하게 설계하는 일은 매우 중요하다.
네트워크 설계와 관련해 가장 중요한 고려 사항 중 하나는 VPC설계이고 다른 하나는 사용자가 VPC에 접속해 리소스를 활용할 수 있게 하는 것이다.

VPC 설계시 고려사항

VPC 생성시에 리소스에 충분한 IP 주소를 할당할 수 있도록 충분한 크기의 CIDR블록을 생성하는 것이 중요하다.

AWS가 리전에 AZ를 추가하는 상황에, 서브넷을 이용해 보안 수준을 높이고 관리 용이성을 높이기 위해서도 여유있는 IP 가 필요하다.

복원성을 지닌 외부 연결

사용자가 기대한 수준으로 애플리케이션이 작동하는 속성이 가용성이라는 점을 이해한다면, 애플리켄이션의 가용성이 네트워크 가용성에 의존한다는 것도 이해할 수 있다.

퍼블릭 인터넷을 대체할수 있는 매우 중요한 애플리케이션을 연결해야할 경우 Direct Connect를 이용해 AWS 리소스를 연결하거나 백업을 전송할 수 있따.
Direct Connect는 1-10 Gbps의 전송 속도 및 일관된 저지연성을 제공하므로 AWS에서 대량의 데이터를 안정적으로 전송하는데 사용할 수 있다.

또한 AWS리소스에 퍼블릭 인터넷으로 연결할 수 없는 경우 보조 수단으로 Direct Connect를 이용할 수 도 있다.

AWS 리소스와 외부 리소스를 연결하는 외부 네트워크(Direct Connect, VPC 피어링, VPN)등을 사용할때는 VPC 주소가 이들 외부 네트워크 주소와 중복되지 않도록 주의 한다.

SQS(Simple Queue Service)

SQS는 애플리케이션을 구성하는 다양한 컴포넌트가 서로에게 메시지를 전송할 수 있도록 돕는 관리형 메시지 서비스이다.
SQS는 고가용성 및 고탄력성을 제공하므로, 수십만 건의 메시지를 불과 수초만에 처리할 수 있따.

Queues

SQS는 처리해야 할 메시지를 담는 큐를 생성하며, 큐에 메시지를 넣는 프로듀서 컴퓨트와, 큐에 있는 메시지를 읽는 컨슈머 컴포넌트로 구성된다.

메시지의 최대크기는 256KB이며 기본적인 처리방식은 아래와 같다.

  1. 프로듀서가 SendMessage액션을 통해 큐에 하나 이상의 메시지를 넣는다.
  2. 컨슈머가 큐에 담긴 새 메시지를 처리할지 확인한다. ReceieveMessage액션을 통해 큐에서 하나 이상의 메시지를 소비한다.
  3. 컨슈머는 메시지를 처리한 뒤 DeleteMessage 액션을 통해 큐에서 삭제한다.

SQS로 전송되는 API 호출 횟수를 줄이기 위해 최대 10개의 메시지를 묶어서 일괄적으로 처리할 수 있따.

가시성 중지기간

컨슈머 객체가 큐에서 메시지를 확인하더라도 메시지는 큐에 그대로 유지된다. 읽은 메시지의 삭제 여부는 컨슈머가 결정할 수 있다.

특정 컨슈머 객체가 메시지를 확인하면 SQS는 이후 일정 시간 동안 해당 메시지를 다른 컨슈머가 확인할 수 없게 하며 이를 가시성 중지기간 이라 부른다.

동일한 메시지를 다른 컨슈머가 중복해서 처리하는 일을 막기 위한 조치이다. (기본은 30초이다)

보유기간

메시지는 큐에 영구적으로 있을 수 없다. 메시지의 기본 보유기간은 4일이며 최소 1분에서 최대 14일까지 설정할 수 있다.

딜레이 큐와 메시지 타이머

큐에 메시지를 넣을 때 큐마다 지연시간을 설정할 수 있다.
기본 큐별 딜레이 시간은 0초고 최대 15분까지 설정할 수 있다.

개별 메시지는 메시지 타이머를 이용해 지연 시간을 설정할 수 있다.
기본 메시지 타이머는 0초이고 최대 15분까지 설정할 수 있다. 메시지 타이머를 설정한 경우 딜레이 큐는 무시된다.

큐타입

큐 기반 애플리케이션의 경우 큐의 성능 또는 작동 방식에 따라 애플리케이션의 성능도 영향을 받게 된다.

스탠다드 큐

스탠다드 큐는 거의 무제한의 처리성능을 제공하며, 신속하게 다수의 메시지를 처리한다. 메시지는 순서와 무관하게 전달되며 때로는 동일한 메시지가 중복해서 전달 되기도 한다.

스탠다드 큐를 사용하는 애플리케이션은 이와 같은 중복 메시지를 처리할 수 있는 기능을 지니고 있어야 한다.

스탠다드 큐 타입은 최대 12만개의 인플라이트 메시지(이동중 메시지)를 처리할 수 있다.

FIFO큐

first in first out 큐는 초당 3천개의 메시지를 큐에 전달할 수 있다.
메시지는 도착 순서대로 큐에 전달되며, 각 메시지는 단 한 번만 기록되므로 중복 메시지 문제를 피할 수 있다.
FIFO큐는 약 2만개의 인플라이트 메시지를 처리할 수 있다.

FIFO 큐는 메시지 단위로 큐를 분할에 큐에 입력된 메시지의 하위 그룹을 만들 수 있다.
따라서 메시지를 전송하는 다수의 프로듀서 객체가 있는 경우 메시지 그룹을 이용해 프로듀서별 메시지 순서를 관리할 수 있따.

폴링

큐에서 메시지를 확인할 때 메시지 도착 여부 조회 옵션인 숏폴링 또는 롱폴링 중 하나를 선택할 수 있다.

기본값인 숏폴링은 일부 메시지 누락이 있더라도 즉시 메시지를 확인해야할때 사용한다.

롱폴링은 약간의 지연이 있더라도 큐에 있는 모든 메시지를 정확하게 확인해야할 떄 사용한다.

데드레터 큐

컨슈머가 제대로 처리하지 못한 메시지가 큐에 남을때가 있다. 이러한 메시지는 큐에서 벗어날 수 없으며 이를 데드레터 라고 한다.

이런 문제를 해결하려고 SQS를 통해 자동으로 이 와 같은 메시지를 소스 큐에서 꺼내서 데드레터 큐에 따로 보관하도록 할 수 있다.
기존 큐와 동일한 타입의 큐를 생성하고 큐의 maxReceiveCount 속성을 이용해 메시지의 최대 인출 시도 횟수를 설정해준다.

하나의 메시지가 데드레터 큐로 옮겨지면 원본 생성 일자를 기준으로 삭제된다.

가용성을 고려한 설계

가용성을 높이기 위해 더 많은 리소스를 프로비전할수록 복잡성은 높아지고 비용은 더 많이 발생하게 된다. 즉 가용성과 복잡성은 비례관계에 있다.

일반적으로는 가용성 기준인 99%(연간 3.5일의 다운타임), 99.9%(연간 9시간의 다운타임), 99.99%(연간 40분) 등의 목표를 달성하기 위한 방법을 고민하게된다.

profile
기록 쌓기

0개의 댓글