끄적이는 보송

[AWS] Glacier 복수 객체 한번에 복원하기 본문

STUDY/AWS

[AWS] Glacier 복수 객체 한번에 복원하기

끄적이는 보송 2022. 9. 20. 17:57
반응형

이전에 S3 Glacier Deep Archive에 있는 객체 복원 관련하여 다뤘었다. 콘솔 환경에 접근해보면 알겠지만 Glacier로 객체 Class 변경은 폴더 단위로 한 번에 변경하는 것이 가능하지만, 그 반대로 적어도 콘솔 환경에서는 다수의 객체를 한 번에 복원하는 것은 불가능하다. 물론 다수의 객체를 선택할 수 있지만 폴더는 해당되지 않는다. (이 기능을 지원하는 게 그렇게 어려운 일인가 싶다.) 이 작업을 수행하려면 CLI명령어나 코드로 수행해야 한다.
[+] https://bosungtea9416.tistory.com/entry/AWS-S3-Glacier-%EA%B0%9D%EC%B2%B4-%EB%B3%B5%EC%9B%90%ED%95%98%EA%B8%B0

 

[AWS] S3 Glacier 객체 복원하기

Amazon S3 Glacier는 콜드 스토리지처럼 저렴하게 장기간 스토리지를 보관할 수 있는 서비스이다. 자주 액세스 하지 않으며 싸게 싸게 오랫동안 보관할꺼라면 이점이 있는 서비스다. 이번에 S3 Glacier

bosungtea9416.tistory.com

물론 AWS에서 이런 부분을 아래 링크에서 가이드하고 있다. 하지만 나에게는 맞지 않는 부분이 있었다.
[+] https://docs.aws.amazon.com/AmazonS3/latest/userguide/restoring-objects.html

 

Restoring an archived object - Amazon Simple Storage Service

Restoring an archived object Amazon S3 objects that are stored in the S3 Glacier Flexible Retrieval or S3 Glacier Deep Archive storage classes are not immediately accessible. To access an object in these storage classes, you must restore a temporary copy o

docs.aws.amazon.com

 

 

Glacier 객체 복원하기 (using AWS CLI 명령어)

나의 경우, NAS에 있는 지저분한 데이터를 Glacier에 옮겨놓았고 이 데이터를 Glacier에서 복원해야 할 일이 있었는데 이 안에 데이터가 작업하기에 좋은 데이터는 아니었다. 아래의 문제점 때문에 AWS에서 가이드하는 CLI를 그대로 활용할 수 없었다. 

- 객체 이름에 한글이 포함되었다.
- 객체 이름에 특수문자가 포함되어 있었다.
- 객체 이름에 공백이 있었다. 
- 폴더 안에 폴더 안에 그 안에 또 폴더...

이 모든 것을 해결할 수 있는 명령어를 한 번 짜보았다.

aws --output json s3api list-objects --bucket <bucket_name> | grep -i key | awk -F : '{print $2}' | sed 's/"//g' | sed 's/,//g'1 | xargs -I %%% aws s3api restore-object --bucket <bucket_name> --restore-request Days=<number_of_days>,GlacierJobParameters={"Tier"="<Standard_or_Bulk>"} --key "%%%"

 

 

다량의 Glacier 객체 복원하기 (using Code)

하지만 단순히 CLI 명령어로는 너무 느렸다. 나의 경우, Glacier에 있는 특정 폴더의 하위 폴더 및 모든 객체를 복원해야 했는데, 그 객체수가 수백만 개였다. 개인적으로 CLI 명령어를 수행했을 땐 초당 4~5개 정도밖에 처리하지 못해 너무 오랜 시간이 걸렸다. 그래서 활용한 게 Python 코드다. 

나는 S3 버킷에 있는 (혹은 특정 경로를 시작해 하위 폴더 및 객체를 대상으로) 객체를 검색한 뒤, 해당 객체가 Glacier Deep Archive의 객체가 아니라면 Restore 하는 코드를 짜보았다. 버킷 객체 검색 및 객체 복원 작업은 스레드로 돌리면 더 빠른 작업이 가능하다.
[+] https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html

 

1. S3의 폴더와 파일 객체 검색하기 (client.list_objects())

나의 경우 S3안에 많은 폴더와 많은 객체가 섞여 있었으며 폴더 안에 폴더... 그 폴더 안의 폴더... 가 많았던 환경이었다. 그래서 객체 중 파일과 폴더를 명확히 구분할 필요가 있었고 'client.list_objects()'의 'Delimiter' 매개변수를 활용하여 이것을 구분했다. 'Delimiter' 매개변수가 추가되면 'CommonPrefixes' 값을 불러올 수 있다. 

s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket_name)
client = boto3.client('s3')

response = client.list_objects(
    Bucket='string',
    Delimiter='string',
    Prefix='string'
)

* 사실 S3에 폴더는 없지만 객체를 그룹화하는 수단으로 폴더 개념을 제공한다. 그리고 각 객체는 키 값을 가지고 있는데, 키 값은 객체가 위치하고 있는 경로와 객체의 이름을 포함하고 있다

#만약 폴더가 있다면
if result.get('CommonPrefixes') != None:
	-> THEN_DO_SOMETHING
#만약 객체 파일이 있다면
if result.get('Contents') != None:
	for i in result.get('Contents'): 
    	#해당 객체가 폴더가 아닌 파일이라면
    	if i.get('Key')[-1] != "/": 
        	THEN_DO_SOMETHING

만약 S3 객체를 검색하려는 해당 경로에 또 다른 폴더가 있다면 result.get('CommonPrefixes')의 값은 'None'이 아니게 된다.

 

2. Glacier Deep Archive 객체 복원하기 

#객체가 Deep Arvhice Class가 아니라면 복원해라
if obj_sum.get('StorageClass') == 'DEEP_ARCHIVE':
	resp = bucket.meta.client.restore_object(
    Bucket=<bucket_name>,
    Key=<obj_key>,
    RestoreRequest={'Days': <number_of_days_available>, 'GlacierJobParameters': {'Tier': <restore_tier>}}
)

 

3. 복원 작업 간 로그 쌓기 

#성공 용, 실패 용 로그 셋업
path1 = "./success_log.txt"
path2 = "./fail_log.txt"
f1 = open(path1, 'w')
f2 = open(path2, 'w')
#작업 성공한 로그 쌓기
obj_name = str(obj_key)
time_stamp = str(datetime.datetime.now())
count = count + 1
f1.write(time_stamp + obj_name + '\n')
#Deep Archive객체가 아니라서 실패한 객체 로그 쌓기
obj_name = str(obj_key)
time_stamp = str(datetime.datetime.now())
count = count + 1
f1.write(time_stamp + obj_name + ' IS NOT DEEP_ARCHIVE! \n')
#그 이외에 무언가 잘못되어 실패한 로그 쌓기
except Exception as e:
obj_name = str(e)
time_stamp = str(datetime.datetime.now())
f2.write(time_stamp + obj_name + '\n')

위의 코드로 Glacier 객체 복원 작업 간, 성공 혹은 실패한 작업을 로그로 쌓을 수 있다. 나의 경우 실시간으로 쌓이는 로그를 다른 한쪽 모니터에 확인하면서 작업의 속도나 상황을 확인하고 싶었다.(무언가가 잘못되면 실패 로그에 로그가 쌓일 테니 말이다!) 실시간으로 쌓이는 로그 모니터링은 아래 글을 참고해보자
https://bosungtea9416.tistory.com/entry/Linux-tail-f-%EB%AA%85%EB%A0%B9%EC%96%B4-vs-less-N-F-%EB%AA%85%EB%A0%B9%EC%96%B4

 

[Linux] Line Number와 함께 실시간 로그 조회하기 (less -N + F 명령어)

실시간으로 쌓이는 로그를 모니터링을 할 때 'tail -f '을 즐겨 사용했다. 그러다 문뜩 떠오른 생각이 있었는데... "실시간으로 쌓이는 로그에 Line Number도 같이 출력할 수 없을까? 실시간으로 쌓이

bosungtea9416.tistory.com

반응형
Comments