sqlite3数据存储最多存储多少条数据?达到上限如何处理?_分布式存储系统架构模式...

分布式存储已经是相当普及的技术了,Github上能找到各种各样的分布式存储项目,覆盖Filesystem, KVStore, Database, Object Store等各个存储层次。面对众多的开源项目,如何快速的从技术角度分析各个项目的设计特点,如果要自己再造一个轮子,应该注意哪些方面的设计?本文尝试提供一个分布式存储的分析框架,覆盖分布式存储主要技术点,用以分析现有的各种分布式存储系统。

关于分布式系统

首先我们需要准备一些分布式系统的知识,由于这不是本文的重点,因此这里只做一个简单的介绍,提供一些链接供有兴趣的读者参考。

分布式系统是一个其组件运行在多个网络节点上的系统,组件之间通过消息传递进行通信来协调彼此之间的行为,对外呈现一个整体。相比单机系统,分布式系统具有更好的性能、扩展性和可靠性,同时也更加复杂。分布式系统的复杂性来源于两个方面。

一个是分布式系统自身的固有复杂性,比如所有组件并发运行,因此对于所有共享资源的操作,都必须正确的同步,由于缺乏全局时钟,没有办法使用一种简单的方式确定系统内事件发生的先后顺序,节点和网络总会出错,分布式系统必须考虑在出错的情况下如何正常运行。另一个是现有解决方案引入的新的复杂性,比如通过数据复制实现了数据的高可用,同时带来了一致性的问题。

分布式领域有些已经被深入研究的基本问题,比如时间同步。推荐阅读

Time, Clocks, and the Ordering of Events in a Distributed System

另外一个更重要的问题是分布式共识,它是解决分布式系统中很多重要问题的关键。由于分布式系统中各个组件都是并发运行的,有些资源不支持并发操作,在操作这些资源过程中,必须确保其他组件不能操作资源,类似这种需求就需要通过分布式共识算法解决,还有Leader选举,分布式初始化等各种问题都需要通过分布式共识解决。Paxos可能是最知名的分布式共识协议,另外还有更简单容易理解的Raft,它们的论文非常值得阅读。

Paxos Made Simple

In Search of an Understandable Consensus Algorithm

State Machine Replication

在分布式存储领域还有一个非常重要的理论:CAP,CAP分别表示Consistency, Availability, Partition tolerance,CAP理论支持一个分布式存储系统不可能同时满足一致性、可用性和分区容错性,所有的系统只能满足3个特性里的最多两个。关于CAP的文章也很多,这里就不赘述了,推荐阅读:

CAP Twelve Years Later

Perspectives on the CAP Theorem

分布式存储系统的分类

按照接口和数据模型的不同,分布式存储系统也可以分为很多类型,比如提供了Posix Filesystem接口的分布式文系统,具有SQL能力的NewSQL分布式数据库,本文并不关注接口和数据模型,重点介绍Object Storage和KVStore这种非结构化简单接口的存储。实际上更复杂的存储服务可以基于Object Storage和KVStorage实现,比如Ceph,提供了Posix FileSystem, S3等各种接口,其核心是一个Object Storage。

当然了,不同的分布式存储系统解决的问题不同,需求场景不同,在设计时的侧重点会有所不同,比如Object Storage通常用于存储较大的数据,几百兆以上,通常采用优化系统以实现较高的吞吐。而KVStore通常存储较小的数据,但对延迟敏感。

关键设计

对于几乎所有的分布式存储系统,在设计上都要重点解决如下几个问题

  • 架构风格,主流的分布式存储有master-based和masterless两种风格,架构决定了一些方案的选择。
  • 分区和寻址,数据如何切分,数据和数据的副本应该放到哪些节点上,访问的时候如何定位节点。
  • 复制策略和副本的使用策略,写操作是否等待所有副本写完后才返回,副本是不是可以用来响应读请求
  • 失败检测和恢复,磁盘坏掉、节点失败、网络不通等各种情况下系统能否正常工作,数据会不会丢失,会不会损坏。在处理错误的时候系统如何处理,能否自愈。
  • 安全,有没有权限控制,通信链路是否安全

对于这些问题,系统可以选择各种可行的方案,方案的选择决定了系统的各种性质:可靠性,一致性,分区容错性,扩展性,自愈能力,安全。各种存储系统之所以不同,

master-based vs masterless

这是两种普遍存在的架构风格。master-based风格的典型代表是Google File System和它的后辈HDFS,

b90ecf9fb3b0587ba46df7e195f4b4ee.png

masterless的典型代表则是Dynamo,还有它的后辈Cassandra

74cb89fb137d09e2daf823273d4882ed.png

还有介于两者之间的一些选择,比如Ceph,它没有master,但是有一个monitor,承载了部分master的功能,属于master-based和masterless的折中。

master-based架构中,master自身采取一主多备的形式,通过分布式共识算法选取一个节点作为leader,履行master的职责,其他节点作为backup. master既可以作为中心化的存储,保存一些关键数据,也可以作为协调服务,处理资源分配,节点管理等工作。由于master的存在,很多设计变得简单,对于寻址问题,master可以使用复杂的策略,将数据分配到节点上,master可以指定一个节点作为处理某些数据的primary节点,而且master可以确保不会出现重复的primary,避免数据写冲突。

master-based架构的缺点也相当明显,中心化的master很容易成为整个系统的瓶颈,master的性能上限决定了系统的性能上线,达到上限后,无法继续通过添加新节点扩展系统。而且master失败将导致整个系统不可用,master的可靠性决定了整个系统的可靠性。

masterless架构中所有节点都是对等的,每个节点都是对等的,没有master,理论上可以系统可以无限的通过增加新节点扩容,而且可靠性非常高,任何节点失败都不会影响整个系统。由于没有中心化存储和协调,masterless架构中很多功能实现起来相对困难。在masterless架构的一个关键问题是成员管理,这是数据分布和寻址基础。成员管理是一个很大的话题,简单来说,masterless中不存在一个强一致性的成员管理协议,因此解决数据的一致性变得非常困难。

现有的masterless架构的分布式存储系统在成员管理上都做了优化,比如dynamo将成员的永久性变更设定为手工操作,而不是依赖节点之间的失败检测。

数据的存储单位

系统处理数据时,总是以某个特定的粒度为最小单位,不同的系统里,这个单位有不同的称呼,比如KVStore,以一条KV数据为单位,Object Storage通常将Object切分成固定大小的Block,以Block作为存储单位,每个Block具有全局ID,时序数据存储通常按小时或者按天作为最小单位,每个时间段的数据是一个Segment。

系统内部,每条数据都有唯一标识,这个标识可以是外部可见的,比如KVStore里的Key,也可以是纯粹的内部表示,比如ObjectStore的一个Block ID

副本

分布式系统的一个基本假设就是节点可能会出现故障,而保证节点故障情况下系统依然能正常工作的方式就是冗余,每一份数据都要额外的几个副本,保存在其他节点上,任何一个节点出现故障,其他节点可以使用备份的数据继续服务。

对于副本,最重要的考量点有两个:副本的数量和副本位置。副本越多数据可靠性越好,但响应的需要浪费更多的资源,所以选择合适的副本数量就很重要,很多系统使用3副本,支持根据需要调整。副本的位置也很重要,如果数据和它的副本在同一个节点上,等同于没有副本,完全不能提供任何可靠性。不同的副本应该处于不同的故障域中,按照故障域的范围还可以进一步细分为跨物理机,跨机架,跨交换机甚至跨机房和跨区域。

分区和寻址

数据分区是分布式存储系统的根本。通过将数据划分更小的块,存储在不同的节点上,分布式系统解决了单机存储容量和性能的问题。寻址表示应该将数据放在哪个节点上,根据ID找到定位负责处理对应数据的节点(包括副本)。数据应该存在哪个节点上,这是个很严肃的问题。一个好的分区方案,应该满足

  1. 数据尽可能均匀的分布在各个节点上,不会出现严重的不均衡
  2. 根据key,能够快速定位其所在的节点
  3. 副本分布在不同的故障域

有些系统可能会增加一个抽象层,Key --> Namespace --> Node,数据先映射到一个Namespace里,Namespace再映射到节点上。增加了一层Namespace能够简化节点出错时数据迁移相关的工作。

常见的寻址方式有两类

  • 映射表,一个单独的服务负责分配数据到节点的映射,并记录到映射表,读取时先查表找到对应节点。在master-based的架构中比较常见。
  • 计算Key的Hash,再映射到一个节点上,用一个函数表示就是map(hash(key))。结果相同的Key处于同一个节点。考虑节点可能要增加/移除,节点可能失败,一般使用一致性Hash,而不是普通的Hash方式。除了一致性Hash,另外一种更好的方式是Rendezvous Hash,Ceph的Crush算法就是一种Rendezvous Hash的实现。

映射表方式的优势是灵活,支持非常复杂的计算策略,而且由于寻址方式持久化到映射表中,系统可以随时更新寻址策略而不影响已有的数据分配,甚至可以手工修改映射表来调整数据分配。缺点是需要一个中心节点,和master-based架构一样,一个中心节点限制了整个系统的扩展性和可靠性。另外,为了防止映射表膨胀,对于KVStore这种包含大量数据条目的系统并不适合直接将Key作为映射表的条目,而是先引入一个中间层,比如HBase里的KeyRange

Hash方式的优势在于不需要中心节点,因此完全没有扩展性和可靠性的限制,缺点是由于每个节点独立计算Hash,为了确保所有节点的计算结果一致,节点本地维护的成员列表必须一致。另外只支持根据预先定义好的规则计算Key到节点的映射,不支持更灵活的策略,也不能中途调整。

复制和一致性

引入副本之后,随之而来的是一堆新的问题:数据写操作如何同步到副本上,读取的时候,读到的数据是不是能保证总是最新的(强一致性)。

分布式存储系统中,为了避免写冲突,通常将其中一个副本选择为primay,所有的写操作只能在primary上,由primary同步复制到其他副本。复制过程中,primary向replica发送的数据通常取决于具体的实现。如何选出primary呢?在一个有master的系统中,primary可以由master指定,masterless,通常采用hash寻址primary可以是第一个hash节点。

对于一个n-replicas的存储系统,一个需要权衡的点是多少个replica写成功可以认为本次写操作成功。如果只有primary写成功,之后primary失败,新写入的数据将会丢失。

有些系统为了提升读性能,允许读请求访问secondary replica,为了实现强一致性,primary必须确保写请求复制到所有的replica才能返回。Dynamo里,写操作可以在多个副本上进行,因此它对一致性的处理采用了另外一种不同的方式:Quorum,写W个replica,读R个replica,只要W+R>N,根据数据的时间戳就可以确保拿到最新的数据,从而实现强一致性。

根据CAP理论,系统不可能同时满足,强一致性的代价是分区容错和高可用必须舍弃一个。广泛的共识是由于网络分区必然存在,实际上只能在强一致性和高可用里选择一个,Dynamo就是典型的选择了AP的最终一致性系统,实际上选择CP的系统也并不少见,选择AP还是CP是由系统自身的需求场景决定的。选择了CP是否一定意味着系统没有高可用呢?取决于高可用到底是多高,实际生产环境中 ,我们会对每个服务定义一个SLO,一个典型的存储系统,SLO通常是99.95%到99.99%,而是100%,最后的0.01%需要投入巨大的成本。选择CP,出现网络分区的情况下系统不可用,如果网络分区本身出现的概率很小,比如在一个数据中心内部,并且拥有良好的网络设计,出现网络分区的概率小于0.01%,系统依然可以满足我们的可用性需求。

失败检测和恢复

节点失败,网络故障,都是分布式系统的常态,一个分布式存储系统不应该因为节点失败导致数据丢失或者服务不可用。

节点可能出现各种各样的故障类型,单纯的进程crash或宕机,这属于比较“好”的故障,其他系统能够探测到节点失败了。最坏的情况下节点看上去正常,但是输出的数据完全是错误的,外界无法简单的判断节点是否失败,这种成为拜占庭故障,这里我们假设不存在拜占庭故障,节点失败能够被探测到。

常见的检测节点失败的方式是心跳。在master-based系统中,master和其他节点定期通信,可以是master主动pinging,也可以是节点主动上报,如果一个节点长时间不响应或没有心跳信息,master可以认为这个节点已经失败了。在masterless系统中,节点从成员列表中随机的选择几个节点,发送pinging,探测对方是否存活,然后通过gossip在所有成员之间传递探测的结果。

pinging或者心跳都存在一个问题,当一个节点无法通信时,并不意味着节点失败,也可能是到这个节点的网络出现问题。解决这个问题的一个办法是当检测到节点失败时,请求其他节点进一步判断目标节点是否可达。

发现失败节点后,master-based系统选择新的节点负责处理失败节点上的数据,采用hash寻址的masterless系统选择hash结果的后继节点处理失败节点上的数据。为了确保数据不丢失,所有的数据至少应该具有一个额外的副本。

安全

数据安全通常要求做到机密性和完整性,数据不会被窃听,不会被未授权账号访问,不会被篡改。具体到实现上,存储系统通常包含权限体系,数据加密和通信加密。这些功能实际上并不是分布式存储系统独有的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值