简介
OpenStack Object Storage(Swift) 是 OpenStack 开源云计算项目的子项目之一。Swift使用普通的服务器来构建 冗余的 、 可扩展的 分布式 对象存储 集群,存储容量可达PB级。Swift的是用Python开发,前身是 Rackspace Cloud Files 项目,随着Rackspace加入到OpenStack社区,Racksapce也将Cloud Files的代码贡献给了社区,并逐渐形成现在Swift。Swift最新的发型版本为essex 1.4.6。
功能
Swift提供的服务与AWS S3相同,可以用以下用途:
- 作为IaaS的存储服务
- 与OpenStack Compute对接,为其存储镜像
- 文档存储
- 存储需要长期保存的数据,例如log
- 存储网站的图片,缩略图等
Swift使用RESTful API对外提供服务,目前 1.4.6版本所提供的功能:
- Account(存储账户)的GET、HEAD
- Container(存储容器,与S3的bucket相同)的GET、PUT、HEAD、DELETE
- Object(存储对象)的GET、PUT、HEAD、DELETE、DELETE
- Account、Container、Object的元数据支持
- 大文件(无上限,单个无文件最大5G,大于5G的文件在客户端切分上传,并上传manifest文件)、
- 访问控制、权限控制
- 临时对象存储(过期对象自动删除)
- 存储请求速率限制
- 临时链接(让任何用户访问对象,不需要使用Token)
- 表单提交(直接从HTML表单上传文件到Swift存储,依赖与临时链接)
- 静态WEB站点(用Swift作为静态站点的WEB服务器)
架构
在介绍Swift的架构之前,先介绍一下OpenStack的 设计原理 :
- Scalability and elasticity are our main goals (可扩展性和伸缩性是我们的主要目标)
- Any feature that limits our main goals must be optional (任何影响到可扩展性和伸缩性的功能都必须是可选的)
- Everything should be asynchronous,If you can't do something asynchronously, see #2 (所有的环节必须是异步的,如果不能异步实现,参考第二条设计原理)
- All required components must be horizontally scalable (所有的基础组件必须能横向扩展)
- Always use shared nothing architecture (SN) or sharding ,If you can't Share nothing/shard, see #2 (始终使用无共享的架构,如果不能实现,参见第二条)
- Distribute everything,especially logic. Move logic to where state naturally exists.(所有的都是分布式的,尤其是逻辑。把逻辑放在状态应该存在的地方)
- Accept eventual consistency and use it where it is appropriate. (接受最终一致性,并在适合的条件下使用)
- Test everything (充足的测试)
依赖组件
- Memcached,分布式缓存系统,在swift中主要被用于token和account信息,container信息的存储
- Sqlite,轻量级数据库引擎,在swift中主要被用于管理account和container数据库
- rsync,远程同步工具,用于storage node之间的数据同步
- XFS文件系统
- WSGI,Python Web服务网关接口,通过paste.deploy工具包管理swift各服务进程、中间件的处理流程
- Eventlet,Python搞并发网络编程库,swift所有的服务器进程均依赖于该库
主要组件
- Ring文件 在基本架构图中,我并没有画出ring文件,但是它却是整个Swift中最重要的组件。ring文件是由一致性哈希算法生成,它的主要作用是存储名字到位置的映射。 ring文件分为三类,分别是:account.ring,container.ring,object.ring。 对于account的请求,就能通过account_name查询account.ring得到{'/account_name' : account_db_position}的映射,从而知道account数据库文件在集群的位置; 对于container的请求,通过account_name和container_name查询container.ring文件,得到{'/account_name/container_name' : container_db_position}的映射; 对于object的请求,通过account_name,container_name,object_name查询object.ring文件,得到{'/account_name/container_name/object_name' : object_position}的映射; Ring文件作为一个静态文件存储在每个节点的/etc/swift目录下,被用于各节点之间的位置查询,使得swift的内部网络是一个P2P网络,不依赖某几个节点进行位置查询,避免了单点瓶颈。 生成ring文件的一致性哈希算法不但为数据的冗余性,分区容忍性提供了保证,也为整体架构上实现性能、容量的横向扩展奠定了基础。 Ring的详细构造过程将在下一节介绍。
- proxy-server proxy-server是proxy node中唯一运行的服务进程,也是swift集群的endpoint,向用户提供RESTful API。 对于用户的请求,proxy-server会根据配置文件的配置,将请求交给各个中间件进行处理,其中最重要的就是Auth中间件(认证),在处理完成后会根据请求路径将请求转发给相应的storage node中的account-server。container-server或object-server进程处理。 swift集群的流入数据和流出数据都需要经过proxy-server,proxy-server不会对数据进行缓存。
- auth-server 验证服务进程,为用户生成token和验证每个请求的token及token的权限。swift的验证服务是作为一个中间件被proxy-server使用,是可选的,可以自己开发,也可以使用OpenStack Keystone。Keystone是官方开发的验证服务,使用Keystone可以无缝的与其它OpenStack项目整合。
- account-server account-server是storage node中负责处理对account的GET、HEAD、PUT、DELETE、RELICATION请求的服务进程,account-server使用sqlite的数据库文件保存account的相关信息。
- container-server container-server是storage node中负责处理对container的GET、HEAD、PUT、DELETE、RELICATION请求的服务进程,container-server使用sqlite的数据库文件保存container的相关信息。
- object-server object-server是storage node中负责处理对object的GET、HEAD、PUT、PSOT、DELETE、RELICATION请求的服务进程,object-server直接操作object,并利用XFS文件系统的xattr包存object的元数据。
- account-auditor、container-auditor、object-auditor 这三个进程运行在storage node中,分别检测account的db文件,container的db文件,object是否损坏,如果损坏,将会向存储有其它副本的storage node请求副本,替换损坏的。
- account-replicator、container-replicator、object-replicator 这三个进程运行在storage node中,分别负责account的db文件,container的db文件,object在集群中副本的同步。 例如,一个object在swift集群中通常被存储在3个不同的storage node中,对于一个PUT /account/container/object的请求,proxy-server会根据 /account/container/object查询ring文件,得到该object应该存储的节点列表(长度为3),proxy-server会将请求转发到这三个节点。如果只有两个节点写入成功,就认为这次PUT操作成功。写入失败的节点在一段时间后将会得到写入成功的节点object-replicator进程推送过来的数据。
- container-updater、account-updater 这两个进程运行在storage node中,负责container数据库和account数据库的异步更新。使用异步更新的原因:在请求来量大时,container-server和account-server不能实时处理对数据库更新的请求,这些请求将被本地化到队列中,由updater进程进行异步更新。
原理
Swift利用一致性哈希算法构建了一个冗余的可扩展的分布式对象存储集群。下面将引用我的同事 http://www.cnblogs.com/yuxc/ 的文章对ring实现原理进行讲解。 链接: http://vdisk.weibo.com/s/1rqxy
特性
- 满足冗余性、可扩展性、分区容忍性
- 内部网络是P2P网络,无单点瓶颈
- 横向扩展能力强,性能、容量的扩展只需要简单地增加节点、
- 服务进程使用高并发编程库,请求处理能力强,参见 http://gashero.iteye.com/blog/442177 http://oddments.org/scalestack-vs-node-vs-twisted-vs-eventlet
- 一致性模型可选( http://alexyang.sinaapp.com/?p=95 )
总结
经过对Swift原理、代码的学习研究以及一系列地测试,我认为Swift简单、冗余、可扩展的架构保证了它能作为IaaS的一个基础服务。至于服务的可用率能达到几个9需要看运营这个服务的公司的运维能力。如果要达到像AWS S3这种规模的服务,还需要对Swift的部份组件进行优化。