将无模式演化为分布式SQL数据库

将无模式演化为分布式SQL数据库

介绍

2016年,我们发表了博客文章(雷竞技到底好不好用一世II)关于SmanceAless - Uber Engineering的可扩展数据存储。我们越过了艺术模式的设计,并解释了发展背后的推理。今天在这篇文章中,我们将讨论模板的演变为名为DocStore的通用事务数据库。

Docstore是一个通用的多模型数据库,它提供了一个严格的分区级别上的可序列化一致性模型并且可以水平扩展以服务高容量的工作负载。诸如事务、物化视图、关联和变更数据捕获等特性与建模灵活性和丰富的查询支持相结合,显著提高了开发人员的工作效率,并减少了新应用程序在Uber的上市时间。

Docstore目前处于生产状态,提供关键业务用例。

动机

无模式最初被设计为仅限申请的数据存储。最小的实体称为单元格,它是不可变的。去除变形性降低了系统的复杂性,使其变得越来越容易发生。然而,随着时间的推移,我们意识到限制性的API和建模能力使用户难以用作通用数据库。

Schemaless的缺点导致了Cassandra的引入,它确实提供了很大的灵活性和易用性。然而,卡桑德拉还有其他缺点。优步拥有庞大的数据足迹,在这样的规模下,可扩展性和效率必须齐头并进。我们发现Cassandra在Uber的规模上缺乏运营成熟度,同时也没有提供理想的效率水平。Cassandra提供的最终一致性也最终阻碍了开发人员的生产力,因为他们不得不围绕缺乏强一致性进行设计,这使应用程序体系结构变得复杂。

拥有开发和操作的艺术模式和Cassandra的第一手经验,得出结论,即将概况进入通用事务数据库是最佳选择。Mleaneless传统上是一个高度可靠的系统,但现在我们需要专注于可用性,同时实现类似或更好的可靠性!

设计注意事项

我们不想建立一个NoSQL系统。我们希望提供最佳世界:文档模型的架构灵活性,以及​​传统关系模型中看到的架构实施。

我们在Docstore中设计了表来对数据强制使用模式。使用数据的应用程序通常假定某种结构。这意味着它们要么利用读时模式(在这种情况下,应用程序在读取数据时解释数据),要么利用写时模式(这确保模式是显式的,并且数据库确保数据符合模式)。默认情况下,我们支持“写时模式”的后一种方法。

连同上面描述的模式强制,Docstore还提供了模式灵活性。模式发展。允许具有不同模式的记录共存,模式更新不需要重新构建全表。第一流的特性是稀疏性和对复杂嵌套数据类型的支持。

特性集

Docstore具有以下内置特性。它与优步软件生态系统集成,只需点击一个按钮就可以提供。

图1 - Docstore特性

体系结构

Docstore具有分层架构,Docstore部署称为实例。每个实例被划分为查询引擎层、存储引擎层和控制平面。

图2 - Docstore分层架构

查询层是无状态的,负责将请求路由到存储层。

负责存储数据的存储引擎被组织为一组分区,并且数据分布在这些分区上。控制平面负责将碎片分配给DocStore分区,并自适应地调整换档放置响应失败事件。

docstore有一个表的概念。表看起来像关系数据库表,因为它们是由行,列和值的结构化。对于如何在Docstore中建模表没有任何限制,并且通过使用用户定义的类型,Docstore可以将嵌套记录存储为行。这很有用,例如,当数据具有类似于文档的结构时,整个层次结构一次加载。Docstore还支持“关联”,允许表示一对多和多对多的关系。我们称其为灵活文档模型,因为它允许对关系数据模型和层次数据模型进行建模。我们将在本系列博客的第2部分中介绍Docstore中的数据建模。雷竞技到底好不好用

每个表都可以具有一个或多个物化视图。物化视图是允许的视图通过使用不同的列,将数据与主表进行不同的分区。添加一个由非主键列划分的物化视图可以有效地通过该列查找数据,并允许不同的查询访问模式。

每个表必须有一个主键,而主键可以由一个或多个列组成。主键标识表中的行并实施唯一约束。在内部,主键和分区键列被存储为一个字节数组,值是通过对键列值进行保留顺序的编码来派生的。Docstore按照主键值的顺序存储行。与复合分区键结合使用,可以实现复杂的查询模式,包括使用给定的分区键获取所有行,或者使用主键的其余部分来缩小特定查询的相关行。

图3 - Docstore表布局

对于我们来说,设计过程的下一步自然是处理分片逻辑的实现。表被分片并跨多个分片分布——对应用程序是透明的。每个分片表示表中的一组行,其顺序为几百gb,整个分片被分配给一个分区。一个分区可以包含一个或多个碎片。

重要的设计考虑因素是让应用程序通过它们的键选择来控制数据位置。这就是我们如何引入分区键除了主键。应用程序可以选择显式定义架构中的分区键,否则DocStore使用主键以分离数据。

通常,每个Docstore实例中有多个分区。为了消除单点故障,分区是由3-5个节点组成的一组,每个节点是物理隔离的一个单元,并部署到一个独立的区域。每个分区被复制到多个地理位置,以提供数据中心故障的弹性。

图4 - DocStore数据分区

复制状态机

为了确保一致性,每个分区都运行raft共识协议。只有一个领导者和多个追随者。

图5 -文档存储复制状态机

所有的写入都是由领导发起的。实现的共识协议用于在分区中的节点之间保持复制的日志的一致性。这保证了分区中的所有节点以相同的顺序包含相同的写入,确保了可序列化性。运行在每个节点上的状态机只有在达成共识时才会提交写操作。这提供了一个非常好的属性:如果成功提交了对键的写入,那么通过同一键的所有后续读操作将返回由这个特定操作或某个稍后操作写入的相同数据。

一致性模型

Docstore在分区级别上提供了严格的序列化一致性模型。这为用户提供了一个很好的属性,在这个属性中,他们可以想象事务是按顺序执行的。事务的顺序是:事务a在事务B之前启动并提交,总是在事务B之前。这确保了读操作总是返回最近写操作的结果。从CAP理论术语来看,Docstore更注重一致性而非可用性,因此是一个CP系统。

交易

Docstore使用MySQL作为底层数据库引擎。复制状态机中的复制单元是一个MySQL事务。所有的操作都在MySQL事务的上下文中执行,以保证ACID语义。然后使用筏共识协议在节点之间复制这些事务。

图6 -事务中的操作序列

我们依赖于MySQL进行并发控制。MySQL依赖行锁来实现对写操作(插入、更新、删除)的并发控制,这一点很重要。因此,对相同行的并发更新被MySQL有效地序列化了,当控制流到达发出提交的客户端时,所有的锁都被处理了。

我们使用图7中的流程图来显示两个交易交互及时交互的情况发生了什么。我们在时间轴上使用不同位置的框以表达交错,即不同框对应于不同的“事件”。

图7 -交错插入

基于大量的复制状态机实现允许暴露MySQL的客户事务在一个高度可用的方式,即所有的副本相互协调申请副本之间的交易,以便自动故障转移是可能的事务的ACID属性时仍保持即使发生了故障转移。注意,因为我们依赖于向客户端公开MySQL的事务,所以MySQL事务的所有好处和约束都被继承了。

图8 - Docstore事务流程

结论

在本文中,我们已经涵盖了Genesis和DocStore背后的动机。我们也深入了解架构,并解释了如何在DocStore中处理事务。在此多部分系列的下一部分中,我们将专注于数据建模和架构管理。我们将介绍DocStore如何支持层次结构和关系模型以及哪种类型的应用程序应选择这些数据模型。在本系列的第三个和结论部分中,我们将详细介绍DocStore的物化视图。这包括动机,MV刷新框架以及我们计划如何利用MVS,即使在查询中未明确提及。

如果你喜欢这篇文章,并想从事与全球分布式系统相关的系统和挑战,为Uber的运营存储提供动力,请探索并申请Uber的存储团队的空缺职位门户网站

评论
前一篇文章 快速和可靠的模式无关的日志分析平台
下一篇文章 优步如何应对大型iOS应用
OVAIS是优步核心存储团队的SR.经理。他领导了运营存储平台集团,重点是提供一个世界一流的平台,为优步提供支持所有关键业务功能和业务行。该平台为数千万QPS提供了99.99%或更多的可用性,并存储了数十张Petabytes的操作数据。
Deba担任UBER基础架构团队的SR.产品经理。在Uber之前,Deba在数据库启动和Oracle中工作了各种产品管理角色。在进入产品管理之前,Deba负责管理大数据仓库的性能。Deba从upenn拥有硕士技术管理。
HIMANK是优步学士学位的科技领先权。他的主要焦点面积正在建立分布式数据库,与优步的超增长一起扩展。在Uber之前,他在亚洲邮件后端团队工作了一个元数据存储。Himank拥有纽约州立大学的计算机科学硕士学位,专业化分布式系统。

没有帖子显示