DevOps & SRE/AWS & Cloud

[클라우드 인프라와 API의 구조] 10. 오브젝트 스토리지 리소스를 제어하는 방법

반응형

1. 스토리지의 종류

  1. 블록 스토리지
    • 스토리지 관점: 블록 단위로 데이터를 인식
    • OS 관점: 블록 스토리지 안의 파일들을 파일 시스템상의 다른 파일들과 동일하게 인식하고 처리
    • 서버 관점: 스토리지를 디바이스로 인식하는데 주로 로컬 디스크나 데이터베이스를 사용하면서 온라인 시스템의 정보 처리 용도로 많이 활용
  2. 네트워크 스토리지
    • TCP/IP로 네트워크에 연결하는 특징.
    • 대표적인 프로토콜에는 NFS (Network File System)이 있음.
    • NFS 서비스를 마운트 해서 사용하기 때문에 OS의 파일 시스템 관점에서는 다른 파일들과 다를 바 없이 똑같이 파일로 인식
  3. 오브젝트 스토리지
    • 파일단위로 데이터를 관리하고 HTTP/HTTPS 프로토콜로 데이터에 접근.

 

2. 오브젝트 스토리지의 내부 구조

  • HTTP, HTTPS로 파일을 제어하기 때문에 내부에 HTTP 서버를 내장.
  • 이러한 이유로 손쉽게 웹 사이트를 만들고 서비스를 할 수 있음. (S3를 이용한 프론트 배포)
  • 오브젝트 스토리지에는 HTTP 서버, 파일 시스템, 네트워크 디바이스 접속까지 필요한 내용은 모두 포함.

 

2-1. 블록 스토리지 vs 오브젝트 스토리지

2-1-1. API 제어 범위 측면

블록 스토리지

  • 블록스토리지의 파일은 서버 리소스의 파일 시스템에서 인식.
  • 블록 스토리지 자체는 리소스로 인식되어 API로 제어할 수 있었지만, 파일은 API가 아닌 OS 명령으로 제어해야 함.

 

오브젝트 스토리지

  • 오브젝트 스토리지에서는 파일 자체를 클라우드에서 제어할 수 있기 때문에 API를 사용하여 제어가 가능.

 

2-1-2. 내구성 측면

  • 기본적으로 파일을 여러 곳에 Replication 하는 기능이 있어 백업을 따로 할 필요가 없음. (블록 스토리지의 경우 파일을 원격지에 분산 저장하여 동기화를 시킨다거나 스냅샷을 활용한 백업 등을 고려해야 함)
  • 이러한 이유로 내구성 측면에서는 오브젝트 스토리지가 블록 스토리지보다 상대적으로 우수.

 

2-1-3. 용량 측면

블록 스토리지

  • 미리 필요한 저장 용량을 예측한 다음 블록 디바이스를 OS에 마운트할 때 용량을 정해줘야 하고, 실제 서비스를 운영 중이라면 미리 상정한 용량을 초과하지 않도록 감시해야 함.

오브젝트 스토리지

  • 총 용량에 대해 신경 쓸 필요가 없음.

 

2-2. 오브젝트 스토리의 특징 정리

  • 파일은 HTTP/HTTPS로 접근
  • API로 파일을 제어할 수 있음.
  • 여러 곳에 리플리케이션된다.
  • 미리 용량 산정을 할 필요가 없음

 

2-3. 사용하는 용도

오브젝트 스토리지

  • 정적인 웹 사이트나 용량이 큰 동영상 파일을 제공할 때 활용
  • 빅데이터와 같이 데이터 양이 폭발적으로 늘어나서 분석이 쉽지 않은 로그 파일을 저장.
  • 최근에는 오브젝트 스토리지를 OS에서 직접 파일 시스템의 형태로 접근하는 방식으로도 사용됨.

 

블록 스토리지

  • 안정적으로 높은 I/O 성능을 내야 하고 파일의 정합성을 보장하기 위한 락(Lock)까지 고려해야 할 경우

 

3. 오브젝트 스토리지를 구성하는 요소

오브젝트 스토리지는 기본적으로 파일을 관리하는 목적으로 만들어짐.

Account, Bucket, Object 세 가지 리소스로 구성됨.

Account, Bucket, Object

Bucket

  • 파일 시스템에 비유하자면 최상위 폴더 개념.
  • Amazon S3에서는 버킷의 이름이 고유해야 함. (버킷 이름이 인터넷 상에 FQDN으로 공개되기 때문에 Account 범위 밖에서도 고유해야 함)

 

Object

  • 버킷 안에 저장되는 파일
  • Prefix와 파일명을 포함한 것을 켜라고 부름.

 

세 리소스 간의 관계

Account : Bucket = 1 : n

Bucket : Object = 1: n

 

4. API를 통한 리소스 제어

  • 버킷 생성, 오브젝트 저장
  • 버킷과 오브젝트 설정 정보 변경
  • 오브젝트 목록 조회
  • 오브젝트 복사
  • 멀티파트 업로드

등을 API를 통해 제어할 수 있음. (CLI로도 가능)

 

4-1. 멀티파트 업로드

필요성

오브젝트 스토리지는 조작할 수 있는 파일의 크기에 제약이 있음.

파일 크기가 커질수록 전송할 때 부하가 더 커져서 스루풋을 향상시킬 목적으로 파일을 분할한 후, 병렬로 처리할 수 있음.

이러한 요구사항을 지원하기 위해 오브젝트 스토리지는 멀티파트 업로드라는 기능을 제공함.

 

4-1-1. 멀티파트 업로드 동작 순서

  1. 오브젝트를 분할해서 파트를 생성.
  2. 생성된 파트를 업로드
  3. 파트를 결합해서 원래 오브젝트를 생성.

AWS S3에서는 세 단계 각각에 대한 API가 따로 존재.

 

5. 오브젝트 스토리지의 설정 변경을 위한 API

5-1. ACL 기능의 활성화

ACL이란?

  • 버킷, 오브젝트, 모두를 대상으로 접근 제어를 할 수 있는 기능.
  • AWS S3는 그룹 정보를 활용.

 

5-2. 버저닝과 수명 주기

버저닝 (Versioning)

  • 한 오브젝트가 변경될 때마다 그 사실을 이력으로 남겨 여러 버전을 보관하는 기능
  • 버저닝을 사용할 때는 버킷 전체를 대상으로 설정하는데 버저닝 된 오브젝트에는 버전 ID가 부여됨.
  • 버저닝 기능이 활성화되어 있는 경우 최신 버전의 파일을 삭제하더라도 이전 버전의 오브젝트는 남게 됨.

 

수명주기

  • 일정 기간 후에 오브젝트를 물리적으로 삭제하도록 규칙을 정할 수 있는 기능
  • S3에서는 PUT Bucket lifecycle API를 통해 활성화할 수 있음.
  • 예를 들어 오브젝트 생성 일자 기준 며칠 후, 해당 오브젝트가 최신 버전이 되고 며칠 후, 최신 버전이 아니게 된 지 며칠 후 등 다양한 방식으로 구성 가능

 

5-3. 암호화

보안에 민감한 주요 정보를 오브젝트 스토리지에 저장하는 경우, 암호화 기능이 필요함.

암호화 방식

  • 서버 측 암호화
  • 클라이언트 측 암호화

 

서버 측 암호화

  • 버킷 전체에 암호화를 적용하는 방법
  • 오브젝트를 버킷에 저장할 때 암호화하고 사용자가 오브젝트를 가져갈 때 복호화.
  • 접근 권한과 키 정보만 있으면 오브젝트의 암호화 여부와는 상관없이 파일에 접근할 수 있음.

 

클라이언트 측 암호화

  • 클라이언트가 오브젝트를 암호화한 후 업로드하는 방식
  • 사용된 암호화 키는 클라우드 안에 메타 데이터로 관리.
  • 이 오브젝트를 다운로드하면 암호화된 상태 그대로 받아지기 때문에 복호화하기 전에는 그 내용을 알 수 없음.
  • 클라우드에 의존하지 않는 방법으로 암호화를 하고 싶은 경우 사용.

 

5-4. 웹사이트 기능

오브젝트 스토리지는 HTTP 프로토콜로 입출력을 하기 때문에 오브젝트 파일이 HTML 파일이라면 공개 권한을 설정한 후에 HTTP/HTTPS를 통해 FQDN 형식의 URL을 요청하면 웹 페이지처럼 오브젝트의 내용을 볼 수 있음.

 

5-5. CORS (Cross Origin Resource Sharing)

오브젝트 스토리지를 정적 웹 사이트로 활용할 때 CORS를 고려해야 함.

CORS는 XMLHttpRequest가 서로 다른 도메인을 넘나들 때 보안상 접근이 제한되는 제약이 있는데 이것을 해결하는 방법.

오브젝트 스토리지에 CSS나 동영상, 각종 스크립트 파일 등을 저장한 후, 외부 도메인의 웹 사이트에서 XMLHttpRequest를 통해 접근을 시도하면 동일 출처 정책(Same-origin Policy)에 제약이 걸리게 됨.

AWS S3에서는 이러한 제약을 극복하기 위해 CORS 설정을 할 수 있음.

  • AllowedOrigin: 허용할 사이트 (오리진의 도메인 지정)
  • AllowedMethod: 허용할 HTTP 메소드를 정의
  • AllowedHeader: 사전 요청으로 허용된 HTTP 헤더가 지정.

 

사전 요청

  • 크로스 도메인 접근을 허용하는지 사전에 확인하는 요청
  • 크로스 도메인 접근이 가능한지는 오브젝트의 경로가 포함된 URI에 대해 OPTION 방식으로 API를 호출하면 확인할 수 있음.

 

6. 오브젝트와 API의 관계

6-1. 최종 정합성

정합성

  • 오브젝트의 상태가 확정되면 그 상태를 확인할 때 모순 없이 현재 상태 그대로가 재확인된다는 특성.
  • 파일 시스템이나 관계형 데이터베이스에도 정합성이라는 특성이 있음.
  • 반면 오브젝트 스토리지에서는 정합성이 신규 생성 시에만 적용됨. (오브젝트를 생성한 후, 읽기를 할 때만 정합성이 보장됨)

 

최종 정합성

  • 분산 환경에서 나타나는 특성
  • 오브젝트의 상태가 확정되더라도 그 상태를 확인하는 시기에 따라 현재 상태가 아닌 이전 상태가 확인될 수도 있다는 특성.
  • PUT을 사용해서 파일을 변경할 때의 타임스탬프는 클라이언트 측에서 실행된 시간이 아니라 변경 요청이 네트워크를 통과한 후의 서버 측의 시간을 따름. 따라서 기존의 오브젝트에 대해 PUT이 두 번 이상 실행된 경우, 처음 실행한 요청이 네트워크 지연으로 인해 두 번째 요청한 PUT보다 늦게 처리가 되었다면 처음 수정하려 시도했던 것이 나중에 다시 수정한 것을 뒤늦게 덮어써버리는 역전 현상이 발생하기도 함.
  • 이러한 현상이 발생하는 이유는 변경 작업을 위한 락 처리가 되지 않기 때문인데, 락 처리가 필요하다면 별도로 직접 제어 로직을 구현해야 함.
  • DELETE의 경우도 마찬가지.

 

6-2. Etag를 사용한 오브젝트 확인

최종 정합성을 가지는 구조인 오브젝트 스토리지에서 오브젝트가 제대로 저장되었는지 확인하려면 HTTP의 Etag헤더를 활용.

Etag

  • 엔티티 태그를 의미, 값이 MD5 해시 알고리즘으로 만들어짐.
  • HTTP 응답에 이 Etag 값이 포함되어 있다면 HTTP 처리뿐만 아니라 오브젝트에 대한 처리까지 완료되어 파일이 정상적으로 반영되었다고 판단할 수 있음.

 

6-3. 멱등성과의 관계

멱등성

  • 몇 번을 실행해도 같은 결과가 나온다는 특성

GET, HEAD는 물론 PUT, DELETE까지 멱등성이 보장되도록 만들어져 있음.

 

7. 오브젝트 스토리지의 내부 구성

오픈 스택 Swift의 내부 구성.

Swift는 크게 프론트와 백엔드로 나뉨

  • 프론트: HTTP 요청을 접수하는 액세스 티어
  • 백엔드: 오브젝트를 데이터로 저장하는 스토리지 티어

 

7-1. 액세스 티어의 아키텍처

오브젝트 스토리지는 HTTP 프로토콜을 통해 파일을 주고받음.

오픈스택은 액세스 티어에 HTTP 프록시가 구성되어 있고 대량의 HTTP 요청에도 견딜 수 있도록 로드 밸런서를 두어 부하를 분산하고 있음.

백엔드인 스토리지 노드에 대한 접근 제어 설정을 Ring이라고 하고, Ring은 스토리지에 저장된 엔티티의 이름과 실제 물리적인 저장 위치를 연결시킴.

 

7-2. 스토리지 노드의 아키텍처

오브젝트를 저장하는 스토리지 노드군을 존이라고 부름.

내구성을 높이기 위해 존들은 서로 물리적으로 분리되어 있고, 오브젝트가 저장될 때에는 Ring에 설정된 레플리카 정보에 따라 분산 배치할 존이 정해짐.

리플리케이션

  • 파일의 리플리케이션은 어카운트, 버킷, 오브젝트 각각의 파일에 대해 별도로 처리된다.
  • 리플리케이션을 할 때는 확인 → 복사의 두 단계로 처리하는데 내부적으로 리플리케이터라는 파일 동기 프로세스가 이런 작업을 수행함.
  • 리플리케이터는 파일의 복사본이 Ring에 설정한 존에 제대로 잘 들어 있는지 확인하기 위해 정기적으로 각 파티션을 살펴보는데 이때 해시와 타임스탬프 정보를 서로 비교.

 

7-3. 읽기, 쓰기의 동작 방식

오브젝트는 여러 개의 존에 분산되어 있음.

 

Read

  • Read를 할 때는 GET 요청이 실행되는데 분산된 존 중 한 곳에서 오브젝트를 읽어온다.
  • 이것은 API 요청이 들어오면 부하 분산을 해서 어느 한 존이 처리하도록 한다는 의미로, 같은 여러 번 들어오면 다른 존의 파일을 가져가도록 분산됨.

 

Write

  • POST나 PUT 요청이 실행되면 부하를 분산하고 여러 존 중에서 결정된 한 존에 오브젝트를 생성하거나 변경함.
  • 생성이나 변경이 완료되면, 이후 Ring에 설정된 다른 존에 이 파일을 리플리케이션함.

Read를 할 때는 Ring에 설정된 존에만 접근하면 되고 Write를 할 때는 Ring에 설정된 레플리카 전체에 접근해야 하기 때문에 HTTP 프록시에 병목만 걸리지 않으면 Read를 Write보다 더 많이 처리할 수 있음.

 

7-4. 분산 리플리케이션과 최종 정합성의 관계

Write는 PUT을 한 다음 내부적으로 리플리케이션을 하고, Read는 실행 빈도가 높으면서도 부하 분산도 됨.

그래서 Read를 실행하는 타이밍에 따라 변경 이전의 데이터를 참조할 수도 있는데 이런 현상이 바로 최종 정합성의 특성.

반응형