分布式存储Swift原理分析

在“分布式系列之分开源分布式存储技术分析”中曾提到swift是完全无中心架构,采用一致性哈希算法获得数据的位置。本文简要总结swift存储的整体架构和关键技术,进一步了解不同分布式存储技术实现原因上的差异。


1、Swift整体架构

Swift是对象存储,用于永久类型的静态数据的长期存储,这些数据可以检索、调整,必要时进行更新。Swift通过在软件层面引入一致性哈希技术和数据冗余性,牺牲一定程度的数据一致性来达到高可用性和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决非结构化数据存储问题。最适合存储的数据类型的例子是虚拟机镜像、图片存储、邮件存储和存档备份。

1.1 Swift数据模型

Swift是对象存储,采用层次数据模型,包括三层逻辑结构:Account、Container和Object。每层的节点数均没有限制,可以任意扩展。

  • Account:层次结构的顶层,Swift天生支持多租户,在OpenStack中account中可以理解为租户,用来做顶层的隔离机制。Swift租户的隔离性体现在metadata上,而不是object data上,数据包括元数据和container列表,保存在SQLite数据库中。
  • Container:容器,类似于文件系统中的目录,由用户自定义,它包含自身的元数据和容器内的对象列表,数据保存在 SQLite 数据库中。一个account中可以创建任意数量的container,两个不同container中的同名object表示不同的object。
  • Object:对象,包含数据和数据的元数据,以文件的形式保存在文件系统中。

在这里插入图片描述

1.2 Swift系统架构

Swift采用完全对称、面向资源的分布式系统架构设计,所有组件都可扩展,避免因单点失效而扩散并影响整个系统运转;通信方式采用非阻塞式I/O模式,提高了系统吞吐和响应能力。Swift组件如下图所示,包括:

在这里插入图片描述

  • 代理服务(Proxy Server):对外提供对象服务 API,会根据环的信息来查找服务地址并转发用户请求至相应的账户、容器或者对象服务;由于采用无状态的 REST 请求协议,可以进行横向扩展来均衡负载。
  • 认证服务(Authentication Server):验证访问用户的身份信息,并获得一个对象访问令牌(Token),在一定的时间内会一直有效;验证访问令牌的有效性并缓存下来直至过期时间。
  • 缓存服务(Cache Server):缓存的内容包括对象服务令牌,账户和容器的存在信息,但不会缓存对象本身的数据;缓存服务可采用 Memcached 集群,Swift 会使用一致性散列算法来分配缓存地址。
  • 账户服务(Account Server):提供账户元数据和统计信息,并维护所含容器列表的服务,每个账户的信息被存储在一个 SQLite 数据库中。
  • 容器服务(Container Server):提供容器元数据和统计信息,并维护所含对象列表的服务,每个容器的信息也存储在一个 SQLite 数据库中。
  • 对象服务(Object Server):提供对象元数据和内容服务,每个对象的内容会以文件的形式存储在文件系统中,元数据会作为文件属性来存储,建议采用支持扩展属性的 XFS 文件系统。
  • 复制服务(Replicator):会检测本地分区副本和远程副本是否一致,具体是通过对比散列文件和高级水印来完成,发现不一致时会采用推式(Push)更新远程副本,例如对象复制服务会使用远程文件拷贝工具 rsync 来同步;另外一个任务是确保被标记删除的对象从文件系统中移除。
  • 更新服务(Updater):当对象由于高负载的原因而无法立即更新时,任务将会被序列化到在本地文件系统中进行排队,以便服务恢复后进行异步更新;例如成功创建对象后容器服务器没有及时更新对象列表,这个时候容器的更新操作就会进入排队中,更新服务会在系统恢复正常后扫描队列并进行相应的更新处理。
  • 审计服务(Auditor):检查对象,容器和账户的完整性,如果发现比特级的错误,文件将被隔离,并复制其他的副本以覆盖本地损坏的副本;其他类型的错误会被记录到日志中。
  • 账户清理服务(Account Reaper):移除被标记为删除的账户,删除其所包含的所有容器和对象。
1.2.1 Proxy Server

Proxy Server可以说是Swift的核心,运行着swift-proxy-server进程。它提供Swift API的服务,负责Swift其余组件间的相互通信。对于每个客户端的请求,它在Ring中查询相应Account、Container以及Object的位置,并且转发这些请求。

  • 提供了Rest-full API,开发者可以通过这个接口快捷构建定制的客户端与Swift交互。
  • Proxy Server也会处理存储错误,当一个服务器无法对一个对象的PUT操作进行响应,它将从Ring中查询一个可以接手的服务器并将请求传递给它。
  • Ring是数据到物理设备映射的集合,通过Zone(区域)、Device(设备)、Partition(分区)和Replica(副本)来维护映射信息
1.2.2 存储节点

存储节点需要运行account和container、objectserver等服务

  • Object Server:对象服务是一个简单的二进制大对象存储服务,可以用来存储、检索和删除本地设备上的对象。在文件系统上,对象以二进制文件的形式存储,它的元数据存储在文件系统的扩展属性(xattrs)中。这要求用于对象服务的文件系统需要支持文件有扩展属性。
  • Container Server:容器服务的首要工作是处理对象的列表。容器服务并不知道对象存在哪,只知道指定容器里存的哪些对象。 这些对象信息以sqlite数据库文件的形式存储,和对象一样在集群上做类似的备份。容器服务也做一些跟踪统计,比如对象的总数,容器的使用情况。
  • Account Server:账户服务与容器服务非常相似,不同的是负责处理容器的列表而不是对象。
1.3 关键技术
1.3.1 一致性哈希

Swift是基于一致性哈希技术,通过计算将对象均匀分布到虚拟空间的虚拟节点上,在增加或删除节点时可大大减少需移动的数据量;虚拟空间大小通常采用2的n次幂,便于进行高效的移位操作;然后通过独特的数据结构 Ring(环)再将虚拟节点映射到实际的物理存储设备上,完成寻址过程。衡量一致性哈希的4个指标:

  • 平衡性(Balance):平衡性是指Hash的结果能够尽可能分布均匀,充分利用所有缓存空间。
  • 单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
  • 分散性(Spread):分散性定义了分布式环境中,不同终端通过Hash过程将内容映射至缓存上时,因可见缓存不同,Hash结果不一致,相同的内容被映射至不同的缓冲区。
  • 负载(Load):负载是对分散性要求的另一个纬度。既然不同的终端可以将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。

在这里插入图片描述

Swift使用一致性HASH算法的主要目的是在改变集群的node数量时(增加/删除服务器),能够尽可能少地改变已存在key和node的映射关系,以满足单调性。在一致性HASH中引入了虚拟节点的概念,一个实际节点对应了若干个“虚拟节点”,“虚拟节点”在哈希空间中以哈希值排列。因此,在Swift中存在两种映射关系,对于一个文件,通过哈希算法(MD5)找到对应的虚节点(一对一的映射关系),虚节点再通过映射关系(ring文件中二维数组)找到对应的设备(多对多的映射关系),这样就完成了一个文件存储在设备上的映射。

1.3.2 数据一致性模型

根据CAP理论,无法同时满足一致性、可用性和分区容忍性,Swift放弃严格一致性(满足ACID事务级别),而采用最终一致性模型(Eventual Consistency),来达到高可用性和无限水平扩展能力。Swift采用Quorum仲裁协议,算法如下:

  • 定义:N表示数据的副本总数;W表示写操作被确认接受的副本数量;R表示读操作的副本数量。
  • 强一致性:R+W>N,以保证对副本的读写操作会产生交集,从而保证可以读取到最新版本;如果W=N,R=1,则需要全部更新, 适合大量读少量写操作场景下的强一致性;如果R=N,W=1,则只更新一个副本,通过读取全部副本来得到最新版本,适合大量写少量读场景下的强一致性。
  • 弱一致性:R+W<=N,如果读写操作的副本集合不产生交集,就可能会读到脏数据;适合对一致性要求比较低的场景。

在这里插入图片描述

Swift中默认配置是N=3,W=2>N/2,R=1或2,即每个对象会存在3个副本,这些副本会尽量被存储在不同区域的节点上;W=2表示至少需要更新2个副本才算写成功;当R=1时意味着某一个读操作成功便立刻返回,此种情况下可能会读取到旧版本(弱一致性模型);当R=2时,需要通过在读操作请求头中增加 x-newest=true 参数来同时读取2个副本的元数据信息,然后比较时间戳来确定哪个是最新版本(强一致性模型)。

注:如果数据出现了不一致,后台服务进程会在一定时间窗口内通过检测和复制协议来完成数据同步,从而保证达到最终一致性

1.3.3 Ring

Ring将虚拟节点(partition)均衡的映射到一组物理设备上,其数据结构由以下信息组成:

  1. 存储设备列表(List of Devices),表示集群中设备的列表,在Ring类内部被称为devs,设备信息包括唯一标识号(id)、区域号(zone)、权重(weight)、IP 地址(ip)、端口(port)、设备名称(device)、元数据(meta);
  2. Partition Assignment List,用于存放每个replica与device间映射关系,在Ring类内部被称为分区到设备映射关系(replica2part2dev_id数组);
  3. Partition Shift Value,表示计算数据hash的移位量,计算分区号的位移(part_shift整数)

Swift为account、container和object分别定义了ring,其查找过程如下:

在这里插入图片描述

  • 使用对象的层次结构account/container/object作为键,使用MD5散列算法得到一个散列值
  • 对该散列值的前4个字节进行右移操作得到分区索引号,移动位数由上面的part_shift设置指定(一致性哈希映射到虚拟节点);
  • 按照分区索引号在分区到设备映射表(replica2part2dev_id)里查找该对象所在分区的对应的所有设备编号,这些设备会被尽量选择部署在不同区域(Zone)内

Swift中Ring使用zone来保证数据的物理隔离,每个partition的replica都确保放在不同的zone中,Ring中默认有3个replica。Zone只是一个抽象概念,它可以是一个磁盘(disk drive),一台服务器(server),一个机架(cabinet),一个交换机(switch),甚至是一个数据中心(datacenter),建议至少部署5个zone。

总的来说,Ring引入一致性哈希的原因是为了减少由于增加结点导致数据项移动的数量来提高单调性;引入partition的原因是为了减少由于节点数过少导致移动过多的数据项(数据负载不均衡);引入replica的原因是防止数据单点、提高冗余性;引入zone的原因是为了保证分区容忍性;引入weight的原因是为了保证partition分配的均衡。

1.4 Swift存储结构

Swift存储内容一般放在/srv/node/sdb1之类的路径下,其目录结构如下所示:accounts、async_pending、containers、objects、quarantined和tmp。其中accounts、containers、objects分别是账号、容器、对象的存储目录,async_pending是异步待更新目录,quarantined是隔离目录,tmp是临时目录。

在这里插入图片描述

  • objects:在objects目录下存放的是各个partition目录,其中每个partition目录是由若干个suffix_path名的目录和一个hashes.pkl文件组成,suffix_path目录下是由object的hash_path名构成的目录,在hash_path目录下存放了关于object的数据和元数据;object的数据存放在后缀为.data的文件中,它的metadata存放在以后缀为.meta的文件中,将被删除的Object以一个0字节后缀为.ts的文件存放。
  • accounts:在accounts目录下存放的是各个partition,而每个partition目录是由若干个suffix_path目录组成,suffix_path目录下是由account的hsh名构成的目录,在hsh目录下存放了关于account的sqlite db;在account的db文件中,包含了account_stat、container、incoming_sync 、outgoing_sync 4张表;其中,表account_stat是记录关于account的信息,如名称、创建时间、container数统计等等;表container记录关于container的信息;表incoming_sync记录到来的同步数据项;表outgoing_sync表示推送出的同步数据项。
  • containers:containers目录结构和生成过程与accounts类似,containers的db中共有5张表,其中incoming_sync和outgoing_sync的schema与accounts中的相同。其他3张表分别为container_stat、object、sqlite_sequence;表container_stat与表account_stat相似,其区别是container_stat存放的是关于container信息。
  • tmp:tmp目录作为account/container/object server向partition目录内写入数据前的临时目录。例如,client向server上传某一文件,object server调用DiskFile类的mkstemp方法创建在路径为path/device/tmp的目录。在数据上传完成之后,再调用put()方法,将数据移动到相应路径。
  • async_pending:async_pending存放未能及时更新而被加入更新队列的数据。本地server在与remote server建立HTTP连接或者发送数据时超时导致更新失败时,将把文件放入async_pending目录。这种情况经常发生在系统故障或者是高负荷的情况下。如果更新失败,本次更新被加入队列,然后由Updater继续处理这些失败的更新工作;account与container的db和object两者的pending文件处理方式有所不同:db的pending文件在更新完其中的一项数据之后,删除pending文件中的相应的数据项,而object的数据在更新完成之后,移动pending文件到目标目录。
  • quarantined:quarantined路径用于隔离发生损坏的数据。Auditor进程会在本地服务器上每隔一段时间就扫描一次磁盘来检测account、container、object的完整性。一旦发现不完整的数据,该文件就会被隔离,该目录就称为quarantined目录。为了限制Auditor消耗过多的系统资源,其默认扫描间隔是30秒,每秒最大的扫描文件数为20,最高速率为10Mb/s。account和container的Auditor的扫描间隔比object要长得多。

2、Swift all in one安装部署

单节点部署swift环境,感兴趣的可以参考“https://docs.openstack.org/swift/latest/development_saio.html


参考资料:

  1. https://blog.csdn.net/sinat_27186785/article/details/51921458
  2. https://docs.openstack.org/swift/latest/development_saio.html
  3. https://www.cnblogs.com/Skybiubiu/p/14614288.html
  4. https://blog.51cto.com/u_15352876/3773632
  5. https://blog.csdn.net/sinat_27186785/article/details/51930074
  6. 分布式系列之开源分布式存储技术分析

转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/123837321
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!

在这里插入图片描述

原文地址:https://blog.csdn.net/solihawk

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘贴.待开发的功能:1.支持自动生成约束2.开发设置页面3.做一个浏览器插件,支持不需要下载整个工程,可即时操作当前蓝湖浏览页面4.支持Flutter语言模板生成5.支持更多平台,如Sketch等6.支持用户自定义语言模板
现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。目前我们在计算机上进行音频播放都需要依赖于音频文件。那么音频文件如何生成的呢?音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号的过程,我们人耳所能听到的声音频率范围为(20Hz~20KHz),因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,音频文件的采样率一般在40~50KHZ之间。奈奎斯特采样定律,又称香农采样定律。...............
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿遍又亿遍,久久不能离开!看着小仙紫姐姐的蹦迪视频,除了一键三连还能做什么?突发奇想,能不能把舞蹈视频转成代码舞呢?说干就干,今天就手把手教大家如何把跳舞视频转成代码舞,跟着仙女姐姐一起蹦起来~视频来源:【紫颜】见过仙女蹦迪吗 【千盏】一、核心功能设计总体来说,我们需要分为以下几步完成:从B站上把小姐姐的视频下载下来对视频进行截取GIF,把截取的GIF通过ASCII Animator进行ASCII字符转换把转换的字符gif根据每
【Android App】实战项目之仿抖音的短视频分享App(附源码和演示视频 超详细必看)
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至2022年4月底。我已经将这篇博客的内容写为论文,上传至arxiv:https://arxiv.org/pdf/2204.10160.pdf欢迎大家指出我论文中的问题,特别是语法与用词问题在github上,我也上传了完整的项目:https://github.com/Whiffe/Custom-ava-dataset_Custom-Spatio-Temporally-Action-Video-Dataset关于自定义ava数据集,也是后台
因为我既对接过session、cookie,也对接过JWT,今年因为工作需要也对接了gtoken的2个版本,对这方面的理解还算深入。尤其是看到官方文档评论区又小伙伴表示看不懂,所以做了这期视频内容出来:视频在这里:本期内容对应B站的开源视频因为涉及的知识点比较多,视频内容比较长。如果你觉得看视频浪费时间,可以直接阅读源码:goframe v2版本集成gtokengoframe v1版本集成gtokengoframe v2版本集成jwtgoframe v2版本session登录官方调用示例文档jwt和sess
【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)
用Android Studio的VideoView组件实现简单的本地视频播放器。本文将讲解如何使用Android视频播放器VideoView组件来播放本地视频和网络视频,实现起来还是比较简单的。VideoView组件的作用与ImageView类似,只是ImageView用于显示图片,VideoView用于播放视频。...
采用MATLAB对正弦信号,语音信号进行生成、采样和内插恢复,利用MATLAB工具箱对混杂噪声的音频信号进行滤波
随着移动互联网、云端存储等技术的快速发展,包含丰富信息的音频数据呈现几何级速率增长。这些海量数据在为人工分析带来困难的同时,也为音频认知、创新学习研究提供了数据基础。在本节中,我们通过构建生成模型来生成音频序列文件,从而进一步加深对序列数据处理问题的了解。
基于yolov5+deepsort+slowfast算法的视频实时行为检测。1. yolov5实现目标检测,确定目标坐标 2. deepsort实现目标跟踪,持续标注目标坐标 3. slowfast实现动作识别,并给出置信率 4. 用框持续框住目标,并将动作类别以及置信度显示在框上
数字电子钟设计本文主要完成数字电子钟的以下功能1、计时功能(24小时)2、秒表功能(一个按键实现开始暂停,另一个按键实现清零功能)3、闹钟功能(设置闹钟以及到时响10秒)4、校时功能5、其他功能(清零、加速、星期、八位数码管显示等)前排提示:前面几篇文章介绍过的内容就不详细介绍了,可以看我专栏的前几篇文章。PS.工程文件放在最后面总体设计本次设计主要是在前一篇文章 数字电子钟基本功能的实现 的基础上改编而成的,主要结构不变,分频器将50MHz分为较低的频率备用;dig_select
1.进入官网下载OBS stdioOpen Broadcaster Software | OBS (obsproject.com)2.下载一个插件,拓展OBS的虚拟摄像头功能链接:OBS 虚拟摄像头插件.zip_免费高速下载|百度网盘-分享无限制 (baidu.com)提取码:6656--来自百度网盘超级会员V1的分享**注意**该插件必须下载但OBS的根目录(应该是自动匹配了的)3.打开OBS,选中虚拟摄像头选择启用在底部添加一段视频录制选择下面,进行录制.
Meta公司在9月29日首次推出一款人工智能系统模型:Make-A-Video,可以从给定的文字提示生成短视频。基于**文本到图像生成技术的最新进展**,该技术旨在实现文本到视频的生成,可以仅用几个单词或几行文本生成异想天开、独一无二的视频,将无限的想象力带入生活
音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结一、前言之前一直对硬件上的内容比较关注,但是可能是因为硬件方面的东西可能真的是比较杂,而且需要渗透的东西太多了,所以学习进展比较缓慢。因为也很少有单纯的硬件学习研究,总是会伴随着各种理论需要硬件做支撑,所以还是想要慢慢接触理论学习。但是之前总找不到切入点,不知道从哪里开始,就一直拖着。最近稍微接触了一点信号处理,就用这个当作切入点,开始接触理论学习。二、信号分析及加噪信号处理选用了matlab做工具,选了一个最简单的语音信号处理方
腾讯云 TRTC 实时音视频服务体验,从认识 TRTC 到 TRTC 的开发实践,Demo 演示& IM 服务搭建。
音乐音频分类技术能够基于音乐内容为音乐添加类别标签,在音乐资源的高效组织、检索和推荐等相关方面的研究和应用具有重要意义。传统的音乐分类方法大量使用了人工设计的声学特征,特征的设计需要音乐领域的知识,不同分类任务的特征往往并不通用。深度学习的出现给更好地解决音乐分类问题提供了新的思路,本文对基于深度学习的音乐音频分类方法进行了研究。首先将音乐的音频信号转换成声谱作为统一表示,避免了手工选取特征存在的问题,然后基于一维卷积构建了一种音乐分类模型。
C++知识精讲16 | 井字棋游戏(配资源+视频)【赋源码,双人对战】
本文主要讲解如何在Java中,使用FFmpeg进行视频的帧读取,并最终合并成Gif动态图。
在本篇博文中,我们谈及了 Swift 中 some、any 关键字以及主关联类型(primary associated types)的前世今生,并由浅及深用简明的示例向大家讲解了它们之间的奥秘玄机。