编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

FoundationDB的配置与功能分析

wxchong 2024-11-22 22:05:58 开源技术 31 ℃ 0 评论

十年前,FoundationDB作为一个开源事务性键值存储初次面世,它不仅具有NoSQL架构的灵活性和可伸缩性,还结合了ACID事务的强大功能,是推动计算机学科前进发展的坚实基础之一。

FDB的特色与基本原理

FoundationDB的具有高伸缩度和容错率,这主要是因为其内部结构是非捆绑式的。与传统存储系统不同,FDB将紧密联系的内存事务管理器、分布式存储器和内置分布式配置器分成了三个子系统。每个子系统都可以独立工作,用户也能对每个系统单独配置。

FoundationDB包括一个确定性模拟框架,它的主要应用范围是在故障不确定的情况下,测试每个对象的新特性。这种严格的测试使FoundationDB非常稳定,并允许开发人员以快速的节奏引入和发布新特性。

FoundationDB还提供了一个最小且精确的特性集,这使得一系列不同的系统都可以构建在上面。Apple、Snowflake和其他公司都应用了FoundationDB,并将其作为云端设施的基础,因为它具有一致性、稳健性,以及存储用户数据、系统元数据和配置等关键信息的可用性。

FDB有三个主要的设计原则。

第一个原则是分而治之,也就是分离关注点。

FDB将事务管理系统与分布式存储解耦,也就是将写路径与读路径区分开,并独立扩展它们。在事务管理系统中,每个流程都分别在事务管理不同方面发挥作用。此外,集群范围的编排任务,比如过载控制和负载平衡等,也由额外的异构角色划分和服务。

FDB的第二个设计原则是接受失败,让失败成为常事。对于分布式系统而言,故障是一种常态。为了应对FDB事务管理系统中的故障,开发者通过恢复路径来处理,当事务系统检测到故障时,它会主动关闭。

因此,所有的故障处理都被简化为一个恢复操作,从而形成一个常见的、经过良好测试的代码路径。为了提高可用性,FDB还努力最小化平均恢复时间(MTTR)。在实践的生产集群中,平均恢复总时间通常不到5秒。

FDB第三个设计原则是利用模拟测试。FDB依赖于一个随机的、确定性的模拟框架来测试其分布式数据库的正确性。模拟测试不仅可以暴露深层次的故障,还可以提高开发人员的生产力和FDB的代码质量。

FDB集群的基本结构

FDB集群中有一个用于管理关键系统元数据,还有一个集群范围的编排控制平面,以及一个用于事务处理和数据存储的数据平面,如图1所示。

就FDB控制平面来说,控制平面负责在协调器上持久化关键的系统元数据,即事务系统的配置。这些协调器组成一个Paxos组并选出一个集群控制器。

集群控制器监视集群中的所有服务器并维护三个集群进程,测序器,数据分配器和速率保持器。如果它们失败或崩溃,则测序器会重新启动它们,数据分配器负责监控故障和平衡数据,速率保持器则为集群提供过载保护。

在FDB数据平面,FDB针对的OLTP的工作内容主要是阅读,即每个事务都读写一小组关键字节,这使FDB具有伸缩性。同时,FDB选择了一种非捆绑的体系结构:分布式事务管理系统(TS)。这项系统由三个由无状态的进程组成,即测序器、代理和解析器。

进一步来说,FDB中的日志系统LS 会为TS存储WAL ,而单独的分布式存储系统SS 会存储数据和读取服务。LS中包含一组log存储器, SS中包含多个存储服务器。这可以很好地适应苹果最大的事务性工作负载。

SS由许多存储服务器组成,每个存储服务器存储一组数据分片,即连续的键范围,并为客户端读取提供服务。存储服务器形成了是系统中的大多数进程,它们一起构成了一个分布式树。

目前,FDB的存储服务器上引入的都是SQLite引擎,并在后台对它进行了优化 ,这样就让其的清除效率有所提高,不仅增加的范围,还加快的速递,除此之外,优化后SQLite引擎能够支持FDB进行异步编程。

如上所述,在FDB中,每个流程都有其特定任务,被分配了不同的角色,在后续工作杀红,FDB还会为每个角色添加新流程来完成扩展。

客户端需要从分片的存储服务器读取数据,因此读取数据与存储服务器的数量呈线性增长,所以FDB需要通过添加更多代理、解析器和日志服务器来扩展写操作。而控制平面的单例进程和协调器不是FDB的性能瓶颈,它们只执行有限的元数据操作。

所有用户数据和大多数系统元数据都存储在存储服务器s中。关于存储服务器s的元数据保存在Log存储器中,而Log存储器的配置数据保存在所有协调器中。协调器是一个磁盘Paxos组,如果集群控制器不存在,服务器将会尝试让自己成为该集群控制器。

新选出的集群控制器从协调器读取旧的LS配置,并生成新的TS和LS。代理可以从旧的LS恢复系统元数据,包括关于所有存储服务器的信息。测序器会等到新的TS完成恢复后,将新的LS配置写入所有协调器。然后,新的事务系统就可以接受客户端事务了。

测序器进程监视代理、解析器和录音服务器的运行状况。无论何时TS或LS出现故障,或者数据库配置发生更改,测序器都会终止。集群控制器会检测到测序器故障,然后重启并生成一个新的TS和LS。

FDB事务管理功能

FDB的事务管理主要包括端到端事务处理、严格的序列化性以及日志记录和恢复。

在端到端事务处理方面,如图1所示,客户端事务端首先会与一个代理联系,获得读版本,即时间戳。然后,代理会向测序器发出请求,得到一个与之前事务提交版本一样大的读版,并将这个读版发送回客户端。

然后,客户端可以向存储服务器发出阅读操作请求,并在特定的读版上获取相应值。客户端的写操作则在本地进行缓冲,在不与集群联系的情况下,将数据库查找的结果与事务的未提交写操作相结合,保留读写语义。

在提交时,客户端会将事务数据,包括读写集发送到其中一个代理,并等待提交或中止响应。如果事务数据不能成功提交,客户端可以选择重新启动它。

具体来说,代理会通过三个步骤提交客户端事务。

首先,它与测序器联系,获取一个比任何现有的读版或提交版本都大的提交版本。测序器会以每秒一百万次的速度选择提交版本。然后,代理将事务信息发送给范围分区的解析器,该解析器负责检查读写冲突,激活FDB的正向并发控制。

如果所有的解析器都正常返回而没有冲突,则事务可以进入最终提交阶段。否则,代理就会将事务标记为中止。

最后,提交的事务被发送到一组logserver进行持久化。在所有指定的log存储器都回复代理后,事务会变为已提交状态,代理需要继续将提交的版本报告给测序器,以确保以后的事务的读版在此提交之后,然后给客户端进行反馈。存储服务器s也会不断地从log存储器提取突变日志,并将提交的更新应用到磁盘。

除了上述读写事务之外,FDB还支持只读事务和快照读取。FDB中的只读事务是可序列化和高性能的。这意味这客户端可以在本地提交这些事务,而无需联系数据库

FDB中的快照读取则选择性地放松隔离属性,即并发写操作不会与快照读操作发生冲突。FDB通过结合OCC和MVCC实现了可串行快照隔离(SSI)。为了确保日志序列号之间没有间隔,测序器会在每个提交版本中检查前一个提交版本。

代理则互将日志序列号和之前的序列号同时发送给解析器和日志服务器,以便它们可以按照序列号的顺序串行地处理事务。类似地,存储服务器也会按照日志序列号递增的顺序,从log存储器上提取日志数据。

与快照隔离类似,解析器也使用了无锁冲突检测算法,不同之处在于,FDB会在冲突检测之前选择提交版本,这让FDB能有效地批量处理版本分配,并进行冲突检测。

日志记录功能方面,在FDB中,存储服务器s可以将来自log存储器的非持久重做日志应用到内存索引中。在通常情况下,这项程序会在提交的读版被分发给客户端之前进行,这样能让服务器的后续阅读延迟降低。

因此,当客户端读请求到达存储服务器s时,请求的版本通常已经是可用的了。如果在存储服务器副本上无法读取新数据,客户端要么等待数据变为可用,要么在另一个副本上重新发出请求,如果两者都读取超时,客户端会简单地重新启动事务。

由于日志数据在log存储器上已经是持久的,因此存储服务器可以在内存中缓冲更新,并定期将批量数据持久化到磁盘,从而提高I/O效率

FDB能够执行事务系统恢复功能。传统的数据库系统通常采用ARIES恢复协议,在恢复过程中,系统会通过将重做日志记录重新应用于相关数据页,然后处理上次检查点的重做日志记录。这将使数据库处于一致状态。

对于FDB,恢复的成本非常低,因为它不需要应用undo日志条目,这极大地简化了设计选择,使重做日志处理与正常的日志转发路径相同。

在FDB中,存储服务器从log存储器中提取日志,并在后台应用它们。恢复过程从检测故障和启动新的事务系统开始。在旧Log存储器中的所有数据被处理之前,新的TS就可以接受事务,所以恢复只需要找出重做日志的末尾:与正常的转发操作一样,此时存储服务器会异步重放日志。

对于每个epoch, 集群控制器分几个步骤执行恢复。首先,它从协调器读取先前的TS配置,锁定该信息,以防止另一次并发恢复。

接下来,它会恢复以前的TS系统状态,包括关于旧录音服务器的信息,阻止它们接受事务,并启动一组新的测序器、代理、解析器和logs存储器。在停止以前的Lo存储器并启动新的TS之后,集群控制器就会将新的TS信息写入协调器。

因为代理和解析器是无状态的,所以它们的恢复不需要额外的工作。相反,log存储器可以保存已提交事务的日志,用户只需要确保所有这些事务都是持久的,并且可以被存储服务器检索。

恢复旧log存储器的本质是确定重做日志的结束,即恢复版本RV。回滚undo日志本质上来说,是丢弃旧Log存储器和存储服务器中RV之后的任何数据。图2说明了RV是如何由测序器确定的。

在基本常识中,对Log存储器的代理请求会附带它的KCV,即该代理已提交的最大日志序列号,以及当前事务的日志序列号。每个录音服务器保留会接收到的最大KCV和一个持久版本(DV), DV是录音服务器持久化的最大LSN 序列号。

在恢复期间,测序器尝试停止所有旧的录音服务器,其中每个响应包含该录音服务器上的DV和KCV。假设旧录音服务器的数量为m,Log存储器的复制度为k。一旦测序器收到超过m - k个应答,测序器就知道上一个epoch已经提交了事务,这将成为上一个epoch的结束版本(PEV),图3是PEV的一个演示实例。

结束版本之前的所有数据都已完全复制。对于当前epoch,它的起始版本是PEV + 1, 测序器会选择所有DVs中的最小值作为RV。

[PEV + 1, RV]范围内的日志将从上一个epoch的Log存储器复制到当前的Log存储器,以便在Log存储器出现故障时重现复制程度。复制这个范围的成本非常小,因为它只包含几秒钟的日志数据。

当测序器接受新事务时,它通知存储服务器 RV,以便它们可以回滚任何大于RV的数据。

当前的FDB存储引擎由的SQLite树和内存中的多版本重做日志数据组成。

只有离开MVCC窗口的突变,也就是即提交的数据才会被写入SQLite。回滚只是在存储服务器中丢弃内存中的多版本数据。然后,存储服务器将从新的Log存储器中提取任何大于PEV版本的数据。

用户也可以复制FDB,在不同数据的基础上,使用多种复制策略的组合来容忍失败。

第一种复制策略是元数据复制。控制平面的系统元数据通过Active Disk paxos存储在协调器上的,只要有大多数的协调器处于激活状态,这些元数据就可以恢复。

第二种复制策略是日志复制。当代理向log存储器写入日志时,每条分片日志记录在k = f + 1个log存储器上同步复制。只有当所有的k都以成功储存后,代理才能将提交响应发送回客户端,即使日志服务器故障,事务系统也能正常恢复。

第三种复制策略是存储复制。每个分片,即键范围被异步复制到k = f + 1个存储服务器s中,这就是一个团队。存储服务器通常是主机的许多分片,以便其数据可以均匀分布在许多团队中。存储服务器发生故障时,数据分配器就会将数据移动到其他正常运行的团队。

FDB在实践中已经得到了良好应用,图4展示了FDB与真实数据的模拟与作用方式。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表