Category: Amazon S3


AWS API 호출하기 (2) – Amazon S3 객체에 대한 미리 선언된(pre-signed) URL 생성하기

이번 블로그 포스팅은 지난 번에 올렸던 AWS API 호출하기(개론편)의 후속편입니다. 아마도 개론편 블로그를 끝까지 읽으시고도 애매모호 하셨을 것으로 생각됩니다. 실제로 HTTP/HTTPS API 호출 요청을 만들어 보면서 전체적인 흐름을 파악하고 이해를 돕도록 하겠습니다.  

‘어떤 예제가 간단하면서도 실제 업무에 도움이 될 수 있을까?’ 많이 고민하였는데요. 제목에서 추측하셨겠지만, Amazon S3 버킷에 있는 객체를 특정 시간 내에만 유효하게 공유할 수 있는 미리 선언된(pre-signed) URL을 만들어 보도록 하겠습니다. 물론 이곳을 참조해서, Java, .NET 그리고 Ruby용 SDK를 이용해 미리 선언된 URL을 쉽게 만들 수 있습니다. 또한 AWS Explorer나 기타 상용 도구에서도 이런 기능을 이용할 수 있습니다.

이번 블로그 포스팅에서는 bash 쉘 스크립트를 이용해서 이 기능을 지원하는 HTTP/HTTPS API 호출 요청을 직접 만들어 보도록 하겠습니다.

예제 쉘 스크립트는 미리 선언된 URL을 만드는데 서명 버전 4를 사용하였습니다. Amazon S3 경우 2014년 1월 30일 이후에 생성된 리전에서는 서명 버전 V2는 더 이상 지원하지 않습니다. 따라서 2016년 1월 7일 개설된 서울 리전도 서명 버전 V4 만 지원합니다.

1. 사전 준비 사항
스크립트를 작성하기 위해서는 openssl(1) 버전 1 또는 그 이상이 필요합니다. 서명키를 만들 때 키값이 문자열이 아닌 이진키값을 입력으로 받아야 하기 때문에 버전 1 이상이 필요합니다. 버전 확인은 아래와 같이 하시고, 예제와 같이 0.9.8zg 버전이면 이곳에서 소스 코드를 받아 설치하시면 됩니다. 설치 방법은 이 블로그 범위를 벗어나기 때문에 따로 설명드리지는 않겠습니다.

$ openssl version
OpenSSL 0.9.8zg 14 July 2015

그리고 사용자 신원 정보와 리전 정보를 얻기 위해서 환경 변수 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 및 AWS_DEFAULT_REGION 을 이용하였습니다. 설정 방법은 이곳이나 아래를 참조하시면 됩니다. AWS 계정에 대한 중요한 신원 정보를 스크립트 코드 내에 포함시키는 것은 위험합니다. 따라서 사용 환경에 설정하는 것을 권장합니다.

$ export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY_ID>
$ export AWS_DEFAULT_REGION=<AWS_REGION>

로케일 언어 설정은 UTF-8인코딩으로 설정합니다. 이 로케일 설정이 여러분의 작업 환경과 다르다면 bash 쉘 스크립트 내에 포함시켜도 무방합니다.

$ export  export LC_ALL=ko_kr.UTF-8
$ export LANG=ko_kr.UTF-8

2. 스크립트 작성하기
위 선행 작업이 완료되었다면, 이제 스크립트를 작성할 준비가 되었습니다.  Amazon S3 API 호출 요청은 Amazon S3 API Reference를 기본적으로 참조하였으며, 미리 선언된 URL을 만들기 위한 전반적인 작업 순서는 아래와 같습니다:

  1. 표준 요청(Canonical Request) 형식으로 메시지 내용들을 정렬하기
  2. 서명하기 위한 문자열(String To Sign) 만들기
  3. AWS 서명 버전 4(Signature) 계산하기
  4. 생성한 서명 정보를 HTTP/HTTPS API 요청에 추가하기

위 서명 계산 절차를 구체적이고 이해하기 쉽게 도식화해 놓은 것이 아래 다이어그램이며, 이 순서를 따라서 스크립스틀 작성하였습니다. 그리고 각 항목에대한 구체적인 설명은 이곳을 참조하시면 많은 도움을 얻을 수 있습니다.

아래는 위 절차에 따라 생성된 미리 선언된 URL의 한 예입니다. 가독성을 높이기 위해 URL에 줄바꿈 문자를 추가했습니다. 실제로는 한 줄로 표현되어야 합니다.

https://examplebucket.s3.amazonaws.com /test.txt?
X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=<YOUR_ACCESS_KEY_ID>/20160115/ap-northeast-2/s3/aws4_request&
&X-Amz-Date=20160115T000000Z
&X-Amz-Expires=86400
&X-Amz-SignedHeaders=host
&X-Amz-Signature=<SIGNATURE_VALUE>

그리고 URL에서 X-Amz-Credential 헤더의 값도 가독성을 위해서 “/”문자를 사용해서 표현하였습니다. 실제로는 %2F로 인코딩되어서 아래와 같이 사용되어야 합니다.

&X-Amz-Credential=<YOUR_ACCESS_KEY_ID>%2F20160115%2Fap-northeast-2%2Fs3%2Faws4_request

URL내에 인증 정보를 제공하기 위해, 다음과 같은 다양한 쿼리 매개변수들이 포함되어 있습니다.

매개변수 설명
X-Amz-Algorithm 서명 버전과 알고리즘을 식별하고, 서명을 계산하는데 사용. 서명 버전 4를 위해서 “AWS4-HMAC-SHA256” 로 설정
X-Amz-Credential 액세스 키 ID와 범위 정보(요청 날짜, 사용하는 리전, 서비스 명). 리전 명은 리전 및 엔드포인트에서 확인 가능
X-Amz-Date 날짜는 ISO 8601형식. 예: 20160115T000000Z
X-Amz-Expires 미리 선언된 URL이 유효한 시간 주기. 초단위. 정수 값. 최소 1에서 최대 604800 (7일) 예: 86400 (24시간)
X-Amz-SignedHeaders 서명을 계산하기 위해 사용되어지는 헤더 목록. HTTP host 헤더가 요구됨
X-Amz-Signature 요청을 인증하기 위한 서명

주의: X-Amz-Signature 헤더를 제외한 모든 쿼리 매개변수들은 표준 쿼리 문자열(Canonical Query String)에 포함시킵니다. 표준 헤더(Canonical Headers)는 HTTP host 헤더를 포함해야 합니다. 미리 사인된 URL을 만들 때 실제 페이로드에 대해 알 수 없기 때문에 표준 요청(Canonical Request)에 있는 페이로드 해시는 포함 안 시킵니다. 대신 “UNSIGNED-PAYLOAD” 문자열을 사용합니다.

이를 바탕으로 만든 완성된 스크립트는 아래와 같습니다. Bash 쉘 스크립트에 대한 블로그 포스팅이 아니기 때문에 bash 쉘 문구에 대해서는 따로 설명하지 않겠습니다.

#!/bin/bash
#
export PATH="/usr/local/ssl/bin:$PATH"
urlEncode() {
  LINE="$1"
  LENGTH="${#LINE}"
  I=0
  while [ $I -lt $LENGTH ]
    do
    C="${LINE:I:1}"
  case $C in
    [a-zA-Z0-9.~_-]) printf "$C" ;;
    *) printf '%%%02X' "'$C" ;;
  esac
    let I=I+1
  done
}

getHexaDecimalString() {
  read LINE
  LENGTH="${#LINE}"
  I=0
  while [ $I -lt $LENGTH ]
    do
    C="${LINE:I:1}"
   printf '%2x' "'$C"
   let I=I+1
  done
}

getSignatureKey() {
  SECRET_KEY=$1
  DATESTAMP=$2
  REGIONNAME=$3
  SERVICENAME=$4
  STRING_TO_SIGN=$5

  HEX_KEY=$(echo -n "AWS4${SECRET_KEY}" | getHexaDecimalString)
  HEX_KEY=$(echo -n "${DATESTAMP}" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${HEX_KEY})
  HEX_KEY=$(echo -n "${REGIONNAME}" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${HEX_KEY#* })
  HEX_KEY=$(echo -n "${SERVICENAME}" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${HEX_KEY#* })
  SIGNING_KEY=$(echo -n "aws4_request" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${HEX_KEY#* })

  SIGNATURE=$(echo -en "${STRING_TO_SIGN}" | openssl dgst -binary -hex -sha256 -mac HMAC -macopt hexkey:${SIGNING_KEY#* })
  echo "${SIGNATURE#* }"
} 

getHexaHash() {
  PAYLOAD="$@"
  HASH=$(echo -n "${PAYLOAD}" | openssl dgst -sha256)
  echo  "${HASH#* }"
}

### Main ###
if [ -z $AWS_DEFAULT_REGION ] || [ -z $AWS_SECRET_ACCESS_KEY ] || [ -z $AWS_ACCESS_KEY_ID ]
then
  echo "Please set $AWS_DEFAULT_REGION, $AWS_SECRET_ACCESS_KEY, and $AWS_ACCESS_KEY_ID environment variables"
exit 1
fi
SK="$AWS_SECRET_ACCESS_KEY"
AK="$AWS_ACCESS_KEY_ID"
REGION="$AWS_DEFAULT_REGION"

[ $# -ne 6 ] && exit 2
 
while getopts ":b:k:e:" OPT; do
  case $OPT in
        b)
         BUCKET=$OPTARG
         ;;
        k)
         S3KEY=$OPTARG
         ;;
        e)
         EXPIRES=$OPTARG
         ;;
       *)
   echo "Invalid option: -$OPTARG" >&2
   exit 3
   ;;
   esac
done

SERVICENAME="s3"
HOST="${BUCKET}.${SERVICENAME}.amazonaws.com"
ENDPOINT="http://${BUCKET}.${SERVICENAME}.amazonaws.com"

# step 1. Create a Canonical request
AMZ_DATE=$(date -u +%Y%m%dT%H%M%SZ)
DATESTAMP=$(date -u +%Y%m%d)
AMZ_EXPIRES=$((${EXPIRES}*60))   # minute -> second

HTTPMETHOD="GET"
CANONICAL_URI="/${S3KEY}"
#
CANONICAL_HEADERS="host:${HOST}\n"
SIGNED_HEADERS="host"
PAYLOAD_HASH="UNSIGNED-PAYLOAD"
#
ALGORITHM="AWS4-HMAC-SHA256"
CREDENTIAL_SCOPE="${DATESTAMP}/${REGION}/${SERVICENAME}/aws4_request"
#
CANONICAL_QUERYSTRING="X-Amz-Algorithm=${ALGORITHM}"
CANONICAL_QUERYSTRING="${CANONICAL_QUERYSTRING}&X-Amz-Credential=$(urlEncode "${AK}/${CREDENTIAL_SCOPE}")"
CANONICAL_QUERYSTRING="${CANONICAL_QUERYSTRING}&X-Amz-Date=${AMZ_DATE}"
CANONICAL_QUERYSTRING="${CANONICAL_QUERYSTRING}&X-Amz-Expires=${AMZ_EXPIRES}"
CANONICAL_QUERYSTRING="${CANONICAL_QUERYSTRING}&X-Amz-SignedHeaders=${SIGNED_HEADERS}"
CANONICAL_REQUEST="${HTTPMETHOD}\n${CANONICAL_URI}\n${CANONICAL_QUERYSTRING}\n${CANONICAL_HEADERS}\n${SIGNED_HEADERS}\n${PAYLOAD_HASH}"

# step 2. String To Sign
STRING_TO_SIGN="${ALGORITHM}\n${AMZ_DATE}\n${CREDENTIAL_SCOPE}\n$(getHexaHash "$(echo -e "${CANONICAL_REQUEST}")")"

# step 3. Signature
SIGNATURE="$(getSignatureKey $SK $DATESTAMP $REGION $SERVICENAME $STRING_TO_SIGN)"

# step 4.  Create a request URL
CANONICAL_QUERYSTRING="${CANONICAL_QUERYSTRING}&X-Amz-Signature=${SIGNATURE}"

echo "request_url = ${ENDPOINT}/${S3KEY}?${CANONICAL_QUERYSTRING}"

스크립트의 간결성을 유지하기 위해서 대부분의 에러 처리 루틴을 배제하였습니다. 따라서 범용적으로 사용하기 위해서는 적절한 에러 처리 루틴들이 추가되어야 하고 충분한 테스트를 거친 후 사용하시길 권장합니다.

아래는 이 스크립트를 이용해서 한 시간동안만 버킷 examplebucket에 포함된 오브젝트test.txt를 다른 사람에게 공유하기 위해 미리 사인된 URL을 만든 예입니다.

$ ./apis3.sh -b examplebucket -k test.txt -e 60
request_url = http://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<YOUR_ACCESS_KEY_ID>%2F20160115%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20160115T130732Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=d0578b9fe721c9964765f2ab6bf6f8a1fc7c4966956785688b881783b661bdfd

이 URL은 생성된 시간부터 60분간 유효하며, 공유하고 싶은 임의의 사람에게 전달하면 됩니다. 그리고 공유된 링크를 클릭하거나 curl(1) 명령어로 실행하게 되면,  해당 API 호출 요청이Amazon S3 엔드포인트로 전달되고 적절히 처리됩니다.

아래는 curl(1) 를 이용해서 오브젝트를 성공적으로 다운로드한 예입니다.

$ curl -o "test.txt" "http://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<YOUR_ACCESS_KEY_ID>%2F20160115%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20160115T130732Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=d0578b9fe721c9964765f2ab6bf6f8a1fc7c4966956785688b881783b661bdfd"
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100  3619  100  3619    0     0   6305      0 --:--:-- --:--:-- --:--:--  6304

그리고 아래는 시간이 초과되어 다운로드가 실패한 예입니다.

$ curl -o "test.txt" "http://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<YOUR_ACCESS_KEY_ID>%2F20160115%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20160115T130732Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=d0578b9fe721c9964765f2ab6bf6f8a1fc7c4966956785688b881783b661bdfd"
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Request has expired</Message><X-Amz-Expires>60</X-Amz-Expires><Expires>2016-01-15T140732:52Z</Expires><ServerTime>2016-01-18T20:13:55Z</ServerTime><RequestId>F865CB514FF4C92A</RequestId><HostId>f6Bv6Jtht91bSqt8OPsxirsrHZkWs7Qcc4kNYjZ2tJbPUmt8BW9Wv1hAUY2YFDKqSpEvFr8PLbI=</HostId></Error>

지금까지 총 2회의 포스팅을 통해서 AWS API 호출 요청을 어떻게 만들 수 있는지 살펴보았습니다. 특히 실전편에서 제공된 예는 많은 사용자들이 문의하신 내용이기도 합니다. 이번 글을 통해서 앞으로AWS API 호출을 활용하실 수 있고,  S3 오브젝트를 안전하게 공유하는데 조금이라도 도움이 되었으면 합니다.
본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박철수 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon S3 멀티 파트 다운로드 이용하기

Amazon S3는 내구성 및 확장성을 요구하는 업무에 활발하게 이용되고 있는 오브젝트 스토리지입니다. 현재까지 꾸준히 기능이 추가 및 개선되고 있으며, AWS 모든 서비스의 맏형격으로 다양한 워크로드와 서비스들의 중앙에 위치해서 정적인 멀티미디어 컨텐츠부터 로그 데이터 저장, 백업과 아카이빙, 빅데이터 분석 및 재난 복구 등을 위해 널리 활용되고 있습니다.

Amazon S3에 저장된 오브젝트는 HTTP/HTTPS프로토콜을 통해 일반적으로 인터넷을 경유해서 이동하게 됩니다. 작은 크기의 파일은 짧은 시간 내에 전송되겠지만, 큰 크기의 파일을 하나의 작업으로 전송하는 것은 시간적인 측면에서 이용자에게 적잖은 부담으로 남게 됩니다. AWS는 하나의 큰 오브젝트를 Amazon S3상에 빠르게 올릴 수 있는 방법을 제공하고 있습니다.

일명 멀티파트 업로드. 기본적으로 Amazon S3에 단일 작업으로 올릴 수 있는 객체 크기는 최대 5GB입니다. 따라서 5GB보다 큰 오브젝트는 멀티파트 업로드를 반드시 이용해서 업로드해야하며, 최대 5TB 크기 오브젝트를 업로드할 수 있습니다.

일반적으로 오브젝트 크기가 100MB를 넘게되면 멀티파트 업로드를 권장하며, 멀티파트 업로드 API를 이용해서 큰 오브젝트를 여러 조각으로 나눠서 병렬적으로 빠르게 업로드 할 수 있습니다. 또한 AWS 명령줄 인터페이스를 이용하여 쉽게 멀티 파트 업로드할 수 있는 환경도 제공하고 있습니다.

그러면, Amazon S3상에서 있는 큰 크기의 오브젝트를 내려받는 것은 어떨까요? 아마도 ‘멀티파트 다운로드할 수 있는 API를 동일하게 제공하겠지?’라고 생각할 수 있습니다. 하지만 멀티파드 업로드 API처럼 오브젝트를 간편하게 멀티파트로 다운로드하는 API는 존재하지 않습니다. 다행히 AWS 명령줄 인터페이스의 s3 cp명령은 사용자에게 투명하게 오브젝트를 멀티파트로 내려받을 수 있도록 설계되어있습니다.

$ time aws s3 cp s3://shared/sample.zip sample.zip
download: s3://shared/sample.zip to ./sample.zip
real       3m46.765s
user       0m18.265s
sys        0m10.454s

기본적으로8MB 크기로 구성된 파트들로 멀티파트 다운로드하게 되며, 아래 예처럼 aws 명령줄 인터페이스 구성파일(~/.aws/credentials)을 수정해서 사용자화할 수 있습니다.

[profile development]
aws_access_key_id = xxxxxxxxxxxxxxxxxxxx
aws_secret_access_key = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
max_concurrent_requests = 20
max_queue_size = 10000
multipart_threshold = 64MB
multipart_chunksize = 16MB

이 블로그 포스팅의 목적은 AWS 명령줄 인터페이스의 s3명령을 통해서 멀티 파트 다운로드 받는 방법을 소개하려는 것은 아닙니다. 사용자가 직접 간단하게 구현할 수 있는 멀티 파트로 다운로드 방법을 소개하고자 합니다. 이 방법을 이용하면 자신만의 코드로 작성된 앱 내에서도 멀티 파트 다운로드를 간단히 구현할 수 있고, 경우에 따라서는 이어받기 기능까지 응용할 수 있습니다.

원리는 W3 표준인 RANGE GET를 활용하는 것입니다. AWS에서 제공하는 GET Object REST API를 이용해서 RANGE 헤더를 사용할 수 있고, AWS 명령줄 인터페이스의 s3api 명령을 이용해서도 RANGE 헤더를 사용할 수 있습니다.

아래는 두번째 방법인 AWS 명령줄 인터페이스의 s3api 명령을 사용해서 멀티파트 다운로드 스크립트를 간단히 구현해 보고, 멀티파트 다운로드에 대한 기본 아이디어와 실제로 다운로드 속도가 어느정도 개선되는지 살펴보도록 하겠습니다. (참고로 AWS 명령줄 인터페이스에서 내부적으로 투명하게 제공되는 멀티파트 다운로드 기능은 s3 명령에서만 지원되고, s3api 명령에서는 지원되지 않습니다.)

사전 준비 사항
스크립트를 작성하기 위해서는 아래 AWS 명령줄 인터페이스가 준비되어야 합니다. AWS 명령줄 인터페이스는 여기를 클릭하시면 다운로드 받을 수 있으며, 설치 가이드와 사용법도 확인할 수 있습니다.

스크립트 작성하기
위 선행 작업이 완료되었다면, 이제 스크립트를 작성할 준비가 되었습니다. 멀티파트 다운로드 스트립트의 작업 순서를 아래와 같이 아주 단순합니다:

  1. 다운로드 하려는 S3 상의 오브젝트 크기 확인
  2. 사용자가 원하는 분할 개수에 맞도록 파트 크기 계산
  3. RANGE GET을 이용해서 오브젝트의 파트들을 병렬적으로 다운로드
  4. 모든 파트들이 다운로드 될 때까지 대기
  5. 다운로드된 모든 파트들을 하나로 묶기

우선 특정 버킷내에 있는 오브젝트 목록 및 속성을 얻는 명령을 알아보도록 하겠습니다. 이는 첫번째 단계인 오브젝트 크기를 확인하는데 사용됩니다. AWS 명령줄 인터페이스의 s3api list-objects 명령을 이용하면 오브젝트에 대한 속성을 알 수 있습니다. 아래는 shared 버킷내에 있는 모든 오브젝트의 정보를 얻을 수 있는 예입니다.

$ aws s3api list-objects –bucket shared

하지만, 실제로 필요한 값은 원하는 특정 오브젝트의 크기 정보입니다. 이는 --query 옵션을 통해서 가능하고, 오브젝트 이름은 Key, 크기는 Size 속성으로 참조할 수 있습니다. 아래 명령줄을 통해서 shared 버킷 내에 있는 sample.zip 오브젝트에대한 크기만 추출해보겠습니다.

$ aws s3api list-objects --bucket shared --query "Contents[?Key==`sample.zip`]|[0].Size"

위 명령어에서 `sample.zip`을 둘러싸고 있는 것은 백쿼터(`…`)인 것에 유념해야 합니다. 그리고 파이프 연산자를 이용해서 파이프 앞에 있는 쿼리 결과를 뒤로 전달하도록 하였으며, [0].Size를 통해서 오브젝트 크기만 추출합니다.

위에서 얻은 오브젝트의 크기를 분할하고 싶은 파트 개수로 나누게 되면 각 파트의 크기를 얻을 수 있습니다. 그리고 W3 표준인 RANGE GET에서 소개된 형식을 바탕으로 각 파트의 순서에 맞도록 BYTE RANGE 연산자를 활용하여 다운로드할 각 파트의 바이트 범위를 명시합니다. AWS 명령줄 인터페이스에서는 --range 옵션을 사용합니다. 아래는 몇가지 사용 예입니다:

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=0-33554431 sample.zip.part.1

위 예는 sample.zip 오브젝트의 첫번째 파트입니다. 파트 크기를 첫 바이트부터 총 32MB(bytes=0-33554431) 크기로 내려받아서 sample.zip.part.1로 저장합니다.

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=33554432-67108863 sample.zip.part.2

sample.zip 오브젝트의 두번째 파트는 이후 두번째 32MB(33554432-67108863)를 내려받아서 sample.zip.part.2에 저장합니다.

$ aws s3api get-object --bucket shared --key sample.zip --range bytes=268435456- sample.zip.part.9

그리고 sample.zip 오브젝트의 마지막 파트 부분으로 나머지 부분을 모두 받게 됩니다. 위 예는bytes=268435456-으로 표현되어 있는데요, 256MB지점부터 끝까지 내려받아서 sample.zip.part.9에 저장한 예입니다.

BASH 쉘 상에서 내려받는 명령어들은 모두 백그라운드로 수행시켜서 병렬로 다운로드 받게합니다. 그리고 이런 백그라운드 프로세스들이 모두 종료될 때까지 wait(1) 명령어를 이용해서 대기합니다.

끝으로 모든 파트를 다운로드하면 파트 순서에 맞춰서 한 파일로 함께 연결하면 됩니다.

지금까지 스크립트를 구성하는 주요 내용에 대해 설명드렸습니다. 아래 스크립트는 앞서 설명드린 내용들을 기반으로 작성한 간단한 bash 쉘 스크립트입니다.

#!/bin/bash
#
[ $# -ne 6 ] && exit 1

while getopts ":b:k:s:" OPT; do
  case $OPT in
    b)
      BUCKET=$OPTARG
      ;;
    k)
      KEY=$OPTARG
      ;;
    s)
      SPLIT=$OPTARG
      ;;
    *)
      echo "Invalid option: -$OPTARG" >&2
      exit 2
      ;;
  esac
done

# MAIN
readonly THRESHOLD_PART_SIZE=8388608   # 8MB (8*1024*1024)
readonly TMP_DIR="./tmp.$$";

OBJECT_SIZE=$(aws s3api list-objects --bucket $BUCKET --query "Contents[?Key==\`${KEY}\`]|[0].Size")

let PART_SIZE=OBJECT_SIZE/SPLIT
[ $PART_SIZE -lt $THRESHOLD_PART_SIZE ] && echo "Part size is $PART_SIZE. Each part size except last one must be larger than $((${THRESHOLD_PART_SIZE}/1024/1024))MB" &&  exit 3
[ ! -d "${TMP_DIR}" ] && mkdir ${TMP_DIR}

I=1
START=0
let END=PART_SIZE-1
while [ $I -le $SPLIT ]
do
   aws s3api get-object --bucket $BUCKET --key $KEY   --range bytes=${START}-${END}  ${TMP_DIR}/${KEY}.${I} > /dev/null 2>&1 &
   let I=I+1
   let START=START+PART_SIZE
   let END=END+PART_SIZE; [ $I -eq $SPLIT ] && END=''
done

wait > /dev/null 2>&1

[ -f $KEY ] && rm $KEY
I=1
while [ $I -le $SPLIT ]
do
   cat ${TMP_DIR}/${KEY}.${I} >> $KEY
   let I=I+1
done
rm -rf $TMP_DIR

스크립트의 간결성을 유지하기 위해서 대부분의 에러처리 루틴을 배제하였습니다. 따라서 범용적으로 사용하기 위해서는 적절한 에러 처리 루틴들이 추가되어야 하고 충분한 테스트를 거친 후 사용하시길 권장합니다.

아래 두 예는 S3에 저장된 약 700MB sample.zip 파일을 위 스크립트를 활용해서 20개로 나눠 다운로드했을 때와 한번의 작업으로 다운로드 받을 때의 결과를 보여주고 있습니다.

$ time ./s3md.sh -b shared -k sample.zip -s 20
real       2m12.268s
user       0m26.010s
sys        0m11.952s

700MB의 단일 파일을 20개로 나눠서 받았을 때, 약 2분 12초 정도 시간이 소요되었습니다. 그리고 이어지는 AWS 명령줄 인터페이스는 단일 작업으로 해당 오브젝트를 내려받는 결과입니다.

$ time aws s3api get-object --bucket shared --key sample.zip sample.zip > /dev/null
real       4m17.417s
user       0m19.199s
sys        0m9.284s

단일 작업으로 다운로드 하였을 경우 약 4분 17초정도 소요되었습니다. 위 예에서는 멀티 파트로 다운로드 받을 경우 약 50%정도의 시간이 단축된 것을 확인할 수 있었습니다. 다만 고려 해야 할 것은 인터넷 환경 및 클라이언드 환경에 따라 위 결과와 다르게 나올 수 있습니다.

끝으로 Amazon S3상에서 큰 데이터를 자주 조작 하시는 IT팀이나 앱 내에서 S3로 파일을 주고 받아야 하는 경우, 오늘 소개해드린 멀티 파트 다운로드 방법이 조금이라도 아이디어를 제공해드렸기를 기대해봅니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박철수 솔루션즈 아키텍트께서 작성해주셨습니다.

AWS 스토리지 업데이트 – 신규 저가형 S3스토리지 옵션 및 Glacier 가격 인하

AWS의 모든 서비스처럼 Amazon S3팀은 고객의 요구사항을 더 잘 이해하기 위해서 고객의 목소리에 항상 귀기울이고 있습니다. 그동안 해 주신 많은 피드백과 사용자 접근 유형 분석을 한 결과 S3팀은 자주 사용하지 않는 객체 및 파일에 잘 맞는 새로운 스토리지 옵션을 제공할 필요성을 알게되었습니다.

즉, 저희팀은 많은 AWS 고객들이 자주 접근하지 않는 백업이나 로그 파일들을 S3에 저장하고 있다는 것을 발견했습니다. 다른 회사들은 공유 문서 또는 즉각적인 분석을 위한 RAW 데이터도 업로드합니다. 이 파일들은 대게 업로드가 된 직후에는 자주 사용을 하지만, 시간이 지남에 따라서 사용률이 급격히 떨어집니다. 물론 이 데이터들은 여전히 중요하며 높은 내구성을 요구합니다. 이러한 스토리지 모델은 자주 접근하지 않는 경우에 특화되어 있더라도, 고객들은 파일에 빠른 접근을 요구하기 때문에 검색 성능 역시 중요합니다.

새로운 스토리지 옵션, 저빈도 접근(Infrequent Access)
많은 고객의 요구사항에 부합하기 위해서 접근 빈도가 낮은 데이터를 위한 새로운 스토리지 클래스를 추가합니다. 새로운 S3 Standard – Infrequent Access (Standard – IA) 스토리지 클래스는 S3 Standard와 같이 높은 내구성, 낮은 지연 시간, 높은 처리량을 제공합니다. 여러분은 이제 99.999999999%의 내구성을 지닌 세 개의 S3 스토리지 클래스(Standard, Standard – IA, Glacier) 중 하나를 선택할 수 있습니다. Standard – IA의 SLA는 99%입니다.

새로운 스토리지 클래스는 여러분이 알고있는(선호하시듯) 안전한 보안과 접근관리, 데이터 생명주기 정책, 리전간(cross-region) 복제, 그리고 이벤트 알림을 포함한 기존 S3 기능을 모두 가지고 있습니다.

Standard – IA의 가격은 최소 30일 이상 유지시 기가바이트당 월 $0.0125부터 시작하며 일반적인 데이터 전송과 요청 요금을 제외한 검색(retrieval)은 기가바이트당 $0.01의 비용이 발생합니다. 과금을 위해서 128 킬로바이트보다 작은 객체들은 128 킬로바이트로 과금됩니다. 이러한 비용 모델이 매우 경제적이면서도 필요한 경우 오래된 데이터를 빠르게 검색하는데 도움을 줄것입니다. 새로나온 스토리지 클래스를 장기 보관 스토리지, 백업, 그리고 재해 복구용으로 사용할 수 있습니다.

S3 스토리지 클래스간 데이터 이동 생명주기 정책을 정의할 수 있습니다. 예를 들어, 새로 업로드된 데이터를 Standard 스토리지 클래스를 사용해서 저장할 수 있고, 이 데이터가 업로드된지 30일이 지난 후에 Standard – IA로 이동하고, 60일이 지난 후에는 Amazon Glacier로 이동하도록 설정할 수 있습니다.

새로운 Standard – IA 스토리지 클래스는 단순히 S3의 각 객체와 연관된 속성들 중 하나입니다. 객체들이 같은 S3 버킷에 있고 Standard – IA로 이행될 때 같은 URL로 접근할 수 있기 때문에 애플리케이션 코드 변경을 하지 않아도 생명주기 정책을 통해서 Standard – IA를 바로 사용할 수 있습니다. 즉 여러분은 어플리케이션 변경이나 성능에 영향없이 즉시 정책을 적용하고 S3 비용을 줄일 수 있습니다.

AWS 관리 콘솔을 통해서 새로운 객체를 업로드할 때 새로운 스토리지 클래스를 선택할 수 있고, 이는 모든 리전에 바로 적용됩니다.

또한, 각 S3 버킷별 생명주기 룰을 설정할 수 있습니다. 다음은 위에서 설명한 정책 구성 방법입니다.

이 기능은 AWS Command Line Interface (CLI), the AWS Tools for Windows PowerShellAWS SDKs, S3 API를 통해서도 적용 가능합니다.

아래는 이 기능을 초기에 써 보신 고객의 피드백입니다.

“13년 이상 SmugMug는 고객에게 무제한 사진 저장 서비스를 해왔습니다. 페타바이트급 데이터가 Amazon S3에 저장되어 있고 저희 사용자들이 예전에 올린 사진이라 하더라도 바로 빠르게 데이터를 접근하는 것이 매우 중요합니다. Amazon S3 Standard – IA를 통해 높은 내구성과 성능을 가진 Amazon S3 기본 기능을 계속 활용하면서도 저희 고객들에게 더 빠르고 고품질의 사진 및 동영상을 제공할 수 있게 되었습니다.”

Don MacAskill, CEO & Chief Geek
SmugMug

“저희는 많은 동영상을 제공하는데 대부분 Amazon S3에 사용자 동영상의 복제본을 저장합니다. 즉, 내구성이 매우 중요하다는 것을 의미하는데 Amazon S3 Standard – IA를 통해 스토리지 비용도 낮추면서 내구성도 확보하는 것이 가능해졌습니다. 몇 번의 클릭으로 스토리지 생명 주기를 설정할 수 있어서 쉽게 전환이 가능합니다. 이를 통해 새로운 버킷을 만들어 이동하는 등 사용자 경험에 영향을 주는 걱정이 없어졌습니다.”

Brian Kaiser, CTO
Hudl

새로운 스토리지 클래스의 전체 가격에 대한 정보는 S3 가격 페이지에서 확인 가능합니다.

Glacier 스토리지 가격 인하
2015년 9월 1일부터 Amazon Glacier에 저장된 데이터 가격을 기가 바이트당 월 $0.01에서 $0.007로 인하합니다. 여느 때와 같이 가격 인하는 자동으로 적용될 것이며 여러분이 가격 인하를 받기 위해서 하실 건 없습니다. 이 가격은 US East(Northern Virginia), US West(Oregon), Europe(Ireland) 지역에 해당하는 것으로 다른 지역에 대한 가격 정보는 Glacier 가격 페이지에서 확인하시기 바랍니다.

Jeff;

이 글은 AWS Storage Update – New Lower Cost S3 Storage Option & Glacier Price Reduction의 한국어 번역으로 AWS 코리아의 기술 지원 엔지니어로 근무하는 이범석(Beomseok Lee)님이 번역해 주셨습니다.

Route53 지연 속도 기반 라우팅 활용하기

AWS는 전 세계에 11개의 리전(Region)과 30개의 가용 영역(Availability Zone)으로 글로벌 서비스를 제공함으로써, 각 국가 또는 지역 사용자에게 가장 빠른 서비스를 제공합니다. 뿐만 아니라 Amazon CloudFront라는 전용 콘텐츠 전송 네트워크를 통해 네트워크 속도 측면에서 가장 가까운 53개의 에지(Edge)에서 더 빠르게 정적 콘텐츠 및 동적 캐싱을 통해 더 빠른 서비스 전달이 가능합니다.

이를 위해 원래 콘텐츠 위치(Origin)인 S3 버킷에서 가장 빠른 클라우드프론트 에지를 찾아야 할 필요가 있습니다. 그래야 더 빠르게 콘텐츠를 배포할 수 있을 테니까요. 많은 고객들이 이러한 질문을 해주셨습니다.

이 글에서는 도메인 네임 서비스로 알려진 Amazon Route53의 여러 가지 기능 중 지연 속도 기반 라우팅(Latency based routing)을 통해 위와 같은 질문에 대한 해결 방법을 찾아 보도록 하겠습니다.

지연 속도 기반 라우팅(Latency based routing) 설정하기
만약 AWS 위에서 운영 중인 서비스가 동경 리전(Tokyo region)과 버지니아 리전(Virginia region)을 통해 서비스 되고 있을 경우, 이 서비스 도메인 이름을 Route53을 통해 등록하고 지연 속도 기반 라우팅을 설정 할 수 있습니다. 이러한 경우 Route53은 해당 서비스의 DNS 질의를 했을 때, Tokyo와 Virginia region 중 고객 입장에서 보다 낮은 지연 속도(Latency)를 가질 수 있는지 판단하여 지연이 낮은 리전의 주소를 반환합니다.

대부분의 경우, 아시아쪽 고객은 동경 리전으로 미국쪽 고객은 버지니아 리전으로 DNS 주소를 반환하고, 사용자의 접속 속도는 훨씬 빨라지게 되므로 사용자의 경험은 증가할 것입니다.

우리는 이러한 라우팅이 잘 동작하는지 검증하기 위한 도구를 만들기 위해 버지니아, 아일랜드 및 동경 리전에 각각 S3 버킷을 만들고 정적 웹 호스팅을 구현한 후 location.txt라는 파일을 만들어 각각 자신의 리전이름(예: I’m in Virginia)을 표시하도록 하였습니다.

  • 버지니아: Virginia.cloudinternal.com
  • 아일랜드: Ireland.cloudinternal.com
  • 동경: Tokyo.cloudinternal.com

버킷 생성과 Index 문서 설정이 끝났다면, Route53으로 이동하여 해당 버킷이 도메인명을 통해 인터넷에서 접근할 수 있도록 Route53 Alias 기능을 이용해 ireland.cloudinternal.com, tokyo.cloudinternal.com, virginia.cloudinternal.com을 등록합니다.

사실 lbr.cloudinternal.com이 실제 지연 속도 기반 라우팅으로 설정할 도메인 이름입니다. 레코드에 등록할 때 Routing PolicyLatency로 설정하고, Region은 타겟 S3 버킷 위치에 해당하는 리전을 설정합니다. 예를 들어, ireland.cloudinternal.com을 Target으로 등록할 때는 리전을 eu-west-1으로 선택하게 됩니다.

즉, eu-west-1(아일랜드 리전)에 가까우면 ireland.cloudinternal.com로, ap-northeast-1(동경 리전)에 가까우면 tokyo.cloudinternal.com로, us-east-1(버지니아 리전)에 가까우면 virginia.cloudinternal.com으로 DNS 응답을 받을 수 있도록 설정합니다.

라우팅 결과 살펴보기
각 지역의 가까운 곳에서 DNS Lookup을 하여 실제로 가까운 S3 버킷으로 연결되는지 시험합니다. 아일랜드와 오레곤 리전에 각각 t2.micro로 인스턴스를 실행하고, dig 명령을 실행합니다. 동경은 한국에서 연결될 가능성이 높으니 직접 자신의 랩탑에서 시험해도 좋습니다.

Oregon Instance에서 DNS lookup실행

$ ssh -i [your_key_file1]  ec2-user@52.27.81.xxx 'dig +short lbr.cloudinternal.com'
virginia.cloudinternal.com.s3-website-us-east-1.amazonaws.com.
s3-website-us-east-1.amazonaws.com.
54.231.16.60

Ireland Instance에서 DNS Lookup 실행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com'
ireland.cloudinternal.com.s3-website-eu-west-1.amazonaws.com.
s3-website-eu-west-1.amazonaws.com.
54.231.129.36

한국 내에서 DNS Lookup 실행

$ dig +short lbr.cloudinternal.com
tokyo.cloudinternal.com.s3-website.ap-northeast-1.amazonaws.com.
s3-website.ap-northeast-1.amazonaws.com.
54.231.230.12

가까운 AWS 리전의 S3 주소가 반환되는 것을 확인 할 수 있습니다.

빠른 CloudFront S3 Origin 설정하기

이제 lbr.cloudinternal.com으로 CloudFront Origin을 설정하면 자동으로 가까운 S3 버킷을 Origin으로 객체(Object)를 가져오겠지만, S3는 HTTP Request header 의 Host 정보를 참조하여 Bucket 이름과 다르면 404 Not Found 페이지를 반환합니다. 따라서 추가적인 설정이 필요합니다. 지연 속도 기반 라우팅이 잘 동작하니, CDN 서비스를 요청하는 클라이언트는 Route53을 통해 내가 어느 쪽 리전으로 접근해야 하는지 확인한 후, URL에 해당 리전 정보를 포함하여 요청하면 지연 속도가 낮은 쪽의 S3 버킷을 원래 소스 저장소(Origin)로 선택할 수 있습니다.

WHERE = `dig +short lbr.domainname.com`
CF_URL = dfoijefo2eoifjeaf.cloudfront.net/$WHERE/target_file.jpg

위와 같은 로직을 수행하기 위해서 CloudFront에서 Origin과 Behavior를 아래와 같이 설정합니다.

Origin 설정

Behavior 설정

간단히 아래와 같이 가까운 Region위치를 알 수 있습니다.
한국에서 수행

$ dig lbr.cloudinternal.com +short | awk -F "." '{ print $1 }' | head -1
tokyo

Oregon region 인스턴스에서 수행

$ ssh -i [your_key_file] ec2-user@52.27.81.xxx  'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
virginia

Ireland region 인스턴드에서 수행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
ireland

최종적으로 알게된 리전을 URL Prefix에 포함하여 요청하여 원하는 결과를 얻을 수 있습니다.

$ curl http://d2r05xiwqufy6.cloudfront.net/ireland/location.txt
I'm in Ireland.
$ curl http://d2r05xiwqufy6.cloudfront.net/tokyo/location.txt
I'm in Tokyo
$ curl http://d2r05xiwqufy6.cloudfront.net/virginia/location.txt
I'm in Virginia

지금까지 우리는 Route 53의 지연 속도 라우팅 방식을 기반으로 CloudFront의 소스 파일이 위치한 가장 가까운 S3 버킷의 위치를 찾는 문제를 해결해 보았습니다. 이를 위해 S3 정적 웹 호스팅 및 CloudFront의 몇 가지 기능을 활용하기 위한 설정이 필요했지만, 단순히 리전간에 구성된 웹 서비스의 Elastic Load Balancing 주소를 지연 속도 기반 라우팅으로 Route 53에 구성하면 복잡한 설정 없이 CloudFront을 통해 동적 콘텐츠도 활용할 수 있는 구성을 할 수 있습니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김일호 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon S3 기능 추가 – 알람 기능 및 버킷 측정 기준 향상

2006년 봄에 Amazon Simple Storage Service (S3)간단한 블로그 공지로부터 시작했습니다. 그동안 간편하지만 강력한 서비스 모델을 유지해 오면서, 가격 인하를 포함하여 중복을 감소한 스토리지, VPC 엔드 포인트, 리전간 복제 기능이벤트 노티피게이션 기능 등을 추가해 왔습니다.

작년에 이벤트 알림 기능을 추가한 이후 다양한 객체 이벤트에 대한 알림을 지원해 왔습니다. 예를 들어, PUT, POST, Copy, Multipart Upload 등의 이벤트가 있을 때 알람을 지원합니다. 이러한 알람 통지 기능은 모든 버킷의 객체가 대상입니다. 오늘 부터 객체들이 삭제 되었을 때, 접두사 및 접미사(prefixes 및 suffixes) 필터링을 지원합니다. 또한, 버킷 수준에서 Amazon CloudWatch 메트릭 지원합니다.

알림 통지 기능 향상
또한, S3 버킷에서 객체가 삭제 된 경우에 알람을 통지하도록 설정할 수 있습니다. 다른 형식의 통지와 마찬가지로, 삭제 통지는 SQS 큐(Queue)나 SNS 토픽(Topic), AWS Lambda function에 연결해서 보낼 수 있습니다. 이러한 객체 삭제 알림은 DELETE 수행이 될 때 S3 객체를 관리하기 위한 인덱스 업데이트 및 데이터 추적 등에 사용할 수 있습니다.

또한, 객체 이름의 접두사와 접미사를 사용한 필터를 사용할 수 있습니다. 다음 예제에서는 특정 버킷에서 “images /” 접두사 “.png” 접미사의 객체가 삭제 된 경우에 알람을 통지 할 수 있습니다.

관리 콘솔에서 여러 개의 알람 통지를 생성 및 편집 할 수 있습니다.

CloudWatch 스토리지 측정 기준
Amazon CloudWatch는 AWS 서비스 및 여러분이 추가한 응용 프로그램의 측정 값 추적 및 알람 기능을 가지고 있습니다. 알람 설정은 경과 시간 동안 임계값을 초과 할 때 발생합니다. S3의 모니터 및 알람 기능을 S3에 대해서도 할 수 있습니다. 지원되는 측정 지표는 버킷 당 총 바이트 수 (표준 및 RRS)과 총 객체 수입니다. 측정 기준에 따른 결과는 AWS 관리 콘솔에서 볼 수 있습니다.

측정 기준은 빌링과 함께 마찬가지로 매일 업데이트 합니다. 또한, 스토리지 라이프 사이클 규칙 등에 의해 Glacier로 이동하도록 설정 된 객체는 제외됩니다.

지금 사용 가능
이 기능들은 오늘 부터 바로 사용이 가능합니다.

Jeff;

이 글은 Amazon S3 Update – Notification Enhancements & Bucket Metrics의 한국어 번역입니다.

Amazon S3 리전간 복제 기능 신규 추가

Amazon Simple Storage Service(S3) 출시가 9년이 되었습니다.

출시 이후 많은 기능을 신규로 추가하거나 글로벌 서비스 및 여러번 스토리지 요금과 데이터 전송 요금을 인하 해왔습니다. 많은 고객은 우리를 신뢰 하고 중요한 데이터 및 다양한 용도로 S3를 이용하고 있습니다. 여러분의 다양하고 아이디어 넘치는 피드백을 통해서 S3가 여러분의 요구에 부응하는 개체 스토리지로 발전해야 한다고 생각하고 있습니다.

버킷 네임 스페이스는 고유하지만 S3는 (다른 AWS 서비스처럼) 각 AWS 리전에서 실행하고 있습니다. 이러한 서비스 모델을 통해 여러분은 데이터 위치를 완벽하게 제어 할 수 있습니다. 로컬 규제 요구 사항, 대기 시간 관점에서 데이터를 고객에게보다 가까이에 두어야 한다는 점 등 기타 다양한 이유에 따라 적절한 저장 위치를​​ 선택할 수 있습니다.

그런데, 그동안 많은 고객으로부터 데이터를 한 곳에서도 복사하고 관리하고 싶다는 요청을 받아 왔습니다. 이러한 요구 사항은 민감한 금융 정보 나 개인 정보 취급에서 엄격한 규정을 준수하기위한 것입니다.

크로스 리전 복제 기능
오늘 S3 개체를 보조 영역으로 복제 할 수있는 크로스 리전 복제 기능을 출시합니다. 이 기능을 이용하여 중요한 고객에게 다른 또는 인접 리전에서 복제를 포함하여 위에서 설명한 바와 같은 요구를 실현 할 수 있게 됩니다.

이 기능을 사용하여 특정 S3 버킷 (또는 특정 Prefix 부하의 객체)에 대한 모든 업로드, 업데이트 및 삭제를 모니터링하고 다른 지역에있는 보조 버킷에 복제합니다.

지금 바로 기능을 활성화하고 사용할 수 있습니다! 이 기능은 기존 S3 버전 관리 기능에 통합되어 있으며, 필요한 경우 콘솔에서도 사용 할 수 있습니다.

버전 관리를 활성화하면 나머지는 간단합니다. 복제할 리전과 버킷(특정 prefix에서만 복제도 가능)을 선택하고 IAM 역할을 설정하면 됩니다.

기존 버킷을 선택할 수도 있으며 이 단계에서 새 버킷을 만들 수 있습니다.

또한, S3가 원래 소스 버킷 목록이나 검색, 복제할 리전의 버킷에 대해 복제 작업을 수행하기 위해 IAM Role(역할)을 설정해야합니다. 정책을 통해 다른 AWS 계정의 버킷 간 복제 등 쉽게 고급 시나리오를 제공 할 수 있습니다. 콘솔을 이용하면 IAM 역할을 설정하는 것을 쉽게 할 수 있습니다.

일단 복제 설정을 완료하고, 최종 복제 리전을 확인해 보면 예상대로 아직 빈 상태입니다. (복제는 새로 생성 된 개체에서 작동합니다.)

AWS S3 마스터 키를 이용하여 낮은 중복 스토리지 (RRS)와 서버 사이드 암호화(SSE)를 사용하여 이미지 파일을 업로드합니다.

최종 버킷 화면을 몇 번 새로 고침하면, 예상대로 개체가 표시되고 복제 자체도 RRS와 SSE가 설정되어 있습니다.

만약 원래 개체를 삭제하면 복제도 삭제됩니다. 복제 프로세스는 대상 객체의 메타 데이터와 ACLs (Access Control Lists)입니다.

S3 API 기능을 이용하여 더 상세한 작업이 가능합니다.

실제 환경에서 크로스 리전 복제를 이용 하시는데 몇 가지 주의해야 할 것이 있습니다.

버전 기능 – 먼저, 원래 소스 버킷의 S3 버전 관리 기능을 활성화해야 합니다. 물론 복제할 리전의 버킷 측도 활성화 합니다.

라이프 사이클 규칙 – 복제할 리전의 버킷은 라이프사이클 규칙을 이용하여 이전 버전의 자동 삭제나 Amazon Glacier로 마이그레이션 관리를 할 수 있습니다.

복제 상태 보기  – 소스 객체의 HEAD 작업에서 복제 상태 확인이 가능합니다. 콘솔에서도 확인이 가능합니다.

리전 간 복제 – 복제은 반드시 AWS 리전간에 해야합니다. 같은 리전에있는 2개의 버킷간에는 이 기능을 이용하여 복제를 할 수 없습니다.

신규 개체 – 소스 버킷의 변경을 감지하여 새 개체를 만들거나 기존 개체의 변경으로 복제가 이루어집니다. 만약 기존 개체의 복제를 수행하려면 S3의 COPY 오퍼레이션을 이용하여 최종 복제할 버킷을 최신 상태로 할 수 있습니다.

더 자세한 사항은 S3 Cross-Region Replication 개발자 가이드를 참고하세요.

지금 사용해 보세요!
이 기능은 오늘부터 이용하실 수 있습니다. 복제할 버킷 스토리지 요금과 데이터 업데이트에 대해서는 AWS의 일반적인 지역 간 데이터 전송 비용이 필요합니다. 더 자세한 정보를 알고 싶다면, S3 요금표 페이지를 확인해주십시오.

Jeff;

이 글은 New – Cross-Region Replication for Amazon S3의 한국어 번역입니다.

AWS 데이터 전송 비용 가격 인하

AWS 중 데이터 송수신 비용에 대해 가격 인하 소식을 알려 드립니다. 아래 가격 정책은 2014년 12월 1일부터 적용됩니다.:

  • 인터넷 데이터 전송(Out)– AWS로부터 인터넷으로 데이터를 보내는 전송 가격을 이번 6~43% 인하합니다.(월별 총 데이터 전송량에 따라 다름)
  • CloudFront에 대한 데이터 전송– AWS에서 Amazon CloudFront에 대한 데이터 전송이 무료로 변경되었습니다.
  • CloudFront 엣지 데이터 전송– 미국, 유럽, 일본 호주에 있는 CloudFront 엣지에서 데이터 전송 가격을 4~29%로 인하합니다(엣지 위치와 지역에 따라 다름)

데이터 전송 가격 인하

아래 사항은 데이터 전송 가격 인하에 대한 개요입니다. 자세한 내용은 EC2 요금 페이지S3 요금 페이지를 살펴 보시기 바랍니다.

요금 조건 미국 서부
(오리건, 북캘리포니아)
유럽
(아일랜드, 프랑크푸르트)
아시아 퍼시픽
(싱가포르)
아시아 퍼시픽
(도쿄)
아시아 퍼시픽
(시드니)
10TB까지/월 -25% -25% -37% -30% -26%
이후 40TB/월 -6% -6% -43% -15% -21%
이후 100TB/월 -37% -5% -13%
이후 350TB/월 -33% -6% -14%

“10TB까지/월”요금은 AWS 무료 이용 한도의 데이터 전송이 끝난 후에 적용됩니다.

CloudFront 데이터 전송 가격 인하

CloudFront 인터넷 데이터 전송 가격에 대한 개요입니다. 자세한 것은 CloudFront의 요금 페이지를 살펴 보시기 바랍니다.

요금 조건 미국 유럽 홍콩, 필리핀
한국, 싱가포르, 대만
일본 호주
초기 10TB/월 -29% -29% -26% -26% -26%
이후 40TB/월 -4% -4% -4%

이들 요금은 AWS 무료 이용 한도 데이터 전송 사용 후에 적용됩니다.

예전 부터 추진하고 있는대로 계속적으로 가격을 인하하는데 초점을 맞추어 고객이 비용을 절약할 수 있도록 노력하겠습니다.

–Jeff

이 글은 AWS Data Transfer Price Reduction의 한국어 번역입니다.

AWS Lambda – 클라우드에서 코드 실행

AWS는 클라우드에서 실행되는 응용 프로그램의 실행을 더욱 쉽게 하여 개발자들이 코드에만 집중할 수 있게 될 뿐만 아니라 확장성, 신뢰성 및 런타임 효율이 충분히 높은 클라우드 중심의 개발 환경이 필요하다고 생각해 왔습니다.

이를 위해 AWS Lambda미리보기를 오늘 출시합니다. AWS Lambda는 클라우드에서 애플리케이션을 실행하는 새로운 플랫폼으로서 기존 프로그래밍 및 AWS 지식을 활용할 수 있습니다. Lambda를 이용하여 간단하게 Lambda function을 만들고 특정 AWS 리소스에 대한 권한을 주고 Lambda function을 AWS 리소스에 연결할 수 있습니다. Lambda는 Amazon Simple Storage Service (S3) 버킷에 업로드된 파일에 대한 변경이나 Amazon Kinesis 스트림에의 특정 데이터 처리, Amazon DynamoDB 테이블 업데이트 같은 이벤트를 통해 여러분이 미리 업로드한 코드를 자동으로 실행합니다.

Lambda는 전혀 관리가 필요 없는 컴퓨팅 플랫폼입니다. EC2 인스턴스를 만들고 설정할 필요가 없습니다. 운영 체제나 프로그래밍 개발 환경을 설치할 필요도 없습니다. 스케일과 탄력성을 고려할 필요도 없으며, 미리 용량을 요청하거나 확보할 필요도 없습니다. 새로 만들어진 Lambda function은 사용자 측에서 아무 것도 하지 않으면서도 높은 비용 효율에 따라 시간당 수백만 건의 요청을 처리 할 수​​ 있습니다.

좀 더 Lambda를 자세히 살펴 보겠습니다. 프로그래밍 모델 및 런타임 환경을 살펴 보고 나서 프로그래밍 예제를 실행 해 보겠습니다. 이 글을 읽음으로서 Lambda 로드맵에 많은 항목이 있다는 것을 아실 수 있고, 앞으로 계속 이어질 기능 추가를 위한 여행의 작은 첫 걸음입니다.

Lambda의 개념

Lambda의 가장 중요한 개념은 Lambda function입니다. Node.js ( JavaScript로 개발된 이벤트 기반 서버 구현)에서 Lambda function을 실행 할 수 있습니다.

JS 코드를 업로드하기 위해 Lambda function을 만드는 Amazon Lambda에 대한 컨텍스트 정보를 설정합니다. 컨텍스트 정보는 실행 환경(언어, 필요한 메모리 제한 기간이나 IAM role)을 지정하고 코드에서 수행할 함수를 지정합니다. 코드와 메타 데이터는 AWS에서 영구적으로 저장하고 나중에 이름과 ARN(Amazon Resource Name)에서 볼 수 있습니다. 필요한 타사 라이브러리도 업로드에 포함할 수 있습니다 (Lambda function마다 하나의 ZIP 파일 형식입니다).

업로드 후 자신의 Lambda function과 특정 AWS 리소스 (특정 S3 버킷, DynamoDB 테이블 또는 Kinesis 스트림)을 연결합니다. Lambda는 Lambda function에 이벤트 (일반적으로 자원이 변경된 경우 실행)을 함께 연결하도록 합니다.

자원에 변경이 있는 경우, Lambda는 그 자원에 연결된 Lambda function을 실행합니다. 수신 요청을 처리하기 위해 필요한 컴퓨팅 리소스(EC2 인스턴스)를 시작 및 관리합니다. Lambda가 여러분 대신 자원을 관리 할 수​​ 있으며, 더 이상 필요 없어지면 실행이 종료됩니다.

Lambda는 AWS Management Console, AWS SDKAWS Command Line Interface (CLI)에서 접근할 수 있습니다. Lambda API는 모든 문서화되어 있으며 기존 코드 편집기 및 기타 개발 도구를 Lambda에 연결하는 데 사용할 수 있습니다.

Lambda 프로그래밍 모델
Lambda function 연결된 AWS 서비스의 자원이 변경될 때 활성화됩니다. 즉, 지정된 Node.js의 함수 실행이 시작되고 거기에서 작업 처리가 진행됩니다. 함수는 (POST와 함께 전달 된 매개 변수를 통해) JSON 형식의 데이터 구조에 접근합니다. 이 데이터 구조는 Lambda function이 활성화되는 계기가 되는 변경(또는 기타 이벤트)에 대한 자세한 정보를 포함합니다.

Lambda는 자원 변경 속도에 뒤쳐지지 않도록 필요에 따라 Lambda function의 추가 복사본을 활성화합니다. Lambda function은 컴퓨팅 인스턴스에 영구적인 상태를 저장할 수 없기 때문에, 대신 S3 또는 DynamoDB를 사용해야 합니다.

여러분의 코드는 Node.js 및 Linux 환경에서 내재된 기능을 사용할 수 있습니다. 다른 AWS 서비스를 호출하기 위해 AWS SDK for JavaScript in Node.js 를 이용할 수도 있습니다.

Lambda의 실행 환경
각 Lambda function에 지정된 컨텍스트 정보는 함수의 최대 실행 시간을 지정합니다. 일반적으로 짧게 설정되어 있지만 (몇 초 정도에 대부분 실행 가능) 필요에 따라 최대 60초까지 지정할 수 있습니다.

Lambda는 여러 IAM role을 사용하여 Lambda function에 대한 접근과 AWS 리소스를 관리합니다. Invocation role은 Lambda에서 특정 Lambda function을 수행할 권한을 부여합니다. Execution role은 Lambda function의 특정 AWS 리소스에 대한 접근 권한을 부여합니다. 세분화 되어 있는 권한의 조합을 이루기 위해 각각 기능에 대해 별도의 IAM role을 사용할 수 있습니다.

Lambda는 각 Lambda function의 실행을 감시하고 요청 수, 지연 시간, 가용성 및 오류 비율 통계를 Amazon CloudWatch 에 저장합니다. 30 일 동안 보관되며 콘솔에서도 볼 수 있습니다.

이제 Lambda를 사용하시려고 할 때 고려해야 할 몇 가지 사항을 알려드립니다.

  • Lambda function 컨텍스트 정보는 실행에 필요한 메모리 양을 지정합니다. 128MB에서 1​​GB까지 원하는 값을 지정할 수 있습니다. 메모리 설정에 따라 Lambda function이 사용 가능한 인스턴스의 CPU 능력, 네트워크 대역폭, IO 대역폭이 결정됩니다.
  • 각 Lambda function의 시작은 최대 256 프로세스 또는 스레드를 사용할 수 있습니다. 최대 512MB의 로컬 스토리지와 102개 이상의 파일 디스크립터도 사용할 수 있습니다. 또한, 최대 10개의 동시 아웃 바운드 연결을 생성합니다.
  • Lambda는 각 AWS 계정에서 일련의 관리 상의 제한을 부과합니다. 미리보기 기간 동안 동시 실행 요청을 25개까지 처리 할 수​​ 있습니다.

Lambda 소개
이제 관리 콘솔을 사용하여 간단한 Lambda function을 만드는 과정을 살펴 보겠습니다. 앞서 말한대로 SDKCLI 에서 실행할 수 있습니다.

아래 화면은 콘솔에서 내 전체 Lambda function을 표시하고 있습니다.

이제 “Create a Lambda function”을 클릭합니다. 자세한 내용을 모두 입력합니다.

아래와 같이 자신의 Lambda function에 이름을 붙이고 설명 사항을 추가합니다.

JS 코드를 직접 입력하거나 ZIP 파일을 업로드합니다. 콘솔에서 시작할 수 있도록 샘플 코드를 선택할 수 있습니다.

Lambda function을 실행하거나 실행시 어떤 IAM role을 사용할지 여부를 지정합니다.

메모리 요구 사항 조정과 실행 시간 제한도 설정할 수 있습니다.

Lambda function을 만든 후 콘솔에서 반복 편집 테스트 할 수 있습니다. 왼쪽 창에는 Lambda function에 전달 된 JSON 데이터 샘플이 표시되어 있습니다.

Lambda function이 예상대로 실행 되고 있다면, Amazon S3 event notification 같은 이벤트 소스를 연결할 수 있습니다. Lambda function의 시작을 위해 필요한 권한을 S3에 제공하기 때문에 Invocation role을 지정합니다.

앞에서 이야기한 대로 Lambda는 각 Lambda function마다 통계 정보를 수집하고 이를 Amazon CloudWatch에 보냅니다. 콘솔에서 통계를 볼 수 있습니다.

로드맵
앞으로 Lambda에 대한 로드맵을 가지고 있으며, 오늘 그 모든 것을 말씀 드릴 수는 없지만 새로운 AWS 서비스 이벤트에 추가 지원 및 프로그래밍 언어 지원을 추가 할 예정임을 알려드립니다. 언제나 마찬가지로 우리는 고객의 의견을 매우 소중히 생각하고 있습니다. 꼭 Lambda Forum에 의견을 남겨주세요.

이용 가격 및 가능한 지역

마지막으로 요금에 대해 이야기 해보면, Lambda는 차별화 된 요금 체계로 되어 있습니다. 100밀리 초 단위의 컴퓨팅 시간과 개별 요청에 대해서만 지불이 됩니다. Lambda 무료 이용은 한달 100만 요청과 한달 최대 320만 초 컴퓨팅 처리 시간을 포함합니다. 컴퓨팅 처리 시간은 Lambda function마다 할당된 메모리의 총량에 따라 다릅니다. Lambda는 오늘부터 US East (Northern Virginia), US West (Oregon), 그리고 Europe (Ireland) 지역에 한정 미리보기가 가능합니다.

– Jeff;

이 글은 AWS Lambda – Run Code in the Cloud의 한국어 번역입니다.