Восстановление данных из Amazon Glacier
Есть ли способ командной строки для восстановления данных из Glacier? Пока что я попробовал:
s3cmd restore --recursive s3://mybucketname/folder/
aws s3 ls s3://<bucket_name> | awk '{print $4}' | xargs -L 1 aws s3api restore-object --restore-request Days=<days> --bucket <bucket_name> --key
Но никакой помощи там нет. PS: я знаю, что мы можем сделать это через консоль.
3 ответа
Вы можете использовать нижний уровень aws s3api
команда:
aws s3api restore-object --request-payer requester \
--key path/to/key.blob \
--bucket my-bucket \
--cli-input-json "$(cat request.json)"
А затем установите свои параметры внутри request.json
, например:
{
"RestoreRequest": {
"Days": 1,
"GlacierJobParameters": {
"Tier": "Standard"
}
}
}
После того, как запрос на восстановление будет инициирован, вам нужно будет позвонить head-object
чтобы определить его статус восстановления:
aws s3api head-object --key path/to/key.blob \
--bucket my-bucket \
--request-payer requester
{
"AcceptRanges": "bytes",
"Restore": "ongoing-request=\"true\"",
"LastModified": "Thu, 30 May 2019 22:43:48 GMT",
"ContentLength": 1573320976,
"ETag": "\"5e9bae0592655103e72d0c026e643184-94\"",
"ContentType": "application/x-gzip",
"Metadata": {
"digest-md5": "7ace7afadfaec591a7dcff2b942df701",
"import-digests": "md5"
},
"StorageClass": "GLACIER",
"RequestCharged": "requester"
}
когда Restore
содержит, ongoing-request="false"
, восстановление будет завершено. Временная копия в S3 будет храниться в течение времени, указанного в команде восстановления. ВStorageClass
всегда GLACIER
(или DEEP_ARCHIVE) для любого восстановленного файла, даже после его восстановления. Это не интуитивно.
Если вы хотите восстановить эту копию на постоянной основе в S3, т.е. и изменить класс хранения с GLACIER на STANDARD, вам нужно будет поместить / скопировать (потенциально поверх себя) восстановленную копию в новый файл. Это раздражает.
Связанные с:
- Навсегда восстановить Glacier до S3
- http://docs.aws.amazon.com/AmazonS3/latest/user-guide/restore-archived-objects.html
Обратите внимание --request-payer requester
не является обязательным. Я использую это в своей настройке, но если вы владелец ведра, он вам не нужен.
К сожалению, это невозможно. Вы можете получить доступ к объектам, которые были заархивированы в Amazon Glacier, только с помощью Amazon S3.
См. http://docs.aws.amazon.com/AmazonS3/latest/user-guide/restore-archived-objects.html
Вот пример использования Java для восстановления объекта. По этой ссылке вы можете сделать что-то похожее на выбранном вами языке.
Восстановление заархивированного объекта с помощью AWS SDK для Java
Вы можете использовать код Python ниже, чтобы восстановить данные ледника до s3.
import boto3, botocore
import subprocess, os, shutil, tempfile, argparse, sys, time, codecs
from pprint import pprint
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
parser = argparse.ArgumentParser()
parser.add_argument('--max-rate-mb', action='store', type=int, default=10000, help='The maximum rate in MB/h to restore files at. Files larger than this will not be restored.')
parser.add_argument('--restore-days', action='store', type=int, default=30, help='How many days restored objects will remain in S3.')
parser.add_argument('--restore-path', action='store', help='The bucket/prefix to restore from')
parser.add_argument('--pretend', action='store_true', help='Do not execute restores')
parser.add_argument('--estimate', action='store_true', help='When pretending, do not check for already-restored files')
args = parser.parse_args()
if not args.restore_path:
print 'No restore path specified.'
sys.exit(1)
BUCKET = None
PREFIX = None
if '/' in args.restore_path:
BUCKET, PREFIX = args.restore_path.split('/',1)
else:
BUCKET = args.restore_path
PREFIX = ''
RATE_LIMIT_BYTES = args.max_rate_mb * 1024 * 1024
s3 = boto3.Session(aws_access_key_id='<ACCESS_KEY>', aws_secret_access_key='<SECRET_KEY>').resource('s3')
bucket = s3.Bucket(BUCKET)
totalsize = 0
objects = []
objcount = 0
for objpage in bucket.objects.filter(Prefix=PREFIX).page_size(100).pages():
for obj in objpage:
objcount += 1
print obj
objects.append(obj)
print u'Found {} objects.'.format(objcount)
print
objects.sort(key=lambda x: x.size, reverse=True)
objects = filter(lambda x: x.storage_class == 'GLACIER', objects)
if objects:
obj = objects[0]
print u'The largest object found is of {} size: {:14,d} {:1s} {}'.format(('a restorable' if obj.size <= RATE_LIMIT_BYTES else 'an UNRESTORABLE'), obj.size, obj.storage_class[0], obj.key)
print
while objects:
current_set = []
current_set_total = 0
unreported_unrestoreable_objects = []
i = 0
while i < len(objects):
obj = objects[i]
if obj.size > RATE_LIMIT_BYTES:
unreported_unrestoreable_objects.append(obj)
elif unreported_unrestoreable_objects:
# No longer accumulating these. Print the ones we found.
print u'Some objects could not be restored due to exceeding the hourly rate limit:'
for obj in unreported_unrestoreable_objects:
print u'- {:14,d} {:1s} {}'.format(obj.size, obj.storage_class[0], obj.key)
print
if current_set_total + obj.size <= RATE_LIMIT_BYTES:
if not args.pretend or not args.estimate:
if obj.Object().restore is not None:
objects.pop(i)
continue
current_set.append(obj)
current_set_total += obj.size
objects.pop(i)
continue
i += 1
for obj in current_set:
print u'{:14,d} {:1s} {}'.format(obj.size, obj.storage_class[0], obj.key)
#pprint(obj.Object().restore)
if not args.pretend:
obj.restore_object(RestoreRequest={'Days': args.restore_days})
#sys.exit(0)
print u'{:s} Requested restore of {:d} objects consisting of {:,d} bytes. {:d} objects remaining. {:,d} bytes of hourly restore rate wasted'.format(time.strftime('%Y-%m-%d %H:%M:%S'), len(current_set), current_set_total, len(objects), RATE_LIMIT_BYTES - current_set_total)
print
if not objects:
break
if not args.pretend:
time.sleep(3690)
Команда для запуска скрипта:
python restore_glacier_data_to_s3.py --restore-path s3-bucket-name/folder-name/