1.基本概念
在OpenStack Folsom版本之后,OpenStack通过Cinder服务为云平台提供块逻辑卷服务。逻辑卷通过Raid与LVM等方法,对数据提供了保护。并且使用并行写入和SAN架构大幅提升读写速率。另外,将若干磁盘进行组合,成为一个大容量的逻辑卷并对外提供服务,极大地提高了容量。
Cinder是OpenStack Block Storage(OpenStack块存储)的项目名称,Cinder的核心功能是对卷的管理,允许对卷、卷的类型、快照进行处理。然而,它并没有实现对块设备的管理和实际服务(提供逻辑卷),而是通过后端的统一存储接口支持不同块设备厂商的块存储服务,实现其驱动支持并于OpenStack进行整合。Cinder可以支持如NetAPP、SolidFire、华为、EMC和IBM等知名存储厂商以及众多开源块存储系统,如图所示。
对于本地存储,Cinder通过cinder-volume子服务来使用LVM驱动。Cinder-volume通过LVM命令创建一个名为cinder-volumes的卷组(vg),当该节点接受到创建卷请求的时候,cinder-volume在该vg上创建LV,并且用iSCSI服务将这个卷作为一个iSCSI的存储设备提供给虚拟机。
2.架构讲解
OpenStack Cinder的架构:
Cinder得到请求后会自动访问块存储服务,它有两个显著的特点。第一,必须用户提出请求,服务才会进行响应;第二,用户可以使用自定义的方式实现半自动化服务。简而言之,Cinder虚拟化块存储设备池,提供给用户自助服务的API用以请求和使用存储池中的资源,而Cinder本身并不能获取具体的存储形式或物理设备信息。
① Auth Manage:负责Cinder的授权工作,在OpenStack中,使用Keystone服务来进行授权管理。
② AMQP:高级消息队列协议,用于存储和传递Rest请求。
③ iSCSI:基于网络的小型计算机系统接口。
④ REST:表征状态转移(representational state transfer),定义了一种软件架构原则,它是一种针对网络应用的设计和开发方式,可以降低开发的成本和复杂度,提供系统的可伸缩性。
⑤ CinderClient:Cinder的客户端软件,通过CLI或API等形式访问并使用Cinder管理块存储。
3.配置文件讲解
为了实现Cinder通过消息队列存储Rest请求实现组件间通信,我们需要指定消息队列的类型及存储消息队列的主机。
编辑/etc/cinder/cinder.conf文件。
# vi /etc/cinder/cinder.conf
[DEFAULT]
auth_strategy = keystone
rpc_backend = cinder.openstack.common.rpc.impl_qpid
qpid_hostname = controller
[database]
connection = mysql://cinder:000000@controller/cinder
Cinder服务的数据存储在MySQL数据库中,需要在Cinder中配置连接参数以连接MySQL数据库。
# mysql -u root –p
mysql> CREATE DATABASE cinder;
mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS';
mysql> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY ' CINDER_DBPASS ';
# su -s /bin/sh -c 'cinder-manage db sync' cinder
为了实现Cinder组件的认证管理,需要通过Keystone创建Cinder用户并设置密码以及权限,并为其创建API端口,以便与其他组件进行通信,需要注意的是,Keystone的API有V1和V2两个版本,为了方便使用,建议分别创建V1和V2版本的API端点。
# openstack user create cinder --password CINDER_PASS --domain demo --email CINDER_EMAIL
# openstack role add –user cinder –project service admin
# openstack service create –name cinder –description "OpenStack Block Storage" volume
为了实现Cinder与OpenStack组件间的正常通信,Cinder需要通过认证管理,对Cinder进行授权。Cinder默认使用本地存储作为后端存储,由于Cinder本地存储方式和iSCSI Target组件有依赖关系,这里需要配置对应的iSCSI组件。
# vi /etc/cinder/cinder.conf
[DEFAULT]
auth_strategy = keystone
rpc_backend = cinder.openstack.common.rpc.impl_qpid
qpid_hostname = controller
control_exchange = cinder
notification_driver = cinder.openstack.common.notifier.rpc_notifier
iscsi_helper = tgtadm
[keystone_authtoken]
auth_uri = http://controller:5000
auth_host = controller
auth_protocol = http
auth_port = 35357
admin_user = cinder
admin_tenant_name = service
admin_password = 000000
4.LVM技术
LVM(logical volume manager)是逻辑卷管理的简称。它是Linux系统环境下对磁盘分区进行管理的一种机制。现在不仅仅是Linux系统上可以使用LVM这种磁盘管理机制,其他的类UNIX操作系统,以及windows操作系统都有类似于LVM这种磁盘管理软件。
LVM的工作原理其实很简单,就是通过将底层的物理硬盘抽象的封装起来,然后以逻辑卷的方式呈现给上层应用。在传统的磁盘管理机制中,上层应用是直接访问文件系统,从而对底层的物理硬盘进行读取,而在LVM中,其通过对底层的硬盘进行封装,当对底层的物理硬盘进行操作时,不再是针对于分区进行操作,而是通过一个叫作逻辑卷的东西来对其进行底层的磁盘管理操作。例如,增加一个物理硬盘,这个时候上层的服务是感觉不到的,因为呈现给上次服务的是以逻辑卷的方式。LVM最大的特点就是可以对磁盘进行动态管理。因为逻辑卷的大小是可以动态调整的,而且不会丢失现有的数据。如果用户新增加了硬盘,也不会改变现有上层的逻辑卷。作为一个动态磁盘管理机制,逻辑卷技术大大提高了磁盘管理的灵活性,如图所示。
LVM工作原理:
5.iSCSI技术
iSCSI(Inernet SCSI)技术由IBM公司研发,是一个供硬件设备使用、可以在网络协议(主要指TCP/IP协议栈)的上层运行的SCSI指令集,这种指令集可以实现在IP网络上运行SCSI协议,使其能够在诸如高速千兆以太网上进行路由选择。SCSI协议主要是在主机和存储设备之间传送命令、状态和块数据,可以说是当今存储技术最重要的协议之一。iSCSI技术是一种新型存储技术,该技术允许将现有的SCSI接口(支持SCSI协议的小型计算机系统接口)与以太网(Ethernet)技术结合,使服务器可以使用IP网络的存储装置互相交换资料。
iSCSI基于TCP/IP的协议,用来建立和管理网络存储设备、服务器和客户之间的相互通信,并创建存储网络(SAN)。SAN可以让SCSI协议应用在高速数据传输的网络中,这种传输以数据块级别在多个存储网络之间进行。iSCSI基于C/S架构,它的主要功能是在TCP/IP网络上的主机系统(启动器Initiator)和存储设备(目标器target)之间进行大量数据的封装和可靠传输过程,如图所示。
iSCSI的基本架构:
6.Cinder基本服务
① API Service:负责接受和处理Rest请求,并将请求放入消息队列中。
② Scheduler Service:负责处理队列中的任务,并根据预先制定的调度策略(优先活跃节点)选择合适的存储节点来执行任务。
③ Volume Service:该服务运行在各个存储节点之上,管理存储空间,每一个存储节点都有一个Volume Service,构建一个庞大的存储资源池。Volume Service本身不实现存储功能,而由Cinder存储后端(Backend Drivers)来实现。
7.Cinder支持的后端存储类型
(1)本地存储
Cinder默认使用LVM技术配合iSCSI协议来实现本地存储,LVM驱动需要在云主机中事先用LVM命令创建一个cinder-volume的卷组,当该主机接收到创建卷的请求时,cinder-volume会在卷组上创建一个逻辑卷,并用iSCSI技术将这个卷组作为一个iSCSI的Target提供给云主机。
(2)其他存储
目前,除了本地存储之外,还包括EMC(EMC是传统存储厂商,主要面对企业级用户,Netapp(目前的数据密集型企业提供统一存储解决方案的居世界最前列的公司)和华为存储为之服务。
(3)Cinder Volume创建流程
当用户从cinder-client发送一个请求创建卷组之后,会将创建的类型、大小和种类等信息通过RESTFUL接口来访问cinder-api,api接受请求之后就会把client传送的请求进行解析,之后通过rpc将请求发送给cinder-scheduler选择合适的volume节点,节点选择完毕再次通过rpc发送给volume,之后调用driver来创建client要求的卷组,如果cinder需要要求backup,这时候就需要调用rpc进行backup操作,如图所示。
实际命令操作
1.对Cinder后端逻辑卷进行扩容
Cinder后端默认使用LVM逻辑卷进行存储,当卷资源不够时,会导致创建Cinder卷失败,为了解决这个问题,需要对LVM逻辑卷进行扩容,从而解决cinder-volume空间不足的问题。
(1)创建一个100G的云硬盘extend-demo
# cinder create --name cinder-volume-demo 100
(2)通过cinder-list命令查看云硬盘信息
# cinder list
云硬盘创建失败,状态为error。用户可以在存储节点运行vgdisplay命令查看逻辑卷空间。
# vgdisplay
通过查看命令发现VG的总容量为48.48G,另外还创建了一张1G的存储卷以及PE占用的4MB,我们的空间已经不足47G,所以无法再创建新的云硬盘。因此需要对VG进行扩容。
(3)对LVM卷进行扩容
① 首先我们通过“pvcreate”命令创建pv。
# pvcreate /dev/md126p4
Physical volume "/dev/md126p4" successfully created
② 接着,我们通过“vgextend”命令扩展已有VG的容量。
# vgextend cinder-volumes /dev/md126p4
Volume group “cinder-volumes” successfully extended
③ 查看扩展后的VG容量。
# vgdisplay
④ 重启cinder-volume服务后再次创建该云硬盘。
# cinder create --name cinder-volume-demo 100
2.指定Cinder卷类型
(1)创建type标识的卷类型
可以通过“cinder type-create”命令来创建卷类型,创建了一个名为“lvm”的卷类型。
# cinder type-create lvm
(2)查询type标识的卷类型
可以通过“cinder type-list”命令来查看现有的卷类型。
# cinder type-list
(3)创建并查询extra_spec表示的卷类型
除了可以通过cinder创建type类型的卷标识外,OpenStack还允许通过cinder创建extra_spec类型的卷类型,两个功能基本类似,extra_spec利用一组键值对来对cinder卷进行标识。
可以通过命令cinder type-key lvm set volume_backend_name=LVM_iSCSI来创建键为volume_backend_name,值为LVM_iSCSI的extra_spec类型标识。
通过cinder extra-specs-list来查看已创建的extra_spec标识。
# cinder extra-specs-list
(4)创建云硬盘
下面以type标识为例,创建一块带“lvm”标识的云硬盘,命令如下。
# cinder create --name type_test_demo --volume-type lvm 1
创建成功后可以通过命令查看结果,可以看到该卷的volume_type字段已修改为“lvm”。查询命令如下。
# cinder show type_test_demo
3.Cinder的CLI命令行使用
Cinder作为OpenStack平台的块存储组件,提供了一系列存储操作的CLI命令行用于管理存储卷,可以灵活地对存储卷进行创建、扩容、删除和加密等操作。
(1)创建cinder存储卷
用户可以通过CLI命令创建一个简单的Cinder存储卷,命令如下。
# cinder create --name cinder-volume-demo 1
该命令用法如下。
cinder create [--consisgroup-id <consistencygroup-id>]
[--snapshot-id <snapshot-id>]
[--source-volid <source-volid>]
[--source-replica <source-replica>]
[--image-id <image-id>] [--image <image>] [--name <name>]
[--description <description>]
[--volume-type <volume-type>]
[--availability-zone <availability-zone>]
[--metadata [<key=value> [<key=value> ...]]]
[--hint <key=value>] [--allow-multiattach]
[<size>]
用户可以通过--display参数指定卷名,然后指定卷组大小,就可以创建一个最简单的云存储卷。
(2)创建特定的镜像
--image-id参数允许用户从一个已创建的镜像来构建一个带镜像内容的Cinder卷,一般可以用于启动虚拟机操作系统。
--snapshot-id参数允许用户从特定的快照来创建Cinder卷,具体用法和--image-id类似。
--source-volid参数允许用户从已创建的Cinder卷来创建一张内容相同的卷,可以用于备份或启动系统。
--description参数允许用户指定镜像的描述信息。
--volume-type参数可以指定卷类型,卷类型是卷的一个标识,各个OpenStack发行者可以根据自身对系统的约束来定义卷类型的使用。在扩展延伸部分会对Cinder卷类型进行详细阐述。
--availability-zone参数可以为创建的Cinder卷指定可用域,不同可用域的资源会被隔离,互不干扰。
--metadata参数可以允许为创建的Cinder卷指定属性信息。
(3)删除指定的Cinder卷
删除Cinder卷的方法比较简单,用户可以通过命令cinder delete <volume> [<volume> ...] 来删除一个或多个Cinder卷。
(4)创建Cinder卷快照
用户可以通过如下命令来创建一个简单的Cinder 卷快照。
# cinder snapshot-create --name snapshot_demo cinder-volume-demo
该命令用法如下。
cinder snapshot-create [--force [<True|False>]] [--name <name>]
[--description <description>]
[--metadata [<key=value> [<key=value> ...]]]
<volume>
其中,--force参数强制创建该快照,不论该卷是否被虚拟机所使用。
(5)查看Cinder卷、快照信息
我们可以通过cinder-list命令查看镜像列表
# cinder list
还可以通过“cinder show <volume>”命令来查看指定云硬盘的详细信息,命令如下。
# cinder show 0643885c-1dc7-4f9f-9309-382c54cc6790
(6)将已创建的Cinder卷挂载到虚拟机实例
云硬盘创建完成后,可以将它挂载到云主机实例上。首先选择右侧标签栏中的云硬盘标签,单击“更多”按钮,选择“管理连接”,
对象存储服务
基本概念
Swift 构筑在比较便宜的标准硬件存储基础设施之上,无需采用RAID(磁盘冗余阵列),通过在软件层面引入一致性散列技术提高数据冗余性、高可用性和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决互联网的应用场景下非结构化数据存储问题。在OpenStack中,Swift主要用于存储虚拟机镜像,用于Glance的后端存储。在实际运用中,Swift的典型运用是网盘系统,代表是“Dropbox”,存储类型大多为图片、邮件、视频和存储备份等静态资源。
Swift不能像传统文件系统那样进行挂载和访问,只能通过Rest API接口来访问数据,并且这些API与亚马逊的S3服务API是兼容的。Swift不同于传统文件系统和实时数据存储系统,它适用于存储、获取一些静态的、永久性的数据,并在需要的时候进行更新。
在了解Swift服务之前首先要明确以下3个基本概念。
(1)Account
出于访问安全性考虑,使用Swift系统,每个用户必须有一个账号(account)。只有通过Swift验证的账号才能访问Swift系统中的数据。提供账号验证的节点被称为Account Server。Swift中由Swauth提供账号权限认证服务。
用户通过账号验证后将获得一个验证字符串(authentication token),后续的每次数据访问操作都需要传递这个字符串。
(2)Container
Swift中的container可以类比Windows操作系统中的文件夹或者UNIX类操作系统中的目录,用于组织管理数据,所不同的是container不能嵌套。数据都以Object的形式存放在container中。
(3)Object
Object(对象)是Swift中的基本存储单元。一个对象包含两部分,数据和元数据(metadata)。其中,元数据包括对象所属container名称,对象本身名称以及用户添加的自定义数据属性(必须是key-value格式)。
对象名称在URL编码后,要求小于1024字节。用户上传的对象最大是5GB,最小是0 bytes。用户可以通过Swift内建的大对象支持技术获取超过5GB的大对象。对象的元数据不能超过90个key-value对属性,并且这些属性的总大小不能超过4KB。
Account、Container和Object是Swift系统中的3个基本概念,三者的层次关系是一个Account可以创建任意多个Container,一个Container中可以包含任意多个Object。可以简单理解为一个Tenant拥有一个Account,Account下存放Container,Container下存储Object。
在Swift系统中,集群被划分成多个区(zone),区可以是一个磁盘,一个服务器,一台机柜甚至一个数据中心,每个区中有若干个节点。Swift将Object存储在节点上,每个节点都是由多个硬盘组成的,并保证对象在多个节点上有备份(默认情况下,Swift会给所有数据保存3个复本)以及这些备份之间的一致性。备份将均匀地分布在集群服务器上,并且系统保证各个备份分布在不同区的存储设备上,这样可以提高系统的稳定性和数据的安全性。它可以通过增加节点来线性地扩充存储空间。当一个节点出现故障,Swift会从其他正常节点对出故障节点的数据进行备份。
3.swift服务优势
(1)数据访问灵活性
Swift通过Rest API接口来访问数据,可以通过API实现文件的存储和管理,使得资源管理实现自动化。同时,Swift将数据放置于容器内,我们可以创建公有的容器和私有的容器。*地访问控制权限既允许用户间共享数据,也可以保存隐私数据。Swift对所需的硬件没有刻意的要求,可以充分利用商用的硬件节约单位存储的成本。
(2)高数据持久性
Swift提供多重备份机制,拥有极高的数据可靠性,数据存放在高分布式的Swift系统中,几乎不会丢失,Swift在5个Zone、5×10个存储节点、数据复制3份时,数据持久性的SLA能够达到10个9,即存储1万个文件到Swift中,经过10万年后,可能会丢失一个文件,这种文件丢失几乎可以忽略不计。
(3)极高的可拓展性
Swift通过独立节点来形成存储系统,首先,在数据量的存储上就做到了无限拓展。另外,Swift的性能也可以通过增加Swift集群来实现线性提升,所以Swift很难达到性能瓶颈。
(4)无单点故障
由于Swift的节点独立的特点,在实际工作时,不会发生传统存储系统的单点故障,传统系统即使通过HA来实现热备,但在主节点出现问题时,还是会影响整个存储系统的性能。而在Swift系统中,数据的元数据(Metadata)是通过Ring算法随机均匀分布的,且元数据也会保存多份,对于整个Swift集群而言,没有单点的角色存在。
4.架构解析
Swift采用了REST架构,REST是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。REST(representational state transfer)是一种轻量级的Web Service架构风格,其实现和操作明显比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。
REST架构遵循了CRUD原则,CRUD原则对于资源只需要4种行为:Create(创建)、Read(读取)、Update(更新)和 Delete(删除),就可以完成对其操作和处理。这4个操作是一种原子操作,即一种无法再分的操作,通过它们可以构造复杂的操作过程,正如数学上的四则运算是数字的最基本的运算一样。
REST架构让人们真正理解网络协议HTTP的本来面貌,对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法,因此REST把HTTP对一个URL资源的操作限制在GET、POST、PUT和DELETE这4个之内。这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
因为其简洁方便性,越来越多的Web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找,雅虎公司提供的Web服务也是REST风格的。
因为Swift采用REST架构,用户不能像普通的文件系统那样对数据进行访问,必须通过它提供的API来访问操作数据,如图1所示。图2和图3分别展示了Swift的上传和下载操作。Rackspace还对这些API做了不同语言的封装绑定,以方便开发者进行开发。目前支持的语言有PHP、Python、Java、C#/.NET 和Ruby。
使用HTTPS(SSL)协议和对象存储进行交互,也可以使用标准的HTTP API调用来完成操作。同样,也可以使用特定语言的API,它使用RESTful API。
通过API访问Swift存储的数据(图1):
通过http的put方法上传数据(图2):
通过http的get方法下载数据(图3):
通过API接口使用put方式将data数据上传到存储系统中,如果需要下载数据则通过get方法将存储系统中的数据下载下来。
Swift集群主要包含认证节点、代理节点和存储节点。认证节点主要负责对用户的请求授权,只有通过认证节点授权的用户才能操作Swift服务。因为Swift是OpenStack的子项目之一,所以一般用keystone服务作为Swift服务的认证服务。代理节点用于和用户交互,接受用户的请求并且给用户做出响应。Swift服务所存储的数据一般都放在数据节点。
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):移除被标记为删除的账户,删除其所包含的所有容器和对象。
环(Ring):Ring是Swift最重要的组件,用于记录存储对象与物理位置间的映射关系。在涉及查询Account、Container和Object信息时,就需要查询集群的Ring信息。Ring使用Zone、Device、Partition和Replica来维护这些映射信息。Ring中每个Partition在集群中都(默认)有3个Replica。每个Partition的位置由Ring来维护,并存储在映射中。Ring文件在系统初始化时创建,之后每次增减存储节点时,需要重新平衡一下Ring文件中的项目,以保证增减节点时,系统因此而发生迁移的文件数量最少。
区域(Zone):Ring中引入了Zone的概念,把集群的Node分配到每个Zone中。其中,同一个Partition的Replica不能同时放在同一个Node上或同一个Zone内。防止所有的Node都在一个机架或一个机房中,一旦发生断电、网络故障等,造成用户无法访问的情况。
5.一致性散列
Ring的寻址过程:
面对海量级别的对象,需要存放在成千上万台服务器和硬盘设备上,首先要解决寻址问题,即如何将对象分布到这些设备地址上。Swift是基于一致性散列技术的,通过计算可将对象均匀分布到虚拟空间的虚拟节点上,在增加或删除节点时可大大减少需移动的数据量;虚拟空间大小通常采用2的n次幂,便于进行高效的移位操作;然后通过独特的数据结构Ring(环)再将虚拟节点映射到实际的物理存储设备上,完成寻址过程
如图所示,以逆时针方向递增的散列空间有4个字节长共32位,整数范围是[0~232-1];将散列结果右移m位,可产生 232-m个虚拟节点,例如,m=29时可产生8个虚拟节点。在实际部署的时候需要经过仔细计算得到合适的虚拟节点数,以达到存储空间和工作负载之间的平衡。
6.数据一致性模型
按照Eric Brewer的CAP(Consistency,availability,partition tolerance)理论,无法同时满足3个方面,Swift 放弃严格一致性(满足ACID事务级别),而最终采用一致性模型(eventual consistency),来达到高可用性和无限水平扩展能力。为了实现这一目标,Swift 采用 Quorum 仲裁协议(Quorum有法定投票人数的含义):设定N为数据的副本总数;W为写操作被确认接受的副本数量;R为读操作的副本数量。
强一致性:R+W>N,以保证对副本的读写操作会产生交集,从而保证可以读取到最新版本;如果W=N,R=1,则需要全部更新,适合大量读少量写操作场景下的强一致性;如果R=N,W=1,则只更新一个副本,通过读取全部副本来得到最新版本,适合大量写少量读场景下的强一致性。
弱一致性:R+W<=N,如果读写操作的副本集合不产生交集,就可能会读到脏数据;适合对一致性要求比较低的场景。
Swift针对的是读写都比较频繁的场景,所以采用了折中的策略,即写操作需要满足至少一半以上成功W>N/2,再保证读操作与写操作的副本集合至少产生一个交集,即 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个副本的元数据信息,然后比较时间戳来确定哪个是最新版本(强一致性模型);如果数据出现了不一致,后台服务进程会在一定时间窗口内通过检测和复制协议来完成数据同步,从而保证数据达到最终一致性,如图所示。
Swift数据的一致性:
7.环的数据结构
环是为了将虚拟节点(分区)映射到一组物理存储设备上,并提供一定的冗余度而设计的,其数据结构由以下信息组成。
存储设备列表、设备信息包括唯一标识号(id)、区域号(zone)、权重(weight)、IP 地址(ip)、端口(port)、设备名称(device)、元数据(meta)、分区到设备映射关系(replica2part2dev_id 数组)、计算分区号的位移(part_shift 整数,即图7-20中的 m)。
如图所示,以查找一个对象的计算过程为例。
层次结构 account/container/object 作为键,使用MD5散列算法得到一个散列值,对该散列值的前4个字节进行右移操作得到分区索引号,移动位数由上面的part_shift设置指定;按照分区索引号在分区到设备映射表(replica2part2dev_id)里查找该对象所在分区的对应的所有设备编号,这些设备会被尽量选择部署在不同区域(Zone)内,区域只是个抽象概念,它可以是某台机器,某个机架,甚至某个建筑内的机群,以提供*别的冗余性,建议至少部署5个区域;权重参数是个相对值,可以根据磁盘的大小来调节,权重越大表示可分配的空间越多,可部署更多的分区。
Swift为账户\容器和对象分别定义了的环,查找账户和容器也是同样的过程。
8.数据模型
Swift采用层次数据模型,共设3层逻辑结构:Account/Container/Object(即账户/容器/对象),每层节点数均没有限制,可以任意扩展。这里的账户和个人账户不是一个概念,可理解为租户,用来做顶层的隔离机制,可以被多个个人账户共同使用;容器代表封装一组对象,类似文件夹或目录;叶子节点代表对象,由元数据和内容两部分组成,如图所示。
9.基本命令
Swift工具是用于用户与OpenStack对象存储(Swift)环境进行通信的命令行接口。它允许一个用户执行多种类型的操作。常用的管理命令有以下几点。
(1)swift stat
功能:根据给定的参数显示账户、对象或容器的信息。
格式:
swift stat [container] [object]
参数说明。
[container]:容器名称。
[object] :对象名称。
(2)swift list
功能:列出该账户的容器或容器的对象。
格式:
Swift list [command-options] [container]
参数说明。
[command-options]:选项。
[container]:容器名称。
(3)swift upload
功能:根据参数将制定的文件或者目录上传到容器内。
格式:
swift upload [command-options] container file_or_directory [file_or_ directory] [...]
参数说明。
[command-options]:选项。
Container:容器名称,或者是容器内的目录。
file_or_directory:本地文件系统内的目录或者文件。
[file_or_directory] :本地文件系统内的目录或者文件,可同时上传多个目录或文件。
(4)swift post
功能:根据给定的参数升级account、container或者object的元数据信息。
格式:
swift post [command-options] [container] [object]
参数说明。
[command-options]:选项。
[container]:容器名称。
[object]:对象名称。
(5)swift download
功能:根据给定的参数下载容器中的对象。
格式:
swift download [command-options] [container] [object] [object] [...]
参数说明。
[command-options]:选项。
[container]:容器名称。
[object]:对象名称(可同时下载多个对象)。
(6)swift delete
功能:根据给定的参数删除容器中的对象。
格式:
swift delete [command-options] [container] [object] [object] [...]
参数说明。
[command-options]:选项。
[container]:容器名称。
[object]:对象名称(可同时下载多个对象)。
1.熟悉swift基本操作
通过命令行实现对swift上数据的操作,首先需要创建一个名称为“xiandian”的容器,命令如下。
# swift post xiandian
有了容器之后,可以查看“xiandian”容器里面的内容,命令如下。
# swift list xiandian
通过显示结果可以看出目前“xiandian”容器里面的内容是空的,这时用户希望将本地的test目录内容递归上传到“xiandian”容器内,首先创建test目录,并同时新建3个文件“iaas.txt”“paas.doc”和“saas.png”。具体命令如下。
# mkdir test
# touch iaas.txt
# touch paas.doc
# touch saas.png
上传时首先需要上传一个空白的“test”目录。命令如下。
# swift upload xiandain test/
接下来,可以将“iaas.txt”文件上传到“xiandian”容器内“test”目录内,命令和执行结果如下。
# swift upload xiandian/test iaas.txt
[root@controller mnt] # swift upload xiandian/test iaas.txt
iaas.txt
换一种方式将剩下的“paas.doc”和“saas.png”递归上传到“xiandian”容器下的“test”目录内,命令和执行结果如下。
# mv paas.doc saas.png test/
# swift upload xiandian test/
test/paas.doc
test/saas.png
数据在swift集群内保存,随时供用户下载使用,现在下载“saas.png”文件,命令和执行结果如下。
# swift download xiandian/test saas.png
目前磁盘容量有限,需要删除一些相对价值低的数据,空出更多的空间。这时已经将“saas.png”下载到本地,所以暂时将“saas.png”从对象存储服务器中删除,命令和执行结果如下。
# swift delete xiandian test/saas.png
[root@controller mnt] # swift delete xiandian test/saas.png
test/saas.png
用户还可以通过swift stat命令来查看整个Account账户下swift状态,命令和执行结果如下。
# swift stat
[root@controller ~]# swift stat
创建私有存储容器:
# swift post 《容器名》
查看容器
# swift list
(4)使用Swift 作为Glance的后端存储,为Glance存储创建名为glance的公共容器
# vi /etc/glance/glance-api.conf
[DEFAULT]
#修改后端存储方式
default_store=swift
#修改swift keyston版本信息
swift_store_auth_version=2
#修改swift认证地址
swift_store_auth_address=http://172.24.2.10:5000/v2.0/
#修改swift默认的租户和用户名称
swift_store_user=service:swift
#修改默认的数据密码
swift_store_key=000000
#修改swift存储glance镜像的容器名称
swift_store_container=glance
#如果存放的容器不存在,即需要创建该容器
swift_store_create_container_on_put=True
#swift存储glance镜像最大容量为5G
swift_store_large_object_size=5120
#swift 默认块大小为200M
swift_store_large_object_chunk_size=200
修改完成后,重新启动glance的相关服务。
# service openstack-glance-api restart
# service openstack-glance-registry restart
上传一个镜像作为测试,查看效果。
# glance image-create --name centos --disk-format qcow2 --container-format bare --is-public True --progress < /tmp/centos_65_x86_6420140327.qcow2
查看镜像id,命令:
# glance index
在swift端执行命令查看存储信息,命令:
# swift --os-username glance --os-password 000000 --os-tenant-name service --os-auth-url http://172.24.2.10:5000/v2.0/ list glance
(5)使用Swift 作为Cinder的后端存储,为Glance存储创建名为glance的公共容器
存储节点的配置文件修改如下。
# vi /etc/cinder/cinder.conf
[DEFAULT]
#后端存储驱动
backup_driver=cinder.backup.drivers.swift
#Swift Endpoint的URL地址
backup_swift_url=http://172.24.2.10:8080/v1/AUTH_
#Swift认证机制
backup_swift_auth=keystone
#Swift的用户
backup_swift_user=swift
#Swift用户密码
backup_swift_key=000000
#默认的Swift存储容器
backup_swift_container=volumebackups
#备份块文件的大小
backup_swift_object_size=52428800
#备份尝试次数
backup_swift_retry_attempts=3
#重试延迟时间
backup_swift_retry_backoff=2
#压缩算法
backup_compression_algorithm=zlib
存储节点重启服务。
# service openstack-cinder-volume restart
# service openstack-cinder-backup restart
控制节点重启服务。
# service /openstack-cinder-api restart
# service openstack-cinder-scheduler restart
创建一个作为cinder后端备份存储的容器Volume_test_backup,执行结果如下。
# swift post Volume_test_backup
# cinder list
# cinder backup-create --container Volume_test_backup Volume_test
# cinder backup-list
储存总结;
1.3种存储的对比
在学习了Glance镜像存储、Cinder块存储以及Swift对象存储之后,3种存储之间有什么相同点和区别 ?尤其作为存储来说的Cinder和Swift之间的区别又是哪些呢?
从前面几节介绍来看,总结以下几点。
swift对象存储是一个系统,可以上传和下载,里面一般存储的是不经常修改的内容,例如用于存储VM镜像、备份和归档以及较小的文件(如照片和电子邮件消息),更倾向于系统的管理。
Cinder块存储具有安全可靠、高并发大吞吐量、低时延、规格丰富、简单易用的特点,适用于文件系统、数据库或者其他需要原始块设备的系统软件或应用。
但是,这些太过于笼统,下面我们从一个简单的小例子来进行说明。
swift可以将object(理解为文件)存储到bucket(可以理解为文件夹)里,用swift创建container,然后上传文件,例如视频、照片,这些文件会被replication到不同服务器上以保证可靠性,swift可以不依靠虚拟机工作。所谓的云存储,OpenStack就是用swift实现的,类似于Amazon AWS S3(Simple Storage Service),可以理解成一个文件系统。
cinder是block storage(块存储),可以把cinder当作优盘管理程序来理解。可以用cinder创建volume,然后将它接到(attach)虚拟机上去,这个volume就像虚拟机的一个存储分区一样工作。如果把这个虚拟机terminate了,这个volume和里边的数据依然还在,你还可以把它接到其他虚拟机上继续使用里边的数据。cinder创建的volume必须被接到虚拟机上才能工作。类似于Amazon AWS EBS(Elastic Block Storage),可以把Cinder理解成一个可移动硬盘。
而Glance则为虚拟机镜像支持,镜像资源都会存放在Glance存储内部。
Swift作为一个文件系统,意味着可以为Glance提供存储服务,同时也可为个人的网盘应用提供存储支持。这个优势是Cinder和Glance无法实现的。
2.Swift 的应用
(1)网盘
Swift的对称分布式架构和多proxy多节点的设计导致它从基因里就适用于多用户并发的应用模式,最典型的应用莫过于类似网盘应用。
Swift的对称架构使得数据节点从逻辑上看处于同级别,每个节点上同时具有数据和相关的元数据。并且元数据的核心数据结构使用的是哈希环,一致性哈希算法对于节点的增减只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。另外,数据是无状态的,每个数据在磁盘上都是完整的存储。这几点综合起来保证了存储本身的良好的扩展性。
另外,在与应用的结合上,Swift是遵循HTTP协议的,这使得应用和存储的交互变得简单,不需要考虑底层基础构架的细节,应用软件不需要进行任何的修改就可以让系统整体扩展到非常大的程度。
(2)Iaas公有云
Swift在设计中的线性扩展、高并发和多租户支持等特性,使得它也非常适合作为IaaS 的选择,公有云规模较大,更多时候会遇到大量虚拟机并发启动的情况,所以对于虚拟机镜像的后台存储来说,实际上的挑战在于大数据(超过G)的并发读性能,Swift在OpenStack中一开始就是作为镜像库的后台存储,经过Rackspace上千台机器的部署规模下的数年实践,Swift已经被证明是一个成熟的选择。
另外,基于IaaS要提供上层的SaaS服务,多租户是一个不可避免的问题,Swift的架构设计本身就是支持多租户的,这样对接起来更方便。
(3)备份文档
Rackspace的主营业务就是数据的备份归档,所以Swift在这个领域也是久经考验,同时他们还延展出一种新业务——“热归档”。由于长尾效应,数据可能被调用的时间窗越来越长,“热归档”能够保证应用归档数据在分钟级别重新获取,和传统磁带机归档方案中的数小时相比,是一个很大的进步。
(4)移动互联网和CDN
移动互联网和手机游戏等产生大量的用户数据,数据量不是很大,但是用户数很多,这也是Swift能够处理的领域。
至于加上CDN,如果使用Swift,云存储就可以直接响应移动设备,不需要专门的服务器去响应这个HTTP的请求,也不需要在数据传输中再经过移动设备上的文件系统,直接是用HTTP协议上传云端。如果把经常被平台访问的数据缓存起来,利用一定的优化机制,数据可以从不同的地点分发到用户那里,这样就能提高访问的速度,Swift的开发社区有人在讨论视频网站应用和Swift的结合,个人以为是值得关注的方向。
齐白白 发布了6 篇原创文章 · 获赞 0 · 访问量 184 私信 关注