OBS 对象上传下载的一致性校验

网友投稿 1600 2022-05-30

1      方案概述

1.1      背景说明

OBS服务在提供各种对象上传下载等服务时,已经为用户提供了安全、高可靠的数据存储能力,为确保传输和应用过程中可能产生的数据一致性问题,OBS服务也为用户提供了各种方式来校验对象的MD5一致性,本文就几中常用的方式进行介绍。

1.2      方案说明

OBS服务为用户提供了不同工具/SDK使用场景下基于MD5校验数据一致性能力:

其中OBS Browser和obsutil工具,在开启MD5校验功能后,进行对象上传时,只有在OBS服务端上已上传对象的MD5值与本地对象MD5值一致时才可以上传成功,从而保证上传数据的一致性,同时也将MD5值存放在了对象元数据中。在开启MD5校验功能后进行对象下载时,OBS服务端会将存放在对象元数据中的MD5值与下载后的对象MD5值进行比对,只有两者一致才能成功下载对象。如图1所示。

图1 OBS Browser和obsutil进行对象上传下载MD5校验流程

另一种方法是OBS SDK,它提供接口参数,利用content-MD5头域能力提供上传数据一致性校验。上传对象完成校验后,对象元数据中的etag值等同于MD5值,但当对象为多段对象或加密对象时,对象元数据中的etag值不是MD5值。在这种情况,MD5没有对比值,OBS SDK也无法对下载对象操作进行MD5校验,但用户可在上传对象时将MD5值存入对象自定义元数据中,供下载对象时进行MD5校验,这部分内容在3.3中会详细讲到。

2      对象上传的校验操作指导

2.1      方式一:OBS Browser

步骤一:登录OBS Browser后,单击页面右上角的“系统配置”图标,在“系统配置>基本配置”窗口,勾选“启用MD5校验”并保存设置,如图2所示。

OBS 对象上传下载的一致性校验

图2 OBS Browser配置MD5校验

步骤二:选择需要上传的对象,单击“确定”后,在页面右上角单击“任务管理”图标,在“正在运行”任务管理列表页签中查看对象上传状态和MD5校验状态,待对象上传完成,可以在“已完成”任务管理列表页签中查看到MD5校验结果,如图3所示。

图3 OBS Browser查看MD5校验结果

说明:

·          开启MD5校验会影响上传下载性能。

·          OBS Browser工具如何使用和下载,请参考对象存储服务OBS帮助文档(链接:https://support.huaweicloud.com/obs/index.html)。

2.2      方式二:obsutil

使用obsutil工具时,可通过附加-vmd5参数来上传对象,此时OBS服务端会帮用户进行MD5校验,只有在OBS服务端上已上传对象的MD5值与本地对象MD5值一致时才可以上传成功,如图4所示。

图4 obsutil查看MD5校验结果

说明:

·          开启MD5校验会影响上传下载性能。

·          obsutil工具如何使用和下载,请参考对象存储服务OBS帮助文档(链接:https://support.huaweicloud.com/obs/index.html)。

2.3      方式三:OBS SDK

除了上述两种方法,您还可以基于华为云SDK,通过编写代码调用华为云API来校验对象上传的一致性。如果不匹配则上传失败,返回HTTP 400错误(Error Message: The Content-MD5 you specified did not match what we received.)

华为云有10种语言SDK可供选择,下面列举其中2种语言MD5校验。

2.3.1     OBS Java SDK

您可以通过ObsClient.base64Md5来直接计算Content-MD5头域,并使用ObjectMetadata.setContentMd5来设置对象MD5值。OBS服务端会将该Content-MD5头域与对象数据计算出的经过Base64编码后MD5值进行对比,示例代码如下。

String endPoint = "https://your-endpoint";

String ak = "*** Provide your Access Key ***";

String sk = "*** Provide your Secret Key ***";

// 创建ObsClient实例

ObsClient obsClient = new ObsClient(ak, sk, endPoint);

// 计算并设置MD5值

ObjectMetadata metadata = new ObjectMetadata();

File file = new File("E:\\README.txt");

FileInputStream fis = new FileInputStream(file);

InputStream is = (InputStream)fis;

String contentMd5 = obsClient.base64Md5(is);

metadata.setContentMd5(contentMd5);

// 带MD5校验功能上传文件

obsClient.putObject("bucketname", "objectkey", file, metadata);

说明:

·          开启MD5校验会影响上传下载性能。

·          OBS SDK各工具如何使用和下载,请参考对象存储服务OBS帮助文档(链接:https://developer.huaweicloud.com/sdk?OBS)。

2.3.2     OBS Python SDK

您可以通过PutObjectHeader.md5来设置对象Content-MD5头域。其中GetFileMd5函数用于计算对象的MD5值(用户可以自定义,仅供参考),示例代码如下。

# 引入模块

from obs import ObsClient

# 创建ObsClient实例

obsClient = ObsClient(

access_key_id='*** Provide your Access Key ***',

secret_access_key='*** Provide your Secret Key ***',

server='https://your-endpoint'

)

from obs import PutObjectHeader

headers = PutObjectHeader()

# 计算MD5

def GetFileMd5(filename):

if not os.path.isfile(filename):

return

myhash = hashlib.md5()

f = open(filename, 'rb')

str = f.read()

myhash.update(str)

f.close()

return myhash.digest()

# 带MD5校验上传文件

filename = ‘E:\\README.txt’

contentMd5 = GetFileMd5(filename)

contentMd5B64 = base64.b64encode(contentMd5).decode()

headers.md5 = contentMd5B64

resp = obsClient.putFile('bucketname', 'objectkey', filename, headers=headers)

if resp.status < 300:

print('requestId:', resp.requestId)

else:

print('errorCode:', resp.errorCode)

print('errorMessage:', resp.errorMessage)

说明:

·          开启MD5校验会影响上传下载性能。

·          OBS SDK各工具如何使用和下载,请参考对象存储服务OBS帮助文档(链接:https://developer.huaweicloud.com/sdk?OBS)。

3      对象下载的校验操作指导

3.1      方式一:OBS Browser

步骤一:登录OBS Browser后,单击页面右上角的“系统配置”图标,在“系统配置>基本配置”窗口,勾选“启用MD5校验”并保存设置,如图5所示。

图5 OBS Browser配置MD5校验

步骤二:选择需要下载的文件,单击“确定”后,在页面右上角单击“任务管理”图标,在“正在运行”任务管理列表页签中可以查看对象下载状态和MD5校验状态,待对象下载完成,可以在“已完成”任务管理列表页签中查看到MD5校验结果,如图6所示。

图6 OBS Browser查看MD5校验结果

说明:

·          OBS Browser工具如果在上传对象时未开启MD5校验的功能,那在下载对象时即使开启了MD5校验功能其实也没有进行MD5校验。

3.2      方式二:obsutil

使用obsutil工具时,若通过附加-vmd5参数来上传对象 ,此时OBS服务端会帮用户进行MD5校验,同时还会把此MD5值存放在该对象的元数据中(如图7所示),以便于下载的时候读取该MD5值,与下载对象计算的MD5值进行比较,如图8所示。

图7 存放在对象元数据中的MD5值

图8 使用obsutil附加-vmd5参数来下载对象

说明:

·          OBS Browser工具如果在上传对象时未开启MD5校验的功能,那在下载对象时即使开启了MD5校验功能其实也没有进行MD5校验。

3.3      方式三:OBS SDK

OBS服务SDK对上传对象的Content-MD5头域进行一致性校验,但未做下载对象的一致性校验,但可以通过在上传对象时把MD5值存放到对象自定义元数据里,对象下载后,将此自定义元数据里的MD5值与下载到本地的对象进行校验比对。

华为云有10种语言SDK可供选择,下面列举其中2种。

3.3.1     OBS Java SDK

在上传对象时通过ObjectMetadata.addUserMetadata来存放对象Content-MD5头域值。对象下载后,将此自定义元数据里的MD5校验值和下载到本地文件的MD5校验值进行对比,示例代码如下。

String endPoint = "https://your-endpoint";

String ak = "*** Provide your Access Key ***";

String sk = "*** Provide your Secret Key ***";

// 创建ObsClient实例

ObsClient obsClient = new ObsClient(ak, sk, endPoint);

// 把Content-MD5头域值存放入对象自定义元数据中

ObjectMetadata metadata = new ObjectMetadata();

File file = new File("E:\\README.txt");

FileInputStream fis = new FileInputStream(file);

InputStream is = (InputStream)fis;

String contentMd5 = obsClient.base64Md5(is);

metadata.addUserMetadata("property1", contentMd5);

// 上传文件

obsClient.putObject("bucketname", "objectkey", file, metadata);

// 获取对象的自定义元数据

ObjectMetadata metadataDown = obsClient.getObjectMetadata("bucketname", "objectkey");

String contentMd5Origin = metadataDown.getUserMetadata("property1");

// 对下载后的对象进行MD5值进行比对

ObsObject obsObject = obsClient.getObject("chongchongbucket001", "cc.txt");

String contentMd5Download = obsClient.base64Md5(obsObject.getObjectContent());

if(contentMd5Origin.contentEquals(contentMd5Download))

System.out.println("Object MD5 validation passes!\n");

else

System.out.println("Object MD5 validation failed!\n");

3.3.2     OBS Python SDK

在上传对象时通过metadata参数来存放对象Content-MD5头域值。对象下载后,将此自定义元数据里的Content-MD5头域值与下载到本地的对象进行校验比对,示例代码如下。

# 引入模块

from obs import ObsClient

# 创建ObsClient实例

obsClient = ObsClient(

access_key_id='*** Provide your Access Key ***',

secret_access_key='*** Provide your Secret Key ***',

server='https://your-endpoint'

)

from obs import PutObjectHeader

headers = PutObjectHeader()

# MD5值计算函数

def GetFileMd5(filename):

if not os.path.isfile(filename):

return

myhash = hashlib.md5()

f = open(filename, 'rb')

str = f.read()

myhash.update(str)

f.close()

return myhash.digest()

# 把MD5值存放入对象自定义元数据中

filename = ‘E:\\README.txt’

contentMd5 = GetFileMd5(filename)

contentMd5B64 = base64.b64encode(contentMd5).decode()

metadata = {'property1' : 'contentMd5B64'}

resp = obsClient.putFile('bucketname', 'objectkey', filename, metadata=metadata)

if resp.status < 300:

print('requestId:', resp.requestId)

else:

print('errorCode:', resp.errorCode)

print('errorMessage:', resp.errorMessage)

# 获取对象自定义元数据中的MD5值

resp = obsClient.putFile('bucketname', 'objectkey')

contentMd5Origin = dict(resp.header).get('property1')

if resp.status < 300:

print('requestId:', resp.requestId)

else:

print('errorCode:', resp.errorCode)

print('errorMessage:', resp.errorMessage)

# 对下载后的对象进行MD5值进行比对

filenameDown = "E:\\README_DOWN.txt"

resp = obsClient.putFile('bucketname', 'objectkey', downloadPath=filenameDown)

contentMd5Download = base64.b64encode(GetFileMd5(filenameDown)).decode()

if (contentMd5Origin == contentMd5Download):

print("Object MD5 validation passes!\n")

else:

print("Object MD5 validation failed!\n")

对象存储服务 OBS 存储

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:节点互信建立、及修复
下一篇:如何写出让同事无法维护的代码?
相关文章