Swift —— 一、架构解析

发布时间 2023-12-14 17:38:48作者: 金笛秀才

一、简介

OpenStack 对象存储 (swift) 用于冗余、可扩展的数据 使用标准化服务器集群存储PB的存储 可访问的数据。它是一种长期存储系统,可存储大量 可以检索和更新的静态数据。对象存储使用 分布式架构 没有中央控制点,提供更大的可扩展性,冗余和持久性。对象写入多个硬件设备,使用 OpenStack 软件负责确保数据 整个群集的复制和完整性。存储集群可扩展 通过添加新节点来水平。如果一个节点发生故障,OpenStack 会努力 从其他活动节点复制其内容。因为 OpenStack 使用 确保数据复制和分发的软件逻辑不同的设备,廉价的商用硬盘驱动器和服务器可以 用于代替更昂贵的设备。
对象存储是经济高效的横向扩展存储的理想选择。它提供完全分布式、可通过API访问的存储平台,该平台可以直接集成到应用程序中或用于备份、归档、 和数据保留。

二、特点和优势

特点 优势
利用商用硬件 无锁定,更低的价格/GB
HDD/节点故障无关 自我修复、可靠的数据冗余可防止故障
无限存储空间 大而扁平的命名空间,高度可扩展的读/写访问, 能够直接从存储系统提供内容。
多维度扩展 横向扩展体系结构:垂直扩展和 水平分布式存储。大型备份和归档 具有线性性能的数据量。
帐户/容器/对象结构 没有嵌套,没有传统的文件系统:针对规模进行了优化, 它可以扩展到数 PB 和数十亿个对象
内置复制 3✕ + 数据冗余(与 2✕ 相比 RAID) 可配置数量的帐户、容器和对象副本 实现高可用性。
轻松添加容量(与RAID调整大小不同) 轻松实现弹性数据扩展。
没有中央数据库 更高的性能,无瓶颈。
不需要 RAID 高效处理许多小的随机读取和写入
内置管理实用程序 账号管理:创建、添加、验证、删除用户; 容器管理:上传、下载、验证;监测: 容量、主机、网络、日志拖网和集群运行状况。
驱动器审核 检测驱动器故障,防止数据损坏
过期对象 用户可以将对象的过期时间或 TTL 设置为 控制访问。
直接对象访问 启用对内容(例如控件)的直接浏览器访问 面板。
实时了解客户请求 了解用户的要求
支持 S3 API 利用专为流行的 S3 API 设计的工具。
限制每个账户的容器 限制访问权限以控制用户的使用情况。

三、对象存储特性

对象存储的主要特点是:

  • Object Storage 中存储的所有对象都有一个 URL。

  • “存储策略”可用于定义不同级别的持久性 用于存储在群集中的对象。这些策略不仅支持 完整的复制品,但也有纠删编码的片段。

  • 对象的所有副本或片段都尽可能唯一地存储 区域以提高持久性和可用性。

  • 所有对象都有自己的元数据。

  • 开发人员通过 RESTful 与对象存储系统进行交互 HTTP API。

  • 对象数据可以位于群集中的任何位置。

  • 群集通过添加其他节点来扩展,而不会牺牲 性能,可实现更具成本效益的线性存储 比叉车升级更能扩展。

  • 数据不必迁移到全新的存储系统。

  • 可以在不停机的情况下将新节点添加到集群中。

  • 故障节点和磁盘可以在不停机的情况下换出。

  • 它运行在行业标准硬件上,例如 Dell、HP 和 Supermicro 超微。
    image

四、组件

对象存储使用以下组件来提供高 可用性、高持久性、高并发性:

  • 代理服务器(Proxy servers) - 处理所有传入的 API 请求。

  • 环(Rings) - 将数据的逻辑名称映射到特定磁盘位置。

  • 区域(Zones ) - 将数据与其他区域隔离。一个区域中的故障在数据复制时不会影响群集的其余部分跨区域。

  • 帐户和容器(Accounts and containers) - 每个帐户和容器都是分布在集群中的独立数据库。一个帐户数据库包含该帐户中的容器列表。一个容器数据库包含该容器中的对象列表。

  • 对象(Objects) - 数据本身。

  • 分区(Partitions) - 分区存储对象、帐户数据库和容器数据库,并帮助管理数据所在的集群位置。

image

4.1 Proxy servers

代理服务器是对象存储的公众形象,可以处理所有 传入的 API 请求。一旦代理服务器收到请求,它就会根据对象的 URL 确定存储节点,例如:
https://swift.example.com/v1/account/container/object
此外,代理服务器还协调响应、处理故障和协调时间戳。

代理服务器使用无共享架构,可以根据预计的工作负载按需进行扩展。应在单独管理的负载均衡器后面至少部署两个代理服务器。如果一台代理服务器发生故障,其他代理服务器将接管。

4.2 Rings

一个环表示集群中存储的实体名称与其在磁盘上的物理位置之间的映射。帐户、容器和对象有单独的环。当系统的组件需要对对象、容器或账户执行操作时,它们需要与相应的环进行交互以确定集群中适当的位置。

环使用区域、设备、分区和副本来维护此映射,默认情况下,环中的每个分区在集群中复制 3 次,分区位置存储在环维护的映射中,该环还负责确定在故障情况下使用哪些设备作为切换。

数据可以隔离到环中的区域中。每个分区副本将尝试驻留在不同的区域中。区域可以代表驱动器、服务器、机柜、交换机,甚至数据中心。

环的分区分布在对象存储安装中的所有设备之间,当需要移动分区时(例如,如果向集群添加设备),环可确保一次移动最少数量的分区,并且一次仅移动分区的一个副本。

可以使用权重来平衡集群中驱动器上的分区分布。例如,当集群中使用不同大小的驱动器时,这可能很有用。

环被代理服务器和多个后台进程(如复制)使用。

image

这些环由外部管理。服务器进程本身不会修改环,而是为它们提供由其他工具修改的新环。
环使用来自路径的 MD5 哈希值的可配置位数作为指定设备的分区索引。哈希保留的位数称为分区幂,2 的分区幂表示分区计数。对完整 MD5 哈希环进行分区允许集群的其他部分同时批量处理项目,这比单独处理每个项目或一次性处理整个集群更高效,或者至少更简单。

另一个可配置的值是副本计数,它指示有多少分区设备分配构成单个环。对于给定的分区索引,每个副本的设备将不会与任何其他副本的设备位于同一区域。区域可用于根据物理位置、电源分离、网络分离或可同时提高多个副本可用性的任何其他属性对设备进行分组。

4.2 Zone

对象存储允许配置区域以隔离故障边界。如果可能,每个数据副本都驻留在单独的区域中。在最小级别,区域可以是单个驱动器或几个驱动器的分组。如果有五个对象存储服务器,那么每个服务器都代表自己的区域。较大的部署将拥有整个机架(或多个机架)的对象服务器,每个机架代表一个区域。区域的目标是让集群能够容忍存储服务器的严重中断,而不会丢失所有数据副本。
image

4.3 Accounts and containers

每个帐户和容器都是分布在集群中的单独 SQLite 数据库。帐户数据库包含该帐户中的容器列表。容器数据库包含该容器中的对象列表。
image
为了跟踪对象数据位置,系统中的每个帐户都有一个引用其所有容器的数据库,并且每个容器数据库引用每个对象。

4.4 Partitions

分区是存储数据的集合。这包括帐户数据库、容器数据库和对象。分区是复制系统的核心。
将分区视为在运营中心仓库中移动的箱子。个别订单被扔进垃圾箱。当该垃圾箱在整个系统中移动时,系统将其视为一个有凝聚力的实体。一个垃圾箱比许多小东西更容易处理。它减少了整个系统中的移动部件。
系统复制器和对象上传/下载在分区上运行。随着系统规模的扩大,其行为仍然是可预测的,因为分区的数量是固定的。
实现分区在概念上很简单:分区只是磁盘上的一个目录,以及它所包含内容的相应哈希表。
image

4.5 Replicators

为了确保到处都有数据的三个副本,复制器会不断检查每个分区。对于每个本地分区,复制器将其与其他区域中的复制副本进行比较,以查看是否存在任何差异。

复制器通过检查哈希值知道是否需要进行复制。为每个分区创建一个哈希文件,其中包含分区中每个目录的哈希值。对于给定分区,会比较每个分区副本的哈希文件。如果哈希值不同,那么就需要复制,需要复制的目录被复制过来。

这就是分区派上用场的地方。系统中的东西越少,传输的数据块就越大(而不是大量的小 TCP 连接,效率低下),并且有一致数量的哈希值可供比较。

集群具有最终一致的行为,其中旧数据可能从错过更新的分区提供,但复制将导致所有分区收敛到最新数据。
image
如果某个区域出现故障,包含副本的节点之一会注意到并主动将数据复制到切换位置。

4.6 用例

以下部分显示对象上传和下载的用例并介绍组件。

上传

客户端使用 REST API 发出 HTTP 请求以将对象放入现有容器中。集群接收请求。首先,系统必须弄清楚数据的去向。为此,帐户名称、容器名称和对象名称都用于确定该对象应驻留的分区。

然后在环中查找找出哪些存储节点包含有问题的分区。

然后,数据被发送到每个存储节点,并被放置在适当的分区中。在通知客户端上传成功之前,三个写入中至少有两个必须成功。

接下来,异步更新容器数据库以反映其中有新对象。
image

下载

收到针对帐户/容器/对象的请求。使用相同的一致性哈希来确定分区索引。环中的查找揭示了哪些存储节点包含该分区。向其中一个存储节点发出请求以获取对象,如果失败,则向其他节点发出请求。

五、集群架构

5.1 接入层

大规模部署会分割访问层,该访问层被视为对象存储系统的中心枢纽。访问层记录来自客户端的传入 API 请求,并将数据移入和移出系统。该层由前端负载均衡器、ssl 终止器和身份验证服务组成。它运行对象存储系统的(分布式)大脑:代理服务器进程。
image

通常,该层由一组 1U 服务器组成。这些机器使用适量的 RAM,并且是网络 I/O 密集型。由于这些系统会处理每个传入的 API 请求,应该为它们提供两个高吞吐量 (10GbE) 接口 - 一个用于传入的前端请求,另一个用于后端访问对象存储节点以放置和获取数据。

node

在大多数配置中,五个区域中的每一个都应具有相同的存储容量。存储节点使用合理数量的内存和CPU。元数据需要随时可用才能快速返回对象。对象存储不仅运行服务来处理来自访问层的传入请求,还运行复制器(replicators)、审计器(auditors)和收割器(reapers)。可以根据预期的工作负载和所需的性能,为存储节点配置单个千兆位或 10 个千兆位网络接口,但可能需要使用第二个接口隔离复制流量。
image

应该记住单线程请求所需的 I/O 性能。该系统不使用 RAID,因此单个磁盘处理对象的每个请求。磁盘性能影响单线程响应率。

为了实现明显更高的吞吐量,对象存储系统被设计为处理并发上传/下载。网络 I/O 容量(1GbE、绑定 1GbE 对或 10GbE)应满足您所需的读取和写入并发吞吐量需求。