【DAOS】Intel DAOS 分布式异步对象存储|Architecture Overview|架构概述

目录

前言

什么是DAOS

为什么要用DAOS

1架构概述

 1.1专业术语和缩写

1.2架构

1.2.1DAOS 特性

1.2.2DAOS 系统

1.2.3 SDK 和 Tools

1.2.4 代理Agent

1.3存储模型(Storage Model)

1.3.1 DAOS Pool

1.3.2 DAOS Container

1.3.3 DAOS Object

1.4 事务模型(Transaction Model)

1.4.1Epoch 和时间戳排序(Epoch and Timestamp Ordering)

1.4.2 Container 快照(Container Snapshot)

1.4.3 分布式事务(Distributed Transactions)

1.5 故障模型 (Fault Model)

1.5.1 分层容错域(Hierarchical Fault Domains)

1.5.2 故障检测(Fault Detection)

1.5.3 故障隔离(Fault Isolation)

1.5.4 故障恢复(Fault Recovery)

1.6 安全模型(Security Model)

1.6.1 验证(Authentication)

1.6.2 Client 库(Client Library)

1.6.3 DAOS 管理网络(DAOS Management Network)

1.6.4 授权(Authorization)

1.6.5 组件证书(Component Certificates)

1.6.6 访问控制列表(Access Control Lists)

1.7 访问控制项(Access Control Entries)

1.8 数据完整性(Data Integrity)

1.8.1 介绍

1.8.2 要求

1.8.3键和值对象(Keys and Value Objects)

1.9 Life of a checksum (WIP)

1.10 Checksum Scrubbing (In Development)

1.11 Scanner

1.12 Corrective Actions

1.13 Design Details & Implementation

管理指南(Administration Guide)

DAOS源码(DAOS Source Code)

Docker 中的 DAOS(DAOS in Docker)

DAOS 分布式异步对象存储|相关组件

DAOS 系统

客户端 API,工具和 I/O 中间件

代理

DAOS 分布式异步对象存储|控制平面

代码组织

开发文档

用户文档

DAOS 分布式异步对象存储|数据平面 

模块接口

线程模型与 Argobot 集成

Thread-local Storage (TLS)

Incast Variable 集成

dRPC 服务器

dRPC 进程

dRPC 处理程序注册

User-level threads and Kernel-level threads 

 相关资料和链接


前言

作者bandaoyu,本文持续更新,地址:http://t.csdn.cn/XySWh

daos doc:https://github.com/daos-stack/daos/tree/master/docs

什么是DAOS

DAOS ( Distributed Asynchronous Object Storage,分布式异步对象存储 ),我理解为DAOS软件栈+硬件栈组成 对象存储容器。 <软件(PMDK+SPDK )+ 硬件(nvme)>



DAOS 与针对高性能储存的英特尔® 傲腾™ 技术;https://www.intel.cn/content/www/cn/zh/high-performance-computing/daos-high-performance-storage-brief.html?wapkw=daos

看说明,应该是和 k-v数据库很像(本身对象存储就是KV存储)。只不过DAOS 是软硬件一体,intel 提供DAOS 软件(api)配合 nvme和ram等硬件,合体成DAOS,变成了一个kv分布式数据库,所以它会有一些数据库特性的介绍:

DAOS API 支持分布式事务,允许将针对属于同一 Container 的对象的任何更新操作组合到单个 ACID 事务中。分布式一致性是通过基于多版本时间戳排序的无锁乐观并发控制机制提供的。DAOS 事务是可串行化的,可以在特定的基础上获取部分需要的数据集。

DAOS 版本控制机制允许创建持久的 Container 快照,该快照提供 Container 的实时分布一致性视图,该视图可用于构建生产者-消费者管道。

分布式异步对象存储 (DAOS) 是一个开源的对象存储系统,专为大规模分布式非易失性内存 (NVM, Non-Volatile Memory) 设计,利用了 SCM(Storage-Class Memory,比如intel的傲腾) 和 NVMe(Non-Volatile Memory express) 等的下一代 NVM 技术。

 可为高性能计算应用提供高带宽、低延迟和高IOPS的存储容器,是英特尔构建百亿亿次级存储堆栈的基础。

DAOS 服务器将其元数据保存在持久内存中,而将数据保存在 NVMe 固态盘中。

 “英特尔® 傲腾™ 持久内存”延伸

1. 英特尔® 傲腾™ 持久内存和标准 DRAM 有什么区别?

相似之处:封装在 DIMMS 中,与 DRAM 驻留在同一总线/通道上,并且可以采取与 DRAM 相同的方式来存储易失性数据;
不同之处:持久内存容量远远高于传统的 DRAM。PMem 模块具有 128GB、256GB 和 512GB 三种容量,远远大于通常从 16GB 到 64GB 的 DRAM 模块,尽管也存在更大容量的 DRAM 模块。英特尔® 傲腾™ 持久内存甚至可以在模块不通电的情况下以持久模式存储数据,通过内置硬件增加安全性来保证数据不受损。从成本/GB 的角度以及容量可扩展能力来看, PMem 的总体拥有成本相比 DRAM 有了很大的改善。

2. 英特尔® 傲腾™ 持久内存和英特尔® 傲腾™ 固态盘之间有什么区别?

两者都使用了相同的英特尔® 傲腾™ 内存介质,但它们是完全不同的产品。英特尔® 傲腾™ 持久内存位于 DIMM 封装中,在 DRAM 总线上运行,可以作为易失性内存或持久内存使用。而英特尔® 傲腾™ 固态盘严格用于标准 NAND 封装模型(AIC、M.2、U.2、EDSFF 等)中的快速存储,并采用 NVMe* 协议驻留于 PCIe 总线上,作为存储设备始终保持数据持久。

摘抄自;Intel DAOS 存储解决方案简略梳理 https://zhuanlan.zhihu.com/p/385625667

为什么要用DAOS

上一代的分布式存储是针对机械硬盘设计和优化的,现在固态硬盘已经大量使用,上一代分布式存储软件已经不适应。需要新一代分布式存储软件--比如:DAOS。

与主要针对旋转介质 机械硬盘设计的传统存储堆栈不同,DAOS 针对全新 NVM 技术进行了重新构建,可在用户空间全绕开操作系统中端对端地运行(RDMA),是一套轻量级的系统。

传统存储堆栈和全新技术栈的不同:

上一代的缺点

元数据存在后端:I/O路径长、同步和互锁机制

上一代的分布式文件系统,由于当时的硬件限制,为了解决元数据的容量瓶颈,部分产品(如CephFS)将元数据保存在后端的RADOS集群里,I/O路径长,并且由于复杂的同步和互锁机制,性能损耗较高,性价比并不理想;

部分产品(如HDFS)采用内存来保存所有的元数据,虽然元数据性能较好,但由于内存的容量有限,系统支持的文件数比较少,扩展能力有限。

下一代改进

新存储介质:SSD (NVMe协议)

存储引擎:高性能LSM存储引擎

新网络模块:高速网络传输模块,原生为RoCE/RDMA高性能网络量身打造
原文链接:https://blog.csdn.net/bandaoyu/article/details/125017127

DAOS 提供了一种为访问高细粒度数据提供原生支持的 I/O 模型,而不是传统的基于高延迟和块存储设计的 I/O 模型,从而释放下一代存储技术的性能。

与传统的缓冲区不同,DAOS 是一个独立的高性能容错存储层,它不依赖其它层来管理元数据并提供数据恢复能力。DAOS 服务器将其元数据保存在持久内存中,而将批量数据直接保存在 NVMe 固态盘中。

https://www.nextplatform.com/2016/05/23/lustre-daos-machine-learning-intels-platform/

https://www.nextplatform.com/2017/04/20/intel-shuts-lustre-file-system-business/

DAOS 分布式异步对象存储|事务模型;https://bbs.huaweicloud.com/blogs/254178

DAOS是什么?https://forum.huawei.com/enterprise/zh/thread-429557.html

针对问题

The fundamental limitations of the legacy storage software stacks became even more obvious later when much faster SSDs options came out. There were a number of bottlenecks in the legacy solutions, but chief among these came from POSIX and block-based IO.

POSIX takes a very pessimistic approach to ensuring data consistency, proactively locking in any situation where a conflict might occur. Imagine if a user opened a million files for writing and the number of locks might happen to preserve a file system consistency? This pessimistic approach just does not scale, so it became necessary to consider other ways to provide data consistency to unlock the filesystem for future scalability. DAOS instead borrows techniques from the database space to offer an optimistic approach to data consistency, eliminating the need for so much locking.

Similarly, all persistent IO up to this point has been done on media that we write to in large size blocks. This poses a real performance dilemma for IOs smaller than the block size, including file system metadata, as small IOs sharing a block would then be cause for more locking and serialization of activity, and less parallelism. Breaking through this bottleneck required innovation not only in the software stack, but also in the underlying storage media.

传统存储软件解决方案存在诸多瓶颈,其中较突出的POSIX和块IO (block-base IO)两个方面。

  • POSIX

POSIX采用保守(悲观,pessimistic)方式确保数据一致性,任何可能发生冲突的场景进行主动锁定;

DAOS借鉴数据库相关技术,提供较乐观(optimistic)方式确保数据一致性,去除大量锁操作。

  • 块IO

多个小IO共享一个块带来更多资源锁定,降低了并行度;

突破此瓶颈不仅需要软件堆栈创新,还需要底层存储介质的创新;如果没有存储硬件的创新、没有从SATA到NVMe过渡、没有存储级内存(SCM)产品出现以及相关协调软件栈创新,则无法突破这些障碍;

英特尔傲腾持久内存(PMem)是DAOS依赖的基础技术。选择硬件(PMem+NVMe)和软件(PMDK+SPDK),并在此基础上设计高效软件栈;

DK 就是Development Kit,PM=Persistent Memory,持久内存,SP=Storage Performance,存储性能。

PMem用于存储元数据信息和小IO,元数据访问粒度非常低;

小IO写入是否需存储至PMem,由DAOS策略引擎定义;可以实现为批量数据写入到NVMe,以达到更好的固态硬盘性能(更大的块大小、更好的带宽)和固态硬盘耐用性。从客户角度,好处是可以使用更便宜的固态硬盘,例如从高耐用性的固态硬盘转为中(或标准)耐用性硬盘。

1架构概述

 1.1专业术语和缩写

Acronym

    Expansion

ABT

        Argobots

ACL

        Access Control List

ACE

        Access Control Entry

ACID

        Atomicity, consistency, isolation, durability

BIO

        Blob I/O

CART

        Collective and RPC Transport

CGO

        Go tools that enable creation of Go packages that call C code

CN

            Compute Node

COTS

        Commercial off-the-shelf

CPU

        Central Processing Unit

Daemon

        A process offering system-level resources.

DAOS

        Distributed Asynchronous Object Storage

PMEM

        Intel Optane Persistent Memory

DPDK

        Data Plane Development Kit

dRPC

        DAOS Remote Procedure Call

gRPC

        gRPC Remote Procedure Calls

GURT

        A common library of Gurt Useful Routines and Types

HLC

        Hybrid Logical Clock

HLD

        High-level Design

ISA-L

        Intel Storage Acceleration Library

I/O

        Input/Output

KV store

    Key-Value store

libfabric

    Open Fabrics Interface

Mercury

    A user-space RPC library that can use libfabrics as a transport

MTBF

        Mean Time Between Failures

NVM

        Non-Volatile Memory

NVMe

        Non-Volatile Memory express

OFI

        Open Fabrics Interface

OS

            Operating System

PM

            Persistent Memory

PMDK

        Persistent Memory Devevelopment Kit

RAFT

        Raft is a consensus algorithm used to distribute state transitions among DAOS server nodes.

RAS

        Reliability, Availability & Serviceability

RDB

        Replicated Database, containing pool metadata and maintained across DAOS servers using the Raft algorithm.

RDMA/RMA

    Remote (Direct) Memory Access

RDG

        Redundancy Group

RPC

        Remote Procedure Call

SCM

        Storage-Class Memory

SWIM

        Scalable Weakly-consistent Infection-style process group Membership

SPDK

        Storage Performance Development Kit

SSD

        Solid State Drive

SWIM

        Scalable Weakly-consistent Infection-style process group Membership protocol

ULT

        User Level Thread

User-level threads and Kernel-level threads

UPI

        Intel Ultra Path Interconnect

UUID

        Universal Unique Identifier

VOS

        Versioning Object Store

1.2架构

分布式异步对象存储 (DAOS) 是一个开源的对象存储系统,专为大规模分布式非易失性内存 (NVM, Non-Volatile Memory) 设计,利用了SCM(Storage-Class Memory) 和 NVMe(Non-Volatile Memory express) 固态盘等的下一代 NVM 技术。

DAOS 是一种横向扩展的对象存储,可以为高性能计算应用提供高带宽、低延迟和高 IOPS 的存储容器,并支持结合仿真、数据分析和机器学习的下一代以数据为中心的工作流程。

与主要针对旋转介质设计的传统存储堆栈不同,DAOS 针对全新 NVM 技术进行了重新构建,可在用户空间中端对端地运行,并能完全绕开操作系统,是一套轻量级的系统。

DAOS 提供了一种为访问高细粒度数据提供原生支持的 I/O 模型,而不是传统的基于高延迟和块存储设计的 I/O 模型,从而释放下一代存储技术的性能。

与传统的缓冲区不同,DAOS 是一个独立的高性能容错存储层,它不依赖其它层来管理元数据并提供数据恢复能力。DAOS 服务器将其元数据保存在持久内存中,而将批量数据直接保存在 NVMe 固态盘中。

1.2.1DAOS 特性

DAOS 依靠 OFI 进行低延迟通信,并将数据存储在存储级内存 (SCM) 和 NVMe 存储上。 DAOS 提供了一个原生的键-数组-值存储接口,它提供了一个统一的存储模型,通过该模型可以移植特定领域的数据模型,例如 HDF5、MPI-IO 和 Apache Arrow。 还可以使用 POSIX I/O 仿真层,通过本机 DAOS API 实现文件和目录。

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

SCM 存储通过内存直接映射到 DAOS server的程序地址空间,该server通过直接加载/存储来管理持久索引。 根据 I/O 特性,DAOS server可以决定将 I/O 存储在 SCM 或 NVMe 存储中。 如图 2-1 所示

  • 对延迟敏感的 I/O,如应用程序元数据和字节粒度数据,通常存储在SCM中,
  • 而检查点和批量数据将存储在NVMe中。

 这种方法允许 DAOS 通过将数据流式传输到 NVMe 存储并在 SCM 中维护内部元数据索引来为批量数据提供原始 NVMe 带宽。 持久内存开发套件 (PMDK) 允许管理对 SCM 的事务访问,存储性能开发套件 (SPDK) 允许用户空间 I/O 到 NVMe 设备。

DAOS旨在提供:

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

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

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

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

考虑到故障域的高级数据放置 软件管理的冗余支持通过在线重建复制和纠删码

端到端数据完整性 具有保证数据一致性和自动恢复的可扩展分布式事务

数据集快照 用于管理对存储池的访问控制的安全框架

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

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

灾难恢复工具

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

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

1.2.2DAOS 系统

        一个数据中心可能有数十万个计算实例通过一个可扩展的高性能网络互连,其中所有实例或称为存储节点的实例子集都可以直接访问NVM存储。

      DAOS安装涉及多个组件,这些组件既可以并置,也可以分布.

存储节点

DAOS系统由一个系统名标识,它由一组连接到同一结构的 DAOS 存储节点组成。DAOS 存储节点运行一个 DAOS 服务实例,该实例为每个物理套接字启动一个 DAOS I/O engine进程。这些 DAOS server 成员关系被记录到系统map中,该map为每个engine分配一个唯一的整数rank 。两个不同的 DAOS 系统由两组不相交的 DAOS 服务器组成,它们之间无法相互配合。

DAOS server

DAOS server 是一个多租户守护进程,运行在每个存储节点的 Linux 环境实例上(可以是物理节点、虚拟机或容器)。DAOS server 的 engine 子进程通过网络导出 公开本地连接的 SCM 和 NVM 存储。它监听一个管理端口(由 IP 地址和 TCP 端口号 确定),以及一个或多个fabric endpoints (由网络 URI 寻址)。

DAOS 服务通过 /etc/DAOS 中的 YAML 文件进行配置,包括其 I/O Engine 子进程的配置。服务的启动可以与不同的守护进程管理或编排框架集成(systemd 脚本、Kubernetes 服务、或类似 pdsh 和 srun 的并行启动程序)。

 DAOS Engine

在 DAOS I/O  DAOS Engine中,存储在多个target之间静态分区以优化并发性,增强并发能力。为了避免竞争,每个 Target 都有其私有存储、自己的服务线程池以及专用的网络上下文,这些上下文可以直接通过fabric 寻址,而不依赖于在同一存储节点上的其他 Target 。

SCM 模块通常以 AppDirect interleaved 模式配置。因此,它们作为每个套接字(在 fsdax 模式)的单个 PMEM 命名空间呈现给操作系统。当配置每个 I/O Engine的 N 个 Target 时,每个 Target 都使用该套接字 fsdax 的 SCM 容量的 1/N​,与其它 Target 独立。每个 Target 还使用连接到此套接字的 NVMe 驱动器容量的一小部分。

Target

Target 没有针对存储介质故障实现任何内部数据保护机制。因此,一个 Target 就是一个单点故障,同时也是故障单元。动态状态与每个 Target 相关联:其状态可以是“up and running”,也可以是“down and not available”。

Target 是性能的单元。与 Target 关联的硬件组件(如后端存储介质、CPU 核心和网络)的能力和容量有限。

DAOS I/O 引擎实例导出的 Target 数是可配置的,取决于底层硬件(I/O 引擎实例的 SCM 模块数和 NVMe SSD 数)。I/O 引擎的 Target 数的最佳配置是该 I/O 引擎服务的 NVMe 驱动器数的整数倍。

DAOS Engine实例 export 的target数量是可配置的,并且取决于底层硬件(特别是该引擎实例所服务的 SCM 模块数量和 NVMe SSD 数量)。 作为最佳实践,引擎的target数量应该是该引擎所服务的 NVMe 驱动器数量的整数倍。

1.2.3 SDK 和 Tools

应用程序、用户和管理员可以通过两个不同的客户端 API 与 DAOS 系统交互。

management API 提供了管理 DAOS 系统的接口。它旨在与不同供应商的存储管理或开源编排框架集成。dmg 命令行工具是在 DAOS 的management API上构建的。

另一方面,DAOS 存储模型由DAOS 的libdaos库 实现,libdaos 它主要面向希望在 DAOS 系统中存储数据集的应用程序和 I/O 中间件开发人员。 daos 命令等用户常用工具的也构建在 API 之上,这样用户就可以通过命令行管理数据集。

 应用程序可以直接通过原生 DAOS API、I/O 中间件库(例如 POSIX 仿真、MPI-IO、HDF5)或通过 Spark 或 TensorFlow 等已经与原生 DAOS 存储集成的框架访问存储在 DAOS 中的数据集 模型。

1.2.4 代理Agent

DAOS 代理是驻留在客户端节点上的守护进程,通过与 DAOS 库交互对应用程序进程进行验证。它是一个可信任的实体,支持使用证书对 DAOS 客户端进行签名。DAOS Agent支持不同的[身份验证框架],并使用 Unix 域套接字(Unix Domain Socket)与DAOS library通信。

1.3存储模型(Storage Model)

下图展示了 DAOS 存储模型的基本抽象概括:

DAOS Pool 是 跨Target 集合分布的的预留存储资源。分配给每个 Target 上持有的 Pool 的实际空间称为池分片 (Pool Shard)。

分配给 Pool 的总空间在创建时确定,后期可以通过调整所有 Pool Shard 的大小(不超过 Target 专用的存储容量限制)或添加更多 Target(添加更多 Pool Shard)来扩展它。

提供了存储虚拟化,(池)是资源调配和隔离的单元。DAOS Pool 不能跨多个系统。

一个 池 Pool 可以承载多个称为 DAOS Container 的事务对象存储。每个 Container 都是一个私有的对象地址空间,可以对其进行事务性修改,并且独立于在同一 Pool 中的其他 Container。Container 是快照和数据管理的单元。一个 Container 内的 DAOS 对象可以分布在当前 Pool 的任何一个 Target 上以提高性能和恢复能力,并且可以通过不同的 API 访问,从而高效地表示结构化、半结构化和非结构化数据。

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

1.3.1 DAOS Pool

池由唯一的池 UUID 标识,并在 pool map 中维护 Target 信息(memberships 成员身份)。memberships 是确定的和一致的,memberships 的变更是按顺序编号的。 pool map 不仅记录活跃 Target 的列表,还以树的形式包含存储拓扑,用于记录(标记) 共享公共硬件组件 的 Target。例如,树的第一级可以表示共享同一主板的 Target,第二级可以表示共享同一机架的所有主板,最后第三级可以表示同一机房中的所有机架。

该框架有效地表示了层次化的容错域,然后使用这些容错域来避免将冗余(备份)数据放置在发生相关故障的 Target 上。在任何时候,都可以将新 Target 添加到 pool map 中,并且可以排除失败的 Target。此外,pool map 是完全版本化的,这有效地为map的每次修改分配了唯一的序列,特别是对于失败节点的删除。

池分片(Pool Shard) 是永久内存的预留空间,可以选择与特定 Target 上 NVMe 预先分配的空间相结合。它有一个固定的容量,并且在满了就操作失败。可以随时查询当前空间使用情况,并报告 池分片(Pool Shard) 中存储的任何数据类型所使用的总字节数。

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

创建 Pool 时,必须定义一组系统属性以配置 Pool 支持的不同功能。此外,用户还可以定义将持久存储的属性。

只有经过身份验证和授权的应用程序才能访问池。 可以支持多种安全框架:从 NFSv4 访问控制列表到基于第三方的身份验证(例如 Kerberos)。 连接到池时会强制执行安全性。 成功连接到池后,连接上下文将返回给应用程序进程。

如前所述,池存储多种不同类型的持久元数据,例如pool map、身份验证和授权信息、用户属性、属性和重建日志。 此类元数据至关重要,需要最高级别的恢复能力。 因此,池元数据被复制到来自不同高级故障域的几个节点上。 对于具有数十万个存储节点的超大型配置,这些节点中只有很小一部分(大约数十个)运行池元数据服务。 由于存储节点数量有限,DAOS 可以依靠共识算法达成一致,在出现故障时保证一致性,并避免裂脑综合症。

要访问一个池,用户进程应该连接到这个池并通过安全检查。 一旦被授予,池连接就可以与其任何或所有对等应用程序进程(类似于 openg() POSIX 扩展)共享(通过 local2global() 和 global2local() 操作)。 当在数据中心上运行大规模分布式作业时,这种集体连接机制有助于避免元数据请求风暴。当发出连接请求的原始进程与 Pool 断开连接时,Pool 连接将被注销。

1.3.2 DAOS Container

       Container是一个逻辑上的概念,用于管理和组织Pool中的对象。与我们熟知的文件夹类似。

        容器表示一个池内的对象地址空间,由容器 UUID 标识。 下图表示用户(I/O 中间件、特定领域数据格式、大数据或 AI 框架等)如何使用容器概念来存储相关数据集:

与 Pool 一样,Container 可以存储用户属性。Container 在创建时必须传递一组属性,以配置不同的功能,例如校验和。

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

Container 中的对象可能具有不同的schema(既数据组织形式),用于应对 数据分布存储和 (管理)Target 上的冗余(副本), 动态或静态条带化、复制或EC(纠删码)是 定义对象schema(既数据组织形式)所需的一些属性。

Object 类为一组对象定义了通用的schema(既数据组织形式)属性,每个 Object 类都被分配一个唯一的标识符,并在 Pool 级别与给定的schema 相关联。任何时候都可以用一个可配置的schema 来定义一个新的 Object 类,这个schema 在创建之后是不可变的(或者至少在属于这个类的所有对象都被销毁之前)。

为了方便起见,在创建 Pool 时,默认情况下会预定义几个最常用的 Object 类:

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

<---------------------------------- 128 bits ---------------------------------->
--------------------------------------------------------------------------------
|DAOS Internal Bits|                Unique User Bits                           |
--------------------------------------------------------------------------------
<---- 32 bits ----><------------------------- 96 bits ------------------------->

Container 是事务和版本控制的基本单元。

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

Container 元数据(快照列表、打开的句柄、对象类、用户属性、属性和其他)存储在持久性内存中,并由专用 Container 元数据服务维护,该服务使用与父元数据 Pool 服务相同的复制引擎或自己的引擎,这在创建 Container 时是可配置的。

与 Pool 一样,对 Container 的访问由 Container 句柄控制。要获取有效的句柄,应用程序进程必须打开 Container 并通过安全检查。然后,可以通过 Container 的 local2global() 和 global2local() 操作与其他peer应用程序进程共享此句柄。

1.3.3 DAOS Object

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

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

  • Multi-level key-array API 是具有局部性特征的本机对象接口。密钥分为分发密钥 (dkey) 和属性密钥 (akey)。dkey 和 akey 都可以是可变长度的类型(字符串、整数或其它复杂的数据结构)。同一个 dkey 下的所有条目都保证被配置在同一个target上。 与 akey 关联的值可以是不能部分修改的单个可变长度值,也可以是固定长度值的数组。akeys 和 dkey 都支持枚举。
  • Key-value API 提供了一个简单的键和可变长度值接口。它支持传统的 put、get、remove 和 list 操作。
  • Array API 实现了一个由固定大小的元素组成的一维数组,该数组的寻址方式是 64 位偏移寻址。DAOS 数组支持任意范围的读、写和 punch 操作。

1.4 事务模型(Transaction Model)

DAOS API 支持分布式事务,允许对属于同一容器的对象的任何更新操作合并到单个 ACID 事务中。 通过基于多版本时间戳排序的无锁乐观并发控制机制提供分布式一致性。 DAOS 事务是可序列化的,可以临时用于需要它的部分数据集。(DAOS 事务是可串行化的,可以在特定的基础上获取部分需要的数据集。DAOS transactions are serializable and can be used on an ad-hoc basis for parts of the datasets that need it.)

DAOS 版本控制机制允许创建持久的 Container 快照,该快照提供 Container 的实时分布一致性视图,该视图可用于构建生产者-消费者管道。

1.4.1Epoch 和时间戳排序(Epoch and Timestamp Ordering)

每个 DAOS I/O 操作都有一个称为 epoch 的时间戳。epoch 是一个 64 位整数,它集成了逻辑和物理时钟(详见 HLC paper)。DAOS API 提供了辅助函数,用于将 epoch 转换为传统的 POSIX 时间(即 struct timespec,详见 clock_gettime(3))。

1.4.2 Container 快照(Container Snapshot)

如下图所示,容器的内容可以随时进行快照

DAOS 快照非常轻量级,并且使用与创建快照的时间相关联的 epoch 进行标记。一旦创建成功,快照将一直保持可读性,直到它被显式销毁。在特定快照未被销毁前,Container的内容可以回滚到特定的快照。

Container 快照功能支持本机生产者/消费者管道:

一旦成功写入数据集的一致版本,生产者 (Producer) 将生成一个快照。使用者 (Consumer) 的应用程序可以订阅 Container 快照事件,以便在生产者提交更新时可以处理新的更新。

快照的不变性保证了使用者可以看到一致的数据,即使生产者继续进行新的更新。生产者和消费者实际上都在 Container 的不同版本上操作,不需要任何串行化操作。一旦生产者生成了数据集的新版本,使用者就可以查询两个快照之间的差异,并且只处理增量修改。

1.4.3 分布式事务(Distributed Transactions)

与 POSIX 不同,DAOS API 不强制执行最坏情况下的并发控制机制来处理冲突的 I/O 操作。取而代之的是,各个 I/O 操作被标记不同的 epoch,并按照 epoch 的顺序使用,而不管执行顺序如何。这个基准模型为不产生冲突的 I/O 工作负载的数据模型和应用程序提供了最大的可伸缩性和最高的性能。典型的例子是 MPI-IO 集合操作、POSIX 文件读/写操作和 HDF5 数据集读/写操作。

对于需要冲突序列化的数据模型部分,DAOS 提供了基于多版本并发控制的分布式可串行化事务。当不同的用户进程要覆盖与 dkey/akey 关联的值时,通常需要该事务。例如 基于 DAOS 的 SQL 数据库或由非协调客户端并发访问的一致 POSIX 命名空间。

在同一操作的上下文中提交的所有 I/O 操作(包括读取)将使用相同的 epoch。DAOS 事务机制自动检测传统的读/写、写/读和写/写冲突,并中止其中一个冲突事务(事务在 -DER_RESTART 参数下提交失败)。然后,用户/应用程序必须重新启动失败的事务。

在目前的实现中,事务 API 具有以下限制,这些限制将在未来的 DAOS 版本中解决:

  • 不支持 Array API
  • 通过同一上下文环境执行的对象获取/列表和键值获取/列表操作所进行的事务对象更新和键值放入操作不可见。

摘抄自:https://zhuanlan.zhihu.com/p/361229134

1.5 故障模型 (Fault Model)

参考:https://www.cnblogs.com/debugzhang/p/14613197.html

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

1.5.1 分层容错域(Hierarchical Fault Domains)

容错域是一组共享同一故障点的服务器,因此很可能同时发生故障。DAOS 假设容错域是分层且不重叠的。实际的层次结构和容错域成员身份必须由 DAOS 用于生成 Pool 映射的外部数据库提供。

Pool 元数据从不同的高级容错域复制到多个节点上,以获得高可用性,而对象数据则根据选定的 Object 类在不同数量的容错域上进行复制或纠删码编码。

1.5.2 故障检测(Fault Detection)

在 DAOS 系统中DAOS 服务器(被) 通过基于 gossip 的协议 SWIM 进行监控,该协议提供了准确、高效和可扩展的服务故障检测。系统通过定期的本地健康评估来监控 那些附加到每个 DAOS 的Target 上的存储,每当本地存储 I/O 错误返回到 DAOS 服务器时,都会自动调用内部健康检查程序。此过程将通过分析 IO 错误代码和设备 SMART/健康数据来进行整体健康评估。 如果结果是否定的,target将被标记为有故障,并且对该target的进一步 I/O 将被拒绝并重新路由。

1.5.3 故障隔离(Fault Isolation)

检测到故障后,必须从pool map中排除故障 的Target 或服务器(实际上是一组 Target)。此过程自动触发或由管理员手动触发。

排除后,新版本的pool map将急切地推送到所有存储 Target。此时,Pool 进入降级模式,可能需要额外的访问处理(例如,用纠删码重建数据)。此时 DAOS 客户端和存储节点无限期地重试 RPC,直到它们从新的 pool map中找到替代的 Target。此时,与被驱逐target的所有未完成的通信都将中止,并且在明确重新集成之前不应向target发送进一步的消息(可能仅在维护操作之后)。

Pool 服务会立即向所有 Target 通知 Pool map的更改。但客户端节点不是这样,它们每次与服务器通信时都会被延迟地通知 Pool map无效。为此,客户端将其当前 Pool map版本打包到每个 RPC 中,服务器将回复当前 Pool map版本。因此,当 DAOS 客户端遇到 RPC 超时时,它会定期与其他 DAOS Target 进行通信,以确保其 Pool map始终是最新的。最终,客户端将知晓 Target 被排除并进入降级模式。

这种机制保证了全局节点排除,并且所有节点最终共享相同的 Target 有效性视图。

1.5.4 故障恢复(Fault Recovery)

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

此重建过程在应用程序持续访问并更新对象时在线执行。

1.6 安全模型(Security Model)

(转自:https://www.cnblogs.com/debugzhang/p/14615969.html)

DAOS 使用了一个灵活的安全模型,将身份验证和授权分离开来。它的设计令其对 I/O 的影响被降到最小。

DAOS 对用于 I/O 传输的网络结构没有提供任何传输安全性保障。在部署 DAOS 时,管理员负责特定网络结构的安全配置。对于以太网 RDMA,建议启用 IPsec。有关更多信息,请参阅 RDMA protocol spec (RFC 5040) 。

DAOS 从两个方面实现自己的安全层:

  • 在用户级别,客户端只能读取和修改被授予访问权限的 Pool 和 Container。
  • 在系统和管理级别,只有经过授权的组件才能访问 DAOS 管理网络。

1.6.1 验证(Authentication)

根据调用者是访问客户端资源还是访问 DAOS 管理网络,有不同的身份验证方法。

1.6.2 Client 库(Client Library)

       客户端库 libdaos 是一个不受信任的组件。 使用客户端库(client library)的 daos 用户级(user-level )命令也是一个不受信任的组件。  DAOS 代理 (daos_agent)是受信任的进程,在每个客户端节点上运行并对用户进程进行身份验证。

DAOS 安全模型的设计旨在支持客户端进程的不同身份验证方法。 目前,我们仅支持 AUTH_SYS 身份验证。

1.6.3 DAOS 管理网络(DAOS Management Network)

每个受信任的 DAOS 组件(daos_server、daos_agent 和 dmg 管理工具)都通过为该组件生成的证书(的方式)进行身份验证。 这些组件通过相互认证的 TLS 在 DAOS 管理网络上相互识别。

1.6.4 授权(Authorization)

客户端访问资源的授权 由资源的访问控制列表 (Access Control List, ACL) 控制。管理网络上的授权是通过配置 DAOS 系统时生成的 certificates 上的设置来实现的。

1.6.5 组件证书(Component Certificates)

对 DAOS management RPCs 的访问是通过设置每个管理组件证书中的 CommonName (CN) 进行控制的。给定的 management RPC 只能由与正确证书连接的组件调用。

通过在 每个管理组件证书中 设置的 CommonName (CN) 来控制对 [DAOS management  RPC] 的访问。 给定的management  RPC只能由与正确证书连接的组件调用。

1.6.6 访问控制列表(Access Control Lists)

客户端对 Pool 和 Container 等资源的访问由 DAOS 访问控制列表 (ACL) 控制。这些 ACL 部分来自 NFSv4 ACL,并针对分布式系统的独特需求进行了调整。

客户端支持对请求对资源的进行只读或读写访问。如果资源的 ACL 没有给它们的请求授予访问级别,客户端将无法连接资源。

连接时,它们对该资源的句柄将被授予特定操作的权限。句柄的权限在其存在期间保持,类似于 POSIX 系统中的打开文件描述符,此时无法注销句柄。

1.7 访问控制项(Access Control Entries)

在 DAOS 工具的输入和输出中,访问控制项 (Access Control Entry, ACE) 是用冒号分隔的字符串定义的,格式如下:

TYPE:FLAGS:PRINCIPAL:PERMISSIONS

所有字段都区分大小写。

TYPE

  • 必须字段
  • ACE 的类型。目前只支持一种类型的 ACE。
    • A (Allow):允许通过给定权限访问指定主体。

FLAGS

  • 可选字段。
  • 提供有关如何解释 ACE 的附加信息。
    • G (Group):主体应被解释为一个群体。

PRINCIPAL

  • 主体(也称为标识)的具体格式为 name@domain。如果名称是本地域的 UNIX 用户/组,则应省略该域。目前,这是 DAOS 支持的唯一方式。
  • 有三个特殊的主体,OWNER@GROUP@ 和 EVERYONE@,它们与传统 POSIX 权限位中的 User、Group 和Other 对齐。当以 ACE 字符串格式提供它们时,它们的拼写必须与此处所写的完全一致:大写,不附加域。GROUP@ 项还必须有 G (Group) 标志。

PERMISSIONS

  • 资源 ACE 中的权限允许特定类型的用户访问资源。
  • ACE 权限字段中权限位(字符)的顺序不重要。
  • 包含不适用于给定资源的权限的 ACE 被视为无效。
  • 要允许用户/组连接到资源,主体的权限必须至少包括某种形式的读取访问(例如 read 或 get-prop)。具有只写权限的用户在请求对资源的 RW 访问时将被拒绝。
PermissionPool MeaningContainer Meaning
r (Read)Alias for 't'Read container data and attributes
w (Write)Alias for 'c' + 'd'Write container data and attributes
c (Create)Create containersN/A
d (Delete)Delete any containerDelete this container
t (Get-Prop)Connect/queryGet container properties
T (Set-Prop)N/ASet/Change container properties
a (Get-ACL)N/AGet container ACL
A (Set-ACL)N/ASet/Change container ACL
o (Set-Owner)N/ASet/Change container's owner user and group
  • 拒绝访问
    • 目前,只支持设置“允许”访问控制项。
    • 但是,可以通过为没有权限的特定用户创建允许项拒绝对其的访问。这与删除用户的 ACE 有本质不同,后者允许 ACL 中的其他 ACE 确定其访问权限。
    • 由于组权限的强制方式,无法以这种方式拒绝对特定组的访问。
  • ACE 示例
    • A::daos_user@:rw
      • 允许名为 daos_user 的 UNIX 用户具有读写访问权限。
    • A::project_users@:tc
      • 允许 UNIX 组 project_users 中的任何人访问 Pool 的内容并创建 Container。
    • A::OWNER@:rwdtTaAo
      • 允许拥有 Container 的 UNIX 用户具有完全控制权。
    • A:G:GROUP@:rwdtT
      • 允许拥有 Container 的 UNIX 组读写数据、删除 Container 和操作 Container 属性。
    • A::EVERYONE@:r
      • 允许其他规则未涵盖的任何用户具有只读访问权限。
    • A::daos_user@:
      • 拒绝名为 daos_user 的 UNIX 用户对资源的任何访问。

强制执行

访问控制项 (ACE) 将按以下顺序执行:

  • 所有者用户 (Owner-User)
  • 命名用户 (Named users)
  • 所有者组和命名组 (Owner-Group and named groups)
  • 所有人 (Everyone)

一般来说,强制执行将第一个匹配,并忽略较低优先级的项。

如果用户是资源的所有者,并且存在 OWNER@ 项,则仅接受所有者权限。即使与其他项匹配,它们也不会在命名用户/组项中接受任何权限。

如果用户不是所有者,或者没有 OWNER@ 项,但用户标识有 ACE,则仅接受用户标识的权限。即使这些组项具有比用户项更广的权限,它们也不会收到任何组的权限。用户最多应匹配一个用户项。

如果找不到匹配的用户项,但存在项与一个或多个用户组匹配,则强制执行将基于所有匹配组(包括所有者组)的 GROUP@ 项的权限。

如果找不到匹配的组,则将使用 EVERYONE@ 项的权限(如果存在)。

默认情况下,如果用户与 ACL 中的 ACE 不匹配,则访问将被拒绝。

ACL 文件

接受 ACL 文件的工具希望它是一个简单的文本文件,每行有一个 ACE。

可以使用 # 作为行上的第一个非空白字符,将该行标记为注释。

例如:

# ACL for my container
# Owner can't touch data - just do admin-type things
A::OWNER@:dtTaAo
# My project's users can generate and access data
A:G:my_great_project@:rw
# Bob can use the data to generate a report
A::bob@:r

权限位和 ACE 本身不需要按任何特定顺序排列。但是,当 DAOS 解析和显示 ACL 时,顺序可能不同。

限制

DAOS ACL 内部的数据结构中 ACE 列表的最大大小为 64KiB。

要计算 ACL 内部数据的大小,需要对每个 ACE 使用以下公式:

  • ACE 的基本大小是 256 字节。
  • 如果 ACE 主体不是特殊主体之一,
    将 PRINCIPAL 字符串的长度 +1。
  • 如果该值不是 64 字节对齐的,则扩展到最近的 64 字节边界。

1.8 数据完整性(Data Integrity)

1.8.1 介绍

数据存储系统最糟糕的事情之一就是在请求者不知情的情况下返回不正确的数据。 虽然系统中的每个组件(网络层、存储设备)都可以提供防止静默数据损坏的保护,但 DAOS 使用 [校验和] 提供端到端数据完整性,以更好地确保用户数据不会静默损坏。

对于 DAOS,端到端意味着客户端将计算和验证校验和,为数据通过整个 I/O 堆栈提供保护(providing protection for data through the entire I/O stack.)。 在写入或更新期间,DAOS 客户端库 (libdaos.so) 在通过网络传输之前计算[校验和]并将其附加到 RPC 消息。 根据配置,DAOS 服务器可能会或可能不会计算校验和来验证接收到的数据。 在获取(fetch)时,DAOS 服务器将向 DAOS 客户端发送请求数据和一个已知良好的校验和,DAOS 客户端将计算接收到的数据的校验和并进行验证。

1.8.2 要求

1.8.2.1关键要求(Key Requirements)

DAOS 将支持两个关键要求。 

1. 检测静默数据损坏 - 将在 DAOS 对象内检测分布和属性键和记录的损坏(Corruption will be detected on the distribution and attribute keys and records within a DAOS object)。 至少,当检测到损坏时,将报告错误。 

2. 纠正数据损坏 - 当检测到数据损坏时,将尝试使用数据冗余机制恢复数据。

1.8.2.2支持/附加要求(Supportive/Additional Requirements)

此外,DAOS 将支持...

端到端数据完整性作为服务质量属性 - 容器属性用于 启用/禁用数据完整性[校验和] 以及定义数据完整性功能的特定属性。有关配置容器的启用校验和的详细信息,请参阅 https://daos-stack.github.io/user/container/#data-integrity。

最小化性能影响 - 当没有数据损坏时,端到端数据完整性功能应该对性能影响最小。如果检测到数据损坏,则可能会影响性能以更正数据。正在努力将性能影响降至最低。

注入错误(Inject Errors) - 破坏特定记录、密钥或校验和中数据的能力对于测试来说是必要的。故障注入用于模拟网络和磁盘上的损坏。用于数据损坏的 DAOS_CSUM_CORRUPT_* 标志在 src/include/daos/common.h 中定义。

日志记录 - 当检测到数据损坏时,会在客户端和服务器日志中捕获错误日志。

尚不支持即将推出的功能

 事件记录 - 当发现静默数据损坏时,应以可以与其他系统运行状况和诊断信息一起检索的方式记录事件。( When silent data corruption is discovered, an event should be logged in such a way that it can be retrieved with other system health and diagnostic information.)

 主动后台服务任务 - Proactive background service task,用于扫描和检测(审核校验和)静默数据损坏并进行更正。

1.8.3键和值对象(Keys and Value Objects)

由于 DAOS 是键/值存储,因此键和值的数据都受到保护,但是,两者的方法略有不同。 对于两种不同的值类型,single 和 array,方法也略有不同。

Keys

在更新和fetch时,客户端计算 用作分布和属性key的数据(the data used as the distribution and attribute keys)的校验和,并将其放置在发送到服务器 的RPC 中。 服务器验证在校验和中的key。 在枚举key时,服务器将计算key的校验和并将其打包到发往客户端的 RPC 消息中。 客户端将验证收到的key(密钥)。

Note:

Key的校验和不存储在服务器上。 Key的hash 被计算出来并用于 索引 在服务器keys树中的Key(请参阅 VOS 密钥阵列存储VOS Key Array Stores)。 还期望keys仅存储在具有可靠数据完整性保护的存储级内存中(Storage Class Memory)。

Values

在更新时,客户端将为Value数据计算 校验和,并将其放到RPC 中发送到服务器。 如果启用了“服务器验证”,服务器将为该Value计算一个新的校验和,并与从客户端收到的校验和进行比较以验证该值的完整性。 如果校验和不匹配,则表示数据损坏,并向客户端返回错误,指示客户端应再次尝试更新。 无论是否启用“服务器验证”,服务器都会存储校验和。 有关 VOS 中是校验和管理和存储的更多信息,请参阅 VOS:https://docs.daos.io/src/vos/README.md

在fetch时,服务器会将存储的校验和连同获取的value返回给客户端,以便客户端可以验证接收到的value。 如果校验和不匹配,则客户端将尝试从另一个副本(如果可用)获取(fetch)未损坏的数据。

对于两种不同类型的值(values),这种方法有一些细微的不同。 下图说展示一个基本示例。 (有关单值和数组值类型(single value and array value)的更多详细信息,请参阅存储模型:Storage Model--https://docs.daos.io/overview/storage/

Single Value

一个Single Value是一个原子值,这意味着写入Single Value将更新整个Value并读取检索整个Value。 其他 DAOS 功能(例如纠删码)可能会将一个Single Value拆分为多个分片,以分布在多个存储节点之间。 整个 Single Value(如果转到单个节点)或每个分片(如果分布式)都将计算校验和,发送到服务器并存储在服务器上。

请注意,Single Value或Single Value的分片可能小于从中得出的校验和。 建议如果应用程序需要许多小的Single Value可以使用Array 类型代替。

==============以下为订正整理===================================

Array Values

与单值(Single Value)不同,数组值(Array Values)可以在数组的任何部分更新和获取。 此外,对数组的更新是受版本控制的,因此一次提取可以包含来自数组的多个版本的部分。 数组的这些版本化部分中的每一个都称为范围(Each of these versioned parts of an array are called extents.)。 下图展示几个示例(有关更多信息,另请参阅 VOS 密钥阵列存储:VOS Key Array Stores):

A single extent update (blue line) from index 2-13.

A fetched extent (orange line) from index 2-6.

The fetch is only part of the original extent written. ![]

(../graph/data_integrity/array_example_1.png)

Many extent updates and different epochs. A fetch from index 2-13 requires parts from each extent. ![Array Example 2](../graph/data_integrity/array_example_2.png)

The nature of the array type requires that a more sophisticated approach to creating checksums is used. DAOS uses a "chunking" approach where each extent will be broken up into "chunks" with a predetermined "chunk size." Checksums will be derived from these chunks. Chunks are aligned with an absolute offset (starting at 0), not an I/O offset. The following diagram illustrates a chunk size configured to be 4 (units is arbitrary in this example). Though not all chunks have a full size of 4, an absolute offset alignment is maintained. The gray boxes around the extents represent the chunks.

数组类型的性质要求使用更复杂的方法来创建校验和。 DAOS 使用“分块”方法,其中每个范围将被分成具有预定“块大小”的“块”。 校验和将从这些块中派生。 块与绝对偏移量(从 0 开始)对齐,而不是 I/O 偏移量。 下图说明了配置为 4 的块大小(在此示例中单位是任意的)。 尽管并非所有块的完整大小都是 4,但仍保持绝对偏移对齐。 范围周围的灰色框代表块。

1.8.4 Checksum calculations

The actual checksum calculations are done by the isa-l and isa-l_crypto libraries. However, these libraries are abstracted away from much of DAOS and a common checksum library is used with appropriate adapters to the actual isa-l implementations. common checksum library

实际的校验和计算由 isa-l 和 isa-l_crypto 库完成。 然而,这些库是从大部分 DAOS 中抽象出来的,一个通用的校验和库与适当的适配器一起用于实际的 isa-l 实现。 通用校验和库

1.8.5 Performance Impact

Calculating checksums can be CPU intensive and will impact performance. To mitigate performance impact, checksum types with hardware acceleration should be chosen. For example, CRC32C is supported by recent Intel CPUs, and many are accelerated via SIMD.

计算校验和可能是 CPU 密集型的,并且会影响性能。 为了减轻性能影响,应选择具有硬件加速的校验和类型。 例如,最近的 Intel CPU 支持 CRC32C,并且许多 CPU 都通过 SIMD 加速。

1.8.6 Quality

Unit and functional testing is performed at many layers.

Test executable

What's tested

Key test files

common_test

daos_csummer, utility functions to help with chunk alignment

src/common/tests/checksum_tests.c

vos_test

vos_obj_update/fetch apis with checksum params to ensure updating and fetching checksums

src/vos/tests/vts_checksum.c

srv_checksum_tests

Server side logic for adding fetched checksums to an array request. Checksums are appropriately copied or created depending on extent layout.

src/object/tests/srv_checksum_tests.c

daos_test

daos_obj_update/fetch with checksums enabled. The -z flag can be used for specific checksum tests. Also --csum_type flag can be used to enable checksums with any of the other daos_tests

src/tests/suite/daos_checksum.c

Unit and functional testing is performed at many layers.

1.8.7 Running Tests

With daos_server not running

./commont_test

./vos_test -z

./srv_checksum_tests

With daos_server running

export DAOS_CSUM_TEST_ALL_TYPE=1

./daos_server -z

./daos_server -i --csum_type crc64

1.9 Life of a checksum (WIP)

1.9.1 Rebuild

In order for rebuild/migrate process to get checksums so it doesn't have to recalculate them, the object list and object fetch task api's provide a checksum iov parameter. If memory is allocated for the iov, then the daos client will pack the checksums into the it. If insufficient memory is allocated in the buffer, the iov_len will be set to the required capacity and the checksums packed into the buffer is truncated.

为了让重建/迁移过程获得校验和,以便不必重新计算它们,对象列表和对象获取任务 api 提供了一个校验和 iov 参数。 如果为 iov 分配了内存,那么 daos 客户端会将校验和打包到其中。 如果缓冲区中分配的内存不足,则 iov_len 将设置为所需的容量,并截断打包到缓冲区中的校验和。

1.9.2 Client Task API Touch Points

  • dc_obj_fetch_task_create: sets csum iov to daos_obj_fetch_t args. These args are set to the rw_cb_args.shard_args.api_args and accessed through an accessor function (rw_args2csum_iov) in cli_shard.c so that rw_args_store_csum can easily access it. This function, called from dc_rw_cb_csum_verify, will pack the data checksums received from the server into the iov.
  • dc_obj_list_obj_task_create: sets csum iov to daos_obj_list_obj_t args. args.csum is then copied to obj_enum_args.csum in dc_obj_shard_list(). On enum callback (dc_enumerate_cb()) the packed csum buffer is copied from the rpc args to obj_enum_args.csum (which points to the same buffer as the caller's)

1.9.3 Rebuild Touch Points

  • migrate_fetch_update_(inline|single|bulk) - the rebuild/migrate functions that write to vos locally must ensure that the checksum is also written. These must use the csum iov param for fetch to get the checksum, then unpack the csums into iod_csum.
  • obj_enum.c is relied on for enumerating the objects to be rebuilt. Because the fetch_update functions will unpack the csums from fetch, it will also unpack the csums for enum, so the unpacking process in obj_enum.c will simply copy the csum_iov to the io (dss_enum_unpack_io) structure in enum_unpack_recxs() and then deep copy to the mrone (migrate_one) structure in migrate_one_insert().

1.9.4 Packing/unpacking checksums

When checksums are packed (either for fetch or object list) only the data checksums are included. For object list, only checksums for data that is inlined is included. During a rebuild, if the data is not inlined, then the rebuild process will fetch the rest of the data and also get the checksums.

当校验和被打包(用于获取或对象列表)时,只包含数据校验和。 对于对象列表,仅包括内联数据的校验和。 在重建期间,如果数据未内联,则重建过程将获取其余数据并获取校验和。

  • ci_serialize() - "packs" checksums by appending the struct to an iov and then appending the checksum info buffer to the iov. This puts the actual checksum just after the checksum structure that describes the checksum.
  • ci_cast() - "unpacks" the checksum and describing structure. It does this by casting an iov's buffer to a dcs_csum_info struct and setting the csum_info's checksum pointer to point to the memory just after the structure. It does not copy anything, but really just "casts". To get all dcs_csum_infos, a caller would cast the iov, copy the csum_info to a destination, then move to the next csum_info(ci_move_next_iov) in the iov. Because this process modifies the iov structure it is best to use a copy of the iov as a temp structure.

1.9.5 VOS

  • akey_update_begin - determines how much extra space needs to be allocated in SCM to account for the checksum

1.9.6 Arrays

  • evt_root_activate - evtree root is activated. If has a csum them the root csum properties are set (csum_len, csum_type, csum_chunk_size)
  • evt_desc_csum_fill - if root was activated with a punched record then it won't have had the csum fields set correctly so set them here. Main purpose is to copy the csum to the end of persistent evt record (evt_desc). Enough SCM should have been reserved in akey_update_begin.
  • evt_entry_csum_fill - Copy the csum from the persistent memory to the evt_entry returned. Also copy the csum fields from the evtree root to complete the csum_info structure in the evt_entry.
  • akey_fetch_recx - checksums are saved to the ioc for each found extent. Will be used to be added to to the result later.

1.9.7 Update/Fetch (copied from vos/README.md)

  • SV Update: vos_update_end -> akey_update_single -> svt_rec_store
  • Sv Fetch: vos_fetch_begin -> akey_fetch_single -> svt_rec_load
  • EV Update: vos_update_end -> akey_update_recx -> evt_insert
  • EV Fetch: vos_fetch_begin -> akey_fetch_recx -> evt_fill_entry

1.9.8 Enumeration

For enumeration the csums for the keys and values are packed into an iov dedicated to csums. - fill_key_csum - Checksum is calcuated for the key and packed into the iov - fill_data_csum - pack/serialize the csum_info structure into the iov.

对于枚举,键和值的 csum 被打包到一个专用于 csum 的 iov 中。 - fill_key_csum - 计算密钥的校验和并将其打包到 iov - fill_data_csum - 将 csum_info 结构打包/序列化到 iov 中。

1.9.9 Aggregation

  • srv_csum_recalc.c - the checksum verification and calculations occur here


1.10 Checksum Scrubbing (In Development)

A background task will scan (when the storage server is idle to limit performance impact) the Version Object Store (VOS) trees to verify the data integrity with the checksums. Corrective actions can be taken when corruption is detected. See Corrective Actions

后台任务将扫描(当存储服务器空闲以限制性能影响时)版本对象存储 (VOS) 树以使用校验和验证数据完整性。 当检测到损坏时,可以采取纠正措施。 查看纠正措施

1.11 Scanner

Goals/Requirements

  • Detect Silent Data Corruption Proactively - The whole point of the scrubber is to detect silent data corruption before it is fetched.
  • Minimize CPU and I/O Bandwidth - Checksum scrubbing scanner will impact CPU and the I/O bandwidth because it must iterate the VOS tree (I/O to SCM) fetch data (I/O to SSD) and calculate checksums (CPU intensive). To minimize both of these impacts, the server scheduler must be able to throttled the scrubber's I/O and CPU usage.
  • Minimize Media Wear - The background task will minimize media wear by preventing objects from being scrubbed too frequently. A container config/tunable will be used by an operator to define the minimum number of days that should pass before an object is scanned again.
  • Continuous - The background task will be a continuous processes instead of running on a schedule. Once complete immediately start over. Throttling approaches should prevent from scrubbing same objects too frequently.

High Level Design

  • Per Pool ULT (I/O xstream) that will iterate containers. If checksums and scrubber is enabled then iterate the object tree. If a record value (SV or array) is not marked corrupted then scan.
    • Fetch the data.
    • Create new ULTs (helper xstream) to calculate checksum for data
    • Compare calculated checksum with stored checksum.
    • After every checksum is calculated, determine if need to sleep or yield.
    • If checksums don't match confirm record is still there (not deleted by aggregation) then update record as corrupted
  • After each object scanned yield to allow the server scheduler to reschedule the next appropriate I/O.

Sleep or Yield

Sleep for sufficient amount of time to ensure that scanning completes no sooner than configured interval (i.e. once a week or month). For example, if the interval is 1 week and there are 70 checksums that need to be calculated, then at a maximum 10 checksums are calculated a day, spaced roughly every 2.4 hours. If it doesn't need to sleep, then it will yield to allow the server scheduler to prioritize other jobs.

睡眠充足的时间以确保扫描不早于配置的时间间隔(即每周或每月一次)完成。 例如,如果间隔为 1 周并且需要计算 70 个校验和,那么每天最多计算 10 个校验和,间隔大约为 2.4 小时。 如果它不需要休眠,那么它会让服务器调度程序优先处理其他作业。

1.12 Corrective Actions

There are two main options for corrective actions when data corruption is discovered, in place data repair and SSD eviction.

当发现数据损坏时,有两种主要的纠正措施选项,数据修复和 SSD 驱逐。

In Place Data Repair

If enabled, when corruption is detected, the value identifier (dkey, akey, recx) will be placed in a queue. When there are available cycles, the value identifier will be used to request the data from a replica if exists and rewrite the data locally. This will continue until the SSD Eviction threshold is reached, in which case, the SSD is assumed to be bad enough that it isn't worth fixing locally and it will be requested to be evicted.

如果启用,当检测到损坏时,值标识符(dkey、akey、recx)将被放入队列中。 当有可用周期时,值标识符将用于从副本请求数据(如果存在)并在本地重写数据。 这将一直持续到达到 SSD 驱逐阈值,在这种情况下,假定 SSD 已经足够糟糕,不值得在本地修复,并将被要求驱逐。

SSD Eviction

If enabled, when the SSD Eviction Threshold is reached the SSD will be evicted. Current eviction methods are pool and target based so there will need to be a mapping and mechanism in place to evict an SSD. When an SSD is evicted, the rebuild protocol will be invoked.

Also, once the SSD Eviction Threshold is reached, the scanner should quit scanning anything on that SSD.

如果启用,当达到 SSD 驱逐阈值时,SSD 将被驱逐。 当前的驱逐方法是基于池和target的,因此需要有适当的映射和机制来驱逐 SSD。 当 SSD 被驱逐时,将调用重建协议。 此外,一旦达到 SSD 驱逐阈值,扫描仪应停止扫描该 SSD 上的任何内容

Additional Checksum Properties > doc/user/container.md / doc/user/pool.md?

These properties are provided when a container or pool is created, but should also be able to update them. When updated, they should be active right away. - Scanner Interval - Minimum number of days scanning will take. Could take longer, but if only a few records will pad so takes longer. (Pool property) - Disable scrubbing - at container level & pool level - Threshold for when to evict SSD (number of corruption events) - In Place Correction - If the number checksum errors is below the Eviction Threshold, DAOS will attempt to repair the corrupted data using replicas if they exist.

这些属性在创建容器或池时提供,但也应该能够更新它们。 更新后,它们应该立即处于活动状态。 - 扫描间隔 - 扫描所需的最少天数。 可能需要更长的时间,但如果只有几条记录会填充,那么需要更长的时间。 (池属性) - 禁用清理 - 在容器级别和池级别 - 何时驱逐 SSD 的阈值(损坏事件的数量) - 就地更正 - 如果校验和错误数低于驱逐阈值,DAOS 将尝试修复损坏的 数据使用副本(如果存在)。

1.13 Design Details & Implementation

Pool ULT

The code for the pool ULT is found in srv_pool_scrub.c. It can be a bit difficult to follow because there are several layers of callback functions due to the nature of how ULTs and the vos_iterator work, but the file is organized such that functions typically call the function above it (either directly or indirectly as a callback). For example (~> is an indirect call, -> is a direct call):

ds_start_scrubbing_ult ~> scrubbing_ult -> scrub_pool ~> cont_iter_scrub_cb ->

    scrub_cont ~> obj_iter_scrub_cb ...

Silent Data Corruption Detection (TODO)

::Still todo::

obj_iter_scrub(coh, epr, csummer, pool_uuid, event_handlers, entry, type)

{

        build_iod

        vos_obj_fetch(coh, oid, epoch, dkey, iod, sgl);

        // for single value

        csum = calc_checksum(type, csummer, iod, sgl)

        compare(csum, entry.csum)

        // for recx

        for each chunk calc csum and compare

}

VOS Layer

  • In order to mark data as corrupted a flag field is added to bio_addr_t which includes a CORRUPTED bit.
  • The vos update api already accepts a flag, so a CORRUPTED flag is added and handled during an update so that, if set, the bio address will be updated to be corrupted.
  • On fetch, if a value is already marked corrupted, return -DER_CSUM

Object Layer

  • When corruption is detected on the server during a fetch, aggregation, or rebuild the server calls VOS to update value as corrupted.
  • (TBD) Add Server Side Verifying on fetch so can know if media or network corruption (note: need something so extents aren't double verified?)

Debugging

  • In the server.yml configuration file set the following env_vars

- D_LOG_MASK=DEBUG

- DD_SUBSYS=pool

- DD_MASK=csum

管理指南(Administration Guide)

DAOS源码(DAOS Source Code)

Docker 中的 DAOS(DAOS in Docker)

DAOS 分布式异步对象存储|相关组件

DAOS 的安装涉及多个组件,这些组件可以是集中式的,也可以是分布式的。

DAOS 软件定义存储 (software-defined storage, SDS) 框架依赖于两种不同的通信通道:

  • 用于带外管理 (out-of-band management) 的 TCP/IP 网络;
  • 用于数据访问的高性能结构。

实际上,同一个网络可以用于管理和数据访问。IP over Fabric 也可用作管理网络。

DAOS 系统

DAOS 服务器是一个多租户守护进程,运行在物理节点、VM 或容器上,管理分配给 DAOS 本地连接的 SCM (Storage-Class Memory) 和 NVM (Non-Volatile Memory) 存储。它监听由 IP 地址和 TCP 端口号寻址的管理端口,以及由网络 URI 寻址的一个或多个结构端点。

DAOS 服务器是通过 YAML 文件 /etc/daos/daos_server.yml(可通过命令行指定的其他路径)进行配置的。服务的启动和停止可以与不同的守护进程管理或编排框架集成(systemd 脚本、Kubernetes 服务、或类似 pdsh 和 srun 的并行启动程序)。

DAOS 系统由一个系统名标识,它由一组连接到同一结构的 DAOS 服务器组成。两个不同的系统由两组不相交的服务器组成,彼此不能相互协调。DAOS Pool 也不能跨多个系统。

在内部,DAOS 服务器由多个守护进程组成:

首先要启动的是控制平面control plane,二进制名 daos_server)。

  • 它负责解析配置文件、配置存储并最终启动和监视数据平面的一个或多个实例。
  • 控制平面用 Go 编写,并在 gRPC 框架上实现 DAOS management API。该框架提供了一个安全的带外通道来管理 DAOS 系统。
  • 每个服务器要启动的数据平面实例的数量以及存储、CPU 和 Fabric Interface Affinity 可以通过 daos_server.yml 进行配置。

然后是数据平面data plane,二进制名 daos_engine)。

  • 数据平面是一个用 C 编写的多线程进程,负责运行 DAOS 存储引擎。它通过 CART 通信中间件处理传入的元数据和 I/O 请求,并通过 PMDK(Persistent Memory Devevelopment Kit,用于 SCM)和 SPDK(Storage Performance Development Kit,用于 NVMe SSD)访问本地 NVM 存储。

  • 数据平面依赖于 ABT (Argobots) 进行基于事件的并行处理,并导出可通过结构独立寻址的多个 Target。

  • 在 DAOS 系统中,每个数据平面实例都被分配一个唯一的等级。

控制平面和数据平面进程通过 Unix Domain Sockets 和被称为 dRPC 的定制轻量级协议进行本地通信。

进一步阅读:

客户端 API,工具和 I/O 中间件

应用程序、用户和管理员可以通过两个不同的客户端 API 与 DAOS 系统交互。

DAOS management Go package 允许从任何可以通过带外管理通道与 DAOS 服务器通信的节点管理 DAOS 系统。此 API 保留给通过特定证书进行身份验证的 DAOS 系统管理员。DAOS management API 旨在与不同供应商的存储管理或开源编排框架集成。名为 dmg 的命令行工具是在 DAOS management API 上构建的。

进一步阅读:

DAOS 库 libdaos 实现了 DAOS 存储模型,主要面向希望将数据集存储到 DAOS container 中的应用程序和 I/O 中间件开发人员。它可以被连接到目标 DAOS 系统所使用的结构的任何节点使用。

应用程序进程通过 DAOS 代理进行身份验证。libdaos 导出的 API 通常称为 DAOS API(不同于 DAOS management API),允许通过不同的接口(例如键值存储或 array API)管理 container 和访问 DAOS 对象。

libdfs 库模拟 libdaos 上的 POSIX 文件和目录抽象,并为需要 POSIX 命名空间的应用程序提供平滑的迁移过程。

进一步阅读:

libdaos 和 libdfs 库为支持特定的数据格式(例如 HDF5 和 Apache Arrow)提供了基础。

进一步阅读:

代理

DAOS 代理 (DAOS agent) 是驻留在客户端节点上的守护程序,它通过 dRPC 与 DAOS 客户端库进行交互,以验证应用程序进程。

DAOS 代理是一个可信任的实体,可以使用本地证书对 DAOS 客户端凭据进行签名,同时支持不同的身份验证框架,并使用 Unix Domain Sockets 与客户端库通信。

DAOS 代理用 Go 编写,通过 gRPC 与每个 DAOS 服务器的控制平面组件进行通信,向客户端库提供 DAOS 系统成员信息,并支持 Pool 列表。

DAOS 分布式异步对象存储|控制平面

 转自:https://www.cnblogs.com/debugzhang/p/14627308.html

DAOS 通过两个紧密集成的平面进行运转。数据平面处理繁重的运输操作,而控制平面负责进程编排和存储管理,简化数据平面的操作。

DAOS 控制平面使用 Go 中编写,并作为 DAOS 服务器 (daos_server) 进程运行。除了实例化和管理在同一主机上运行的 DAOS 数据平面(引擎)进程外,它还负责网络和存储硬件的配置和分配。

代码组织

控制目录的“cmd”子目录包含服务器、代理和 dmg 应用程序方面的操作。这些应用程序导入控制 API (src/control/lib/control) 或服务器包以及外围共享包 common、drpc、fault、logging 和 security,以在必要的时候提供给定的功能。

可以在 lib/ 中找到特定的库包,这些库包通过语言绑定(如 lib/spdk)或特定的格式化功能(如 lib/hostlist 或 lib/txtfmt)提供对本机存储库的访问。

events 包提供 RAS (Reliability, Availability & Serviceability) 框架的 Go 组件,用于通过 dRPC 从 DAOS 引擎接收事件,并将管理服务中的可操作事件转发给 MS leader。

pbin 包提供了一个框架,用于转发代表 daos_server 的具有特权的二进制 daos_admin 的执行的请求。

provider 包包含连接到外部环境的接口,最初只是到 Linux 操作系统。

system 包封装了 DAOS 系统及其相关成员的概念。

开发文档

请参阅具体包的 README 文档。

用户文档

DAOS 分布式异步对象存储|数据平面 

转自:DAOS 分布式异步对象存储|数据平面 - debugzhang - 博客园 (cnblogs.com)

DAOS 通过两个紧密集成的平面进行运转。数据平面处理繁重的运输操作,而控制平面负责进程编排和存储管理,简化数据平面的操作。

模块接口

I/O 引擎支持一个模块接口,该接口允许按需加载服务器端代码。每个模块实际上都是一个库,由 I/O 引擎通过 dlopen 动态加载。模块和 I/O 引擎之间的接口在 dss_module 数据结构中定义。

每个模块应指定:

  • 模块名
  • daos_module_id 中的模块标识符
  • 特征位掩码
  • 一个模块初始化和销毁函数

此外,模块还可以选择配置:

  • 在整个堆栈启动并运行后调用的配置和清理函数
  • CART RPC 处理程序
  • dRPC 处理程序

线程模型与 Argobot 集成

I/O 引擎是一个多线程进程,使用 Argobot 进行非阻塞处理。

默认情况下,每个 Target 都会创建一个 main xstream 和 no offload xstreams。offload xstream 的实际数量可以通过 daos_engine 命令行参数进行配置。此外,还创建了一个额外的 xstream 来处理传入的元数据请求。每个 xstream 都绑定到一个特定的 CPU 核心。main xstream 接收来自客户端和其他服务器的 Target 传入请求。一个特定的 ULT (User Level Thread) 会在网络和 NVMe I/O 操作方面提供帮助。

  DAOS中的ULT DAOS_A_Scale-Out_High_Performance_Storage_Stack_fo.pdf-其它文档类资源-CSDN下载

https://www.researchgate.net/publication/341844608_DAOS_A_Scale-Out_High_Performance_Storage_Stack_for_Storage_Class_Memory

Thread-local Storage (TLS)

每个 xstream 分配的私有存储可以通过 dss_tls_get() 函数进行访问。

注册时,每个模块可以指定一个模块密钥,该密钥的数据结构大小将由 TLS 中的每个 xstream 进行分配。

dss_module_key_get() 函数的作用是:返回特定注册模块密钥的数据结构。

Incast Variable 集成

DAOS 使用 IV (incast variable) 在单个 IV 命名空间(组织结构为树)下的服务器之间共享值和状态。树的根节点称为 IV leader,服务器可以是叶子节点也可以是非叶子节点。

每个服务器都维护自己的 IV 缓存。在获取过程中,如果本地缓存不能完成请求,它会将请求转发给其父缓存,直到到达根缓存 (IV leader)。对于更新操作,服务器首先更新它的本地缓存,然后转发到它的父缓存,直到到达根缓存,然后将更改传播到其他的服务器。

IV 命名空间是属于每个 Pool 的,在 Pool 连接期间创建,在 Pool 断开连接期间销毁。

要使用 IV,每个用户需要在 IV 命名空间下注册自己以获得标识符,然后用户将使用这个 ID 来获取或更新自己在 IV 命名空间下的 IV 值。

dRPC 服务器

I/O 引擎包括一个 dRPC 服务器,它监听给定 Unix Domain Socket 上的活动。

有关 dRPC 的基础知识以及 Go 和 C 中的底层 API 的更多详细信息,请参阅 dRPC Documentation

dRPC 服务器定期轮询传入的客户端连接和请求。它可以通过 struct drpc_progress_context 对象同时处理多个客户端连接,该对象管理监听 Socket 的 struct drpc 对象以及任何活动的客户端连接。

服务器在 xstream 0 自己的 ULT (User Level Thread) 中循环运行。dRPC Socket 已设置为非阻塞的,并且使用无超时轮询。这允许服务器在 ULT 中运行,而不是在自己的 xstream 中运行,预计该通道的流量相对较低。

dRPC 进程

drpc_progress 表示 dRPC 服务器循环的一次迭代。其工作流程如下:

  1. 在监听 Socket 和任何打开的客户端连接上同时进行超时轮询。
  2. 如果在客户端连接上看到任何活动:
    1. 如果数据已输入:调用 drpc_recv 处理输入的数据。
    2. 如果客户端已断开连接或连接被破坏:释放 struct drpc 对象并将其从 drpc_progress_context 中删除。
  3. 如果在监听器上发现任何活动:
    1. 如果有新的连接进入:调用 drpc_accept 并将新的 struct drpc 对象添加到 drpc_progress_context 中的客户端连接列表中。
    2. 如果有错误:将 -DER_MISC 返回给调用者。I/O 引擎中会记录该错误,但不会中断 dRPC 服务器循环。在监听器上获取到错误是意外情况。
  4. 如果没有看到任何活动,则将 -DER_TIMEDOUT 返回给调用者。这纯粹是为了调试目的,实际上,I/O 引擎会忽略此错误代码,因为缺少活动实际上并不是一种错误。

dRPC 处理程序注册

单个 DAOS 模块可以通过注册一个或多个 dRPC 模块 ID 的处理函数来实现对 dRPC 消息的处理。

注册处理程序很简单。在 dss_server_module 的字段 sm_drpc_handlers 中,静态分配一个 struct dss_drpc_handler数组,该数组的最后一项为零,以指示列表的结尾。将字段设置为 NULL 表示没有要注册的处理程序。当 I/O 引擎加载 DAOS 模块时,它将自动注册所有 dRPC 处理程序。

注意:

  • dRPC 模块 ID 与 DAOS 模块 ID 不同。
  • 这是因为给定的 DAOS 模块可能需要注册多个 dRPC 模块 ID,具体数量取决于 DAOS 模块所涵盖的功能。
  • dRPC 模块 ID 必须是系统范围内唯一的,并且列在一个中心头文件 `src/include/daos/drpc_modules.h 中。

dRPC 服务器使用函数 drpc_hdlr_process_msg 来处理传入的消息。此函数检查传入消息的模块 ID,搜索处理程序。

  • 如果找到处理程序,则执行该处理程序,并返回 Drpc_Response
  • 如果找不到,它将生成自己的 Drpc_Response,指示模块 ID 未注册。

User-level threads and Kernel-level threads 

 相关资料和链接

DAOS官网:

https://docs.daos.io

PDF:

PowerPoint Presentation (openfabrics.org)-https://www.openfabrics.org/wp-content/uploads/2020-workshop-presentations/105.-DAOS_KCain_JLombardi_AOganezov_05Jun2020_Final.pdf

其他:

GitHub: https://github.com/storagezhang

Emai: debugzhang@163.com

华为云社区: DAOS 分布式异步对象存储|数据平面-云社区-华为云

DAOS: GitHub - daos-stack/daos: DAOS Storage Stack (client libraries, storage engine, control plane)

本文翻译自 daos/README.md at master · daos-stack/daos · GitHub

DAOS项目:https://daosio.atlassian.net/jira/projects

<https://lenovopress.lenovo.com/lp1421.pdfDesigning DAOS Solutions with Lenovo ThinkSystem SR630 V2 Servers><https://lenovopress.lenovo.com/lp1421.pdf

下面图片来自:https://blog.csdn.net/weixin_39094034/article/details/125004452

DAOS 存储节点的硬件配置

DAOS 的用户接口和生态系统

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值