分布式数据库FoundationDB介绍(一)
FoundationDB是一个开源数据库项目,最初于2012年1月进行Alpha测试,2013年4月进行Beta测试。2013年8月20日正式发布了1.0版本。两年后的2013年3月25日被苹果公司收购以后不再开源。苹果公司于2018I年4月19日再次开源。
本文通过FoundationDB官网学习,记录FoundationDB相关重要知识点。
FoundationDB有哪些优势?
- 多模型数据存储。FoundationDB 是多模型的,这意味着可以在单个数据库中存储多种类型的数据。所有数据都安全地存储,分发和复制在键值存储组件中。
- 易于扩展和容错。FoundationDB 易于安装、扩展和管理。它有一个分布式架构,可以优雅地向外扩展,并在像单个 ACID 数据库一样处理故障的同时。
- 行业领先的性能。FoundationDB 在商品硬件上提供惊人的性能,能够以低成本支持非常重的负载。
- 生产实践。FoundationDB 已在生产环境中运行多年,并通过汲取的经验教训加以巩固。支持 FoundationDB 的是一个无与伦比的基于确定性模拟引擎的测试系统。
FoundationDB架构
FoundationDB 使应用架构灵活且易于操作。应用程序可以将它们的数据直接发送到 FoundationDB 或layer,这是一个用户编写的模块,可以提供新的数据模型、与现有系统的兼容性,甚至可以作为一个完整的框架。在这两种情况下,所有数据都通过一个有序的、事务性的键值 API 存储在一个地方。
FoundationDB 架构详解
FoundationDB 架构选择解耦设计,其中进程被分配不同的异构角色(例如,Coordinators、存储服务器、Master)。通过水平扩展不同角色的进程数量来扩展数据库:
-
Coordinators
所有客户端和服务器都使用群集文件连接到FoundationDB群集,该群集文件包含协调程序的IP:PORT。客户端和服务器都使用协调器与集群控制器连接。如果不存在,服务器将尝试成为集群控制器,并在选出一个后向集群控制器注册。客户端使用集群控制器来保持最新的代理列表。
- 集群控制器
集群控制器是由大多数协调器选出的单例。它是集群中所有进程的入口点。它负责确定进程何时失败,告诉进程它们应该成为哪些角色,并在所有进程之间传递系统信息。
- Master
master 负责协调 write 子系统从一代到下一代的过渡。写入子系统包括主、代理、解析器和事务日志。这三个角色被视为一个单位,如果其中任何一个失败,我们将招募所有三个角色的替代者。master 为代理提供批量突变的提交版本。
历史上,Ratekeeper 和 Data Distributor 与 Master 耦合在同一进程上。从 6.2 开始,两者都成为集群中的单例。生命时间不再与师父绑定。
- 代理
代理负责提供读取版本、提交事务并跟踪负责每个密钥范围的存储服务器。为了提供读取版本,代理将要求所有其他代理查看此时最大的已提交版本,同时检查事务日志是否未停止。Ratekeeper将人为地降低代理提供读取版本的速度。
提交是通过以下方式完成的:
- 从 master 获取提交版本。
- 使用解析器确定事务是否与先前提交的事务冲突。
- 使事务在事务日志上持久化。
以\xff
字节开头的密钥空间是为系统元数据保留的。提交到该密钥空间的所有变更都通过解析器分发给所有代理。该元数据包括键范围和具有该范围键数据的存储服务器之间的映射。代理按需向客户提供此信息。客户端缓存这个映射;如果他们向存储服务器询问它没有的密钥,他们将清除缓存并从代理获取更新的服务器列表。
- 事务日志
事务日志使更改持久化到磁盘以实现快速提交延迟。日志按版本顺序从代理接收提交,并且只有在数据被写入并同步到磁盘上的仅附加突变日志后才响应代理。在数据甚至写入磁盘之前,我们将其转发到负责该突变的存储服务器。一旦存储服务器使突变持久化,它们就会从日志中弹出它。这通常发生在最初将突变提交到日志后大约 6 秒。我们只在进程重新启动时从日志的磁盘中读取。如果存储服务器发生故障,则绑定到该存储服务器的突变将在日志中累积。
- 解析器
解析程序负责确定事务之间的冲突。如果事务读取在事务的读取版本和提交版本之间写入的键,则事务会发生冲突。解析器通过在内存中保存最后 5 秒提交的写入,并将新事务的读取与这组提交进行比较来做到这一点。
- 存储服务器
集群中的绝大多数进程都是存储服务器。存储服务器被分配了密钥范围,并负责存储该范围内的所有数据。他们在内存中保留 5 秒的突变,并在 5 秒前保留数据的磁盘副本。客户端必须在最后 5 秒内读取一个版本,否则会 transaction_too_old出错。SSD 存储引擎将数据存储在基于 SQLite 的 B 树中。内存存储引擎将数据存储在内存中,并带有仅在进程重新启动时从磁盘读取的附加日志。在即将发布的 FoundationDB 7.0 版本中,B-tree 存储引擎将被全新的Redwood 引擎取代。
- 数据分发器
数据分配器管理存储服务器的生命周期,决定哪个存储服务器负责哪个数据范围,并确保数据在所有存储服务器 (SS) 上均匀分布。数据分发器作为集群中的单例由集群控制器招募和监控。
- 监控系统
Ratekeeper 监控系统负载并在集群接近饱和时通过降低代理提供读取版本的速率来降低客户端事务速率。Ratekeeper 作为集群中的单例,由 Cluster Controller 招募和监控。
- 客户
客户端与特定语言绑定(即客户端库)链接,以便与 FoundationDB 集群通信。语言绑定支持加载多个版本的 C 库,允许客户端与旧版本的 FoundationDB 集群通信。目前,官方支持 C、Go、Python、Java、Ruby 绑定。
- 事务处理
FoundationDB 中的数据库事务由客户端联系其中一个代理以获取读取版本开始,该版本保证大于客户端可能知道的任何提交版本(甚至通过 FoundationDB 集群之外的侧通道)。这是必需的,以便客户端将看到已发生的先前提交的结果。
然后客户端可以向存储服务器发出多次读取并获取该特定读取版本的值。客户端写入保存在本地内存中,无需联系集群。默认情况下,读取在同一事务中写入的键将返回新写入的值。
在提交时,客户端将事务数据(所有读取和写入)发送到代理之一,并等待来自代理的提交或中止响应。如果事务与另一个事务冲突而无法提交,客户端可能会选择从头开始重试事务。如果事务提交,代理还将提交版本返回给客户端。请注意,此提交版本大于读取版本,并由 master 选择。
FoundationDB 架构将客户端读取和写入(即事务提交)的扩展分开。由于客户端直接向分片存储服务器发出读取,因此读取与存储服务器的数量成线性关系。类似地,通过向事务系统中的代理、解析器和日志服务器添加更多进程来扩展写入。更多FoundationDB事务处理相关的技术,将在后面单独去讨论。
- 点赞
- 收藏
- 关注作者
评论(0)