AWS re:Invent 리캡

Amazon S3 심층 분석(STG407)

리캡 시리즈

세션 노트

소개

  • 서버 수준의 장애 처리 전략
  • 이 시리즈는 S3 작업의 하위 수준 세부 사항에 중점을 둠
  • 올해의 초점: 가용성을 고려한 설계 접근 방식
  • 두 가지 관점: 시스템 수준 및 서버 수준
  • 장애 아키텍처, read-after-write 일관성 및 장애 구현에 대한 시스템 수준
  • 관점 용어 정의
  • 가용성: 장애에 대처하는 능력
  • 장애: 실패할 수 있는 구성 요소(드라이브, 서버, 랙, 건물)
  • 장애 유형: 영구적 손실 또는 일시적 사용 불가(전력, 네트워크, 과부하)
  • 설계 목표: 목표를 중심으로 시스템 설계(예: 99.99% 가용성, 11 9s 내구성, read-after-write 일관성)
  • S3의 설계 목표
  • 고가용성과 내구성을 위해 설계
  • 2020년에 read-after-write 일관성 도입
  • 2020년 이전에는 일관성 보장을 위반하는 것도 허용 가능한 장애 처리 방식에 포함됨

일관성 출시 전 S3: 장애 처리와 인덱싱 하위 시스템

일관성의 정의

  • 일관성: 객체에 대한 GET이 해당 객체에 수행된 가장 최근 PUT을 반영하는 속성
  • 인덱싱 하위 시스템
  • 객체 메타데이터(이름, 태그, 생성 시간)를 보관
  • 모든 데이터 플레인 요청(GET, PUT, LIST, HEAD, DELETE)에서 액세스됨
  • 스토리지 하위 시스템보다 인덱스에 더 많은 요청이 전달됨
  • 인덱싱 시스템의 핵심: 인덱스 항목을 내구성 있게 보관하는 전용 스토리지
  • 쿼럼 기반 알고리즘
  • 쿼럼 기반 알고리즘을 사용해 복제본 전반에 데이터 저장
  • 장애를 허용함
  • 단일 장애 도메인에서의 상관 장애를 피하기 위해 서버를 별도의 가용 영역(AZ)에서 실행
  • 단일 디스크, 서버, 랙 또는 영역의 장애는 데이터의 일부에만
  • 영향 인덱스의 쿼럼 구현
  • 읽기와 쓰기는 서버 과반수에 도달해야 함
  • 예: 값 A 쓰기가 모든 노드에서 성공
  • 값 B 쓰기: 한 노드가 실패하지만 서버 과반수에서 B가 성공(가용성에 영향 없음)
  • 읽기 작업이 읽기를 시작할 때 한 서버가 실패하지만 나머지 두 서버가 값 B를 반환
  • 연결된 타임스탬프로 충돌 해결(B가 A보다 우선)
  • 요청 처리 도중 서버 장애가 발생해도 읽기와 쓰기가 성공
  • 여러 노드와 장애 허용 덕분에 시스템 가용성이 유지됨

분산 시스템의 쿼럼 기반 알고리즘

개요

  • 쿼럼 기반 알고리즘은 데이터 읽기나 쓰기 같은 작업에 최소 노드 수(쿼럼)의 동의를 요구해 일관성과 내결함성을 보장합니다.
  • 일부 노드가 실패할 때 데이터 손상을 방지합니다.

핵심 개념

쿼럼

  • 전체 노드 수(N), 쓰기 쿼럼(W), 읽기 쿼럼(R)을 정의합니다.
  • 읽기 작업:
  • 읽기 요청을 노드 집합에 보내며, R개 노드에서 응답을 받으면 작업이 성공합니다.
  • 쓰기 작업:
  • 쓰기 요청을 노드 집합에 보내며, W개 노드가 확인하면 쓰기가 커밋됩니다.
  • 일관성:
  • R + W > N 규칙은 읽기 집합과 쓰기 집합이 최소 한 노드에서 겹치도록 하여 모든 읽기가 최신 쓰기 데이터를 보게 합니다.
  • 내결함성:
  • 한 노드가 실패해도 시스템은 쿼럼을 구성할 수 있습니다(예: 5개 중 3개 시스템은 2개 장애를 허용).

예시 및 적용 사례

데이터 복제

  • 클러스터 전반에서 모든 데이터 복사본의 일관성을 유지합니다(예: Cassandra 같은 데이터베이스).
  • 상호 배제(Maekawa 알고리즘):
  • 노드는 공유 리소스(임계 구역)에 액세스하기 위해 자신의 쿼럼에 권한을 요청하여 한 번에 하나의 노드만 진입하도록 합니다.
  • 합의(Paxos):
  • 분산 시스템이 단일 값에 합의하기 위한 기본 프로토콜로, 리더 선출과 상태 머신 복제에 중요합니다.

핵심 매개변수(URW 모델)

  • N: 전체 데이터 복사본(노드) 수.
  • W: 쓰기 쿼럼(쓰기를 확인하는 데 필요한 노드).
  • R: 읽기 쿼럼(읽기를 확인하는 데 필요한 노드).

S3 쿼럼 기반 시스템: 고가용성과 일관성 보장

S3 호환 시스템의 쿼럼 원칙

  • 고가용성과 일관성을 위해 쿼럼 원칙(노드 과반수의 동의)을 활용
  • 클러스터 또는 엣지 구성과 관련됨(예: Amazon S3 on Snowball Edge)

S3 유사 시스템의 작동 방식

분산 합의

  • 모니터 또는 관리자가 쿼럼(일반적으로 3개 이상)을 구성해 노드 상태를 추적
  • 클라이언트에 사용 가능한 스토리지 노드를
  • 알림 쓰기 작업:
  • 스토리지 노드 과반수(쿼럼)가 승인해야 쓰기 성공
  • 클러스터 전반에서 데이터 내구성과 일관성을 보장
  • 읽기 작업:
  • 최신 데이터를 보장하기 위해 복제본 쿼럼을 대상으로 읽기
  • 수행 내결함성:
  • 총 복제본이 2f+1개일 때 f개의 노드 장애를 허용 가능
  • 쿼럼이 유지되는 한 새 리더를 선출하고 작업을 계속할 수 있음

주요 예시

Amazon S3 on Snowball Edge

  • Snowball Edge 디바이스 클러스터는 S3 호환 스토리지에 쿼럼을 사용
  • 디바이스 상태와 데이터 가용성을 관리
  • Ceph:
  • 쿼럼과 함께 모니터 및 OSD(Object Storage Daemon)를 사용합니다.
  • S3 호환 백엔드로서 클러스터 상태와 데이터 가용성을 유지합니다.
  • Object Storage Daemon(OSD)은 Ceph 같은 분산 시스템에서 데이터를 저장하는 핵심 프로세스로, 개별 스토리지 단위 역할을 하며 로컬 디스크(HDD/SSD)를 관리하고 대량의 비정형 데이터에 대한 복제, 복구, 데이터 분산을 처리하므로 확장 가능하고 복원력 있는 객체 스토리지의 기반이 됩니다.
  • 분산 합의 라이브러리:
  • GitHub는 리더 선출과 쿼럼에 S3의 조건부 작업(ETag)을 사용
  • OSD의 핵심 기능:
  • 데이터 스토리지: 로컬 파일 시스템(예: XFS)에 실제 데이터 객체를 저장합니다.
  • 데이터 관리: 클러스터 전반의 데이터 복제(복사본 생성)와 복구(손실 데이터 재구축)를 관리합니다.
  • 하트비트 모니터링: 다른 OSD의 상태를 확인하고 Ceph Monitor에 상태를 보고합니다.
  • 네트워크 액세스: 클라이언트가 저장된 데이터에 네트워크로 액세스할 수 있게 합니다.

핵심 S3와 쿼럼 기반 방식 비교

Amazon S3(핵심)

  • 글로벌 인프라 전반에서 강력한 read-after-write 일관성을 기본 제공
  • 사용자가 쿼럼을 명시적으로 관리할 필요 없음
  • S3 쿼럼 기반(클러스터/엣지):
  • 사용자가 관리하는 S3 호환 디바이스 클러스터 내부에 쿼럼 개념 적용
  • 클러스터 내부의 일관성과 가용성 보장

S3의 시스템 수준 가용성 설계와 캐싱 계층

핵심 개념

  • 라우팅할 여러 노드와 장애에 대비한 여유 용량
  • 99.99% 가용성 목표를 달성하도록 구성하고 규모 산정 2020년
  • 이전의 Read-After-Write 일관성
  • 읽기와 쓰기가 겹쳤기 때문에(둘 다 서버 과반수에 도달해야 했음) 읽는 쪽에서 쓰인 값을 확인
  • 질문: 2020년 이전에는 왜 S3가 read-after-write 일관성을 제공하지 않았는가?
  • 답: 캐싱 계층
  • 캐싱 계층
  • S3 프런트엔드는 자주 액세스하는 객체를 대규모로 캐싱
  • 일관되지 않은 읽기: 마지막으로 쓴 값 C가 아니라 값 B 반환
  • 캐시에서는 읽기와 쓰기가 겹치지 않음
  • 캐시는 핵심 가용성 속성을 갖춤(여러 호스트가 요청을 받을 수 있고 장애를 허용)
  • 캐시에서 읽기와 쓰기가 겹치지 않음
  • 2020년 이전에는 설계 목표에 일관성이 포함되지 않았으므로 허용 가능한 장애 대응
  • 방식 캐싱 계층 예시:
  • 스토리지에는 값 B가 있고 캐시 노드는 비어 있음
  • 읽는 쪽이 캐시 노드를 통해 읽어 값 B가 반환되고 캐시에 상주
  • C 쓰기가 객체를 덮어쓰고 복제본에 유지됨(C C C)
  • 값 B와 C가 별도 노드에 캐싱됨(2020년 이전 설계)
  • 읽기가 이전 캐시 노드로 라우팅되어 값 B를 반환(일관되지 않은 읽기)

캐시 일관성 프로토콜로 중첩 문제 해결

가장 많이 요청된 기능: 일관성

  • 2020년 이전에 가장 많이 요청된 기능은 일관성이었음
  • 목표: 캐싱 계층의 중첩 문제 해결 캐시
  • 일관성 프로토콜
  • 빠르고 효율적이며 가용성이 높아야 했음
  • 일부 서버의 장애를 허용하면서 여러 서버가 요청을 받는 속성 유지
  • 해결책: 복제 저널
  • 복제 저널
  • 노드가 서로 연결된 분산 데이터 구조
  • 쓰기가 노드를 순차적으로 통과
  • 모든 노드가 다음 노드로 전달
  • 저널을 통과한 쓰기는 스토리지 노드 쿼럼으로 전송
  • 저널은 최근 기록을 추적하고 순서에 합의
  • 예: A가 B보다 먼저 옴
  • 쿼럼 기반 시스템은 순서를 올바르게 판단할 수 없었음
  • 저널은 변경에 대해 명확히 정의된 순서를
  • 생성 시퀀스 번호와 워터마크
  • 모든 쓰기에 시퀀스 번호 할당(시간에 따라 증가)
  • 예: A(시퀀스 번호 1), B(시퀀스 번호 2), C(시퀀스 번호 3)
  • 스토리지 노드는 값과 함께 시퀀스 번호를 학습
  • 시퀀스 번호가 값과 함께 캐시에 저장됨
  • 캐시 노드는 특정 시퀀스 번호 이후 쓰기가 도착했는지 확인 가능
  • Witness 시스템
  • 목적: 인덱스 쓰기의 high water mark 추적
  • Witness는 실제 데이터가 아닌 시퀀스 번호만 보관하면 됨
  • Witness는 마지막 시퀀스 번호를 과대 추정해도 됨(호출자에게 데이터가 오래되었다고 알리는 것은 안전)
  • 오래되었다는 응답을 받은 호출자는 스토리지에서 읽어 올바른 결과를 얻음

동적 재구성으로 장애 허용과 일관성 보장

Witness 시스템

  • 저널 옆에 위치한 인메모리 데이터 구조(정수 배열)
  • 캐시 노드가 캐시된 값 이후 쓰기가 들어왔는지 확인할 수 있음
  • 수정된 읽기 및 쓰기 알고리즘:
  • 쓰기는 저널로 전달
  • 읽기는 Witness와 통신하고, 문제가 없으면 캐시에서 반환하며 오래되었으면 스토리지로
  • 이동 장애 허용 상실
  • 기존 저널 아키텍처에서는 노드 하나가 실패하면 쓰기가 시스템을 통과할 수 없음
  • 쿼럼은 쓰기를 동시에 처리하지만 저널은 쓰기를 순차적으로 전송
  • 저널의 노드 장애는 전체 시스템을 중단시킬
  • 수 있음 동적 재구성
  • 장애 허용 문제를 해결하기 위해 도입
  • 저널의 노드는 서로의 가용성을 모니터링
  • 지속적으로 서로 ping하고 시스템을 통해 메시지를 전달
  • 노드는 이웃 노드의 가용성에 대한 최신 정보를 보유
  • 문제가 발생하면 노드는 쿼럼 기반 구성 시스템에 저널 재구성을 요청
  • 노드 장애 후 수 밀리초 이내에 재구성
  • 구성 시스템 자체도 쿼럼 기반
  • 결과
  • 장애를 허용하고 읽기와 쓰기가 겹치는 캐시
  • 이제 S3는 일관성과 고가용성을 모두 제공
  • 처음부터 가용성을 고려해 설계하여 일관성 출시 후에도 고가용성
  • 유지 시스템 전반의 가용성 관점
  • 선택할 수 있는 서버가 많이 필요
  • 일부에서만 성공하면 됨
  • 장애 발생 시 시스템을 신속하게 재구성하는 능력
  • 저널 같은 시스템에도 쿼럼 기반 알고리즘이 항상 존재

구현 수준에서 장애 처리

장애 이해

  • 질문: 무엇이 실패할 수 있는가?
  • 함께 발생하는 장애인 상관 장애가 매우 중요
  • 가용성을 판단할 때 상관 장애가 핵심
  • 쿼럼 설계: 노드 하나의 장애는 괜찮지만 모든 노드가 같은 AZ나 랙에 있으면 안 됨

물리적 장애

S3의 상위 수준 물리적 구조

  • 여러 가용 영역(AZ)
  • 각 AZ에는 여러 서버 랙이 있음
  • 각 서버에는 여러 하드 드라이브가
  • 있음 물리적 장애 유형:
  • 개별 장애: 하드 드라이브 모터 고장, 플래터 긁힘
  • 상관 장애:
  • 서버 장애: 연결된 모든 하드 드라이브가 실패한 것으로 보임
  • 랙 장애: 랙의 모든 드라이브가 실패(예: 스위치 불량)
  • AZ 장애: 전체 AZ 중단(예: 정전)
  • 논리적 장애
  • 예: 플릿에 새 소프트웨어 배포
  • 한 번에 몇 개 노드에 배포하고 점진적으로 확대
  • 새 소프트웨어가 설치된 서버 집합이 장애 도메인을 형성
  • 새 소프트웨어에 버그가 있으면 해당 서버가 모두 함께 실패할 수 있음
  • 잠재적 장애를 허용할 수 있는 지능적인 배포 전략 필요

상관 장애를 고려한 설계

여러 장애 도메인에 워크로드 분산

  • 내구성과 가용성을 위해 여러 위치(예: AZ)에 객체 복제
  • 상관 장애 도메인(예: AZ, 랙, 서버)이 실패해도 데이터를 계속 사용할 수 있도록 보장

장애 유형 이해

Fail-stop 장애

  • 서버 또는 구성 요소가 작동을 중지(예: 전원 코드가 뽑힘)
  • 내결함성 시스템에서 감지하고 대응하기 쉬움
  • AZ 간 스위치의 Fail-stop 장애:
  • 일부 요청은 계속 성공(동일한 AZ 내부)
  • 다른 요청은 실패하기 시작(장애가 난 스위치를 통과)
  • 일부 요청은 성공하고 일부는 실패하는 모호한 장애 모드 발생

모호한 장애 모드를 고려한 설계

  • 중복성이 핵심: AZ 사이에 여러 스위치 배치
  • 각 리전의 3개 AZ를 링 형태로 연결
  • 링크(예: AZ1에서 AZ2)가 실패하면 우회 가능(AZ1에서 AZ3를 거쳐 AZ2)
  • 가용성 문제를 지연 시간 문제로 전환해 가용성 유지
  • 강력한 사고 모델: 한 종류의 문제를 다른 종류로 전환(예: 가용성을 지연 시간으로)

상태 저장 시스템에서 Fail-stop 장애의 과제

상태 저장 시스템의 Fail-stop 장애

  • S3 같은 시스템에서는 판단하기 까다로움
  • 그렇지 않으면 도달할 수 없는 상태로 이어질 수
  • 있음 크래시 일관성
  • Fail-stop 장애 후 시스템이 일관된 상태로 돌아와야 함
  • 예: 파일에 두 줄의 텍스트 쓰기
  • 정상 실행: 파일에 두 줄 모두 존재
  • 실행 중 Fail-stop 장애: 파일에 첫 번째 줄만 있을 수 있음
  • 장애가 없다면 도달할 수 없는 상태에 진입 도달
  • 불가능한 상태를 고려한 설계
  • 이 문제를 다룬 Shodstor(스토리지 노드 소프트웨어) 논문 작성
  • 장애와 동시성이 있을 때 도달 가능한 상태를 판단하는 데 중점

Gray 장애 처리

Gray 장애

  • Fail-stop을 넘어서는 더 복잡한 장애 모드
  • 예:
  • S3의 put 요청
  • 인터넷에서 S3 프런트엔드 서버로 요청이 들어옴
  • 프런트엔드 서버가 스토리지 노드로 데이터를 팬아웃
  • Gray 장애 정의
  • 완전한 장애(예: Fail-stop)는 아니지만 시스템이 예기치 않게 작동하도록 하는 장애
  • 예: 프런트엔드 웹 서버가 요청은 수락하지만 네트워크 문제로 일부 다운스트림 호스트에 연결할 수 없음
  • 서버는 실패한 요청에 오류를 반환하지만 계속 요청을 수락하고 응답 Gray
  • 장애 처리를 위한 재시도
  • 강력한 기법: 요청 실패 시 다른 경로(예: 다른 프런트엔드 웹 서버)에서 재시도
  • AWS SDK에는 의도적으로 다른 IP 주소에서 요청을 재시도하는 정교한 재시도 전략이 있음
  • 재시도로 시스템을 통과하는 다른 경로를 시도할 수
  • 있음 분산 시스템에서 재시도의 위험
  • 모든 서비스가 실패한 요청을 재시도하면 작업량이 엄청나게 증폭될 수 있음
  • 예: 스택 하단의 장애로 원래 요청보다 27배 많은 재시도가 발생할 수 있음
  • 과도한 재시도로 시스템에 과부하 발생
  • 가능 의도적인 재시도 전략 설계
  • 시스템 과부하를 방지하도록 의도적으로 재시도 전략을 설계해야 함
  • 예: 상위 계층에서 재시도가 발생할 것을 고려해 스택 아래쪽에서는 재시도 횟수를 줄이거나 재시도하지 않음
  • 과도한 재시도로부터 시스템을 보호하면서 가용성 보장 부하로
  • 인한 Gray 장애
  • 작업 과부하가 걸린 웹 서버에서 요청이 느려지는 형태로 나타남
  • 강력한 메커니즘: 타임아웃(클라이언트가 느린 요청을 중단하고 다른 곳에서
  • 재시도) 타임아웃의 과제
  • 타임아웃은 완벽하지 않고, 특히 재시도와 함께 사용할 때 설계가 어려움
  • 예:
  • 요청 큐가 있는 과부하 웹 서버
  • 클라이언트가 타임아웃 후 다른 곳에서 재시도
  • 서버는 클라이언트의 재시도를 알지 못한 채 타임아웃된 요청을 계속 처리
  • 클라이언트가 포기한 요청에 서버가 쓸모없는 작업을
  • 수행 혼잡 붕괴
  • 서버가 타임아웃되어 다른 곳에서 재시도된 요청만 처리하는 상태
  • 연쇄 반응: 과부하 서버가 느려져 재시도와 큐 적체가 증가
  • 서버가 재시도에서 비롯된 실패한 타임아웃 처리에만 시간을 쓰는 자기
  • 강화 순환 해결책: 역순 큐 처리
  • 큐가 가득 찬 과부하 서버를 처리하는 메커니즘
  • 큐 뒤쪽부터 처리(후입선출)
  • 불공정하지만 일부 클라이언트에 불이익을 주어 다른 클라이언트를 매우 빠르게 처리

자가 치유 시스템 설계

혼잡 붕괴에서 벗어나기

  • 역순 큐 처리: 큐 뒤쪽부터 처리(후입선출)
  • 일부 요청이 성공하도록 해 느리고 타임아웃된 요청의 적체를 줄임
  • 백오프 및 재시도: 클라이언트가 물러나 더 느리게 재시도
  • 서버가 적체를 해소할 시간을 제공
  • 준안정 장애 모드
  • 원래 문제가 해결된 뒤에도 시스템이 타임아웃된 요청 처리에만 시간을 쓰는 상태
  • 시스템 수준 장애 복구
  • 목표: S3가 수동 개입 없이 스스로 치유해야 함
  • 예: 웹 서버가 요청에 성공적으로 응답하지 못함
  • 클라이언트는 다른 곳에서 재시도하지만 해당 서버를 서비스에서 제거해야
  • 함 상태 확인
  • 서버를 자동으로 치유하는 필수 도구
  • 상태 확인 서버가 웹 서버에 요청을 보내 기능 확인
  • 서버가 상태 확인에 실패하면 서비스에서 제외 가능(예: DNS에서 제거)
  • 클라이언트가 장애 서버에 도달하지 않도록 해 장애 완화
  • S3의 AWS 인프라 사용
  • S3는 고객에게 제공되는 것과 동일한 인프라를 사용해 AWS 위에 구축
  • 웹 서버 용량: Network Load Balancer
  • DNS: Route 53
  • NLB와 Route 53을 사용해 상태 확인 구현

견고한 상태 확인과 시스템 상태에 대한 전역 관점 보장

단일 상태 확인의 위험

  • 상태 확인 서버가 실패하면 웹 서버 장애를 잘못 감지할 수 있음
  • 예: 네트워크 문제가 있는 상태 확인 서버가 모든 웹 서버를 불량으로 표시
  • 서버와 상태 확인 시스템 모두의 가용성을 고려해 설계해야
  • 함 상태 확인을 위한 여러 관점
  • S3는 여러 소스의 상태 확인을 사용:
  • 동일 리전
  • 다른 리전
  • 퍼블릭 인터넷
  • 신호를 결합해 웹 서버 상태에 대한 상세한 관점 구성
  • 상관 장애(예: 네트워크 문제) 진단에 도움
  • 로컬 결정 방지
  • 중요한 원칙: 로컬 시스템이 서비스 상태에 대한 로컬 결정을 내리게 해서는 안 됨
  • 예: 기존 상태 확인이 자체 시스템 관점에 따라 로컬 결정
  • 분산 시스템은 로컬 결정의 실수를 피하기 위해 전역 관점이 필요 시스템
  • 상태에 대한 전역 관점
  • 예: 장애가 발생하는 하드 드라이브 감지 및 복구
  • 소프트웨어가 장애 발생 중인 하드 드라이브 감지
  • 복구 조치 실행(예: 전원 재시작, 기술자의 교체) 상태
  • 확인을 위한 전역 속도 제한기
  • 상태 확인 서비스는 시스템을 변경하기 전에 전역 속도 제한기와 상의해야 함
  • 예: 상태 확인에서 장애가 발생하는 하드 드라이브를 감지하고 서비스에서 제외하려 함
  • 상태 확인 서비스가 오작동할 경우 속도 제한기가 과도한 하드 드라이브 제거를
  • 중단 가용성을 고려한 설계 요약
  • 가용성과 정확성 목표 정의
  • 목표에 맞게 전체 시스템 아키텍처 설계(예: 쿼럼 기반 아키텍처, 강력한 일관성)
  • 장애 모드와 로컬 결정 없는 복구를 이해하고 시스템 구성 요소 구현