设计一个记忆
2003年,Google发表论文GFS,透露解决了索引地球的海量互联网数据的存储问题。2006年,亚马逊推出划时代的AWS云计算服务EC2和S3,开启了改变世界IT格局的云计算时代。谷歌,微软,阿里云等等。跟着走。
上面提到的A Bite os S3 Arch如何构建一个分布式存储系统来支持大规模S3对象存储。云计算还有另外两个重要的基础存储基础架构组件,EBS(弹性块存储)和EFS(弹性文件服务),分别对应传统IT基础架构中的本地磁盘和文件存储服务。
云计算很重要的一点就是超售和灵活性,所以支持EBS和EFS方案的底层基础存储层的支持不太可能是本地本地化方案,必须是分布式的存储资源管理和分配系统。
然而,与S3服务相比,EBS底层的分布式存储系统提供的IO模型实际上有很大不同。S3的基本外部接口函数是PUT/GET/DELETE,它对底层分布式文件系统的要求是Append。EBS和EFS需要支持重写用户的随机地址空间,那么如何设计底层存储系统来支持这两类服务呢?
对于业务架构这一块,目前各大互联网公司基本都是不开源的,基础架构也不是或者很少正面。一方面可能会被视为商业秘密,另一方面可能会从安全、舆论等方面考虑。
当然可以参考一些互联网公司的开源系统和存储系统的论文,比如ceph、Lustre、HDFS、GlusterFS、FastDFS、Window Azure Storage、GFS等等。这些都自称是分布式文件系统,但是在具体场景和文件的定义上有很多不同。以下几个方面差别较大。
EBS底层的分布式存储系统至少要保证以下几点。
EBS底层分布式存储系统需要提供上述重要特性,还有一些重要的核心需求。
那么如何在EBS底层设计和构建一个分布式存储系统来满足业务的需求,也就是如何设计一个分布式存储系统来为上层业务提供随机IO能力。这里有一些可能的方法来建立它。
对于EBS服务来说,抽象来说,它需要底层分布式文件系统能够提供可以随机读写的文件的能力。最直接的方式,可以如下图逻辑映射。1TB Vdisk /dev/sad对应底层分布式文件系统为/foo/sda的文件。1TB地址空间中的Chunk按需分配,分配的基本单位一般是固定的,如下图,4MB。
Qemu等等。提供了用于停靠块设备驱动程序的API。只要实现API来对接分布式文件系统中相应的客户端,块设备就可以向上输出。
网易从0到1实现了这种构造方法。CURVE现在是开源的(百度类似于这个方案),底层抽象为典型的分布式文件系统,向服务输出具有随机读写能力的文件,以支持上层块设备的EBS类服务。架构基本类似于经典分布式文件系统的鼻祖GFS,如下图所示。
基础设施
数据表面核心
底层ChunkServer基于Raft状态机实现副本一致性。有关更多信息,请参见Raft对等复制状态机。所有上层用户的写入都依靠一致性协议来保证多个副本的一致性,每个用户的块都被分配给这些复制组。
如上图所示
这种架构方案优点是:
该方案的缺点:
上面的构造模式1是一个0到1的架构设计和实现。第二种构造方法主要是和圈内的童鞋沟通,细节无法研究,但从整体结构层面解释分析没有大问题。
其基本架构类似于Window Azure Storage的架构。Stream层构建在底层,Partition层构建在Stream层的基础上(类似GFS),EBS方案可以构建在Partition层的基础上(类似BigTable)。
如何支持基于这种架构的服务,需要从另一个角度思考如何解决这个问题。回到问题的出发点,EBS随机地址空间读写方案的核心是什么?
简单地说,块设备为每个地址空间(例如,4KB)提供原子读写(PUT/GET)。换句话说,如果为每个EBS实例的每个4KB内容定义了一个全局可编码的惟一键,那么它的内容就是一个4KB的固定大小值。那么底层的分布式存储系统就是一个专用的分布式键值系统。
施工方法2基本遵循这个思路。
作为上述基本逻辑视图的一个示例,底层物理层的结构如下图所示。
StreamLayer:类似于GFS/HDFS层次结构,每个流类似于一个文件,流只支持append。Stream由盘区组成(类似HDFS/GFS的chunk),盘区使用固定复制组的方案实现多副本/EC(参考微软PacificA协议)。范围支持可变长度。当区段不可用时,seal/new会创建一个新区段,并继续提供写入,以确保写入的高可用性。
分区服务器:提供一个表(根据字典
序列拆分)kv存储服务(添加/删除/更改/检查)。它通过WAL实现了数据的快速及时写入,保证了数据的持久性;然后写入MemStore(SkipList跳表实现)。当MemStore达到固定大小时,比如128MB,Dump就变成SSTable(排序字符串表),块缓存负责读取和缓存SStable热点数据。一个分区服务器负责多个分区。
更具体的架构参考请参考纸质的书籍和资料或者Window Azure Storage的BigTable开源实现,这里就不展开了。
在实践层面上,上EFS实例有相当多的映射关系:
一般来说,为了实现EFS的快照和克隆功能,一个EFS实例一般选择一个表。如果只有一个WAL,写入的吞吐量很容易受到影响。在上层可以通过一些间接的业务逻辑手段,将多个相邻的地址空间切换到不同的区域,使得上层IO可以映射到更多的区域,利用多个WAL写能力提高带宽。例如,地址空间按照1MB的模数分为四个独立的连续字典序区域。
这种架构方案的优点:
抗脆弱:我觉得这是这个方案最大的优点,也是相对于第一个方案的绝对杀手锏。实际上很多分布式存储系统并没有从基层很好的考虑这个问题,或者意识到这个方案的巨大优势。也就是说,从读取层面来看,基本上认识到印章数据的任何副本都是可读的。写数据的话,写仅限于还没封的区块,也就是三个磁盘,万一失败可以随时转移。这两点使得上层一个表的数据分散到下层那么多磁盘上。但从爆炸半径来说,基本可以算是本地盘方案的爆炸半径,甚至在故障过载的情况下,也能实现快速转移。从这个角度来看,这基本上为分布式存储方案彻底干掉本地存储方案打下了极其坚实的基础。
这种施工方案的缺点:
方案3是类似于方案2的变体。核心区别在于构造方案2的全局排序和垃圾收集依赖于后期的比较。然而,构造方法3倾向于尽可能地将块分类到位。
它的基本原理是通过WAL写来保证数据的持久性,然后在内存中使用。在后台,写入习惯于定期随机读写文件(没错,底层不仅需要实现AppendFile,还需要实现弱一致的随机读写文件RandomFile,多本书的数据一致性由客户端负责,这就引入了一个缺点,所以很难对随机读写文件做EC)。wal使用seal-new保证写入可用性,读取使用合并更新数据(WAL)基线数据(随机读写文件数据)读取数据。在内存中建立整个WAL内容的索引,最新的数据将直接从WAL中的WAL中读取,否则从随机读写文件中读取。基本读写流程图如下。
写:照常写WAL,然后更新内存索引,将最新数据的使用指向WAL。但最终转储其实并不是以sstable的方式,而是直接在后台异步转储到RandomFile对应的随机地址空间。
PS 1: WAL也类似于段模式,定期做检查点(RandomFile),所有WAL段的索引都会建在内存中。WAL采用Seal/New模式确保可用性。
PS2: RandomFile是一个随机读写文件。为了保证WAL长度的收敛,后台线程会将WAL数据写入RandomFile。RandomFile无法使用Seal-New的可用性,但它是在后台编写的。因此,如果发现副本失败,后台转储机制将被阻塞(这种方案会导致后台写入在坏盘恢复场景中长时间停滞)。
读取:读取会先通过Memtable找出最新的数据是否在WAL中,如果不存在则读取RandomFile。对于RandomFile没有达到一致性状态的数据,将从WAL中读取。(PS:由于从WAL(AppendFile)到RandomFile的写入都是三个副本,而且总是卡死,所以RandomFile的恢复可以用非常健壮的方式完成,可以直接选择复制组中的任意一个副本作为复制的数据源。)
这个方案在一定程度上是可以解决的。阅读放大,空间利用等问题。不过在克隆、快照等方面会稍微差一点。,而且随机读写文件很难做EC(EC重写比较麻烦)。
如上所述,简要构造了三种构造方法,并说明了它们的优缺点。没有绝对的孰优孰劣。在实践过程中,要结合实际业务特点和所面临的技术条件进行选择,这样才能快速跟上业务发展,对方案进行中长期评估并及时调整。
形而上学地分析问题的本质是非常重要的。只有这样,才能集中精力解决现实问题,把好钢用在刀刃上。
简单来说,块设备为每个地址空间(比如4KB)提供原子读写(PUT/GET)。另一方面,如果为每个EBS实例的每个4KB内容定义了一个全局可编码的惟一键,那么它的内容就是一个4KB的固定大小值。那么底层的分布式存储系统就是一个专用的分布式键值系统。
以上不同的方案,逻辑上向上抽象,都可以认为是为服务提供KV存储。最本质的区别可以认为是分类发生的时间。总体来说,构造方案1是立即全局排序。构造方案2采用局部有序方案。架构方案3使用架构方案1和方案2之间的折衷。
另一个重要的区别是,从堆芯可靠性的角度来看,建设方案1采用多数方案(如Raft)处理分布式封顶问题。构造方案2和3采用PrimayBackup Master(多数)Append仅处理CAP问题的特性。
相关问答:EBS在PVC产品中的添加效果如何?急求解答!!!由于ebs分子带有极性酰胺基团,与pvc树脂有一定的相容性。ebs可以在加工过程中插入pvc树脂中,减少树脂分子间的摩擦,防止糊料达到防粘效果。但一般来说,ebs与pvc树脂的相容性有限,它可以从树脂内部拉到表面,主要作为外部润滑剂,可以避免过大的剪切应力,降低剪切热,减少材料与加工设备的摩擦,防止材料粘在设备上,从而提高产品的尺寸精度,提高产品的表面光泽度。