分布式存储系统设计的若干问题(一)

本文要讨论的分布式存储系统是指狭义存储系统,即提供块存储,文件存储和对象存储的分布式系统。进一步对分布式的限定,我们这里讨论的是部署在同一个机房内的,由商用服务器构成的分布式存储系统。跨机房,跨地域的分布式系统暂不讨论。作为第一篇,我们先罗列定义问题,并说明这些问题对整个系统的意义。每个问题都有不同的答案并各有优缺点,本篇并不讨论具体的优缺点以及该如何进行选择。

问题1: 集中式元数据管理vs分布式元数据

元数据有很多种,从层级或者影响范围看包括 1) 集群的构成,即集群每个节点的基本信息 2) Volume或者File的存放位置 3) 物理空间的使用情况 4) 副本间的主次,健康信息 5)数据的版本等的,不同的系统定义的元数据会各不相同。

集中式元数据管理的典型例子就是HDFS的NameServer,所有数据在集群中的分布信息集中在NameServer上管理,Client需要访问数据时必须先向NameServer查询数据位置。
分布式的元数据管理的典型例子就是Ceph。当Client想要访问数据时,通过CRUSH算法计算得到数据的位置,而不需要向某个管理节点查询。
注意 这里说的元数据单指数据分布元数据,即当client访问某个数据时如何知道数据在哪里。不包括集群本身的元数据(集群由几个节点构成,每个节点的IP地址,NameServer的IP, MetaServer的IP等)。集群本身的构成因为相对不怎么变化且量比较小,都是集中管理(带有高可用的逻辑集中)。

问题2:一致性或者说CAP的选择

CAP原理是分布式系统的一个基本原理,下面是引用自百度的解释:

CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

事实上对于不同的系统,各种选择都是有的,下面是各种数据库系统的选择1
分布式存储系统设计的若干问题(一)_第1张图片

对于一个分布式系统,网络故障是不可避免的(后面还要专门讲故障处理问题,一个可靠的系统必须能容忍故障),所以分布式系统就只有CP, AP两个选择。从上面的图也能看到,只有传统的RDBMS可以选择CA。
CAP原理的严格证明很复杂,但有个简单易懂的说明。假设系统由*{A,B,C}三个部分组成,当发生了网络分裂,导致系统成为{A,B}{C}*两部分的时候:

  • 如果选择Availability , 即两部分都继续对外提供服务,那么因为网络割裂,就无法保证两部分的数据一致。
  • 如果选择Consistency, 就必须放弃一部分对外的服务(比如C停止对外服务),这样整个系统只提供单一的数据出口,在外面看来数据仍然是一致的。

当具体到分布式存储系统时,我们往往管选择CP的系统称为强一致, 选择AP的系统称为弱一致
一般来说,弱一致系统有更好的性能,实现的难点在于当系统从故障状态恢复时如何处理不一致的数据。典型的AP系统如DyanmoDB使用了一个叫做向量时钟(vector clock)2的方法来达到最终一致性。
弱一致性的系统一帮用于非核心业务,比如购物车,里面东西少一个多一个并不会造成太坏的影响。对于核心业务,都会要求强一致性。
强一致性的从原理上其实更好实现,只要能做到R+W>N, (R 表示读的副本数量,W表示写的副本数量,N表示总的副本数量),就可以做到强一致。然而实际情况总会复杂一些,特别是结合故障处理后。

问题3: 前端接口

前端接口是指Client端使用什么方法访问存储系统。比如一个硬盘,可以是SAS接口也可以是IDE接口,操作系统里就要用不同的驱动来访问这个硬盘。对于一个网络存储系统也是这个原理,操作系统要有相应的访问方法。

对于网络存储系统,Client端接口大体可以分为标准接口和非标准接口。所谓的标准接口就是某个访问方式或者驱动已经内置到了OS里面,或者更进一步,这个驱动已经非常成熟,广为接受,你不需要要求用户装额外的软件就可以使用。非标准就是需要用户安装这个存储系统专有的Client软件、驱动才能使用。

能够被称为存储系统的标准接口其实是非常少的。块存储而言也就是iSCSI/SCSI,未来NVME over Fabric有望成为新的标准接口。文件存储也就是NFS, CIFS两种。
标准接口的好处当然是显而易见的,大大降低了用户使用的门槛。然而标准接口的缺陷也同样明显,这些标准接口都是集中存储时代设计出现的,对现在的分布式存储而言已经不太适合,而且都会带来很大的性能开销。所以现在的分布式存储基本都会提供一个高性能的私有接口,同时为了兼容性再提供一个性能稍差的标准接口。

除此之外,现在设计存储系统必须考虑到云平台和虚拟化环境的访问,也要为各种云平台准备Client接口。典型的就是qemu驱动、libvirt驱动、openstack驱动等,各自解决不同平面问题。

问题4: 本地存储空间管理

这里说的本地,意思是指每个存储节点对物理磁盘空间的管理。
之所以要对本地存储空间进行管理而不是把物理设备直接暴露给前端,因为作为一个现代的分布式存储系统,虚拟化是必须有的功能。所谓虚拟化,也就是给前端(client)提供的盘(一般称之为Volume)和后端的物理盘(一般称之为disk)没有一一对应的必然关系。在client看到的一个盘,也许在存储系统里面保存在一个物理盘上,更有可能的是分散保存在多个物理盘上,然而client不需要知道这些具体的细节。有了虚拟化就可以实现thin provision, snapshot, clone,等高级功能。
然而,client虽然可以不关心数据的具体存放位置,作为存储系统的实现,数据的具体存放却是非常重要的问题,这就是本地存储空间管理。
本地空间管理主要就是解决物理空间的分配、使用、回收问题。

这里有很多方法可以选,一个基本的也是很灵活的方法是使用一个本地文件系统,ext4, xfs, zfs等。有了本地文件系统,上层存储可以非常的灵活使用本地存储,无论是存放元数据还是用户数据都很方便。但是本地文件系统往往是一个非常复杂的系统,彻底理解掌握并非易事。
第二种方法是使用当前流行的K-V store,K-V的外部接口相对简单,但是相对简单的背后仍然是复杂的逻辑,更不要说很多K-V系统背后又使用了本地文件系统。对于存储系统,一般是一个大系统的基础,可靠性是重中之重,任何的未知因素都可能导致严重的问题。
第三种就是存储系统自己对物理磁盘进行空间管理。其实当实现了某种程度的空间管理后,就可以算是广义的文件系统了 ,因为提供了物理空间与逻辑空间的映射。我们这里说的自管是说存储系统只实现分布式存储必须的基本功能,和标准文件系统比大幅简化,以确保实现方案的可靠。


  1. https://www.w3resource.com/w3r_images/cap-theoram-image.png ↩︎

  2. https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf ↩︎

你可能感兴趣的:(分布式,存储技术,分布式,大数据,分布式存储)