1       概述

OpenStack Object Storage(Swift)是OpenStack开源云计算项目的子项目之一。Swift的目的是使用普通硬件来构建冗余的、可扩展的分布式对象存储集群,存储容量可达PB级。

Swift并不是文件系统或者实时的数据存储系统,它是对象存储,用于永久类型的静态数据的长期存储,这些数据可以检索、调整,必要时进行更新。最适合存储的数据类型的例子是虚拟机镜像、图片存储、邮件存储和存档备份。

Swift无需采用RAID(磁盘冗余阵列),也没有中心单元或主控结点。Swift通过在软件层面引入一致性哈希技术和数据冗余性,牺牲一定程度的数据一致性来达到高可用性(High Availability,简称HA)和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决互联网的应用场景下非结构化数据存储问题。

2       技术特性

2.1        Swift的主要特征

Swift的主要特性如下:

  • 极高的数据持久性(Durability)。
  • 完全对称的系统架构:“对称”意味着Swift中各节点可以完全对等,能极大地降低系统维护成本。
  • 无限的可扩展性:一是数据存储容量无限可扩展;二是Swift性能(如QPS、吞吐量等)可线性提升。
  • 无单点故障:Swift的元数据存储是完全均匀随机分布的,并且与对象文件存储一样,元数据也会存储多份。整个Swift集群中,也没有一个角色是单点的,并且在架构和设计上保证无单点业务是有效的。
  • 简单、可依赖。

2.2        Swift和HDFS的技术差异

Swift和Hadoop分布式文件系统(HDFS)都有着相似的目的:实现冗余、快速、联网的存储,它们的技术差异如下:

  • 在Swift中,元数据呈分布式,跨集群复制。而在HDFS使用了中央系统来维护文件元数据(Namenode,名称节点),这对HDFS来说无异于单一故障点,因而扩展到规模非常大的环境显得更困难。
  • Swift在设计时考虑到了多租户架构,而HDFS没有多租户架构这个概念。
  • 在Swift中,文件可以写入多次;在并发操作环境下,以最近一次操作为准。而在HDFS中,文件写入一次,而且每次只能有一个文件写入。
  • Swift用Python来编写,而HDFS用Java来编写。
  • Swift被设计成了一种比较通用的存储解决方案,能够可靠地存储数量非常多的大小不一的文件;而HDFS被设计成可以存储数量中等的大文件(HDFS针对更庞大的文件作了优化),以支持数据处理。

3       关键技术

3.1        一致性哈希(ConsistentHashing)

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

图1 一致性哈希环结构

衡量一致性哈希的4个指标:

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

Swift使用该算法的主要目的是在改变集群的node数量时(增加/删除服务器),能够尽可能少地改变已存在key和node的映射关系,以满足单调性。

考虑到哈希算法在node较少的情况下,改变node数会带来巨大的数据迁移。为了解决这种情况,一致性哈希引入了“虚拟节点”(vnode,也称为partition)的概念: “虚拟节点”是实际节点在环形空间的复制品,一个实际节点对应了若干个“虚拟节点”,“虚拟节点”在哈希空间中以哈希值排列。

总的来说,Swift中存在两种映射关系,对于一个文件,通过哈希算法(MD5)找到对应的虚节点(一对一的映射关系),虚节点再通过映射关系(ring文件中二维数组)找到对应的设备(多对多的映射关系),这样就完成了一个文件存储在设备上的映射。

图2 对象、虚结点、节点间的映射关系

在设置虚结点数的时候,需要对系统预期的规模做充分考虑,假如集群的规模不会超过6000个结点,那么可以将虚结点数设置为结点数的100倍。这样,变动任意一个结点的负载仅影响1%的数据项。此时有6百万个vnode数,使用2bytes来存储结点数(0~65535)。基本的内存占用是6*(10^6)*2bytes=12Mb,对于服务器来说完全可以承受。

假设有65536(2^16)个node,有128(2^7)倍的partition数(2^23,则PARTITION_POWER=23)。由于MD5码是32位的,使用PARTITION_SHIFT(等于32- PARTITION_POWER)将数据项的MD5哈希值映射到partition的2^23的空间中。

3.2        数据一致性模型(ConsistencyModel)

按照Eric Brewer的CAP(Consistency,Availability,PartitionTolerance)理论,无法同时满足3个方面,Swift放弃严格一致性(满足ACID事务级别),而采用最终一致性模型(Eventual Consistency),来达到高可用性和无限水平扩展能力。

为了实现这一目标,Swift采用Quorum仲裁协议(Quorum有法定投票人数的含义):

Swift针对的是读写都比较频繁的场景,所以采用了比较折中的策略,即写操作需要满足至少一半以上成功W>N/2,再保证读操作与写操作的副本集合至少产生一个交集,即R+W>N。

在分布式系统中,数据的单点是不允许存在的。线上正常存在的replica数量是1的话将非常危险的,因为一旦这个replica再次错误,就可能发生数据的永久性错误。假如我们把N设置成为2,那么,只要有一个存储节点发生损坏,就会有单点的存在。所以N必须大于2。但N越高,系统的维护和整体成本就越高。所以,工业界通常把N设置为3。

Swift默认配置是N=3,W=2>N/2,R=1或2,即每个对象会存在3个副本,这些副本会被尽量存储在不同区域的节点上;W=2表示至少需要更新2个副本才算写成功。

当R=1时,意味着某一个读操作成功便立刻返回,此种情况下可能会读取到旧版本(弱一致性模型)。

当R=2时,需要通过在读操作请求头中增加x-newest=true参数来同时读取2个副本的元数据信息,然后比较时间戳来确定哪个是最新版本(强一致性模型)。

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

图3 Quorum协议示例

3.3        环(Ring)

Ring是Swift中最重要的组件,用于记录存储对象与物理位置间的映射关系。在涉及查询Account、Container、Object信息时就需要查询集群的Ring信息。

环是为了将虚拟节点(partition,分区)均衡地映射到一组物理存储设备上,并提供一定的冗余度而设计的,其数据结构由以下信息组成:

存储设备列表、设备信息包括唯一标识号(id)、区域号(zone)、权重(weight)、IP 地址(ip)、端口(port)、设备名称(device)、元数据(meta)。

Swift为账户、容器和对象分别定义了的Ring,其查找过程是相同的。Ring中每个partition在集群中都默认有3个replica。每个partition的位置由ring来维护,并存储在映射中。

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

权重参数是个相对值,可以来根据磁盘的大小来调节,权重越大表示可分配的空间越多,可部署更多的分区。

当集群中发生存储节点宕机、新增(删)存储节点、新增(删)zone等必须改变partition和node间的映射关系时,还可以对Ring文件通过重新平衡(rebalance)来进行更新。当虚节点需要移动时,环会确保一次移动最少数量的虚节点数,并且一次只移动一个虚节点的一个副本。

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

4       架构设计

4.1        Swift数据模型

Swift采用层次数据模型,共设三层逻辑结构:Account/Container/Object(账户/容器/对象)。每层节点数均没有限制,可以任意扩展。这里的账户和个人账户不是一个概念,可理解为租户,用来做顶层的隔离机制,可以被多个个人账户所共同使用;容器类似文件夹,代表封装一组对象;对象由元数据和数据两部分组成。

4.2        Swift系统架构

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

Swift组件包括:

图4 Swift系统架构

Swift支持的所有操作可以总结为下表:

表1 SwiftRESTful API总结

资源类型

URL

GET

PUT

POST

DELETE

HEAD

账户

/account/

获取容器列表

-

-

-

获取账户元数据

容器

/account/container

获取对象列表

创建容器

更新容器元数据

删除容器

获取容器元数据

对象

/account/container/object

获取对象内容和元数据

创建、更新或拷贝对象

更新对象元数据

删除对象

获取对象元数据

4.3        Ring的数据结构

Ring 的数据结构由三个顶层域构成,其中:

使用python读取/etc/swift/object.ring.gz存放的数据,可以获得以devs、 part_shift、 replica2part2dev_id 为key的dict类数据。

4.4        Swift存储结构

在Storage Node上运行着Linux系统并使用了XFS文件系统,逻辑上使用一致性哈希算法将固定总数的partition映射到每个Storage Node上,每个data也使用同样的哈希算法映射到partition上。

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

图5 隔离对象的处理流程

5       小结

Swift牺牲一定程度的数据一致性,来达到高可用性和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决互联网的应用场景下非结构化数据存储问题。

有理由相信,因为其完全的开放性、广泛的用户群和社区贡献者,Swift可能会成为云存储的开放标准,从而打破Amazon S3在市场上的垄断地位,推动云计算在朝着更加开放和可互操作的方向前进。

6       参考资料

1) 《Openstack Swift 原理、架构与 API 介绍》,http://www.kankanews.com/ICkengine/archives/66411.shtml

2) 《深入云存储系统Swift核心组件:Ring实现原理剖析》,http://www.cnblogs.com/yuxc/archive/2012/06/22/2558312.html

3) 《深入云存储系统Swift核心组件:Ring数据结构及构建、重平衡操作》,http://www.cnblogs.com/yuxc/archive/2012/06/28/2568584.html

4) 《深入云存储系统Swift存储节点:存储实现分析》,http://www.cnblogs.com/yuxc/archive/2012/07/04/2575536.html

5) 《OpenStack对象存储——Swift开源云计算》,http://dev.yesky.com/244/33228744.shtml

6) 《讨论:HDFS和OpenStack对象存储的技术差异》,http://os.51cto.com/art/201202/314254.htm

OpenStack Swift学习笔记相关推荐

  1. 【转载】OpenStack Swift学习笔记

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:崔炳华      原文地址:http://blog.csdn.net/i_ch ...

  2. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  3. swift学习笔记《5》- 实用

    title: swift学习笔记<5>- 实用 date: 2016-09-21 21:39:00 categories: 学习笔记 Swift学习 tags: Swift 1.setVa ...

  4. Swift学习笔记(4)使用UIImagePickerController实现从设备图片库和照相机获取图片

    Swift学习笔记(4)使用UIImagePickerController实现从设备图片库和照相机获取图片 设备图片库和照相机是图像的两个重要来源,使用UIKit中提供的图像选择器UIImagePic ...

  5. OpenStack开发学习笔记01

    OpenStack概述: openstack可以说是一个开源的操作系统. Openstack的开源协议,Apache License,是一个商业化的有好的开原协议,允许其他公司对其二次修改重新发布,来 ...

  6. openstack 王者归来学习笔记

    rpc.call方法执行的流程:(下次看代码的时候可以根据这流程来看,注意:由于rpc服务器和客户端具有很松的耦合性,因此以上步骤并不是绝对的.) 1.rpc服务器定义和启动rpc服务 2.rpc服务 ...

  7. Swift学习笔记8--Optional Chaining

    Optional Chaining 自判断链接(Optional Chaining)是一种可以请求和调用属性.方法及子脚本的过程,它的自判断性体现于请求或调用的目标当前可能为空(  nil ).如果自 ...

  8. Swift学习笔记 ——(一)

    前言 作为一个前端开发者,经常与javaacript(以下简称:js)打交道.最近想了解一下ios开发,前两天看了一下objective-c(以下简称:oc),相对于js来说还是有很多不同的,但是语言 ...

  9. Swift学习笔记笔记(七) UIKit常用组件的使用

    一.实验目的: 1.掌握Cocoa程序的创建 2.掌握UILabel组件的使用 3.掌握UIButton组件的使用 4.掌握UITextField组件的使用 二.实验原理: 1.Cocoa应用程序框架 ...

最新文章

  1. 【HDU】3635 Dragon Balls (带权并查集 一)
  2. muduo之GzipFile
  3. jQuery 遍历 (each、map)
  4. DotNetNuke与MemberShip的结合(五年版) 三步汇总
  5. 深度学习之自编码器(2)Fashion MNIST图片重建实战
  6. 少儿编程150讲轻松学Scratch(七)-Scratch学习中需要注意的地方
  7. 业务线开发流程图(四)
  8. ajax请求后台php数据时查看报错parse error
  9. 联众创始人鲍岳桥:52 岁还在熬夜写代码! | 人物志
  10. 中国省份名称的映射字典
  11. ADB Interface 找不到驱动程序 怎么破
  12. 大学生vb计算机基础,大学计算机基础课程上机考试登录程序的VB实现
  13. vue 调起浏览器打印
  14. 智伴机器人三级分销模式_微信三级分销模式的可行性?
  15. 修改火狐浏览器滚动条样式
  16. 数据库连接池之自定义连接池(mysql)
  17. 进度管理PV,AC,EV
  18. 没有一颗凑数镜头,拍照最佳的三款手机,均是影像机皇标准
  19. 2021 年广东省职业院校技能大赛(中职组) 网络搭建与应用赛项国赛遴选赛卷(B)
  20. failed to copy ‘xxx‘ to ‘system/bin/xxx‘: remote couldn‘t create file: Read-only file system

热门文章

  1. 【Eclipse最常用快捷键】
  2. Go实战--golang中使用Goji微框架(Goji+Mongodb构建微服务)
  3. 判断是否保持函数依赖
  4. void函数内创建并返回一个结构体
  5. loadrunner+win2003虚拟机的安装
  6. 【Word】插入题注图1-1,并在文章中交叉引用
  7. 2019年个人总结,写在人生不惑之年
  8. 概要设计说明书(实例)
  9. i = i++, i = ++i, j = i++, j = ++i 的区别
  10. 配置管理——配置管理委员会