对象业务的追加写接口

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

本文有如下假定:

  • 对象存储服务基于文件语义实现。
  • 使用PUT方式上传的对象,内部使用一个文件和对应的元数据来承载。
  • 使用多段方式上传的对象,内部使用多个段文件、元数据来承载,其中每个段文件可管理独有的元数据。

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

接口定义

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

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

  • 阿里云OSS
  • 华为云OBS
  • 腾讯云COS
  • 火山引擎

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

POST /ObjectName?append&position=Position HTTP/1.1
Content-Length:ContentLength
Content-Type: ContentType
Host: BucketName.oss.aliyuncs.com
Date: GMT Date
Authorization: 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的约束,但保持最大规格的约束。

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

  • 方案一

    1. 校验加密算法,保证加密方式一致。
    2. 解密对象已有的数据。
    3. 和追加到末尾的数据。
    4. 完整执行加密操作。
    5. 更新元数据。
    6. 保存元数据和数据。
  • 方案二

    1. 校验加密算法,保证加密方式一致。
    2. 解密元数据。
    3. 加密本次追加到末尾的数据。
    4. 更新元数据。
    5. 保存元数据和数据。

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

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

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

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

  • 单个段的上限为5GiB。
  • 段的数量维持在10000个。

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

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

  1. 校验加密算法,保证加密方式一致。
  2. 解密元数据。
  3. 本次追加写的数据,作为单独一个段,执行加密。
  4. 更新元数据。
  5. 保存元数据和数据。

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

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

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

  • 单个段的上限为5GiB。
  • 段的数量维持在10000个。

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

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

  • 方案一

    1. 校验加密算法,保证加密方式一致。
    2. 解密对象的最后一个段的已有的数据。
    3. 和追加到末尾的数据。
    4. 完整执行加密操作。
    5. 更新元数据。
    6. 保存元数据和对象的最后一个段。
  • 方案二

    1. 校验加密算法,保证加密方式一致。
    2. 解密对象的最后一个段的元数据。
    3. 加密本次追加到末尾的数据。
    4. 更新对象的最后一个段的元数据。
    5. 保存对象的最后一个段的元数据和数据。

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

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

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

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

  • 单个段的上限为5GiB。
  • 段的数量维持在10000个。

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

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

  1. 校验加密算法,保证加密方式一致。
  2. 解密元数据。
  3. 本次追加写的数据,作为单独一个段,执行加密。
  4. 更新元数据。
  5. 保存元数据和数据。

参考资料

对象存储

  • AWS S3
  • 阿里云OSS
  • 华为云OBS
  • 腾讯云COS
  • 火山引擎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/21188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【面试题-012】什么是Spring 它有哪些优势

文章目录 Spring有哪些优势有哪些优势Spring和Springboot区别在 Spring 框架中,什么是AOP核心概念应用场景 Spring有哪些通知类型 Spring 是一个开源的 Java 平台,由 Rod Johnson 创建,用于简化企业级 Java 应用程序的开发。它于 2003 年首次…

T-Pot多功能蜜罐实践@debian12@FreeBSD

T-Pot介绍 T-Pot是一个集所有功能于一身的、可选择分布式的多构架(amd64,arm64)蜜罐平台,支持20多个蜜罐和很多可视化选项,使用弹性堆栈、动画实时攻击地图和许多安全工具来进一步改善欺骗体验。GitHub - telekom-sec…

15.FreeRTOS数据结构:StreamBuffer,MessageBuffer和Queue的区别

FreeRTOS数据结构:StreamBuffer,MessageBuffer和Queue的区别 介绍 在嵌入式系统开发中,任务间的通信是非常重要的一部分。FreeRTOS提供了多种数据结构来实现任务间的通信,包括StreamBuffer,MessageBuffer和Queue。这…

SpringBootWeb登录认证

JWT令牌 JSON Web Token JSON Web Tokens - jwt.ioJSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signatur…

MogDBopenGauss查询重写规则uniquecheck

在MogDB&openGauss中,参数rewrite_rule用于控制查询重写,本文介绍查询重写规则uniquecheck uniquecheck表示提升无agg的where子查询 现在有如下例子 orcl> explain analyze select count(*)from test01 t1where t1.data_object_id (select data…

文件系统和日志分析

文件系统 概述 文件是存储在硬盘上的。硬盘上的最小存储单位是扇区,每个扇区的大小是512字节。 inode号:又叫索引号,保存的是元信息(主要有文件的属性 :包括权限,创建者,创建日期等&#xff…

Nodejs 调用langchain的实验

langchain 支持js/ts 语言,可以在nodeJs 中调用langchain 。这有利于在网站后台软件中使用,本博文记录做的小实验。 安装与升级 升级node 直接在官网下载,重新安装就可以了。 安装大模型模块 npm install openai 安装langchain npm insta…

Renesas MCU之使用e² studio搭建开发环境

目录 概述 1 e studio介绍 2 搭建Renesas MUC开发环境 2.1 软件版本信息 2.2 安装软件 3 创建工程 3.1 板卡硬件接口 3.2 FSP配置IO 4 Generate Project 4.1 项目目录介绍 4.2 LED接口相关驱动 5 调试 5.1 测试代码 5.2 J-Link调试代码 5.3 硬件结构 概述 本文主…

ES6-01-简介

一、什么是ES6? 每年一个版本o(╥﹏╥)o。 二、javaScript新特性的特点 1、语法简洁,功能丰富; 2、框架开发应用。 3、岗位需求! 三、let关键字 3-1、声明变量 let a;let a,b;let e100;let f521, gmilk-love, h[]; 3-2、声明的…

python采集汽车价格数据

python采集汽车价格数据 一、项目简介二、完整代码一、项目简介 本次数据采集的目标是车主之家汽车价格数据,采集的流程包括寻找数据接口、发送请求获取响应、解析数据和持久化存储,先来看一下数据情况,完整代码附后: 二、完整代码 #输入请求页面url #返回html文档 imp…

Linux C/C++目录操作

获取当前目录 #include <unistd.h>char *getcwd(char *buf,size_t size); char *get_current_dir_name(void);//注意释放内存 malloc() free()切换工作目录 #include <unistd.h>int chdir(const char *path);//0成功&#xff0c;其他失败&#xff08;目录不存在…

fbd编程语言:深度解析与未来展望

fbd编程语言&#xff1a;深度解析与未来展望 在编程语言的浩瀚海洋中&#xff0c;fbd编程语言以其独特的魅力和潜力&#xff0c;逐渐引起了开发者的关注。那么&#xff0c;fbd编程语言究竟有何特别之处&#xff1f;它的发展前景又如何呢&#xff1f;本文将从四个方面、五个方面…

PostgreSQL的视图pg_class

PostgreSQL的视图pg_class 在 PostgreSQL 中&#xff0c;pg_class 是一个系统目录表&#xff0c;用于存储所有关系&#xff08;如表、索引、视图、序列等&#xff09;的元数据。pg_class 是数据库系统的重要组成部分&#xff0c;包含了关于每个关系的具体信息。 pg_class 视图…

数据结构基础篇(7)

二十三.串、数组和广义表 -串的定义 零个或多个任意字符组成的有限序列串的术语 - 子串&#xff1a;一个串中任意连续字符组成的子序列&#xff08;含空串&#xff09;叫该串的子串- 主串&#xff1a;包含子串的串对应叫主串- 字符位置&#xff1a;字符在序列中序号是该字符串…

react-intl国际化在项目中的使用

前言 使用成熟的第三方库的国际化&#xff0c;可以直接使用封装好的方法&#xff0c;这个国际化的原理其实是使用了react 的第三方库react-intl &#xff0c;感觉主要比较好的就是使用其中的模版&#xff0c;它的本质还是通过了Provider的形式 第一步新建文件夹&#xff0c;计…

Python 限制输入数的范围

Python 限制输入数的范围 在 Python 编程中&#xff0c;我们经常需要限制用户输入的数据范围&#xff0c;以避免一些可能出现的问题。例如&#xff0c;在一个游戏程序中&#xff0c;我们可能想要确保玩家的分数在某个范围内&#xff0c;而不是太高或太低。在这个博文中&#x…

minos 2.4 中断虚拟化——中断子系统

首发公号&#xff1a;Rand_cs 该项目来自乐敏大佬&#xff1a;https://github.com/minosproject/minos 前面讲述了 minos 对 GICv2 的一些配置和管理&#xff0c;这一节再往上走一走&#xff0c;看看 minos 的中断子系统 中断 中断描述符 /** if a irq is handled by minos…

属性(property)

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 创建用于计算的属性 在Python中&#xff0c;可以通过property&#xff08;装饰器&#xff09;将一个方法转换为属性&#xff0c;从而实现用于计算…

几种更新 npm 项目依赖的实用方法

引言 在软件开发的过程中&#xff0c;我们知道依赖管理是其中一个至关重要的环节。npm&#xff08;Node Package Manager&#xff09; 是 Node.js 的包管理器&#xff0c;它主要用于 Node.js 项目的依赖管理和包发布。随着项目的不断发展&#xff0c;依赖库的版本更新和升级成…

字符串-459重复字符串

459. 重复的子字符串 - 力扣&#xff08;LeetCode&#xff09; 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。示例 2: 输入: s "ab…