大规模分布式存储系统原理解析与架构实战

分布式存储基础知识
后几张是讲一些具体产品的内容,对于每一个产品,都需要确实的使用和经验,以后需要的时候再研究不迟,技术永远在使用中进步更大。
以前对存储尤其是分布式存储的整体知识体系不是太清楚,只是片段式的知道一些理论,通过此书的学习,对分布式存储的原理将豁然开朗,不管是理论的还是后面几章讲述的具体产品,都能做到知其然知其所以然。另外,书中对Paxos协议也进行了深入介绍,理解此协议对时下流行的去中心化将有“夫子言之,于我心有戚戚焉”的感觉。
当然,如果想完全彻底了解更底层一些的存储知识,建议阅读冬瓜头的《大话存储2》(此书过后,存储从此无战事矣)。
全书思维导图:
大规模分布式存储系统原理解析与架构实战_第1张图片
 
Paxos协议过程:
大规模分布式存储系统原理解析与架构实战_第2张图片
 
1. 单机存储引擎就是哈希表、B树等数据结构在机械磁盘、SSD等持久化介质上的实 现。单机存储系统是单机存储引擎的一种封装,对外提供文件、键值、表格或者关系模
2.IO南北桥架构:北桥芯片通过前端总线(Front Side Bus,FSB)与CPU相连,内存模块以及PCI-E设备(如高端的SSD设备Fusion-IO)挂接在北桥上。北桥与南桥之间通过DMI连接,DMI的带宽为1GB/s,网卡(包括千兆以及万兆网卡),硬盘以及中低端固态盘(如Intel 320系列 SSD)挂接在南桥上
3.常用硬件性能参数:
大规模分布式存储系统原理解析与架构实战_第3张图片
4.SMP(Symmetric Multi-Processing)结构
大规模分布式存储系统原理解析与架构实战_第4张图片
5.存储引擎是存储系统的发动机,直接决定了存储系统能够提供的性能和功能.
6. 哈希存储引擎是哈希表的持久化实现,支持增、删、改,以及随机读取操作,但不支持 顺序扫描,对应的存储系统为键值(Key-Value)存储系统
7.B树(B-Tree)存储引擎是 B树的持久化实现,不仅支持单条记录的增、删、读、改操作,还支持顺序扫描,对 应的存储系统是关系数据库。当然键值系统也可以通过B树存储引擎实现
8.LSM树 (Log-Structured Merge Tree)存储引擎和B树存储引擎一样,支持增、删、改、随机读 取以及顺序扫描。它通过批量转储技术规避磁盘随机写入问题,广泛应用于互联网的后 台存储系统。
9.   LSM树(Log Structured Merge Tree)的思想非常朴素 就是将对数据的修改增量 保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘,读取时需要合并 磁盘中的历史数据和内存中最近的修改操作。LSM树的优势在于有效地规避了磁盘随 机写入问题,但读取时可能需要访问较多的磁盘文件
10. POSIX(Portable Operating System Interface)是应用程序访问文件系统的API标准, 它定义了文件系统存储接口及操作集。 POSIX标准适合单机 文件系统,在分布式文件系统中,出于性能考虑,一般不会完全遵守这个标准。
11.NFS (Network File System)文件系统允许客户端缓存文件数据,多个客户端并发修改同一 个文件时可能出现不一致的情况。
12. 关系数据库采用B树存储引擎,更新操作性能不如LSM树这样的存储引 擎。另外,如果只有基于主键的增、删、查、改操作,关系数据库的性能也不如 专门定制的Key-Value存储系统。
13. 压缩的本质就是找数据的重复或者规律,用尽量少的字节表示。 Huffman编码是一种基于编码的优化技术,通过统计字符出现的频率来计算最优前 缀编码。LZ系列算法一般有一个窗口的概念,在窗口内部找重复并维护数据字典。常 用的压缩算法包括Gzip、LZW、LZO
14. 分布式系统中有两个重要的协议,包括Paxos选举协议以及两阶段提交协议。 Paxos协议用于多个节点之间达成一致,往往用于实现总控节点选举。两阶段提交协议 用于保证跨多个节点操作的原子性,这些操作要么全部成功,要么全部失败。
15.分布-->复制 -->一致性 -->容错。 副本是分布式存储系统容错技术的唯一手段。由于多个副本的存 在,如何保证副本之间的一致性是整个分布式系统的理论核心。
16.常见分布式故障:
大规模分布式存储系统原理解析与架构实战_第5张图片
大规模分布式存储系统原理解析与架构实战_第6张图片
17.分布式系统中的单层结构和双层结构:
大规模分布式存储系统原理解析与架构实战_第7张图片
18. 主流的分布式存储系统大多带有 总控节点,且能够支持成千上万台的集群规模。
19.尽量减少对总控节点的压力,一般分布式文件系统相比其他分布式系统需要存一些目录信息,可能支持上万集群机器的时候存在瓶颈,可以通过两层结构的方式,总控节点存root信息,第二层节点存meta信息
20. 将存储节点分为若干组,每个组内的节点服务完全相同的数据,其中有一个节点为 主节点,其他节点为备节点。由于同一个组内的节点服务相同的数据,这样的系统称为 同构系统。 同构系统扩容时需要从单个节点拷贝大量数据,不适合自动化
21. 异构系统将数据划分为很多大小接近的分片,每个分片的多个副本可以分布 到集群中的任何一个存储节点。如果某个节点发生故障,原有的服务将由整个集群而不 是某几个固定的存储节点来恢复
22.分布式重要的两个协议: 两阶段提交协议用于保证跨多个节点操作的原子 性,也就是说,跨多个节点的操作要么在所有节点上全部执行成功,要么全部失败。 Paxos协议用于确保多个节点对某个投票(例如哪个节点为主节点)达成一致。 Paxos协议有两种用法:一种用法是用它来实现全局的锁服务或者命名和配置服务, 例如Google Chubby以及Apache Zookeeper。另外一种用法是用它来将用户数据复制到 多个数据中心,例如Google Megastore以及Google Spanner
23. 为了实现高可用性,主节点往往将数据以操作日志的形式同步到备节点。如果主节 点发生故障,备节点会提议自己成为主节点
24. Paxos协议执行步骤如下:
1)批准(accept):Proposer发送accept消息要求所有其他节点(acceptor,接受 者)接受某个提议值,acceptor可以接受或者拒绝。
2)确认(acknowledge): 如果超过一半的acceptor接受,意味着提议值已经生效, proposer发送acknowledge消息通知所有的acceptor提议生效。
当出现网络或者其他异常时,系统中可能存在多个proposer,他们各自发起不同的 提议。这里的提议可以是一个修改操作,也可以是提议自己成为主节点。如果proposer 第一次发起的accept请求没有被acceptor中的多数派批准(例如与其他proposer的提 议冲突),那么,需要完整地执行一轮Paxos协议。过程如下:
1)准备(prepare):Proposer首先选择一个提议序号n给其他的acceptor节点发 送prepare消息。Acceptor收到prepare消息后,如果提议的序号大于他已经回复的所有 prepare消息,则acceptor将自己上次接受的提议回复给proposer,并承诺不再回复小于 n的提议。
2)批准(accept):Proposer收到了acceptor中的多数派对prepare的回复后,就 进入批准阶段。如果在之前的prepare阶段acceptor回复了上次接受的提议,那么, proposer选择其中序号最大的提议值发给acceptor批准;否则,proposer生成一个新的 提议值发给acceptor批准。Acceptor在不违背他之前在prepare阶段的承诺的前提下, 接受这个请求。
3)确认(acknowledge):如果超过一半的acceptor接受,提议值生效。Proposer 发送acknowledge消息通知所有的acceptor提议生效。 Paxos协议需要考虑两个问题:正确性,即只有一个提议值会生效;可终止性,即 最后总会有一个提议值生效。Paxos协议中要求每个生效的提议被acceptor中的多数派 接受,并且每个acceptor不会接受两个不同的提议,因此可以保证正确性。Paxos协议 并不能够严格保证可终止性。但是,从Paxos协议的执行过程可以看出,只要超过一 个acceptor接受了提议,proposer很快就会发现,并重新提议其中序号最大的提议值。 因此,随着协议不断运行,它会往“某个提议值被多数派接受并生效”这一最终目标 靠拢。


分布式存储的类型归类


块存储和文件存储是我们比较熟悉的两种主流的存储类型,而对象存储(Object-based Storage)是一种新的网络存储架构,基于对象存储技术的设备就是对象存储设备(Object-based Storage Device)简称OSD。

首先,我们介绍这两种传统的存储类型。通常来讲,所有磁盘阵列都是基于Block块的模式,而所有的NAS产品都是文件级存储。

首先我们先来了解一下,什么叫做块级?什么叫文件级?

1.块级概念:

块级是指以扇区为基础,一个或我连续的扇区组成一个块,也叫物理块。它是在文件系统与块设备(例如:磁盘驱动器)之间。

2.文件级概念:

文件级是指文件系统,单个文件可能由于一个或多个逻辑块组成,且逻辑块之间是不连续分布。逻辑块大于或等于物理块整数倍,

3.物理块与文件系统之间的关系图:

映射关系:扇区→物理块→逻辑块→文件系统

文件级备份:

文件级备份是指在指定某些文件进行备份时,首先会查找每个文件逻辑块,其次物理块,由于逻辑块是分散在物理块上,而物理块也是分散在不同扇区上。需要一层一 层往下查找,最后才完成整个文件复制。文件级备份时比较费时间,效率不高,实时性不强,备份时间长,且增量备份时,单文件某一小部份修改,不会只备份修改 部份,而整个文件都备份。

块级备份:

块级备份是指物理块复制,效率高,实时性强,备份时间短,且增量备份时,只备份修改过的物理块。

目前文件级备份工具:

Symantec NBU/BE 备份软件、Commvault、CA、Networker

目前块级备份工具:

飞康CDP、Recoverpoint、杭州信核CDP、Novell CDP

备份时间点保留周期:

传统备份软件(文件级备份),可以保留备份时间点多,恢复颗粒度大

CDP备份(块级备份),可以保留备份时间点少,恢复颗粒度小

【块存储】

典型设备:磁盘阵列,硬盘,虚拟硬盘

【文件存储】

典型设备:FTP、NFS服务器,SamBa

【对象存储】

典型设备:内置大容量硬盘的分布式服务器

分布式存储的应用场景相对于其存储接口,现在流行分为三种:

对象存储:也就是通常意义的键值存储,其接口就是简单的GET、PUT、DEL和其他扩展,如七牛、又拍、Swift、S3

块存储:

这种接口通常以QEMU Driver或者Kernel Module的方式存在,这种接口需要实现Linux的Block Device的接口或者QEMU提供的Block Driver接口,如Sheepdog,AWS的EBS,青云的云硬盘和阿里云的盘古系统,还有Ceph的RBD(RBD是Ceph面向块存储的接口)

文件存储:

通常意义是支持POSIX接口,它跟传统的文件系统如Ext4是一个类型的,但区别在于分布式存储提供了并行化的能力,如Ceph的CephFS(CephFS是Ceph面向文件存储的接口),但是有时候又会把GFS,HDFS这种非POSIX接口的类文件存储接口归入此类。

1、块存储

以下列出的两种存储方式都是块存储类型:

1) DAS(Direct AttachSTorage):是直接连接于主机服务器的一种储存方式,每一台主机服务器有独立的储存设备,每台主机服务器的储存设备无法互通,需要跨主机存取资料时,必须经过相对复杂的设定,若主机服务器分属不同的操作系统,要存取彼此的资料,更是复杂,有些系统甚至不能存取。通常用在单一网络环境下且数据交换量不大,性能要求不高的环境下,可以说是一种应用较为早的技术实现。

2)SAN(Storage Area Network):是一种用高速(光纤)网络联接专业主机服务器的一种储存方式,此系统会位于主机群的后端,它使用高速I/O 联结方式, 如 SCSI, ESCON及 Fibre- Channels。一般而言,SAN应用在对网络速度要求高、对数据的可靠性和安全性要求高、对数据共享的性能要求高的应用环境中,特点是代价高,性能好。例如电信、银行的大数据量关键应用。它采用SCSI 块I/O的命令集,通过在磁盘或FC(Fiber Channel)级的数据访问提供高性能的随机I/O和数据吞吐率,它具有高带宽、低延迟的优势,在高性能计算中占有一席之地,但是由于SAN系统的价格较高,且可扩展性较差,已不能满足成千上万个CPU规模的系统。

2、文件存储

通常,NAS产品都是文件级存储。NAS(Network Attached Storage):是一套网络储存设备,通常是直接连在网络上并提供资料存取服务,一套 NAS 储存设备就如同一个提供数据文件服务的系统,特点是性价比高。例如教育、政府、企业等数据存储应用。

它采用NFS或CIFS命令集访问数据,以文件为传输协议,通过TCP/IP实现网络化存储,可扩展性好、价格便宜、用户易管理,如目前在集群计算中应用较多的NFS文件系统,但由于NAS的协议开销高、带宽低、延迟大,不利于在高性能集群中应用。

下面,我们对DAS、NAS、SAN三种技术进行比较和分析:

大规模分布式存储系统原理解析与架构实战_第8张图片

针对Linux集群对存储系统高性能和数据共享的需求,国际上已开始研究全新的存储架构和新型文件系统,希望能有效结合SAN和NAS系统的优点,支持直接访问磁盘以提高性能,通过共享的文件和元数据以简化管理,目前对象存储系统已成为Linux集群系统高性能存储系统的研究热点,如Panasas公司的Object Base Storage Cluster System系统和Cluster File Systems公司的Lustre等。下面将详细介绍对象存储系统。

3、对象存储

总体上来讲,对象存储同兼具SAN高速直接访问磁盘特点及NAS的分布式共享特点。

核心是将数据通路(数据读或写)和控制通路(元数据)分离,并且基于对象存储设备(Object-based Storage Device,OSD)构建存储系统,每个对象存储设备具有一定的智能,能够自动管理其上的数据分布。

对象存储结构组成部分(对象、对象存储设备、元数据服务器、对象存储系统的客户端):

3.1、对象

对象是系统中数据存储的基本单位,一个对象实际上就是文件的数据和一组属性信息(Meta Data)的组合,这些属性信息可以定义基于文件的RAID参数、数据分布和服务质量等,而传统的存储系统中用文件或块作为基本的存储单位,在块存储系统中还需要始终追踪系统中每个块的属性,对象通过与存储系统通信维护自己的属性。在存储设备中,所有对象都有一个对象标识,通过对象标识OSD命令访问该对象。通常有多种类型的对象,存储设备上的根对象标识存储设备和该设备的各种属性,组对象是存储设备上共享资源管理策略的对象集合等。

3.2、对象存储设备

对象存储设备具有一定的智能,它有自己的CPU、内存、网络和磁盘系统,OSD同块设备的不同不在于存储介质,而在于两者提供的访问接口。OSD的主要功能包括数据存储和安全访问。目前国际上通常采用刀片式结构实现对象存储设备。OSD提供三个主要功能:

(1) 数据存储。OSD管理对象数据,并将它们放置在标准的磁盘系统上,OSD不提供块接口访问方式,Client请求数据时用对象ID、偏移进行数据读写。

(2) 智能分布。OSD用其自身的CPU和内存优化数据分布,并支持数据的预取。由于OSD可以智能地支持对象的预取,从而可以优化磁盘的性能。

(3) 每个对象元数据的管理。OSD管理存储在其上对象的元数据,该元数据与传统的inode元数据相似,通常包括对象的数据块和对象的长度。而在传统的NAS系统中,这些元数据是由文件服务器维护的,对象存储架构将系统中主要的元数据管理工作由OSD来完成,降低了Client的开销。

3.3、元数据服务器(Metadata Server,MDS)

MDS控制Client与OSD对象的交互,主要提供以下几个功能:

(1) 对象存储访问。

MDS构造、管理描述每个文件分布的视图,允许Client直接访问对象。MDS为Client提供访问该文件所含对象的能力,OSD在接收到每个请求时将先验证该能力,然后才可以访问。

(2) 文件和目录访问管理。

MDS在存储系统上构建一个文件结构,包括限额控制、目录和文件的创建和删除、访问控制等。

(3) Client Cache一致性。

为了提高Client性能,在对象存储系统设计时通常支持Client方的Cache。由于引入Client方的Cache,带来了Cache一致性问题,MDS支持基于Client的文件Cache,当Cache的文件发生改变时,将通知Client刷新Cache,从而防止Cache不一致引发的问题。

3.4、对象存储系统的客户端Client

为了有效支持Client支持访问OSD上的对象,需要在计算节点实现对象存储系统的Client,通常提供POSIX文件系统接口,允许应用程序像执行标准的文件系统操作一样。

4、GlusterFS 和对象存储

GlusterFS是目前做得最好的分布式存储系统系统之一,而且已经开始商业化运行。但是,目前GlusterFS3.2.5版本还不支持对象存储。如果要实现海量存储,那么GlusterFS需要用对象存储。值得高兴的是,GlusterFS最近宣布要支持对象存储。它使用openstack的对象存储系统swift的上层PUT、GET等接口,支持对象存储。

http://www.openstack.org/blog/2011/07/announcing-the-gluster-connector-for-openstack/

——详细介绍

【块存储】

典型设备:磁盘阵列,硬盘

块存储主要是将裸磁盘空间整个映射给主机使用的,就是说例如磁盘阵列里面有5块硬盘(为方便说明,假设每个硬盘1G),然后可以通过划逻辑盘、做Raid、或者LVM(逻辑卷)等种种方式逻辑划分出N个逻辑的硬盘。(假设划分完的逻辑盘也是5个,每个也是1G,但是这5个1G的逻辑盘已经于原来的5个物理硬盘意义完全不同了。例如第一个逻辑硬盘A里面,可能第一个200M是来自物理硬盘1,第二个200M是来自物理硬盘2,所以逻辑硬盘A是由多个物理硬盘逻辑虚构出来的硬盘。)

接着块存储会采用映射的方式将这几个逻辑盘映射给主机,主机上面的操作系统会识别到有5块硬盘,但是操作系统是区分不出到底是逻辑还是物理的,它一概就认为只是5块裸的物理硬盘而已,跟直接拿一块物理硬盘挂载到操作系统没有区别的,至少操作系统感知上没有区别。

此种方式下,操作系统还需要对挂载的裸硬盘进行分区、格式化后,才能使用,与平常主机内置硬盘的方式完全无异。

优点:

1、 这种方式的好处当然是因为通过了Raid与LVM等手段,对数据提供了保护。

2、 另外也可以将多块廉价的硬盘组合起来,成为一个大容量的逻辑盘对外提供服务,提高了容量。

3、 写入数据的时候,由于是多块磁盘组合出来的逻辑盘,所以几块磁盘可以并行写入的,提升了读写效率。

4、 很多时候块存储采用SAN架构组网,传输速率以及封装协议的原因,使得传输速度与读写速率得到提升。

缺点:

1、采用SAN架构组网时,需要额外为主机购买光纤通道卡,还要买光纤交换机,造价成本高。

2、主机之间的数据无法共享,在服务器不做集群的情况下,块存储裸盘映射给主机,再格式化使用后,对于主机来说相当于本地盘,那么主机A的本地盘根本不能给主机B去使用,无法共享数据。

3、不利于不同操作系统主机间的数据共享:另外一个原因是因为操作系统使用不同的文件系统,格式化完之后,不同文件系统间的数据是共享不了的。例如一台装了WIN7/XP,文件系统是FAT32/NTFS,而Linux是EXT4,EXT4是无法识别NTFS的文件系统的。就像一只NTFS格式的U盘,插进Linux的笔记本,根本无法识别出来。所以不利于文件共享。

【文件存储】

典型设备:FTP、NFS服务器

为了克服上述文件无法共享的问题,所以有了文件存储。

文件存储也有软硬一体化的设备,但是其实普通拿一台服务器/笔记本,只要装上合适的操作系统与软件,就可以架设FTP与NFS服务了,架上该类服务之后的服务器,就是文件存储的一种了。

主机A可以直接对文件存储进行文件的上传下载,与块存储不同,主机A是不需要再对文件存储进行格式化的,因为文件管理功能已经由文件存储自己搞定了。

优点:

1、造价交低:随便一台机器就可以了,另外普通以太网就可以,根本不需要专用的SAN网络,所以造价低。

2、方便文件共享:例如主机A(WIN7,NTFS文件系统),主机B(Linux,EXT4文件系统),想互拷一部电影,本来不行。加了个主机C(NFS服务器),然后可以先A拷到C,再C拷到B就OK了。(例子比较肤浅,请见谅……)

缺点:

读写速率低,传输速率慢:以太网,上传下载速度较慢,另外所有读写都要1台服务器里面的硬盘来承担,相比起磁盘阵列动不动就几十上百块硬盘同时读写,速率慢了许多。

【对象存储】

典型设备:内置大容量硬盘的分布式服务器

对象存储最常用的方案,就是多台服务器内置大容量硬盘,再装上对象存储软件,然后再额外搞几台服务作为管理节点,安装上对象存储管理软件。管理节点可以管理其他服务器对外提供读写访问功能。

之所以出现了对象存储这种东西,是为了克服块存储与文件存储各自的缺点,发扬它俩各自的优点。简单来说块存储读写快,不利于共享,文件存储读写慢,利于共享。能否弄一个读写快,利 于共享的出来呢。于是就有了对象存储。

首先,一个文件包含了了属性(术语叫metadata,元数据,例如该文件的大小、修改时间、存储路径等)以及内容(以下简称数据)。

以往像FAT32这种文件系统,是直接将一份文件的数据与metadata一起存储的,存储过程先将文件按照文件系统的最小块大小来打散(如4M的文件,假设文件系统要求一个块4K,那么就将文件打散成为1000个小块),再写进硬盘里面,过程中没有区分数据/metadata的。而每个块最后会告知你下一个要读取的块的地址,然后一直这样顺序地按图索骥,最后完成整份文件的所有块的读取。

这种情况下读写速率很慢,因为就算你有100个机械手臂在读写,但是由于你只有读取到第一个块,才能知道下一个块在哪里,其实相当于只能有1个机械手臂在实际工作。

而对象存储则将元数据独立了出来,控制节点叫元数据服务器(服务器+对象存储管理软件),里面主要负责存储对象的属性(主要是对象的数据被打散存放到了那几台分布式服务器中的信息),而其他负责存储数据的分布式服务器叫做OSD,主要负责存储文件的数据部分。当用户访问对象,会先访问元数据服务器,元数据服务器只负责反馈对象存储在哪些OSD,假设反馈文件A存储在B、C、D三台OSD,那么用户就会再次直接访问3台OSD服务器去读取数据。

这时候由于是3台OSD同时对外传输数据,所以传输的速度就加快了。当OSD服务器数量越多,这种读写速度的提升就越大,通过此种方式,实现了读写快的目的。

另一方面,对象存储软件是有专门的文件系统的,所以OSD对外又相当于文件服务器,那么就不存在文件共享方面的困难了,也解决了文件共享方面的问题。

所以对象存储的出现,很好地结合了块存储与文件存储的优点。

最后为什么对象存储兼具块存储与文件存储的好处,还要使用块存储或文件存储呢?

1、有一类应用是需要存储直接裸盘映射的,例如数据库。因为数据库需要存储裸盘映射给自己后,再根据自己的数据库文件系统来对裸盘进行格式化的,所以是不能够采用其他已经被格式化为某种文件系统的存储的。此类应用更适合使用块存储。

2、对象存储的成本比起普通的文件存储还是较高,需要购买专门的对象存储软件以及大容量硬盘。如果对数据量要求不是海量,只是为了做文件共享的时候,直接用文件存储的形式好了,性价比高。




分布式存储的服务构建


分布式存储的数据挖掘
大规模分布式存储系统原理解析与架构实战_第9张图片大规模分布式存储系统原理解析与架构实战_第10张图片

分布式存储系统的雪崩效应

在一段时间内数目较多的宕机事件有较大可能性诱发系统的大规模副本补全策略。目前的分布式存储系统的两个特点导致这个大规模副本补全策略容易让系统产生雪崩效应:

   a. 集群整体的free空间较小:通常整体<=30%, 局部机器小于<=20% 甚至10%

   b. 应用混布:不同的应用部署在同一台物理/虚拟机器上以最大化利用硬件资源

今年火起来的各种网盘、云盘类服务就是a的典型情况。在各大公司拼个人存储容量到1T的背后,其实也在拼运营成本、运维成本。现有的云存储大多只增不减、或者根据数据冷热程度做数据分级(类似Facebook的数据分级项目)。云存储总量大,但增量相对小,为了减少存储资源和带宽资源浪费,新创建的文件若原有的存储数据中已有相同的md5或者sha1签名则当做已有文件做内部链接,不再进行新文件的创建。但即使这样,整体的数据量还是很大。

目前云存储相关业务未有明显的收入来源,每年却有数万每台的服务器成本,为运营成本的考虑,后端分布式存储系统的空闲率很低。而瞬间的批量宕机会带来大量的副本修复,大量的副本修复很有可能继而打满原本就接近存储quota的其他存活机器,继而让该机器处于宕机或者只读状态。如此继续,整个集群可能雪崩,系统残废。

三 预防雪崩

本节主要讨论如何在系统内部的逻辑处理上防止系统整体雪崩的发生。预防的重要性大于事故之后的处理,预测集群状态、提前进行优化也成为预防雪崩的一个方向。

下面选取曾经发生过的几个实际场景与大家分享。

1. 跨机架副本选择算法和机器资源、用户逻辑隔离

现场还原:

某天运维同学发现某集群几十台机器瞬间失联,负责触发修复副本的主控节点开始进行疯狂的副本修复。大量用户开始反馈集群变慢,读写夯住。

现场应对:

优先解决——副本修复量过大造成的集群整体受影响。

a. 处理的工程师当机立断,gdb到进程更改修复副本的条件为副本<2,而非原本的3(replicas_num),让主控节点这个时候仅修复副本数小于2个的文件,即保证未丢失的文件有至少一个冗余副本,防止只有一个副本的数据因可能再次发生的挂机造成文件丢失。

b. 紧急解决这批机器失联问题,发现是交换机问题,a.b.c.d ip网段的c网段机器批量故障。催促网络组尽快修复。

c. 副本修复到>=2之后,Gdb更改检测副本不足周期,将几十秒的检测时间推迟到1天。等待网络组解决交换机问题。

d. 网络恢复,原有的机器重新加入集群。大量2副本文件重新变为3副本,部分3副本全丢失文件找回。

e. 恢复主控节点到正常参数设置状态,系统开始正常修复。

改进措施:

在改进措施前,先分析下这次事件暴露的系统不足:

1) Master参数不支持热修正,Gdb线上进程风险过大。

2) 一定数量但局域性的机器故障影响了整体集群(几十台相对一个大集群仍属于局域性故障)。如上所述,月千分之几的故障率总有机会让你的存储系统经历一次交换机故障带来的集群影响。

案例分析后的改进措施出炉:

1)  Master支持热修正功能排期提前,尽早支持核心参数的热修改。

热修改在上线后的效果可观,后续规避过数次线上问题。

2) 在选择数据副本存储宿主机器的pickup算法中加入跨交换机(机架位)策略,强制——或者尽量保证——副本选择时跨机架位。这种算法底下的副本,至少有1个副本与其他两个副本处于不同的交换机下(IP a.b.c.d的c段)。该措施同时作用于新的存储数据副本选择和副本缺失后的副本补全策略,能在副本宿主选择上保证系统不会因为交换机的宕机而出现数据丢失,进而避免一直处于副本补全队列/列表的大量的丢失副本节点加重主控节点负载。

3) 机器按region划分隔离功能提上日程;用户存储位置按照region进行逻辑划分功能提上日程;Pickup算法加入跨region提上日程。

a) 机器按照物理位置划分region、用户按照region进行逻辑存储位置划分,能让集群在局部故障的情况下仅影响被逻辑划分进使用这部分机器的用户。

这样一来,最坏情况无非是这个region不可用,导致拥有这个region读写权限的用户受影响。Pickup算法跨region的设计进一步保证被划分region的用户不会因为一个region不可用而出现数据丢失,因为其他副本存到其他region上了。于是,核心交换机故障导致一个region数百台机器的宕机也不会对集群造成范围过大的影响了。

b) 增加region可信度概念,将机器的稳定性因素加入到副本冗余算法中。

当集群规模达到一定量后,会出现机器稳定性不同的问题(一般来说,同一批上线的机器稳定性一致)。通过标记region的稳定性,能强制在选择数据副本的时候将至少一个副本至于稳定副本中,减少全部副本丢失的概率。

c) Region划分需要综合考虑用户操作响应时间SLA、物理机器稳定情况、地理位置等信息。

合理的region划分对提升系统稳定性、提升操作相应时间、预防系统崩溃都有益处。精巧的划分规则会带来整体的稳定性提升,但也增加了系统的复杂度。这块如何取舍,留给读者朋友深入思考了。

2. 让集群流控起来

流控方面有个通用且符合分布式存储系统特点的原则:任何操作都不应占用过多的处理时间。这里的“任何操作”包含了在系统出现流量激增、局部达到一定数量的机器宕机时进行的操作。只有平滑且成功的处理这些操作,才能保证系统不因为异常而出现整体受影响,甚至雪崩。

现场还原:

1) 场景1 某天运维同学发现,集群写操作在某段时间大增。通过观察某个存储节点,发现不仅是写、而且是随机写!某些产品线的整体吞吐下降了。

2) 场景2 某集群存储大户需要进行业务调整,原有的数据做变更,大量数据需要删除。

运维同学发现,a. 整个集群整体上处于疯狂gc垃圾回收阶段 b. 集群响应速度明显变慢,特别是涉及到meta元信息更新的操作。

3) 场景3 某天运维同学突然发现集群并发量激增,单一用户xyz进行了大量的并发操作,按照原有的用户调研,该用户不应该拥有如此规模的使用场景。

此类集群某些操作预期外的激增还有很多,不再累述。

现场应对:

1) 立刻电联相关用户,了解操作激增原因,不合理的激增需要立刻处理。

我们发现过如下不合理的激增:

a. 场景1类:通过Review代码发现,大量的操作进行了随机读写更改。建议用户将随机读写转换为读取后更改+写新文件+删除旧文件,转换随机读写为顺序读写。

b. 场景3类:某产品线在线上进行了性能测试。运维同学立刻通知该产品线停止了相关操作。所有公有集群再次发通过邮件强调,不可用于性能测试。如有需要,联系相关人员在独占集群进行性能场景测试。

2) 推动设计和实现集群各个环节的流控机制功能并上线。

改进措施:

1) 用户操作流控

a. 对用户操作进行流控限制

可通过系统内部设计实现,也可通过外部的网络限流等方式实现,对单用户做一定的流控限制,防止单个用户占用过多整个集群的资源。

b. 存储节点操作流控

可按照对集群的资源消耗高低分为High – Medium – Low三层,每层实现类似于抢token的设计,每层token数目在集群实践后调整为比较适合的值。这样能防止某类操作过多消耗集群负载。若某类操作过多消耗负载,其他操作类的请求有较大delay可能,继而引发timeout后的重试、小范围的崩溃,有一定几率蔓延到整个集群并产生整体崩溃。

c. 垃圾回收gc单独做流控处理。删除操作在分布式存储系统里面常用设计是:接收到用户删除操作时,标记删除内容的meta信息,直接回返,后续进行策略控制,限流的删除,防止大量的gc操作消耗过多单机存储节点的磁盘处理能力。具体的限流策略和token值设置需要根据集群特点进行实践并得出较优设置。

2) 流控黑名单

用户因为对线上做测试类的场景可以通过人为制度约束,但无法避免线上用户bug导致效果等同于线上测试规模的场景。这类的场景一般在短时间内操作数严重超过限流上限。

对此类场景可进行流控黑名单设置,当某用户短时间内(e.g. 1小时)严重超过设置的上限时,将该用户加入黑名单,暂时阻塞操作。外围的监控会通知运维组同学紧急处理。

3) 存储节点并发修复、创建副本流控

大量的数据副本修复操作或者副本创建操作如果不加以速度限制,将占用存储节点的带宽和CPU、内存等资源,影响正常的读写服务,出现大量的延迟。而大量的延迟可能引发重试,加重集群的繁忙程度。

同一个数据宿主进程需要限制并发副本修复、副本创建的个数,这样对入口带宽的占用不会过大,进程也不会因为过量进行这类操作而增加大量其他操作的延迟时间。这对于采用分发的副本复制协议的系统尤其重要。分发协议一般都有慢节点检查机制,副本流控不会进一步加重系统延迟而增大成为慢节点的可能。如果慢节点可能性增大,新创建的文件可能在创建时就因为慢节点检查机制而缺少副本,这会让集群状况更加恶化。

3. 提前预测、提前行动

1) 预测磁盘故障,容错单磁盘错误。

场景复现:

某厂商的SSD盘某批次存在问题,集群上线运行一段时间后,局部集中出现数量较多的坏盘,但并非所有的盘都损坏。当时并未有单磁盘容错机制,一块磁盘坏掉,整个机器就被置成不可用状态,这样导致拥有这批坏盘的机器都不可用,集群在一段时间内都处于副本修复状态,吞吐受到较大影响。

改进措施:

a) 对硬盘进行健康性预测,自动迁移大概率即将成为坏盘的数据副本

近年来,对磁盘健康状态进行提前预测的技术越来越成熟,技术上已可以预判磁盘健康程度并在磁盘拥有大概率坏掉前,自动迁移数据到其他磁盘,减少磁盘坏掉对系统稳定性的影响。

b) 对单硬盘错误进行容错处理

存储节点支持对坏盘的异常处理。单盘挂掉时,自动迁移/修复单盘的原有数据到其他盘,而不是进程整体宕掉,因为一旦整体宕掉,其他盘的数据也会被分布式存储系统当做缺失副本,存储资源紧张的集群经历一次这样的宕机事件会造成长时间的副本修复过程。在现有的分布式存储系统中, 也有类似淘宝TFS那样,每个磁盘启动一个进程进行管理,整机挂载多少个盘就启动多少个进程。

2) 根据现有存储分布,预测均衡性发展,提前进行负载均衡操作。

这类的策略设计越来越常见。由于分布式存储集群挂机后的修复策略使得集群某些机器总有几率成为热点机器,我们可以对此类的机器进行热点预测,提前迁移部分数据到相对负载低的机器。

负载均衡策略和副本选择策略一样,需要取舍复杂度和优化程度问题。复杂的均衡策略带来好的集群负载,但也因此引入高复杂度、高bug率问题。如何取舍,仍旧是个困扰分布式存储系统设计者的难题。

四 安全模式

安全模式是项目实践过程中产生的防分布式存储系统雪崩大杀器,因此我特别将其单独列为一节介绍。其基本思路是在一定时间内宕机数目超过预期上限则让集群进入安全模式,按照策略配置、情况严重程度,停止修复副本、停止读写,直到停止一切操作(一般策略)。

在没有机器region概念的系统中,安全模式可以起到很好的保护作用。我过去参与的一个项目经历的某次大规模宕机,由于没有安全模式,系统进行正常的处理副本修复,生生将原本健康的存储节点也打到残废,进而雪崩,整个集群都陷入疯狂副本修复状态。这种状态之后的集群修复过程会因为已发生的副本修复导致的元信息/实际数据的更改而变的困难重重。 该事件最后结局是数据从冷备数据中恢复了一份,丢失了冷备到故障发生时间的数据。

当然,安全模式并非完美无缺。“一段时间”、“上限”该如何设置、什么时候停副本修复、什么时候停读、什么时候停写、是自己恢复还是人工干预恢复到正常状态、安全模式力度是否要到region级别,这些问题都需要安全模式考虑,而此类的设计一般都和集群设计的目标用户息息相关。举例,如果是低延迟且业务敏感用户,可能会选择小规模故障不能影响读写,而高延迟、高吞吐集群就可以接受停读写。

五 思考

由于分布式存储系统的复杂性和篇幅所限,本文仅选择有限个典型场景进行了分析和讨论, 真实的分布式存储系统远比这数个案例复杂的多、细节的多。如何平衡集群异常自动化处理和引入的复杂度,如何较好的实现流控和避免影响低延迟用户的响应时间,如何引导集群进行负载均衡和避免因负载均衡带来的过量集群资源开销,这类问题在真实的分布式存储系统设计中层出不穷。如果设计者是你,你会如何取舍呢?



你可能感兴趣的:(分布式存储)