无论是云计算、大数据还是互联网公司的各种应用,其后台基础设施的主要目标都是构建低成本、高性能、可扩展、易用的分布式存储系统。
大规模分布式存储系统的定义如下:分布式存储系统是大量普通PC服务器通过Internet互联,对外作为一个整体提供存储服务。
几个特点:
(1)可扩展:分布式存储系统可以扩展到几百台甚至上千台的集群规模,而且,随着集群规模的增长,系统整体性能表现为线性增长
(2)低成本:自动容错、自动负载均衡机制使其可以构建在普通PC机之上。另外,线性扩展能力也使得增加、减少机器非常方便,可以实现自动运维。
(3)高性能:针对整个集群还是单台服务器,都要求分布式存储系统具备高性能。
(4)易用:分布式存储喜提需要能够提供易用的对外接口,另外,也要求具备完善的监控、运维工具。
分布式存储数据需求比较复杂,大体可以分为三类:
(1)非结构化数据
(2)结构化数据
(3)半结构化数据
不同的分布式存储系统适合处理不同类型的数据,将分布式存储系统分为四类:
(1)分布式文件系统:互联网应用需要存储大量的图片,视频等非结构化数据对象,这类数据以对象的形式组织,对象之间没有关联,这样的数据一般称为Blob数据(Binary Large Object二进制大对象)
分布式文件系统存储三种类型的数据:Blob对象,定长块,大文件
(2)分布式键值系统:存储关系检点的半结构化数据,只提供基于主键的CRUD功能。
(3)分布式表格系统:存储关系较为复杂的半结构化数据。
(4)分布式数据库:一般从单机关系数据库扩展而来,用于存储结构化数据。
1. 单机存储系统
单机存储系统就是哈希表,B树等数据结构在磁盘等持久介质上的实现。
1.1 单机存储引擎
存储系统的基本功能包括:增、删、读、改。其中,读取操作又分为随机读取和顺序扫描。
哈希存储引擎是哈希表的持久化实现,支持增删改,以及随机读取操作,但不支持保持扫描,对应的存储系统为键值存储系统
B树(B-Tree)存储引擎是B树的持久化实现,不仅支持单条记录的增删改查,还支持顺序扫描,对应的存储系统是关系数据库
LSM树(Log-Structured Merge Tree)存储引擎和B树存储引擎一样,支持增删改,随机查和顺序扫描
1.2 数据模型
文件模型,以目录树的形式组织文件,POSIX(Portable Operation System Interface)是应用程序访问文件系统的API标准,它定义了文件系统存储接口及操作集
关系模型,每个关系是一个表格,有多个元组(行)构成,而每个元组又包含多个属性(列),关系名、属性名以及属性类型称作该关系的模式
键值模型,大量的NoSQL系统采用键值模型,每行记录由主键和值两个部分组成。
1.3 事务与并发控制
数据库事务具有原子性,一致性,隔离性,持久性,即ACID属性。这些特性使得多个数据库事务并发执行时互不干扰,也不会获取到中间状态的错误结果。
事务的并发控制一般通过锁机制来是吸纳,锁可以有不同的粒度,可以锁住行,锁住数据块,锁着整个表格。
由于互联网业务中读事务的比例往往远高于写事务,为了提供读事务性能,可以采用写时复制(Copy-On-Write, COW)或多版本并发控制(Multi-Version Concurrency Control, MVCC)技术来避免写事务阻塞读事务。
1.4 故障恢复
数据库运行过程中会发生故障,这个时候某些事务可能执行到一半但没有提交,当系统重启时,需要能够恢复到一致的状态,即要么提交整个事务,要么回滚。
数据库系统以及其他的分布式存储系统一般采用操作日志(或提交日志,Commit Log)技术来实现故障恢复。操作日志分为回滚日志(UNDO Log)、重做日志(REDO Log)以及UNDO/REDO日志。
如果记录事务修改前的状态,则为回滚日志;如果记录事务修改后的状态,则为重做日志。
1.5 数据压缩
数据压缩分为有损压缩和无损压缩
有损算法压缩比率高,但数据可能失真,一般用于压缩图片、音频、视频;
无损压缩算法能够完全还原原始数据。
Huffman编码和LZ系列压缩算法
读操作需要先读取磁盘中的内容再解压缩,写操作需要先压缩再将压缩结果写入到磁盘,整个操作的延时包括压缩/解压缩和磁盘读写的延迟,压缩比越大,磁盘读写的数据量越小,而压缩/解压缩的时间也会越长。
所以需要一个很好的权衡点。
列式存储
传统的行式数据库将一个个完整的数据行存储在数据页中。如果处理查询时需要用到大部分的数据列,这种方式在磁盘IO上是比较高效的。一般来说,OLTP(Online Transaction Processing,联机事务处理)应用适合采用这种方式。
列式数据库将同一个数据列的各个值存放在一起,插入某个数据行时,该行的各个数据列的值也会存放到不同的地方。
2. 分布式系统
分布式系统的基础理论包括:数据分布、复制、一致性、容错、分布式协议等。
分布式系统面临的第一个问题就是数据分布,即将数据均匀地分布到多个存储节点。另外,为了保证可靠性和可用性,需要将数据复制多个副本,这就带来了多个副本之间的数据一致性问题。大规模分布式存储系统的重要目标就是节省成本,因而只能采用性价比较高的PC服务器。这些服务性能很好,但是故障率很高,要求系统能够在软件层面实现自动容错。当存储节点出现故障时,系统能够自动检测出来,并将原有的数据和服务迁移到集群中其他正常工作的节点。
2.1 异常
在分布式存储系统中,将一台服务器或服务器运行的一个进程称为一个节点,节点与节点之间通过网络互联。
异常类型
(1)服务器宕机
(2)网络异常,网络分区
(3)磁盘故障,分为两种情况:磁盘损坏和磁盘数据错误。磁盘损坏将丢失存储在上面的数据,因而,分布式存储系统需要考虑将数据存储到多台服务器,即使其中一台服务器磁盘出现故障,也能从其他服务器上恢复数据。对于磁盘数据错误,一般采用校验和(checksum)机制来解决。
2.2 超时
由于网络异常的存在,分布式存储系统中请求结果存在:“三态”,即成功、失败、超时(未知状态)。
2.3 一致性
由于异常的存在,分布式存储系统设计会将数据冗余存储多份,每一份称为一个副本(replica/copy)。当某一个节点出现故障时,可以从其他副本上读到数据。可以这样认为,副本是分布式存储系统容错技术的唯一手段。
由于多个副本的存在,如何保证副本之间的一致性是整个分布式系统的理论核心。
可以从两个理解一致性:(1)用户(客户端),即客户端读写操作是否符合某种特性;(1)存储系统,即存储系统的多个副本之间是否一直,更新的顺序是否相同。
从客户端的角度来看,一致性包含如下三种情况:
(1)强一致性:
(2)弱一致性:
(3)最终一致性:“不一致窗口”,指从A写入值,到后续A,B,C读取到最新值的这段时间。“不一致性窗口”的大小依赖于几个因素:(1)交互延迟(2)系统的负载(3)复制协议要求同步的副本数。
最终一致性有几个变体:
(1)读写一致性
(2)会话一致性
(3)单调读一致性
(4)单调写一致性
从存储系统的角度看,一致性主要包括如下几个方面:
(1)副本一致性:存储系统的多个副本之间的数据是否一致,不一致的时间窗口等。
(2)更新顺序一致性:存储系统的多个副本之间是否按照相同的顺序执行更新操作。
2.4 衡量标准
评价分布式存储系统一些常见的指标:
2.4.1 性能:系统的吞吐量以及系统的响应时间。
吞吐能力指系统在某一段时间可以处理的请求总数,通常用每秒处理的读操作数QPS,或写操作TPS来衡量
2.4.2 可用性
系统在面对异常时可以提供正常服务的能力。系统的可用性可以用系统停服务的时间与正常服务的时间的比例来衡量。 例如某系统的可用性为4个9(99.99%),相当于系统一年停服务的时间不能超过365*24*60/10000=52.56分钟。
系统可用性往往体现系统的整体代码质量以及容错能力。
2.4.3 一致性
2.4.4 可扩展性
系统的扩展性指分布式存储系统通过扩展集群服务规模来提高系统存储容量、计算量和性能的能力。
2.5 数据分布
数据分布的方式主要有两种:(1)哈希分布(2)顺序分布
将数据分散到多台机器后,需要尽量保证多台机器之间的负载是比较均衡的。
衡量机器负载涉及的因素很多,比如机器load值,cpu,内存,磁盘,网络等资源使用情况,读写请求数及请求量。
分布式存储系统需要能够自动识别负载高的节点,当某台机器的负载较高时,将它服务的部分数据迁移到其他机器,实现自动负载均衡。
分布式存储系统的一个基本要求就是透明性:数据分布透明性,数据迁移透明性,数据复制透明性,故障处理透明性。
2.5.1 哈希分布
传统的哈希分布算法有一个问题:当服务器上线或下线时,N值变化,数据映射完全被打乱,几乎所有的数据都需要重新分布,将带来大量的数据迁移。
一种思路是不再简单地将哈希值和服务器个数做除法取模映射,而是将哈希值与服务器的对应关系作为元数据,交给专门的元数据服务器来管理。
另一种思路就是采用一致性哈希(Distributed Hash Table, DHT)算法。
2.5.2 顺序分布
哈希散列破坏了数据的有序性,只支持随机读取操作,不能够支持顺序扫描。
2.5.3 负载均衡
分布式存储系统的每一个集群中一般有一个总控节点,其他节点为工作节点,由总控节点根据全局负载信息进行整体调度。
工作节点纲上线时,总控节点需要将数据迁移到该节点,另外,系统运行过程中也需要不断地执行迁移任务,将数据从负载较高的工作节点迁移到负载较低的工作节点。
2.6 复制
客户端将写请求发送给主副本,主副本将写请求复制到其他备副本,常见的做法是同步操作日志Commit Log,主副本首先将操作日志同步到备副本,被副本回放操作日志,完成后通知主副本。
接着主副本修改本地,等到所有的操作都完成子啊通知客户端写成功。
主备副本之间的复制一般通过操作日志来实现。
2.6.1 一致性与可用性
CAP理论:一致性,可用性,分区可容忍性三者不能同时满足。
一致性:读操作总是能够读取到之前完成的写操作结果,满足这个条件的系统成为强一致性,这里的“之前”一般对同一个客户端而言。
可用性:读写操作在单台机器发生故障的情况下仍然能够正常执行。
分区可容忍性:机器故障,网络故障,机房停电等异常情况下仍然能够满足一致性和可用性。
分区可溶性总是需要满足,因此,一致性和写操作的可用性不能同时满足。
如果采用强同步复制,保证了存储系统的一致性,然而,当主备副本之间出现网络或其他故障时,写操作将被阻塞,系统的可用性无法得到满足。如果采用异步复制,保证了存储系统的可用性,但是无法做到强一致性。
2.7 容错
2.7.1 故障检测
A和B之间需要对B是否应该被认为发生故障而停止服务达成一致,Finsher指出,异步网络中的多台机器无法达成一致。
可以通过租约(Lease)机制进行故障检测,租约机制就是带有超时时间的一种授权。假设A需要检测B是否发生故障,A可以给B发放租约,B持有的租约在有效期内才允许提供服务,否则主动停止服务。
B的租约快要到期的时候向A重新申请租约。正常情况下,B通过不断申请租约来延长有效期,当B出现故障或与A之间的网络发生故障时,B的租约将过期,从而A能够确保B不再提供服务,B的服务可以被安全迁移到其他服务器。
2.8 可扩展性
通过数据分布,复制以及容错等机制,能够将分布式存储系统部署到成千上万台服务器。
分布式存储系统大多数带有总控节点,很多人会自然地联想到总控节点的瓶颈问题,认为P2P架构更加优势。然而,事实却并非如此,主流的分布式存储系统大多带有总控节点,且能够支持成千上万台的集群规模。
2.8.1 总控节点
分布式存储系统中往往有一个总控节点用于维护数据分布信息,执行工作机管理,数据定位,故障检测和恢复,负载均衡等全局调度工作。
通过引入总控节点,可以使得系统的设计更加简单,并且更加容易做到强一致性,对用户友好。那么,总控节点是否会称为性能瓶颈。
分为两种情况:
(1)分布式文件系统的总控节点除了执行全局调度,还需要维护文件系统目录树,内存容量可能会率先称为性能瓶颈。
(2)另一类分布式存储系统的总控节点只需要维护数据分片的位置信息,一般不会称为瓶颈。
2.9 分布式协议
分布式系统涉及的协议很多:租约,复制协议,一致性协议,其中以两阶段提交协议和Paxos协议最具代表性。
两阶段提交协议用于保证跨多个节点操作的原子性,也就是说,跨多个节点的操作要么在所有节点上全部执行成功,要么全部失败。
Paxos协议用于确保多个节点对某个投票(例如哪个节点为主节点)达成一致。
2.9.1 两阶段提交协议
Two-phase Commit, 2PC,经常用来实现分布式事务,一般包含两类节点:一类为协调者,通常一个系统中只有一个,另一类为事务参与者,一般包含多个。
(1)请求阶段,协调者通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地执行成功)或取消(事务参与者本地执行失败)
(2)提交阶段,协调者将基于第一阶段的投票结果进行决策:当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行相应的操作。
两阶段提交协议可能面临两种故障:
(1)事务参与者发送故障:给每个事务设置一个超时时间,如果某个事务参与者一直不响应,到底超时时间后整个事务失败。
(2)协调者发送故障:协调者需要将事务相关信息记录到操作日志并同步到备用协调者,假如协调者发生故障,备用协调者可以接替它完成后续的工作。
总而言之,两阶段提交协议是阻塞协议,执行过程中需要锁住其他更新,且不能容错,大多数分布式存储系统都不采用,放弃对分布式事务的支持。
2.9.2 Paxos协议
Paxos协议用于解决多个节点之间的一致性问题。
2.9.3 Paxos和2PC
Paxos协议和2PC协议在分布式系统中国索契的作用并不相同。Paxos协议用于保证同一个数据分片的多个副本之间的数据一致性。2PC协议用于保证属于多个分片上的操作的原子性。
这些数据分片可能分布在不同的服务器上,2PC协议保证多台服务器上的操作要么全部成功,要么全部失败。
2.10 跨机房部署
机房之间的网络延时较大,且不稳定,跨机房问题主要包含两个问题:数据同步以及服务切换。
跨机房部署有三个方案:(1)集群整体切换(2)单个集群跨机房(3)Paxos选主副本