写点什么

对象业务的追加写接口

  • 2024-06-04
    福建
  • 本文字数:3988 字

    阅读完需:约 13 分钟

类似文件的追加写操作,在对象的末尾增加新的数据内容。


本文有如下假定:


  • 对象存储服务基于文件语义实现。

  • 使用 PUT 方式上传的对象,内部使用一个文件和对应的元数据来承载。

  • 使用多段方式上传的对象,内部使用多个段文件、元数据来承载,其中每个段文件可管理独有的元数据。


下面讨论追加写操作时的方案和注意事项。


接口定义


业界主流对象存储服务比如AWS S3并未定义追加写操作,而国内的各家公有云对象存储服务基于对象语义和文件语义的理解,提供了对象的追加写操作。


国内的公有云对象存储服务,提供的追加写操作,相关文档的链接(排名不分先后),如下:



阿里云 OSS AppendObject为例,接口定义如下:

POST /ObjectName?append&position=Position HTTP/1.1Content-Length:ContentLengthContent-Type: ContentTypeHost: BucketName.oss.aliyuncs.comDate: GMT DateAuthorization: SignatureValue
复制代码


本接口的关键参数,如下:


  • 对象名,指定执行追加写操作的对象名。

  • 操作名,参数名为append,不需要指定参数值。

  • 追加写的位置,参数名为position,参数值为追加写的开始位置。

  • 数据的长度,使用 HTTP 头部Content-Length承载。


另外允许更新对象的元数据,对象的元数据的说明见文档


实现思路


考虑到对象上传特点的特点,可以划分为 PUT 方式上传的对象,和使用多段方式上传的对象,因此在实现追加写时,需要考虑这两种对象和上传方式的差异,借鉴实现思路。


对于 PUT 方式上传的对象,实现追加写时,可以考虑如下方案:


  • 参照文件的追加写,即把对象当成文件,将追加写操作的数据追加到对象的数据的尾部。

  • 参照多段对象,将追加写的数据当成一个新的段,原有的对象当成多段方式上传的第一个段。

对于多段方式上传的对象,实现追加写时,可以考虑如下方案:

  • 参照文件的追加写,即把对象的最后一个段当成文件,将追加写操作的数据追加到最后一个段的数据的尾部。

  • 参照多段对象,将追加写的数据当成一个新的段,追加到对象的段的尾部。


下面从对象服务特性的角度,分别评估上述方案。


ETag


参考AWS S3数据一致性ETag基于对象的数据,使用MD5算法计算得到。


客户应用在请求的头部增加Content-MD5,指定本次上传数据的MD5值,或者对象数据整体的MD5值。


本次上传数据的MD5


客户应用在请求的头部增加Content-MD5,指定本次上传数据的MD5值。对象存储服务收到数据后,计算数据的MD5值,并和Content-MD5值对比:


  • 假如二者一致,则判定数据一致。

  • 假如二者不一致,则判定数据不一致。


对象存储服务处理追加写操作成功后,在返回的消息中使用ETag字段,返回服务端依据接收到的数据计算得到的MD5值,方便对象存储的客户应用执行客户端的校验。


本方案中,由于只需要计算追加的数据的MD5值,因此客户应用并不需要获得对象的完整数据。相应的,对象存储的服务端同样只需要计算追加的数据的MD5值,不需要读取对象的完整数据,操作简单。


对象数据整体的MD5客户应用在请求的头部增加Content-MD5,指定对象数据整体的MD5值。对象存储服务收到数据后,需要读取对象的数据,结合本次上传的数据,一并计算,得到MD5值。然后和Content-MD5值对比:


  • 假如二者一致,则判定数据一致。

  • 假如二者不一致,则判定数据不一致。


对象存储服务处理追加写操作成功后,在返回的消息中使用ETag字段,返回服务端的对象的MD5值,方便对象存储的客户应用执行客户端的校验。


本方案中,由于需要计算完整对象的MD5值,因此客户应用在执行追加写操作前,本地需要获得对象的全部数据,结合本次追加写操作的数据,一起计算MD5值。相应的,对象存储的服务端需要执行类似的操作,操作流程相对复杂,加大了服务端的负担。


多版本


按照AWS S3多版本中的说明,多版本特性的开关作用在桶级,包含如下状态:


Buckets can be in one of three states:

  • Unversioned (the default)

  • Versioning-enabled

  • Versioning-suspended


当未开启多版本特性,即Unversioned,对象执行追加写操作时,通过直接修改对象的数据来实现。

当开启多版本特性,即Versioning-enabled,有如下选择:


  • 当未指定版本号时,有如下选择:当前版本为delete-marker,返回失败。修改对象的当前版本。新增对象,数据包括原对象的数据和本次追加写的数据。

  • 当指定版本号时,有如下选择:指定版本是delete-marker,返回失败。指定版本不是delete-marker,修改对象的指定版本。返回失败,不允许修改历史版本。


当暂停多版本特性,即Versioning-suspended,有如下选择:


  • 当未指定版本号时,有如下选择:当前版本为delete-marker,返回失败。修改对象的当前版本。

  • 当指定版本号时,有如下选择:指定版本是delete-marker,返回失败。指定版本不是delete-marker,修改对象的指定版本。返回失败,不允许修改历史版本。


不过依据前述接口的定义,没有定义versionId,推断不支持修改历史版本,因此可以不考虑这么复杂的特性。


分级


参考AWS S3 归档AWS S3 分级中的说明,处于归档状态的对象,需要先取回才能访问。显而易见,此处为了维护对象语义,照顾对象存储服务的实现,当对象处于归档状态时,不允许通过调用追加写接口来追加数据。


WORM


参考AWS S3 Object Lock中的说明,开启 WORM 后:

  • 在保护期内的对象,不允许修改,不允许删除。

  • 在保护期外的对象,不允许修改,允许删除。

因此从维护对象语义的角度讲,在保护期内的对象、保护期外的对象,均不允许通过调用追加写接口来修改对象。


生命周期


参考AWS S3 Lifecycle,追加写操作过程中,被操作的对象可能符合生命周期规则,从而被恰好正在运行的后台任务删除掉。此时有如下选择:

  • 生命周期的后台任务具备更高的优先级,提前中断追加写操作,正常删除掉对象,对象存储服务对客户应用返回追加写操作失败。

  • 生命周期的后台任务优先级相对较低,跳过当前对象,待下次运行时再决策是否删除。


数据加密


依据SSE-C的说明,客户应用在执行 PUT/GET/Head/Copy 操作时,均需要提供加密数据的密钥。

即在发起请求时,提供如下头部:

  • x-amz-copy-source​-server-side​-encryption​-customer-algorithm

  • x-amz-copy-source​-server-side​-encryption​-customer-key

  • x-amz-copy-source-​server-side​-encryption​-customer-key-MD5

另外说明对象的元数据和数据均被加密。


事件通知


依据AWS S3 事件通知中的说明,对象存储服务可以提供事件通知,目前支持的事件类型见文档,显然不包括追加写操作,可以扩展事件名,比如:

  • s3:ObjectAppended:Put,使用 PUT 方式追加。

  • s3:ObjectAppended:Post,使用 POST 方式追加。

依据AWS S3 消息格式,为了适配追加写操作,可以考虑在 object 中增加扩展字段,用于说明追加写操作,比如:

  • sizeAppended,本次追加写操作的数据量,单位为bytes

  • eTagAppended,本次追加写操作的数据的MD5值。


并发一致性


依据AWS S3 data consistency model的说明,对象存储服务提供read-after-write的模型。

当多客户端对相同对象并发的发起追加写操作时,实现方案较复杂,需要平衡语义、功能、性能等方面的诉求,设计实现方案。


方案的差异


PUT 方式上传对象的文件追加写方案


参照文件的追加写,即把对象当成文件,将追加写操作的数据追加到对象的数据的尾部。


对象规格使用 PUT 方式上传的对象,默认小于 5G,因此实现时有两种选择,一是维持约束,将 5G 作为对象大小的上限,二是打破 5G 的约束,但保持最大规格的约束。


加密存储可行的实现方案,如下:


  • 方案一

校验加密算法,保证加密方式一致。

解密对象已有的数据。

和追加到末尾的数据。

完整执行加密操作。

更新元数据。

保存元数据和数据。


  • 方案二

校验加密算法,保证加密方式一致。

解密元数据。

加密本次追加到末尾的数据。

更新元数据。

保存元数据和数据。


方案二中,在对象的元数据中需要记录每次追加数据的明文、密文的长度,以及加密算法需要保留的信息。


PUT 方式上传对象的多段方案


参照多段对象,将追加写的数据当成一个新的段,原有的对象当成多段方式上传的第一个段。


对象规格维持多段对象的限制,在接口中增加必要的校验,即

  • 单个段的上限为 5GiB。

  • 段的数量维持在 10000 个。


按照上述限制,对象的大小,至多为约 48.8TiB。


加密存储可行的实现方案,如下:

  1. 校验加密算法,保证加密方式一致。

  2. 解密元数据。

  3. 本次追加写的数据,作为单独一个段,执行加密。

  4. 更新元数据。

  5. 保存元数据和数据。


多段方式上传的对象的文件追加写方案


参照文件的追加写,即把对象的最后一个段当成文件,将追加写操作的数据追加到最后一个段的数据的尾部。


对象规格依据多段对象的限制,如下:

  • 单个段的上限为 5GiB。

  • 段的数量维持在 10000 个。


假如直接在多段对象的最后一个段执行追加写操作,如维持上述约束,则可追加写的数据的总和不超过 5GiB,应用场景受限。假如允许多次追加操作后的数据量超出 5GiB,则可能破坏对象语义。


加密存储可行的实现方案,如下:

  • 方案一

校验加密算法,保证加密方式一致。

解密对象的最后一个段的已有的数据。

和追加到末尾的数据。

完整执行加密操作。

更新元数据。

保存元数据和对象的最后一个段。


  • 方案二

校验加密算法,保证加密方式一致。

解密对象的最后一个段的元数据。

加密本次追加到末尾的数据。

更新对象的最后一个段的元数据。

保存对象的最后一个段的元数据和数据。


方案二中,在对象的最后一个段的元数据中需要记录每次追加数据的明文、密文的长度,以及加密算法需要保留的信息。


多段方式上传的对象的多段方案


参照多段对象,将追加写的数据当成一个新的段,追加到对象的段的尾部。


对象规格维持多段对象的限制,在接口中增加必要的校验,即

  • 单个段的上限为 5GiB。

  • 段的数量维持在 10000 个。


按照上述限制,对象的大小,至多为约 48.8TiB。


加密存储可行的实现方案,如下:


  1. 校验加密算法,保证加密方式一致。

  2. 解密元数据。

  3. 本次追加写的数据,作为单独一个段,执行加密。

  4. 更新元数据。

  5. 保存元数据和数据。


文章转载自:jackieathome

原文链接:https://www.cnblogs.com/jackieathome/p/18227896

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
对象业务的追加写接口_对象_不在线第一只蜗牛_InfoQ写作社区