一致的后端和 UX:采用有哪些障碍?

Avatar of Brecht De Rooms
Brecht De Rooms

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

在很少情况下,最终一致性数据库比强一致性数据库更可取。此外,在需要扩展的多区域应用程序场景中,选择非分布式数据库或最终一致性数据库都是非常值得商榷的。那么,是什么促使工程师忽视强一致性分布式数据库呢?我们已经看到了很多原因,但错误的假设是其中大多数的原因。

“CAP 定理表明这是不可能的”

正如我们在 本系列的第 1 部分 中解释的那样,CAP 定理被广泛接受,但也经常被误解。当很多人误解一个著名的定理时,它会留下印记。在这种情况下,许多工程师仍然认为最终一致性是不可避免的弊端。

“构建强一致性分布式数据库太难/不可能”

人们逐渐认识到,不应该牺牲一致性,但许多数据库仍然将一致性放在第二位。这是为什么呢?一些流行的数据库提供了能够提供更高一致性的选项,但代价可能是非常高的延迟。他们的销售信息甚至可能声称在多区域分布式数据库中以低延迟提供一致性非常困难,甚至是不可能的,开发人员群体对在未针对一致性构建的数据库中遇到非常糟糕的延迟记忆犹新。这些因素共同加剧了强一致性分布式数据库在低延迟下不可能实现的误解。

“过早优化是万恶之源”

许多工程师根据 “过早优化是万恶之源”(唐纳德·克努斯)原则进行构建,但该声明只适用于 小的低效率。在强一致性分布式可扩展数据库上构建您的初创公司可能看起来像过早优化,因为最初您的应用程序不需要扩展,也可能不需要分布式。但是,我们在这里讨论的不是小的低效率。当您的应用程序变得流行时,扩展或分布式的需求可能会在一夜之间出现。此时,您的用户会体验到糟糕的体验,您将面临着重大挑战来更改您的基础设施和代码。

“对分布式数据库进行编程很困难”

这句话以前有一定的道理,因为分布式数据库是新事物,许多数据库都有着严重的限制。它们不允许连接,只允许键值存储,或者要求您根据预定义的分片键查询数据,而且您无法再更改这些键。如今,我们拥有具有灵活模型的分布式数据库,它们提供了您在使用传统数据库时所习惯的灵活性。这一点与前一点密切相关,前一点忽略了如今,与传统数据库相比,开始对强一致性分布式数据库进行编程一样容易,而且从长远来看可能更容易。如果一样容易,为什么不从一开始就优化呢?

使用最终一致性数据库就像…

分布式数据库通常是由那些经历过最终一致性问题的人创建的。例如,FaunaDB 是由前 Twitter 工程师创建的,他们此前经历过在最终一致性数据库(如 Cassandra)之上构建可扩展系统是多么困难。这些问题通常会在新公司开始扩展时出现,因此许多年轻的工程师从未亲身经历过这些问题。

有时痛苦的事情可以教会我们一些我们认为不需要知道的教训。

— 艾米·波勒

讨论最终一致性的危险通常会导致那些尚未遇到任何问题的工程师提出“对我来说有效”的论点。由于这通常需要几个月(如果幸运的话,可能需要几年),让我们看一个类比。

…骑一辆松动轮子的自行车。

前一段时间,我最好的朋友快要错过约会了,所以我借给了他我的自行车。我很高兴能帮到他,他也非常高兴,一切都进展顺利。当他试图将自行车跳到人行道上时,这种快乐很快变成了痛苦。你明白吗…我那天早些时候摆弄过自行车,忘记把前轮拧紧了。他回来时腿上有一个巨大的紫色的淤青。

自行车示例与使用非强一致性数据库非常相似。在您尝试抬起自行车的车轮(或者换句话说,在您的公司起飞并开始扩展之前)之前,一切都会进展顺利。

当您的应用程序需要扩展时,您通常会通过复制服务来实现扩展。当数据库成为瓶颈时,您会复制传统数据库或迁移到分布式数据库。不幸的是,此时,当您开始复制数据库时,应用程序中的功能可能会失效。到目前为止,您还没有注意到这些问题,因为数据库运行在一个节点上。此时,可能会发生两件事:

  • **情况 1,围绕它构建/修复它:** 开发人员很快就会意识到,他们正在“骑”的数据库对于他们已经构建或正在尝试构建的功能不可靠。他们的选择归结为取消功能、简化功能或更改数据库。
  • **情况 2,彻底失败:** 开发人员没有从供应商(我是一个糟糕的自行车供应商)那里得到关于风险的充分信息,现在他们缺乏了解正在发生的事情的微妙含义的信息。这并不一定是因为工程师能力不足。定义不清晰的标准和过于乐观的营销会有效地模糊不同数据库的一致性保证。

最终处于第一种情况的开发人员通常已经非常熟悉处理最终一致性系统。他们现在要么接受他们无法交付某些功能,要么在数据库之上构建一个复杂且难以维护的层以获取他们所需的功能。本质上,他们试图在最终一致性数据库之上开发一个强一致性数据库。这很可惜,因为其他人已经从头开始设计了分布式数据库,这些数据库不仅更高效,而且不需要您的开发团队维护!

…骑一辆轮子松动的隐形自行车。

最终处于第二种情况的开发人员正在骑一辆部分隐形的自行车。他们没有意识到车轮是松动的,没有看到车轮脱落,当他们跌倒后抬起头时,他们仍然看到一辆完好无损的自行车。

当问题出现时,由于以下几个原因,解决这些错误的复杂性很高:

  • **确定它是否是一个最终一致性错误。** 问题可能是应用程序错误,也可能是由于误解了底层数据库的保证而导致的错误。为了确定原因,我们需要调查应用程序逻辑,如果应用程序逻辑在非分布式环境中是合理的,工程师必须具备本能,评估这种情况是否可能是由最终一致性导致的。
  • **原因消失了。** 其次,由于数据库最终会变得一致,因此问题的根源可能已经消失了(车轮神奇地重新连接到自行车上,你看到的只是一辆完美的自行车)。
  • 修复它! 确定问题后,您可以选择绕过它,尝试在数据库之上构建一层(hello 延迟和其他潜在的 bug),删除功能或更改数据库。 最后一个选项有时被认为很容易。 但是,即使是最细微的数据库差异也会使这项工作变得非常具有挑战性。 在您的应用程序起飞时,您已经忙得不可开交。 这不是您想要交换数据库的时刻!

…骑着一辆看不见的自行车,车轮松动,一群人站在你的肩膀上。

看不见的自行车示例仍然过于宽容。 实际上,其他人可能依赖于您的应用程序。 因此,基本上,您正在骑着一辆看不见的自行车,而其他人(您的客户)则站在您的肩膀上。

您不仅会摔倒,而且他们也会与您一起摔倒,然后重重地痛苦地落在您身上。 您甚至可能无法从这次坠落中幸存下来; 换句话说,您的公司可能无法从客户的负面反馈风暴中幸存下来。

这个故事的寓意是什么? 如果您一开始就选择了强一致性(而不是最终一致性)的数据库,您就不必考虑在客户已经感到沮丧的情况下,进行像迁移数据库这样的复杂且资源密集型项目。

结论

几年前,选择最终一致性数据库进行扩展是合理的,因为当时别无选择。 但是,我们现在拥有现代数据库,它们可以有效地扩展,而不会牺牲数据一致性或性能。 此外,这些现代数据库还包括许多其他超越一致性的强大功能,例如易用性、无服务器定价模型、内置身份验证、时间性、原生 GraphQL 等等。 使用现代数据库,您可以扩展而不打开潘多拉的盒子!

而且,如果您在阅读完本系列文章后,仍然选择不使用强一致性分布式数据库,请至少确保将车轮拧紧(换句话说,阅读并了解不同数据库的 一致性保证)。