DAOS整体设计分析 (一)

DAOS 是一种开源软件并支持横向扩展的对象存储系统,可为应用程序提供高带宽和高 IOPS 存储容器,并支持结合模拟、数据分析和机器学习的下一代以数据为中心的工作流。DAOS 完全使用新的 NVM 技术,并且非常轻量级,因为它在用户空间中运行端到端 (E2E),完全绕过操作系统。传统的存储模型需要按最小io粒度对齐,并且需要经过内核态的块设备栈。DAOS 提供了一种支持细粒度数据访问并释放下一代存储技术性能的模型。

一、整体介绍

1、DAOS io模型

DAOS 依靠 OFI ( Open Fabrics Interface)进行低延迟通信,并将数据存储在存储级内存 (SCM) 和 NVMe 存储上。 DAOS 提供了一个原生的key-array-value存储接口,它提供了一个统一的存储模型。

DAOS I/O 操作被记录下来,然后插入到 SCM 中维护的持久索引中。 每个 I/O 都标有称为 epoch 的特定时间戳,并与数据集的特定版本相关联。 内部不执行读-修改-写操作。 写操作是非破坏性的并且对对齐不敏感。 根据读取请求,DAOS 服务遍历持久索引并创建一个复杂的分散-聚集远程直接内存访问 (RDMA) 描述符,以直接在应用程序提供的缓冲区中重建请求版本的数据。

SCM 存储通过DMA(内存映射)直接映射到 DAOS 服务的地址空间,通过load/store操作来管理持久索引。 根据 I/O 特性,DAOS 服务可以决定将 I/O 存储在 SCM 或 NVMe 存储中。 如图 2-1 所示,对延迟敏感的 I/O,如应用程序元数据和字节粒度数据,通常存储在前者中,而检查点和批量数据将存储在后者中。 这种方法允许 DAOS 通过将数据流式传输到 NVMe 存储并在 SCM 中维护内部元数据索引来为批量数据提供原始 NVMe 带宽。 持久内存开发套件 (PMDK) 允许管理对 SCM 的事务访问,存储性能开发套件 (SPDK) 允许用户空间 I/O 到 NVMe 设备。

DAOS特征:

(1)任意对齐和大小的高吞吐量和IOPS

(2)具有真正零拷贝I/O到SCM的细粒度I/O操作

(3)通过跨存储服务器的可扩展集体通信支持大规模分布式NVM 存储

(4)允许I/O和计算重叠的非阻塞数据和元数据操作

(5)故障域的高级数据放置

(6)软件管理的冗余支持通过在线重建复制和纠删码

(7)端到端数据完整性

(8)具有保证数据一致性和自动恢复的可扩展分布式事务

(9)数据集快照

(10)用于管理对存储池的访问控制的安全框架

(11)软件定义的存储管理,用于通过COTS硬件供应、配置、修改和监控存储池

(12)对DAOS数据模型上的分层数据格式 (HDF)5、MPI-IO 和 POSIX 命名空间的本机支持

(13)灾难恢复工具

(14)与Lustre 并行文件系统无缝集成

(15)Mover代理用于在 DAOS 池之间以及从并行文件系统到 DAOS 之间迁移数据集,反之亦然

2、DAOS系统

DAOS 系统由系统名称标识,由一组连接到同一网络的 DAOS 存储节点组成。 DAOS 存储节点为每个节点运行一个 DAOS server实例然后每个物理套接字启动一个 DAOS 引擎进程。 DAOS server的成员资格被记录到系统映射中,它为每个引擎进程分配一个唯一的整数rank

DAOS server侦听管理端口(由 IP 地址和 TCP 端口号寻址)以及一个或多个结构端点(由网络 URI 寻址),通过 /etc/daos 中的 YAML 文件进行配置,包括其 Engine 子进程的配置。

在 DAOS Engine中,存储在多个target之间静态分区以优化并发性。 为避免争用,每个target都有自己的私有存储、自己的服务线程池和专用网络上下文,可以独立于同一存储节点上托管的其他target,通过结构直接寻址。 SCM 模块配置为 AppDirect 模式。 因此,它们作为每个套接字的单个 PMEM 命名空间(在 fsdax 模式下)呈现给操作系统。 当每个引擎配置 N 个target时,每个target使用该套接字 fsdax SCM 容量的 1/N,独立于其他target。 每个target还使用连接到该插槽的 NVMe 驱动器的 NVMe 容量的一小部分。

target没有实现任何针对存储介质故障的内部数据保护机制。 因此,target是单点故障和故障单元。 动态状态与每个target相关联:其状态可以是“启动并运行”或“关闭且不可用”。

target是性能单位。 与target相关联的硬件组件,例如后端存储介质、CPU 内核和网络,具有有限的能力和容量。DAOS 引擎实例导出的target数量是可配置的,并且取决于底层硬件(特别是该引擎实例所服务的 SCM 模块数量和 NVMe SSD 数量)。作为最佳实践,引擎的target数量应该是该引擎所服务的 NVMe 驱动器数量的整数倍。

3、sdk和tool

应用程序、用户和管理员可以通过两个不同的客户端 API 与 DAOS 系统交互。 (1)管理 API 提供了管理 DAOS 系统的能力。 它旨在与不同供应商特定的存储管理或开源编排框架集成。 dmg CLI 工具是基于 DAOS 管理 API 构建的。 (2)DAOS 库(libdaos)实现了 DAOS 存储模型。 它主要面向希望在 DAOS 系统中存储数据集的应用程序和 I/O 中间件开发人员。 daos 命令等用户实用程序也是基于 API 构建的,以允许用户从 CLI 管理数据集。

4、代理模块

DAOS 代理是驻留在客户端节点上的守护进程,它与 DAOS 库交互以验证应用程序进程。 它是一个可信实体,可以使用证书签署 DAOS 库凭据。 代理可以支持不同的身份验证框架,并使用 Unix Domain Socket (drpc)与 DAOS 库进行通信

 二、存储模型

下图表示DAOS存储模型的基本抽象

 DAOS 池是分布在target集合中的存储预留。 每个target上分配给池的实际空间称为池shard。 分配给池的总空间在创建时决定。 它可以通过调整所有池shard的大小(在专用于每个target的存储容量的限制内)或跨越更多target(添加更多池shard)来随着时间的推移进行扩展。 池提供存储虚拟化,是配置和隔离的单元。 DAOS 池不能跨越多个系统。

一个池可以托管多个称为 DAOS 容器的事务对象存储。 每个容器都是一个私有对象地址空间,可以事务性地修改,并且独立于存储在同一池中的其他容器。 容器是快照和数据管理的单元。 属于容器的 DAOS 对象可以分布在池的任何target上以获得性能和弹性,并且可以通过不同的 API 访问以有效地表示结构化、半结构化和非结构化数据。

下表显示了每个 DAOS 概念的target可扩展性级别:

DAOS Concept

Scalability (Order of Magnitude)

System

105 Servers (hundreds of thousands) and 102 Pools (hundreds)

Server

101 Targets (tens)

Pool

102 Containers (hundreds)

Container

109 Objects (billions)[a1]

1、pool

池由唯一的池UUID标识,并在称为池映射的持久版本化列表中维护target成员资格。成员资格是确定的和一致的,成员资格变化按顺序编号。池映射不仅记录活动target的列表,还包含树形式的存储拓扑,用于识别共享公共硬件组件的target。例如,树的第一层可以表示共享同一主板的target,然后第二层可以表示共享同一机架的所有主板,最后第三层可以表示同一机箱中的所有机架。该框架有效地表示了分层故障域,然后用于避免在受相关故障影响的target上放置冗余数据。在任何时间点,都可以将新target添加到池映射中,并且可以排除失败的target。此外,池映射是完全版本化的,这有效地为映射的每次修改分配了一个唯一的序列,特别是对于失败的节点删除。

池shard是持久内存的保留,可选择与特定target上NVMe存储上的预分配空间相结合。它具有固定的容量,并且在满时失败。可以随时查询当前空间使用情况,并报告存储在池分片中的任何数据类型使用的总字节数。


在target失败并从池映射中排除时,池内的数据冗余会自动在线恢复。这种自我修复过程称为重建。重建进度定期记录在存储在持久内存中的池中的特殊日志中,以解决级联故障。添加新target时,数据会自动迁移到新添加的target,以在所有成员之间平均重新分配空间使用量。此过程称为空间重新平衡,并使用专用的持久日志来支持中断和重新启动。池是分布在不同存储节点上的一组target,数据和元数据分布在这些节点上以实现水平可扩展性,并进行复制或EC编码以确保持久性和可用性。

创建池时,必须定义一组系统属性来配置池支持的不同功能。 此外,用户可以定义将永久存储的属性。只有经过身份验证和授权的应用程序才能访问池。

如前所述,池存储多种不同类型的持久元数据,例如池映射、身份验证和授权信息、用户属性、属性和重建日志。 此类元数据至关重要,需要最高级别的弹性。 因此,池元数据被复制到来自不同高级故障域的几个节点上。 对于具有数十万个存储节点的超大型配置,这些节点中只有很小一部分(大约数十个)运行池元数据服务。 由于存储节点数量有限,DAOS 可以依靠raft共识算法达成一致,在出现故障时保证一致性,并避免裂脑综合症。
池连接可以与其任何或所有对等应用程序进程(类似于 openg() POSIX 扩展)共享(通过 local2global() 和 global2local() 操作)。 当在数据中心上运行大规模分布式作业时,这种集体连接机制有助于避免元数据请求风暴。 当发出连接请求的原始进程与池断开连接时,池连接将被撤销。

2、Container

容器表示池内的对象地址空间,由容器 UUID 标识。与池一样,容器可以存储用户属性。 必须在容器创建时传递一组属性以配置不同的功能,例如校验和。

要访问容器,应用程序必须首先连接到池,然后打开容器。 如果应用程序被授权访问容器,则返回容器句柄。 这包括授权应用程序中的任何进程访问容器及其内容的功能。 打开过程可以与其任何或所有对等体共享该句柄。 他们的能力在容器关闭时被撤销

容器中的对象可能具有不同的模式用于数据分布和target上的冗余。 动态或静态条带化、复制或EC是定义对象模式所需的一些参数。 对象类定义一组对象的通用模式属性。 每个对象类都被分配了一个唯一标识符,并与池级别的给定模式相关联。 可以随时使用可配置模式定义新的对象类,该模式在创建后是不可变的(或至少在属于该类的所有对象都被销毁之前)。 为方便起见,在创建池时将默认预定义几个最常用的对象类,如下表所示。

Sample of Pre-defined Object Classes

Object Class (RW = read/write, RM = read-mostly

Redundancy

Layout (SC = stripe count, RC = replica count, PC = parity count, TGT = target

Small size & RW

Replication

static SCxRC, e.g. 1x4

Small size & RM

Erasure code

static SC+PC, e.g. 4+2

Large size & RW

Replication

static SCxRC over max #targets)

Large size & RM

Erasure code

static SCx(SC+PC) w/ max #TGT)

Unknown size & RW

Replication

SCxRC, e.g. 1x4 initially and grows

Unknown size & RM

Erasure code

SC+PC, e.g. 4+2 initially and grows

如下所示,容器中的每个对象都由唯一的 128 位对象地址标识。 对象地址的高 32 位保留给 DAOS 用于编码内部元数据,例如对象类。 剩余的 96 位由用户管理,并且在容器内应该是唯一的。 只要保证唯一性,堆栈的上层就可以使用这些位来对其元数据进行编码。 DAOS API 中提供了每个容器的 64 位可扩展对象 ID 分配器。 应用程序要存储的对象 ID 是完整的 128 位地址,该地址仅供一次性使用,并且只能与单个对象模式相关联。

容器是事务和版本控制的基本单元。 所有对象操作都由 DAOS 库使用称为epoch的时间戳隐式标记。 DAOS 事务 API 允许将多个对象更新组合到一个原子事务中,并具有基于epoch排序的多版本并发控制。 所有版本更新都可以定期聚合,以回收重叠写入所使用的空间并降低元数据的复杂性。 快照是一个永久引用,可以放置在特定时期以防止聚合

容器元数据(快照列表、容器打开句柄、对象类、用户属性、属性等)存储在持久内存中,并由专用容器元数据service维护,该service使用与父元数据池服务相同的复制引擎,或者 有自己的引擎。 这在创建容器时是可配置的。
与池一样,对容器的访问由容器句柄控制。 要获得有效句柄,应用程序进程必须打开容器并通过安全检查。 然后可以通过容器 local2global() 和 global2local() 操作与其他对等应用程序进程共享此容器句柄。

 3、object

为了避免传统存储系统常见的扩展问题和开销,DAOS 对象有意简化。 没有提供超出类型和架构的默认对象元数据。 这意味着系统不维护时间、大小、所有者、权限甚至跟踪开启者。 为了实现高可用性和水平可伸缩性,提供了许多对象模式(复制/EC、静态/动态条带化等)。 架构框架灵活且易于扩展,以允许将来使用新的自定义架构类型。 分布是根据对象标识符和池映射在对象打开时通过算法生成的通过在网络传输和存储期间使用校验和保护对象数据来确保端到端完整性。

DAOS 对象可以通过不同的 API 访问:

• 多级键数组API 是具有局部性特征的本机对象接口。 The key分为分布(dkey)和属性(akey)密钥。 dkey 和 akey 都可以是可变长度和类型(字符串、整数甚至复杂的数据结构)。 同一个 dkey 下的所有条目都保证被配置在同一个target。 与 akey 关联的值可以是无法部分覆盖的单个可变长度值,也可以是固定长度值的数组。 akeys 和 dkeys 都支持枚举。

• Key-value API 提供了一个简单的键和可变长度的值接口。 它支持传统的 put、get、remove 和 list 操作。

• Array API 实现了一个由64 位偏移量寻址的固定大小元素的一维数组。 DAOS 数组支持任意范围读取、写入和打孔操作。

4、Transaction

DAOS API 支持分布式事务,允许对属于同一容器的对象的任何更新操作合并到单个 ACID 事务中。 通过基于多版本时间戳排序的无锁乐观并发控制机制提供分布式一致性。 DAOS 事务是可序列化的,可以临时用于需要它的部分数据集。DAOS 版本控制机制允许创建持久的容器快照,这些快照提供容器的时间点分布式一致视图,可用于构建生产者-消费者管道。

每个 DAOS I/O 操作都标有一个称为 epoch 的时间戳。 epoch是一个 64 位整数,它集成了逻辑时钟和物理时钟。

对于需要冲突序列化的数据模型部分,DAOS 提供了基于多版本并发控制的分布式可序列化事务。 当不同的用户进程可以覆盖与 dkey/akey 对关联的值时,通常需要事务。 在同一操作的上下文中提交的所有 I/O 操作(包括读取)将使用相同的 epoch。 DAOS 事务机制会自动检测传统的读/写、写/读和写/写冲突,并中止冲突的事务之一(事务提交失败,使用 -DER_RESTART)。 失败的事务然后必须由用户/应用程序重新启动。

5、Fault

DAOS 依赖于大规模分布式单端口存储。 因此,每个target实际上都是单点故障。 DAOS 通过在不同故障域中的targe之间提供冗余来实现数据和元数据的可用性和持久性。 DAOS 内部池和容器元数据通过强大的共识算法进行复制。 然后通过在内部透明地利用 DAOS 分布式事务机制,安全地复制或EC DAOS 对象。 本节的目的是提供有关 DAOS 如何实现容错和保证对象弹性的详细信息。

DAOS 服务器在 DAOS 系统内通过称为 SWIM的协议进行监控, 每当本地存储 I/O 错误返回到 DAOS server时,都会自动调用内部健康检查程序。 此过程将通过分析 IO 错误代码和设备 SMART/健康数据来进行整体健康评估。 如果结果是否定的,target将被标记为有故障,并且对该target的进一步 I/O 将被拒绝并重新路由。

一旦检测到,故障target或服务器(实际上是一组target)必须从池映射中排除。 此过程由管理员手动或自动触发。 排除后,新版本的池映射会推送到所有存储target。 此时,池进入降级模式,可能需要额外的访问处理(例如,从纠删码中重建数据)。 因此,DAOS 客户端和存储节点会无限期地重试 RPC,直到它们从新的池映射中找到替代的target。 此时,与被驱逐target的所有未完成的通信都将中止,并且在明确重新集成之前不应向target发送进一步的消息(可能仅在维护操作之后)。

池服务会及时通知所有存储target池映射更改。 客户端节点的情况并非如此,它们每次与servers通信时都会延迟通知池映射失效。 为此,客户端在每个 RPC 中打包其当前池映射版本。 服务器不仅回复当前池映射版本。 因此,当 DAOS 客户端遇到 RPC 超时时,它会定期与其他 DAOS target通信以确保其池映射始终是最新的。 然后客户端将最终被告知target排除并进入降级模式。

这种机制保证了全局节点驱逐,并且所有节点最终共享相同的target活跃度视图。

从池映射中排除后,每个target都会自动启动重建过程以恢复数据冗余。 首先,每个target创建一个受target排除影响的本地对象列表。 这是通过扫描底层存储层维护的本地对象表来完成的。 然后对于每个受影响的对象,确定新对象分片的位置,并为整个历史(即快照)恢复对象的冗余。 重建所有受影响的对象后,将再次更新池映射以将target报告为失败。 这标志着集体重建过程的结束以及此特定故障的降级模式退出。 此时,池已完全从故障中恢复,客户端节点现在可以从重建的对象分片中读取。

当应用程序继续访问和更新对象时,此重建过程在线执行。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值