REL 5: 분산 시스템에서 장애 완화 또는 극복을 위한 상호 작용은 어떻게 설계합니까?
분산 시스템에서 구성 요소(예: 서버 또는 서비스)는 통신 네트워크를 사용하여 상호 연결됩니다. 워크로드는 이러한 네트워크에서 데이터 손실 또는 지연 시간이 발생하더라도 안정적으로 작동해야 합니다. 분산 시스템의 구성 요소는 다른 구성 요소나 워크로드에 부정적인 영향을 미치지 않는 방식으로 작동해야 합니다. 이러한 모범 사례를 준수하면 워크로드가 스트레스 또는 장애를 견디고, 더 빠르게 이를 복구하며, 이러한 장애의 영향을 완화할 수 있습니다. 그러면 결과적으로 MTTR(평균 복구 시간)이 개선됩니다.
리소스
Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders’ Library
(DOP328)
Error Retries and Exponential Backoff in AWS
Amazon API Gateway: Throttle API Requests for Better Throughput
The Amazon Builders' Library: Timeouts, retries, and backoff with jitter
The Amazon Builders' Library: Avoiding fallback in distributed systems
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
The Amazon Builders' Library: Caching challenges and strategies
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies
to Improve Reliability
CircuitBreaker (summarizes Circuit Breaker from “Release It!” book)
Michael Nygard “Release It! Design and Deploy Production-Ready Software”
모범 사례:
-
관련 하드 종속성을 소프트 종속성으로 변환하는 정상적인 성능 저하 구현: 구성 요소의 종속성이 비정상 상태인 경우에도 구성 요소 자체가 성능이 저하된 방식으로 작동할 수 있습니다. 예를 들어 종속성 호출이 실패하면 미리 결정된 정적 응답으로 장애 조치됩니다.
-
요청 조절: 예기치 않은 수요 증가에 대응하기 위한 완화 패턴입니다. 일부 요청은 처리되지만 정의된 제한을 초과하는 요청은 거부되고 병목 현상이 발생했음을 나타내는 메시지를 반환합니다. 클라이언트는 요청을 다시 중단하고 중단하거나 더 느린 속도로 다시 시도할 것이라는 기대입니다.
-
재시도 호출 제어 및 제한: 지수 백오프를 사용하여 점진적으로 더 긴 간격 후에 다시 시도합니다. 지터를 도입하여 이러한 재시도 간격을 무작위로 지정하고 최대 재시도 횟수를 제한합니다.
-
빠른 실패 및 대기열 제한: 워크로드가 요청에 성공적으로 응답할 수 없는 경우 빠르게 실패합니다. 이렇게 하면 요청에 연결된 리소스를 해제할 수 있고 리소스가 부족한 경우 서비스 복구를 허용할 수 있습니다. 워크로드가 성공적으로 응답할 수 있지만 요청 속도가 너무 높은 경우에는 대기열을 사용하여 요청을 버퍼링합니다. 하지만 긴 대기열을 허용하지 마십시오. 대기열이 길면 클라이언트가 이미 포기한 무효 요청을 처리할 수 있습니다.
-
클라이언트 시간 제한 설정: 시간 제한을 적절히 설정하고, 체계적으로 확인합니다. 기본값을 사용해서는 안 됩니다. 기본값은 일반적으로 너무 높게 설정됩니다.
-
가능한 경우 서비스를 상태 비저장으로 설계: 서비스는 상태를 필요로 하지 않거나 디스크 또는 메모리의 로컬로 저장된 데이터에 종속성이 없도록 서로 다른 클라이언트 요청 간에 상태를 오프로드해야 합니다. 이렇게 하면 가용성에 미치는 영향 없이 서버를 대체할 수 있습니다. Amazon ElastiCache 또는 Amazon DynamoDB는 오프로드된 상태에 적합한 대상입니다.
-
비상 레버 구현: 이 프로세스는 워크로드의 가용성에 미치는 영향을 신속하게 완화할 수 있는 프로세스입니다. 이 프로세스는 근본 원인이 없는 상태에서 작동할 수 있습니다. 이상적인 비상 레버는 완전히 결정적인 활성화 및 비활성화 기준을 제공하여 확인자에 대한 인지 부담을 0으로 줄여줍니다. 레버의 예로는 모든 로봇 트래픽을 차단하거나 정적 응답을 제공하는 것이 있습니다. 레버는 수동인 경우가 많지만 자동화할 수도 있습니다.
개선 계획
관련 하드 종속성을 소프트 종속성으로 변환하는 정상적인 성능 저하 구현
- 정적 응답을 반환함으로써 워크로드는 종속성에서 발생하는 장애를 완화합니다.
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies to Improve Reliability - 재시도 작업이 실패할 가능성이 있는 경우 이를 감지하고 회로 차단기 패턴을 이용해 클라이언트가 실패한 호출을 실행하지 못하도록 합니다.
CircuitBreaker
요청 조절
- Amazon API Gateway 사용
Throttle API Requests for Better Throughput
재시도 호출 제어 및 제한
Error Retries and Exponential Backoff in AWS
- Amazon SDK는 기본적으로 이 기능을 구현합니다. 자체 종속 서비스를 호출할 때 종속성 계층에 비슷한 로직을 구현합니다. 사용 사례를 기반으로 시간 초과 대상 및 재시도 중단 시점을 결정합니다.
빠른 실패 및 대기열 제한
- 서비스가 부담을 받고 있는 상황에서 빠른 실패 구현
Fail Fast - 대기열 제한: 대기열 기반 시스템에서는 처리가 중지되었는데도 메시지가 계속 수신될 경우 처리되지 않은 메시지가 대용량 백로그에 누적되어 처리 시간이 늘어날 수 있습니다.
작업이 너무 늦게 완료되어 결과가 소용 없게 되고, 결국 대기열을 통해 방지되었어야 할 가용성 히트가 발생할 수 있습니다.
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
클라이언트 시간 제한 설정
AWS SDK: Retries and Timeouts
가능한 경우 서비스를 상태 비저장으로 설계
- 요청 파라미터에 실제로 저장될 수 있는 상태를 제거합니다.
- 일부 데이터(쿠키 등)는 헤더 또는 쿼리 파라미터로 전달될 수 있습니다.
- 리팩터링을 통해 요청에 빠르게 전달될 수 있는 상태를 제거합니다.
- 상태가 필요한지 여부를 조사한 후 상태 추적을 Amazon ElastiCache, Amazon RDS, Amazon DynamoDB 또는 타사 분산
데이터 솔루션과 같은 복원성이 있는 다중 영역 캐시 또는 데이터 스토어로 옮깁니다.: 복원성이 있는 데이터 스토어로 옮길 수 없는 상태를 저장합니다.
- 일부 데이터는 요청별로 필요하지 않으며 요청에 따라 검색 시 검색될 수 있습니다.
- 비동기식으로 검색할 수 있는 데이터를 제거합니다.
- 필수 상태 요구 사항을 충족하는 데이터 스토어를 결정합니다.
- 비관계형 데이터를 위한 NoSQL 데이터베이스를 고려합니다.
비상 레버 구현
- 비상 레버 구현 및 사용을 위한 팁
- 레버가 활성화되면 더 적은 수의 작업을 수행
- 단순하게 유지하고 바이모달 동작을 방지
- 레버를 정기적으로 테스트
- 다음은 비상 레버가 아닌 작업의 예입니다.
- 용량 추가
- 서비스를 사용하는 클라이언트의 서비스 소유자를 호출하고 호출을 줄이도록 요청
- 코드 변경 및 릴리스