译文:将Uber的万亿条分类账数据从DynamoDB迁移到L...

以云看科技 2024-09-08 01:26:28

介绍

上周,我们探索了LedgerStore (LSG) – Uber 的附加式账本式数据库。本周,我们将深入探讨如何将 Uber 的业务关键型账本数据迁移到 LSG。我们将详细介绍如何透明且不造成中断地移动超过一万亿个条目(占几 PB 的数据),并讨论我们在迁移过程中学到的东西。

历史

Gulfstream 是 Uber 的支付平台。它于 2017 年推出,使用 DynamoDB 进行存储。在 Uber 的规模下,DynamoDB 变得昂贵。因此,我们开始在 DynamoDB 中仅保留 12 周的数据(即热数据),并开始使用 Uber 的 blobstore TerraBlob 来存储较旧的数据(即冷数据)。TerraBlob 类似于 AWS S3。

对于长期解决方案,我们希望使用LSG。它是专门为存储支付数据而设计的。其主要功能包括:

它是可验证的不可变的(即,您可以使用加密签名检查记录是否被更改)分层存储以管理成本(热数据保存在最适合服务请求的地方,冷数据存储在针对存储进行优化的地方)最终一致的二级索引的滞后效果更佳

因此,到 2021 年,湾流公司将使用 DynamoDB、TerraBlob 和 LSG 的组合来存储数据。

DynamoDB 过去 12 周的数据TerraBlob,Uber 的内部 blob 存储库,用于存储冷数据LSG,我们在那里写入数据,并希望迁移到它为什么要迁移?

由于 LSG 具有不可更改性,因此更适合存储账本式数据。迁移到 LSG 可以节省大量经常性成本。

从三个存储变为一个存储将简化负责与存储交互和创建索引的 Gulfstream 服务的代码和设计。这反过来又使服务更易于理解和维护。

LSG 承诺缩短索引延迟(即写入记录和创建其二级索引之间的时间)。此外,由于它在 Uber 数据中心内部运行,因此它可以缩短网络延迟时间。

图 1:迁移前后的数据流

数据性质及相关风险

我们正在迁移的数据是 Uber 自 2017 年以来所有业务的账本数据:

不可变记录 – 压缩后大小为 1.2 PB二级索引 – 未压缩大小为 0.5 PB

不可变记录不应被修改。因此,出于所有实际目的,一旦我们写入记录,就无法更改。我们确实可以灵活地修改二级索引数据以纠正问题。

检查

为了确保回填在各方面都是正确且可接受的,我们需要检查是否可以处理当前流量,并且当前未访问的数据是否正确。其标准是:

完整性:所有记录均已补填。正确性:所有记录均正确。负载:LSG 应该能够处理当前负载。延迟:LSG 的 P99 延迟在可接受范围内。延迟:二级索引是在后台创建的。我们希望确保索引创建过程的延迟在可接受的范围内。

检查是采用影子验证和离线验证相结合的方式进行的。

影子验证

这会将我们在迁移之前返回的响应与使用 LSG 作为数据源时返回的响应进行比较。这有助于我们确保当前流量不会因数据迁移问题或代码错误而中断。我们希望我们的回填至少达到 99.99% 的完整度和正确度(通过影子验证来衡量)。我们还为此设定了 99.9999% 的上限。设定上限的原因是:

迁移历史数据时,总是存在数据损坏问题。有时这是因为在服务初始开发时数据写入不正确。由于规模,也有可能看到数据损坏。例如,S3 提供 11 个 9 的耐用性保证,那么 1 万亿条记录中可能会出现 10 次损坏。索引最终是一致的,这意味着一些记录会在几秒钟后出现。因此,影子验证会将它们标记为缺失。这是一种大规模出现的误报。对于 6 个 9,您必须查看 1 亿次比较的数据才能得出可信度高的结果。这意味着,如果您的影子验证每秒比较 1,000 条记录,那么您需要等待一天多一点的时间才能收集到足够的数据。对于 7 个 9,您将不得不等待 12 天。实际上,这会使项目停滞不前。有了明确定义的上限,您就不必考虑您怀疑的每一个潜在问题。假设某个问题的发生率是上限的 1/10,您甚至不需要调查它。如果正确率达到 6 个 9,我们最终可能会得到略多于 100 万条的损坏记录。尽管 6 个 9 的确认正确性可能对公司来说意味着实际成本,但该项目带来的节省超过了潜在成本。

在影子验证期间,您实际上是在 LSG 上复制生产流量。因此,通过监控 LSG,我们可以验证它是否可以处理我们的生产流量,同时满足我们的延迟和滞后要求。这让我们对我们为从 LSG 访问数据而编写的代码充满信心。此外,它还让我们对数据的完整性和正确性充满信心,特别是对于当前正在访问的数据。我们开发了一个通用的影子验证代码,该代码在迁移的不同部分被多次重复使用。

在迁移过程中,我们发现了由于不同部分中的多个错误而导致的延迟和滞后问题,并对其进行了修复。

分区键优化,实现索引数据更好的分布索引问题导致扫描记录而不是点查找

不幸的是,实时影子验证无法为我们很少访问的历史数据提供强有力的保证。

离线验证和增量回填

这会将 LSG 中的完整数据与 DynamoDB 中的数据转储进行比较。由于各种数据问题,您必须跳过不良记录以确保回填能够顺利完成。此外,回填作业本身也可能存在错误。离线验证可确保数据回填正确进行并且涵盖完整数据。除了影子验证之外,还必须进行此操作,因为实时流量往往只访问最近的数据。因此,如果冷数据中隐藏着不经常访问的问题,影子验证将无法发现它。

离线验证的关键挑战是数据大小。我们处理的最大数据是压缩后 70 TB(未压缩时估计为 300 TB),我们在单个作业中比较了 7600 亿条记录。这种类型的 Apache Spark TM作业需要数据改组,而分布式改组即 Spark 服务与动态资源分配和推测执行相结合,让我们能够在资源受限的情况下以合理的速度完成这一任务。

离线验证发现缺失记录,其输出用于增量回填。我们在离线验证和回填之间进行迭代,以确保所有记录都已写入。

回填问题

每次回填都存在风险。我们使用 Uber 内部提供的 Apache Spark 进行回填。以下是我们遇到的不同问题以及我们如何处理它们。

可扩展性

您需要从小规模开始,然后逐渐扩大规模,直到达到系统的极限。如果您只是盲目地超越这一点,那么您实际上是在对自己的系统发起 DDoS 攻击。此时,您需要找到瓶颈,解决它,然后扩大您的工作。大多数情况下,这只是扩大下游服务的问题,其他时候则可能是更复杂的事情。无论哪种情况,您都不希望将回填作业的规模扩大到超出系统瓶颈的能力。最好以小幅度增加规模并在每次扩大后密切监控。

增量回填

当您尝试在 3 个月内回填 3 年的数据时,您产生的流量是正常流量负载的 10 倍,系统可能无法应对这种流量。例如,当您的生产通常以 1K/秒的速率处理时,您需要 120 天才能以 10K/秒的速率回填 100B 条记录。因此,您可以预料到系统会超载。如果回填作业有可能导致持续问题,即使可能性很小,您也必须将其关闭。因此,期望回填作业可以一次性从头到尾运行是不现实的,因此您必须逐步运行回填。

一种简单有效的方法是将回填分成可以逐个完成的小批次,以便每个批次可以在几分钟内完成。由于您的作业可能会在批次中间关闭,因此它必须是幂等的。每次完成一个批次时,您都希望将统计信息(例如读取的记录、回填的记录等)转储到文件中。随着回填的继续,您可以从中汇总数字以检查进度。

如果您可以删除或更新现有记录,则可以降低补填期间出现错误和代码错误的风险和成本。

速率控制

为了安全地进行回填,您需要确保您的回填作业的行为一致。因此,您的作业应该具有速率控制,可以轻松调整以扩大或缩小规模。在 Java/Scala 中,您可以使用 Guava 的 RateLimiter。

动态速率控制

在某些情况下,当生产流量较少时,您可能能够加快速度。为此,您需要监视系统的当前状态并查看是否可以加快速度。我们按照加法增加/乘法减少的路线调整了 RPS 。为了安全起见,我们仍然对流量设置了上限。

紧急停止

迁移过程需要能够在发生中断或甚至怀疑过载时快速停止回填。中断期间的任何回填都必须停止,这既是预防措施,也是潜在的噪音源。即使在中断后,系统在恢复时也往往会承受额外的负载。停止回填的能力也有助于调试与规模相关的问题。

数据文件大小

转储数据时,请将文件大小保持在 1GB 左右,并在两侧提供 10 倍的灵活性。如果文件大小太大,您会遇到诸如不同工具的 MultiPart 限制之类的问题。如果文件大小较小,则文件太多,甚至列出它们都需要花费大量时间。在 shell 中运行命令时,您甚至可能会开始达到 ARGMAX 限制。这变得非常重要,以确保每次对数据执行操作时,它都已应用于所有文件,而不仅仅是其中一些文件。

容错

所有回填作业都需要某种数据转换。执行此操作时,不可避免地会遇到数据质量/损坏问题。每次发生这种情况时,您都不能停止回填作业,因为此类不良记录往往是随机分布的。但您也不能忽略它们,因为这也可能是由于代码错误造成的。为了解决这个问题,您可以单独转储有问题的记录并监控统计数据。如果失败率很高,那么您可以手动停止回填,解决问题,然后继续。否则,让回填继续并并行查看故障。

记录未写入的另一个原因是 RPC 超时。您可以重试,但在某些时候,无论原因是什么,您都必须放弃并继续前进,以确保您可以取得进展。

日志记录

在回填期间记录日志以帮助调试和监控进度是很有诱惑力的,但这可能无法实现,因为它会给日志基础设施带来压力。即使您可以保留日志,也会有太多的日志数据无法保留。解决方案是使用速率限制器来限制您生成的日志量。您只需要对生成大部分日志的部分进行速率限制。如果错误不经常发生,您甚至可以选择记录所有错误。

降低风险

除了分析来自不同验证和回填统计数据的数据外,我们对 LSG 的推出也持保守态度。我们在几周内推出了它,并得到了我们服务主要呼叫者的值班工程师的批准。我们最初推出了回退功能(即,如果在 LSG 中找不到数据,我们将尝试从 DynamoDB 中获取数据)。在删除回退之前,我们查看了回退日志。对于回退日志中标记为丢失的每条记录,我们都会检查 LSG,以确保它不是真的丢失。即使在那之后,我们仍将 DynamoDB 数据保留了一个月,然后才停止向其中写入数据,进行了最后一次备份,并删除了表。

图 2:LSG 的推出

结论

在本文中,我们介绍了将大量业务关键型资金数据从一个数据存储迁移到另一个数据存储的过程。我们介绍了迁移的不同方面,包括迁移标准、检查、回填问题和安全性。我们能够在两年内完成此迁移,迁移期间或迁移后没有任何停机或中断。

致谢

感谢 Amit Garg 和 Youxian Chen 帮助我们将数据从 TerraBlob 迁移到 LSG。感谢 LSG 团队的 Jaydeepkumar Chovatia、Kaushik Devarajaiah 和 Rashmi Gupta 在整个工作过程中给予我们的支持。感谢 Menghan Li 迁移Uber Cash账本的数据。

封面照片归属:美国鱼类和野生动物管理局山地草原拍摄的“休伦湿地管理区日落时分的水禽迁徙”标有公共领域标记 1.0。

Amazon Web Services、AWS 和 Powered by AWS 徽标是 Amazon.com, Inc. 或其附属公司的商标。

Apache®、Apache SparkTM 和 SparkTM 是 Apache 软件基金会在美国和/或其他国家/地区的注册商标或商标。使用这些商标并不代表 Apache 软件基金会对其的认可。

作者:

Raghav Gautam

Raghav Kumar Gautam is a Staff Software Engineer on the Money Data and Insights teams at Uber. He primarily focuses on data related problems for the Money Team. Raghav holds a Master’s degree in Internet Science and Engineering from Indian Institute of Science, Bengaluru.

Erik Seaberg

Erik Seaberg is a former Staff Software Engineer who joined Uber to focus on transaction storage and reporting at scale. He has a Bachelor’s degree in Computer Science from the University of Washington in Seattle.

Abhishek Kanhar

Abhishek Kanhar is a Senior Software Engineer at Uber. Currently, he focuses on developing a scalable and unified architecture for generating reports tailored to Uber’s large enterprise partners. Abhishek holds a bachelor’s degree in computer science from the Indian Institute of Technology, Roorkee.

出处:https://www.uber.com/en-JP/blog/migrating-from-dynamodb-to-ledgerstore/

0 阅读:0

以云看科技

简介:感谢大家的关注