Uber的无模式数据存储的多数据中心复制引擎

0
Uber的无模式数据存储的多数据中心复制引擎

无模式Uber的容错和可扩展的数据存储支持我们运营的600多个城市和每天在我们平台上发生的1500万次出行,更不用说Uber Eats、Uber Freight和其他业务线了。自2014年以来,我们已经部署了50多个Schemaless实例,每个实例都有多个数据存储和数千个存储节点。

随着我们的业务在全球市场的扩展,我们需要将数据复制到多个数据中心的能力,以支持我们的active - active架构.复制的数据集让我们的应用程序尽可能无缝地跨数据中心进行读写在数据中心故障的情况下,允许应用程序继续正常工作。

为了满足这些需求,我们构建了Herb,我们的复制解决方案。Herb是用Go构建的,Go是Uber Engineering公司比较流行的语言之一。每当数据写入一个数据中心时,Herb可以将该数据复制到其他数据中心,以确保弹性和可用性。Herb还与传输协议无关,允许网络灵活性和对未来体系结构的适用性。

设计的挑战

当我们开始设计和确定Herb将解决的复制问题时,我们确定了一些要求,这些要求将迫使我们对我们的解决方案具有创造性:

草药设计挑战
图1:我们设计的复制系统需要解决五个关键问题。

  • 一致性:为了创建无缝的用户体验,我们需要确保参与复制的所有数据中心之间的数据是新鲜的和一致的。不一致的数据可能会导致我们平台上的次等体验。
  • 至少一次交付:由于Schemaless只是附加的,数据存储重新应用更新这不是问题。
  • 按顺序交付新更新:所有更新都必须基于数据中心的来源进行排序。例如,来自DC的更新1在华盛顿会有同样的订单吗2,反之亦然。通过这种方法,应用程序可以从任何数据中心读取数据,并根据源查看相同的有序更新。
  • 不同的消费速度:不同的数据中心以不同的速度消耗数据。随着Uber的扩展,我们必须确保较慢的数据中心不会阻止复制到较快的数据中心。
  • 容错:我们需要一个容错的解决方案,这意味着一个数据中心的故障不会影响到其他数据中心的复制。

系统设计与体系结构

草药图
图2:此图表示具有“n”个数据中心的网格复制拓扑,即Herb将每个无模式实例连接到其他数据中心中的所有其他实例。

每个Herb数据中心管理一个拓扑。在完整的网格拓扑中,每个节点都直接连接到其他节点。在此上下文中,每个数据中心连接到所有其他数据中心复制Etup由多个流组成,每个数据中心的每个方向都有一个流。当在数据中心的一个Schemaless实例中发生写操作时,Herb负责将写操作传输到所有其他数据中心。这样,如果一个数据中心出现故障,其他数据中心仍然可以访问它的数据。

草药图
图3:在本例中,有5个任务,其中3个分配给Host1上的Herb worker,其余2个由Host2上的Herb worker处理。

Herb部署在多台主机上。对于主机发现,它利用了Uber命名方案(UNS),这是Uber自主开发的服务注册解决方案。每个Herb流程可以有多个任务,换句话说,一个Herb流程中的一个工作单元,如上面的图3所示。任务之间没有依赖关系,每个任务都是独立执行的Goroutine

我们将Herb的传输设计为可配置的,因此它不与任何单一的协议耦合。例如,我们首先使用传输控制协议(TCP),然后转移到超文本传输协议(HTTP),并且目前正在使用YARPC, Uber的开源远程过程调用(RPC)平台用于Go服务。我们实现传输层的方式允许轻松扩展到任何其他协议。

对于数据库阅读器,我们最初尝试在原型中使用轮询阅读器。然而,数据库查询是资源密集型的,我们发现不断轮询零或低流量数据存储会导致不必要的数据库负载。这种方法既不高效也不可扩展,所以我们实现了一个流阅读器。我们选择提交日志作为流源,因为这些日志包含所有最近的更新,不需要数据库查询来捕获它们的数据。

确保更新的本地数据中心顺序是我们设计的一个重要部分,因为这个约束极大地简化了使用数据的应用程序的逻辑。这些应用程序不需要担心本地起源的顺序,因为从任何地方读取更新都会得到相同的顺序。当Herb收到来自一个数据中心的写确认时,它更新该数据中心的偏移量。这种单独的偏移量跟踪帮助数据中心在重启或故障等场景中以不同的速度运行。同时,Herb维护我们数据中心更新的顺序。

为了理解赫伯是如何维护它的顺序,假设我们有更新一个bcd,e在华盛顿订购1(见图7和图8)另一个数据中心DC2可能已经申请并确认更新d而直流3.正在更新中一个.在这个例子中,如果赫伯在华盛顿1重新启动,然后它将发送更新e到DC2但直流3.还会从什么时候开始接收更新b.由于所有这些更新都起源于一个数据中心,这意味着更新顺序应该保留在DC2和直流3.

无模式的更新只附加到数据存储。在重新启动的情况下,我们重放来自最后一个持久偏移量的更新。因为写是幂等的,所以再次应用更新应该不是问题。例如,假设DC2已收到更新一个b,c.同时,赫伯在华盛顿1重新启动,只收到更新确认一个.在本例中,DC1可以重放更新开始在b和直流2可能会收到更新b而且c同样不影响数据存储。

流媒体

Uber将pb级的数据存储在多个数据存储中。随着数据的增加,关键是我们的复制解决方案能够相应地扩展。为了支持我们的增长,我们构建了高效的Herb,同时还减少了数据中心之间的端到端复制延迟。在最初的测试中,我们发现查询数据库的读取不能扩展。作为一种替代方案,我们提出了一种更有效的方法,通过该方法读取数据库日志来识别需要在数据中心之间复制的更新数据。这种基于日志的流模型使我们能够加快Herb的速度,并将端到端延迟减少到毫秒。

草药性能图表
图4:Herb的复制性能中值是每秒接收550-900个细胞,延迟约为82 -90毫秒。延迟还包括数据中心之间的网络通信时间,大约为40毫秒。

上面的图4显示了从生产实例中的一个数据存储中获取的图夹层,我们的无模式数据存储。该数据存储每秒接收大约550到900个单元;Herb需要大约82到90毫秒来复制这些更新,而其他数据中心可以读取这些单元。Herb的实际延迟甚至比图4所示的还要小,因为延迟中值包括了数据中心之间的网络时间,这使总延迟增加了约40毫秒。

提交日志

Herb读取的日志是事务性的,记录了应用到我们数据库的每一个更改。每个记录条目被分配一个惟一的、单调递增的数字。当然,Herb不能修改日志中的现有记录,但它会扫描并解释这些记录,以捕获对数据库所做的更改。

数据结构图
图5:日志文件存储在磁盘上,每个记录存储在一个数据文件中。对应的偏移量存储在索引文件中。

如上面的图5所示,日志由包含单个记录的数据文件和索引文件组成。索引文件用于索引给定数据文件中记录的磁盘偏移量,以避免扫描该文件。通过这样做,它以较低的延迟获得更改,并且不会影响数据库的性能。

部署模型

从部署模型的角度来看,Schemaless实例的完整集合被划分为我们称为“复制队列”的子集。

草本植物队列图
图6:每个Herb的复制队列都包含一些Schemaless实例,根据它们的需求进行分割。例如,一个高流量实例可能与一个低流量实例共享资源,因此两者可以在一个复制队列中。我们还有专门用于测试、分期和其他目的的复制队列。

一个复制队列是Herb中的一个部署单元,它包含多个Schemaless实例。队列中的实例可以彼此共享复制资源,一个部署处理Schemaless实例的一个队列。通过将关键实例放在自己的队列中,可以将它们与其他实例隔离开来。在队列中,每个实例都保证拥有最小的资源集。

调度

由于每个复制队列包含运行Herb worker的多个实例,我们需要通过无缝调度过程确保合作和协调。为了实现这一点,我们决定利用Ringpop这款开源软件专为应用程序之间的负载平衡和协调而设计。在我们的实现中,每个Herb工作者宣布自己,成为环中的一个节点,并发现其他节点。任务分配发生在成功形成环之后。

一致性

数据更新顺序图
图7:Herb防止数据中心接收无序更新。

Herb保证从本地数据中心接收到的更新的顺序,并在将这些更新传输到其他数据中心时保持该顺序。作为一个例子,上面的图7显示了数据中心DC1收到四个更新,我们将它们标记为101、201、301和401,以单调递增的顺序存储。Herb在我们的第二个数据中心DC复制数据时维护这个更新顺序2首先写101,然后是201,301和401。

由于系统支持异步复制,我们的数据中心最终会变得一致。只要远程数据中心确认了写操作,就认为它完成了。

验证和推出

作为微软杰出科学家莱斯利·兰波特有句名言在1987年,“分布式系统是一个你甚至不知道存在的计算机的故障可以使你自己的计算机无法使用的系统。”这句话说明了验证分布式系统是否正常工作的必要性,确保即使部分故障也不会破坏数据。通过Herb,我们构建了工具来验证更新的顺序,并确保数据中心之间的数据是一致的。

跟踪的交通

尽管我们在发布前测试了Herb的各个组件,但我们需要看看它在实际生产流量下的表现,以及复制的数据是否一致。使用离线工具,我们从生产实例中读取数据,并使用Herb将这些更新复制到测试实例中。当我们对Herb的一致性感到满意时,我们将其部署到生产中。

持续检查

我们还构建了一个近乎实时的验证框架来审计Herb复制的数据。该框架报告由复制引起的任何数据差异,使我们能够在生产环境中持续监视系统。

数据中心的有序更新图
图8:Herb的连续检查框架读取Schemaless节点并验证顺序。如图所示,数据块代表两个数据中心的cluster1,我们可以看到来自数据中心A的更新(101、301、401和501),两个数据中心的更新顺序相同。类似地,更新(201,601)在数据中心之间的顺序是相同的。

下一个步骤

在这个版本的Herb中,我们的主要关注点是跨地理数据中心的数据复制,并使我们的Schemaless系统活跃。在构建Herb时,我们确定了该领域的另一个改进领域:schemalless数据流,即管道数据之间OLTP数据存储到我们的数据仓库,并进一步将数据传输给消费者。考虑到这一点,下一步我们计划构建新的特性,将这些变更日志流传输给消费者,并使它们与源代码无关。

如果您对构建具有全球影响的可扩展系统感兴趣,可以考虑申请一个职位我们的团队

订阅我们的通讯以跟上优步工程的最新创新。

评论