OpenStack的存储服务

时间:2024-03-04 11:58:24

    OpenStack的存储服务被多个服务组件使用,非常的重要,而我的工作内容由Web转向底层IAAS建设,基本上都是一脸懵,所以做点笔记mark一下。

    存储又被分成临时存储和持久存储两类。临时存储是指数据被虚拟机实例使用,一旦虚拟机实例被关机、重启或删除,该虚拟实例中的所有数据信息全部丢失。OpenStack项目中,部署完Nova计算服务组件之后,用户可以使用nova boot 命令创建虚拟机实例,这时候虚拟机实例使用的就是临时存储,安全性没有任何保障。

    持久存储包括对象存储、块存储和文件系统存储,不管虚拟机实例是否终止,它们的数据都是持续可用的,安全性比较高。

    a.块存储是和主机打交道的,就好比硬盘一样直接挂到主机上,一般用于主机的直接存储空间和数据库应用(如: mysql)的存储,分两种
  • DAS:Direct-Attached Storage(直连式存储)一台服务器一个存储,多机无法直接共享,需要借助操作系统的功能,如共享文件夹。
  • SAN:Storage Area Network(存储区域网络)高成本的存储方式,涉及到光纤和各类高端设备,有很高的可靠性和性能,就是设备贵、运维成本高。

    b.文件系统存储与较底层的块存储不同,上升到了应用层,一般指的就是 NAS,一套网络储存设备,通过TCP/IP进行访问,协议为NFSv3/v4由于通过网络,且采用上层协议,因此开销大,延时肯定比块存储高,一般用于多个云服务器共享数据,如服务器日志集中管理,办公文件共享。

    c.对象存储跟自己开发的应用程序打交道(如网盘),具备块存储的高速以及文件存储的共享等特性,较为智能,有自己的CPU、内存、网络和磁盘,比块存储和文件存储更上层,云服务商一般提供用户文件上传下载读取的Rest API,方便应用集成此类服务。

他们的层级是越来越高的。

1、块存储服务(Cinder)介绍

    块存储又称为卷存储(Volume Storage),为用户提供基于数据块的存储设备访问,用户对数据块存储设备对访问和交互是通过将数据块存储设备映射到正在运行到虚拟机实例上进行到,可以对其进行读写、格式化等。

    块存储属于持久存储,当取消块存储设备与虚拟机实例之间当映射或将整个块存储重新映射给其他虚拟机实例的时候,该块存储上的数据都不受影响。块存储由OpenStack项目中的Cinder块存储服务组件提供,根据已经包含的存储驱动,其目前支持多种类型的后端存储。

    OpenStack项目中的Cinder块存储服务组件为虚拟机实例提供了块存储设备,同时为管理存储设备提供了一整套方法,如卷快照、卷类型等。块存储类型是由驱动或者后端设备配置的驱动决定的,如NAS、NFS、SAN、ISCSI、Ceph。Cinder块存储服务组件的API和cinder-scheduler服务通常运行在控制节点上,cinder-volume服务可以运行在控制节点、计算节点或者独立的存储节点上。

    Cinder块存储服务组件由以下服务进程组成

(1)cinder-api:接收API请求,并将请求转发到cinder-volume。

(2)cinder-volume:与块存储直接进行交互通信,处理一些任务(如由cinder-scheduler分配的),同时通过消息队列与这些任务交互通信。还会维护块存储的状态,通过驱动与各种类型的存储进行交互通信。

(3)cinder-scheduler daemon:选择最佳存储节点创建卷。(nova-scheduler具有相似功能)

(4)cinder-backup daemon:提供任意类型卷的备份。

(5)messaging queue:负责在各进程间传递消息。

许多存储驱动支持虚拟机实例直接访问底层存储,不用再经过层层转化导致性能的消耗,提升了整体的I/O性能。同时,Cinder块存储服务组件也支持使用文件作为块设备,如NFS、GlusterFS。在NFS和GlusterFS文件系统中,可以创建一个独立文件作为块设备映射给虚拟机实例使用。类似于在QEMU中创建虚拟机实例,这些虚拟机实例是一个个文件,保存在/var/lib/nova/instances目录中。

2、对象存储(Swift)服务介绍

    OpenStack项目中的Swift对象存储服务组件通过REST API提供对象数据存储和检索,它至少要和Keystone身份认证服务组件配合使用,部署Swift对象存储组件之前得确定Keystone 已经就绪。Swift组件支持多租户,投入成本低,具有高扩展性和存储大量非结构化数据的特性。

    Swift对象存储服务组件包括下面几个部分:

  • Proxy servers(swift-proxy-server):代理服务器负责Swift架构的其余组件间的相互通信,接收对象存储的API和HTTP请求,修改metadata、创建containers,对于每个客户端的请求,它将在环中查询帐号、容器或者对象的位置并且相应地转发请求。也可以使用公共API向代理服务器发送请求。同时也在web图形界面上提供文件或者containers列表,还使用MemCached提供缓存功能,提高性能。
  • Account servers(swift-account-server):账户服务器,管理对象存储内的账户
  • Container servers(swift-container-server):容器服务器的首要工作是处理对象的列表,管理对象存储内containers和文件夹之间的映射。容器服务器并不知道对象存在哪,只知道指定容器里存的哪些对象。 这些对象信息以sqlite数据库文件的形式存储,和对象一样在集群上做类似的备份。容器服务器也做一些跟踪统计,比如对象的总数,容器的使用情况。
  • Object servers(swift-object-server):对象服务器管理真正的对象数据,是一个简单的二进制大对象存储服务器,可以用来存储、检索和删除本地设备上的对象。每个对象使用对象名称的哈希值和操作时间戳组成的路径来进行存储。最后一次写操作一定会成功,同时最新一次的对象版本会被处理。删除也被视为文件的一个版本(一个以".ts"结尾的0字节文件,ts表示墓碑)。这保证了被删除的文件能被正确地复制,并且不会因为遭遇故障场景导致早些的版本神奇再现。
  • Various periodic processes:执行日常事务,其中的复制服务能够保证数据的连续性和有效性,还包括审核服务、更新服务和删除服务。
  • WSGI middleware:处理认证相关的问题,与keystone身份认证服务组件连接。
  • swift client:允许各种具有权限的用户在该客户端上提交命令,执行操作。
  • swift-init:初始化Ring 文件的脚本,需要守护进程名字作参数,并提供操作命令。
  • swift-recon:CLI工具,用于检索集群各种性能指标和状态信息。
  • swift-ring-builder:创建和重平衡Ring的工具。

    Swift对象存储依靠软件逻辑设计使数据均匀分布存储,一般情况下默认保存三份数据,三份数据保存位置对集群整体性能对影响很大,可以选择在同一服务器对不同硬盘中,也可以分布在同一机架内的不同服务器中。在Swift对象存储集群中,当出现存储数据当主机节点宕机时,整个集群的负载压力很大(某个副本出问题,瞬间会有几倍的数据需要传输、重平衡),生产上要尽可能多地使用网卡聚合和固态磁盘等技术来提高整体性能。

    Swift对象存储特点:

  1. 所有数据存放和访问都有一个URL地址,通过URL可以直接访问数据。
  2. 所有的数据保存三份(默认)副本,分布在不同的Zone区,随机存放在集群中的任意位置。
  3. 所有的数据都有自己的元数据metadata(存储文件所需的信息如:创建时间、时间更新、访问规则等)。
  4. 开发人员可以通过API与Swift对象存储进行交互操作。
  5. 集群添加存储节点不产生性能损耗,是横向扩展,而不是纵向叠加,也不需要停机添加存储节点。
  6. 数据不需要一次性迁移到新存储。
  7. 故障存储节点或硬件设备不需要停机更换
  8. Swift对象存储运行在标准的x86服务器上,如Dell、HP和Lenovo服务器。

    Proxy Server是Swift对象存储的公共接口,接收并处理所有传入的请求。接收到请求后根据对象数据到URL定位到相应的存储节点上,如果某个请求存储节点不可用,它将会查询可传送的服务器并转发请求,同时它还负责协助处理请求反馈、请求失败和标记时间戳等。Proxy Server采用共享无状态架构,能够根据业务负载压力扩展Proxy Server,最小等Proxy Server集群包含两个主机节点,当其中一个节点出现故障的时候,另一个主机能够接管所有的业务请求。

    Ring是对象数据的名称与其在磁盘上具体位置之间的映射。Account、Container、Object都有相应的Ring,它们之间的组合会产生许多Rings。当swift的其它组件(比如复制)要对Account、Container或Object操作时,需要与相应的Ring进行交互操作来确定其在磁盘上的集体位置。Ring使用区域Zone、磁盘设备、虚节点Partition和数据副本来维护这些映射信息。Ring中每个Partition在集群中都(默认)有3个副本。每个虚节点的位置由Ring来维护,并存储在映射中。当代理服务器转发的客户端请求失败时,Ring也负责决定由哪一个设备来接手请求。Ring使用Zone对数据进行隔离,理想状态下每个副本都存储在不同的Zone中。在swift安装的时候,Ring的虚节点会均衡地划分到所有的设备中。当虚节点需要移动时(例如新设备被加入到集群),Ring会确保一次移动最少数量的虚节点数,并且一次只移动一个虚节点的一个副本。通过设置权重值可以平衡Partition虚节点的分布,控制数据流向,避免集群在压力负载大时各主机节点的压力负载不均衡。

    Zone主要功能是Swift对象隔离风险,当某一Zone内的数据丢失或被破坏时,不影响其他Zone内的数据副本,保持了数据整体上的完整性和可用性。Zone可以是一块磁盘、一台服务器、甚至是一个数据中心,其标志性作用是允许存储节点出现停机时间而数据仍然保持实时可用。

    AccountContainer都有自己独立的SQLite数据库,SQLite数据库采用分布式部署在Swift对象存储集群的多个存储节点上。每个Account数据库中包含属于它的Container列表,同样,每个Container数据库中也包含属于它的对象数据列表。

    Object对象服务器是一个简单的二进制大对象存储服务器,可以用来存储、检索和删除本地设备上的对象。在文件系统上,对象以二进制文件的形式存储,它的元数据存储在文件系统的扩展属性(xattrs)中。这要求用于对象服务器的文件系统需要支持文件有扩展属性。每个对象使用对象名称的哈希值和操作的时间戳组成的路径来存储。最后一次写操作总可以成功,并确保最新一次的对象版本将会被处理。删除也被视为文件的一个版本(一个以".ts"结尾的0字节文件,ts表示墓碑)。这确保了被删除的文件被正确地复制并且不会因为遭遇故障场景导致早些的版本神奇再现。

    Partition代表需存储数据的一个集合,包含多个Account数据库、Container数据库和相应的对象数据。关于Partition的概念很简单,它就是存放在磁盘中的一个目录,有自己的哈希表,关联着属于该Partition的Account数据库、Container数据库和相应的对象数据。数据副本的复制和对象数据的上传下载都是基于Partition进行的。

    Replicator会持续检查每个Partition,保证存放在Swift对象存储集群中三份数据副本的一致性,其中新数据的同步优先级较高。Replicator通过检查哈希表确认是否需要进行数据重同步。每个Partition都有一张哈希表,包含一个含有哈希表的目录。在集群中某个存储节点宕机后,包含同样数据副本的存储节点会进行检查和发出通知,并将数据复制到其他存储节点上。

3、文件系统存储

    文件系统存储是一个远端的、可以被挂载的文件系统。它是共享的,通过挂载到虚拟机实例上,可以供多个租户使用。文件系统存储可以在同一时间被多个用户同时挂载和访问。可以进行一系列操作,比如:创建指定容量大小的文件和文件系统协议、创建的文件可以分布在一个或多个服务器、指定访问规则和安全协议、支持快照、通过快照恢复一个文件系统、查看使用率等。OpenStack项目中,文件系统存储的程序代号是manila,支持多种后端存储驱动,通过多种存储协议进行共享。