Swift对象存储—基础架构及访问分析

架构概述

Swift主要有三个组成部分:Proxy Server、Storage Server和Consistency Server。其架构如图1所示,其中Storage和Consistency服务均允许在Storage Node上。Auth认证服务目前已从Swift中剥离出来,使用OpenStack的认证服务Keystone,目的在于实现统一OpenStack各 个项目间的认证管理。

arc-1

图1 Swift部署架构

下面本文对Swift的主要组件进行简单介绍。

Proxy Server

Proxy Server是提供Swift API的服务器进程,负责Swift其余组件间的相互通信。对于每个客户端的请求,它将在Ring中查询Account、Container或 Object的位置,并且相应地转发请求。Proxy提供了Rest-full API,并且符合标准的HTTP协议规范,这使得开发者可以快捷构建定制的Client与Swift交互。

Storage Server

Storage Server提供了磁盘设备上的存储服务。在Swift中有三类存储服务器:Account、Container和Object。其中Container 服务器负责处理Object的列表,Container服务器并不知道对象存放位置,只知道指定Container里存的哪些Object。这些 Object信息以sqlite数据库文件的形式存储。Container服务器也做一些跟踪统计,例如Object的总数、Container的使用情况。Account服务与Container服务类似,不同的是用来处理Container相关的内容。而Object服务则用来具体处理对象数据

Consistency Servers

在磁盘上存储数据并向外提供Rest-ful API并不是难以解决的问题,最主要的问题在于故障处理。Swift的Consistency Servers的目的是查找并解决由数据损坏和硬件故障引起的错误。主要存在三个Server:Auditor、Updater和Replicator。 Auditor运行在每个Swift服务器的后台持续地扫描磁盘来检测对象、Container和账号的完整性。如果发现数据损坏,Auditor就会将该文件移动到隔离区域,然后由Replicator负责用一个完好的拷贝来替代该数据。图2给出了隔离对象的处理流图。 在系统高负荷或者发生故障的情况下,Container或账号中的数据不会被立即更新。如果更新失败,该次更新在本地文件系统上会被加入队列,然后Updaters会继续处理这些失败了的更新工作,其中由Account Updater和Container Updater分别负责Account和Object列表的更新。Replicator的功能是处理数据的存放位置是否正确并且保持数据的合理拷贝数,它的设计目的是Swift服务器在面临如网络中断或者驱动器故障等临时性故障情况时可以保持系统的一致性。

arc-2

图2 隔离对象的处理流图

Ring

Ring是Swift最重要的组件,用于记录存储对象与物理位置间的映射关系。在涉及查询Account、Container、Object信息 时,就需要查询集群的Ring信息。 Ring使用Zone、Device、Partition和Replica来维护这些映射信息。Ring中每个Partition在集群中都(默认)有3 个Replica。每个Partition的位置由Ring来维护,并存储在映射中。Ring文件在系统初始化时创建,之后每次增减存储节点时,需要重新平衡一下Ring文件中的项目,以保证增减节点时,系统因此而发生迁移的文件数量最少(采用一致性哈希算法,具体参考下面章节介绍)。

数据模型

对象存储的数据存储除了“对象”的概念外,还有账户(account,非权限管理里面的账户)和容器(container)两个概念,这两个概念可以理解为存储对象的存储区域,用于存储具体的数据,可以与操作系统的文件夹对比理解,但不一样。

通过账户和容器实现对对象的隔离,也即不同账户是不可以相互访问的。而且不同的账户和容器里面可以有相同的对象。

arc-3

图3 数据逻辑关系

数据可靠性

对象存储为了保证数据的可靠性,通过副本和矫删码进行数据保护。数据的放置按照一定的规则进行。对象存储将存储数据的设备划分为若干逻辑区域,逻辑区域可以与物理区域对应,也可以不对应,但其决定了数据存放的位置。

对于一个对象存储集群,有三个相对较大的区域概念,分别是区域、分组和节点。其中区域可以与物理中的IDC或者某一个IDC中的房间对应;而分组可以与机柜对象;节点可以与物理服务器对应。每个节点中可能有若干物理磁盘,具体如图4所示。由图可以看出,区域是分大小的,而且有包含关系。也即,节点在分组内,而分组又在区域内。

基于上述逻辑关系,对象存储在放置数据的副本时遵循一定的规则,也即尽量的将数据放置在多个高级别的区域当中。如果集群中有两个Region,则对象存储会为每个Region分配最少一个副本,以此类推。

arc-4

图4 对象存储逻辑区域划分

数据访问流程及定位

对象存储的软件分为若干层,其中最上层是proxy,也只有该层能被客户看到,所有的请求都通过该层转发到下层进行处理,具体如图5所示。在数据转发过程中,最为核心的是Ring,也即Ring文件。在对象存储集群中包含三种Ring文件,分别是object.ring,container.ring和account.ring,分别用来定位object、container和account的具体位置,也即所在的物理服务器及磁盘的位置。

以上传一个对象数据为例,请求会首先经过proxy服务,该服务中保存着object的ring文件信息。proxy服务通过该文件信息既可以计算并查到该数据应该保存的服务器信息,由此将数据转发到具体的object服务进行处理。而container和account等信息也可以通过类似的方式得出。

arc-5

图5 对象存储软件架构

上文提及通过ring文件的信息获得存储数据的服务器信息。具体定位方式是根据账户、容器和对象名称信息(可能还包括前缀)计算出MD5值,然后根据MD5值进行移位操作,定位到具体的分区编号。根据分区编号及Ring文件中的信息可以定位到具体那个设备存储数据。这样就能实现数据的读写操作。具体如图6所示。

arc-6

图6 数据定位过程示意

如果引用本站的原创文章,请注明原文链接:,本站保留追究责任的权利!

发表评论