使用OBS SDK通过对象名删除桶内百万个对象
OBS提供了SDK,方便客户调用进行各种桶和对象的操作,下面介绍一个批量删除的例子。
客户诉求
需要将华为云中3个桶:共400万左右的数据进行删除。客户已经将对象名整理好,分别存放在本地的3个文件中。如下图所示:
图1
客户提供的3个文件名即桶名,文件的内容就是该桶内需要删除的对象名,比如ocs-intern这个文件中的内容(也即对象名)如下,可以看出ocs-intern桶中有一个一级目录,名字也叫ocs-intern。
图2
解决办法
使用python SDK的批量删除接口进行操作。并且在本地记录删除的结果(包括删除的对象名、是否删除成功、requestID)。具体如下所示:
分别在桶中获取客户对象的元数据,以便确认客户提供的对象名真的在桶中存在。如果对象在桶中存在,则将对象名写入keyExitInBucketLog.txt文件本地保存;如果对象名不存在,则将对象名写入keyNotExitInBucketLog.txt文件本地保存。
从keyExitInBucketLog.txt文件中读取对象名,进行批量删除。如果删除成功,则将删除成功的对象及其相关信息写入deleteSucResultLog.txt文件在本地保存;如果删除失败,则将删除失败的对象名及其相关信息写入。
说明:
本次测试主要用到了Python版SDK中“getObjectMetadata”、“deleteObjects”接口,以及Python读写windows主机本地文件的功能。
源码解析
#!/usr/bin/python
# -*- coding:utf-8 -*-
'''
This sample demonstrates how to delete objects under specified bucket
from OBS using the OBS SDK for Python.
'''
AK = 'Q2HSIJQCxxxxxxxxx'
SK = 'BhoMxrR8wp3keV9xxxxxxxxxxxxxxxxxxxxxxxxxx'
server = 'https://obs.cn-east-2.myhwclouds.com'
bucketName = '10002' #共3个文件夹,可以在这里分别更换3个文件夹名称,分别运行
from obs import *
import os
# Constructs a obs client instance with your account for accessing OBS
obsClient = ObsClient(access_key_id=AK, secret_access_key=SK, server=server, proxy_host="proxy.huawei.com", proxy_password="1xxxxxxx", proxy_port=8080, proxy_username="w00221114")
filename = r'D:\OBS-NEW\ocs-intern'
keysfirst = []
keyExitInBucketLog = "keyExitInBucketLog.txt"
keyNotExitInBucketLog = "keyNotExitInBucketLog.txt"
deleteSucResultLog = "deleteSucResultLog.txt"
deleteFailResultLog = "deleteFailResultLog.txt"
childKeysLength = 1000
#从本地的文件中读取对象名
f = open(filename,'r')
for line in f.readlines():
line = line.strip('\n')
# print line
keysfirst.append(Object(key=line))
print keysfirst
f.close()
#拿着本地文件获取到的对象名,再去OBS桶中获取下这个对象的元数据,从而判断出对象是否在桶中存在。如果存在,则在本地新建keyExitInBucketLog.txt文件,并将对象名记录。
#如果不存在,则在本地新建keyNotExitInBucketLog.txt文件,并将不存在的对象名在此记录。
print ('\nGet objectsMetadata\n')
for dict in keysfirst:
print dict
objectKey = dict['key']
# print objectKey
resp = obsClient.getObjectMetadata(bucketName, objectKey)
if resp.status < 300:
f = file(keyExitInBucketLog, 'a+')
contextSuc = str(objectKey) + '\t' + str(resp.status) +'\t' + str(resp.reason) + '\t' + str(resp.body.lastModified) + '\n'
# print contextSuc
f.write(contextSuc)
f.close()
print('Get objectMetadata ' + objectKey + ' successfully!\n')
else:
f = file(keyNotExitInBucketLog, 'a+')
contextError = str(objectKey) + '\t' + str(resp.status) +'\t' + str(resp.reason) + '\n'
# print contextError
f.write(contextError)
f.close()
# 从这里开始,批量删除对象,每次删除1000个,直到删完为止。
print('\nDeleting all objects\n')
exitKeys = []
#从keyExitInBucketLog.txt文件中读取对象名,将这些要删除的对象的对象名放进一个列表中,如果用户有400万对象,则这个列表长度就为400万。
if os.path.exists(keyExitInBucketLog):
f = open(keyExitInBucketLog, 'r')
for line in f.readlines():
line = line.strip('\n').split('\t', 1)
# print line
objName = line[0]
exitKeys.append(Object(key=objName))
# print exitKeys
f.close()
count = len(exitKeys)
print count
#定义一个函数,这个函数将很大的列表按每个列表长度为1000,进行分割,分割成多个列表
def list_of_groups(init_list, children_list_len):
list_of_groups = zip(*(iter(init_list),) * children_list_len)
end_list = [list(i) for i in list_of_groups]
count = len(init_list) % children_list_len
end_list.append(init_list[-count:]) if count != 0 else end_list
return end_list
childKeysList = list_of_groups(exitKeys,childKeysLength)
#每次对子列表中1000个对象进行批量删除。如果删除成功,则在deleteSucResultLog.txt文件中记录删除成功的对象名。如果删除失败,则在deleteFailResultLog.txt文件中记录删除失败的文件名。
for childKeys in childKeysList:
# print len(childKeys)
resp = obsClient.deleteObjects(bucketName, DeleteObjectsRequest(False, childKeys))
if resp.status < 300:
f = file(deleteSucResultLog, 'a+')
for delete in resp.body.deleted:
# print delete['key']
deleteSucResult = str(delete['key']) + '\t' + str(resp.status) + '\t' + str(resp.reason) + '\t' + str(
resp.requestId) + '\n'
# print deleteSucResult
f.write(deleteSucResult)
f.close()
else:
f = file(deleteFailResultLog, 'a+')
for err in resp.body.error:
# print err['key']
deleteErrResult = str(err['key']) + '\t' + str(resp.status) + '\t' + str(resp.reason) + '\t' + str(
resp.requestId) + '\n'
# print deleteErrResult
f.write(deleteErrResult)
f.close()
else:
print "all the objects which list is not in bucket! "
- 点赞
- 收藏
- 关注作者
评论(0)