缓慢的应用程序扼杀了业务。格雷格-林顿(在这个现已归档的甲板上)指出,100毫秒的延迟使亚马逊的销售额降低了1%。玛丽莎-梅尔(Marissa Mayer)在解释A/B测试的结果时指出,速度真的很重要,"500毫秒的额外加载时间使谷歌搜索下降了20%"。
如果缓慢的应用程序会扼杀用户体验,那么由于自然灾害、人为错误或网络攻击而导致的应用程序瘫痪又是怎么回事呢?应用程序失去对云数据中心的访问可能是令人惊讶的普遍现象。例如,一家美国金融服务公司最近与我们分享了一个关于自然灾害的故事,那场灾害离他们的两个数据中心只有几英里。
最后,世界各国政府都颁布了数据归属地的立法,旨在使用户数据贴近用户,并限制对这些数据的访问。数据归属的要求可能会迫使开发人员创建多个逻辑上相等的数据库副本,并在他们的应用程序中添加复杂的逻辑,将流量路由到适当的数据库。更多的数据库意味着更多繁琐的、重复的和容易出错的工作,使开发人员很难创建应用程序来为多个地区的用户提供服务。
无论是增加容错性以确保你的服务永不中断,还是通过在扩大市场时降低延迟来提高质量,或者遵守数据归化法规,任何企业都可以从多地区应用中受益。那么,为什么这么多的应用程序仍然在单区域部署中苦苦挣扎?
因为多区域应用从来都不容易建立或部署。在这篇文章中,我们将介绍CockroachDB如何在三个步骤中轻松构建多区域应用程序。
CockroachDB如何(最终)使多区域变得简单
CockroachDB的建立是为了将多区域架构的规模和弹性带给所有人,从业余开发者到最大的企业。你可以在任何地方部署CockroachDB(例如,自我托管的数据中心、云运行的数据中心、多云部署)。但是建立多区域的应用已经明显复杂了。
我们想让任何开发团队都能实现多区域应用--如此简单,任何人都能利用以前只留给世界上的Netflixes和Googles的规模和弹性。有了CockroachDB,你现在可以通过三个步骤在多个地区建立和部署一个应用程序。
- 将你的应用程序部署到多个地区,而不需要做任何改变。
- 将你的数据库部署到多个地区。
- 根据你的延迟需求,选择性地增强你的表模式。
大多数应用程序在单一区域开始使用单一区域的数据库。这种模式为同一地区的用户提供了很好的延迟,但当地理上有距离的用户访问时,它可能会非常慢。任何多区域应用程序的第一步是将你的应用程序部署到多个区域,最好是在适当的时候使用HTTP缓存和全局负载平衡。
将现有的应用程序部署到多个地区,是提供改进的规模和弹性的最合理的直接模式,但数据库呢?如果你的数据库没有部署在多个区域,你仍然容易受到单一故障域的影响,而用户在数据库区域外的体验会很差。
2.将你的数据库部署到多个区域
CockroachDB并不要求你改变你的应用,从单一区域发展到多区域的应用。如果传统的数据库甚至可以支持多区域的应用,而许多数据库不能,它们会要求你改变你的应用,使其成为多区域的应用。
与分片一样,其他数据库要求多区域应用程序了解其部署的区域,以便将这些信息传回数据库。传统的数据库可能需要对区域信息进行加盐或散列,并将其传递给数据库。要正确地做到这一点是很困难的,这意味着要花大量的开发人员时间重新编写应用程序和数据库。
如果没有这种意识,就很难评估全局的唯一性。例如,一个用户住在哪个地区?如果不在查询的WHERE 谓语子句中传递区域信息,即应用程序需要获得的区域信息来创建查询,开发人员将被迫对数据库中的每个区域进行唯一性检查。这种检查将引入昂贵的延迟,降低用户体验,这对认证或其他现代微服务会产生削弱作用。
集群和数据库区域
CockroachDB可以很容易地将你的数据库部署到多个区域。只需在启动时使用节点启动定位选项为集群中的每个节点设置区域信息。
cockroach start --locality=region=us-east-1,zone=us-east-1b # ...
CockroachCloud让这一点更加容易实现,因为我们会根据你选择的云提供商(例如AWS美国东部,GCP欧洲西部1)为每个多区域集群自动设置地域标志。
在节点启动过程中添加的区域在被添加到数据库时成为数据库区域。要向数据库添加第一个区域,请使用ALTER DATABASE ... PRIMARY REGION 语句。当然,你可以通过CREATE DATABASE ...PRIMARY REGION ,从一开始就创建一个多区域数据库。要添加另一个数据库区域,使用ALTER DATABASE ... ADD REGION 语句。
就这样了。
你不需要做任何其他事情来使你的应用程序和支持它的数据库成为多区域的。
默认情况下,CockroachDB将为你的数据库中的所有表提供低延迟的读写,这些表来自于第一个区域,即添加到数据库的主区域。因此,通过添加新的区域,很容易将你的集群扩展到多个区域,而不会影响到现有的用户。在添加新区域后,他们将看到与单区域数据库相同的读写延迟。
CockroachDB还将确保你在任何一个单独的节点或可用性区域(只要你有至少三个或更多的节点)的损失中自动生存,而不需要任何手动配置。
3.增强你的多区域数据库
如果我们到此为止,CockroachDB仍然是一个很好的选择,但是我们更进一步地进行了可选的配置,使你能够轻松地为你的用户提供正确的体验。
区域存活率
默认情况下,CockroachDB提供区域级的生存能力。然而,对于许多公司来说,这并不能满足他们的生存目标。因此,我们引入了区域级的生存目标,确保你的数据库在整个区域瘫痪的情况下,仍能保持完全可用的读写。这种额外的生存能力是有代价的:写延迟将至少增加到最近的区域的往返时间。读取性能将不会受到影响。换句话说,你是在增加网络跳数,使写的速度变慢,以换取健壮性。
你可以使用ALTER DATABASE ... SURVIVE REGION FAILURE 语句来配置数据库,使其在区域故障时也能生存。
表的位置
多区域数据库中的每个表都有一个 "表定位设置"。CockroachDB使用表定位设置来决定如何优化对该区域的表数据的访问。默认情况下,多区域数据库中的所有表都是区域表。也就是说,CockroachDB优化了从单一区域(默认为数据库的主区域)对表的数据的访问。
区域表提供了从单一区域对整个表进行低延迟的读写。CockroachDB为增加延迟配置提供了两种额外的表模式。
- 区域性按行表和区域性表一样,只是表中的不同行可以被优化为来自不同区域的访问。
- 全局表被优化为从所有区域的低延迟读取。
区域按行表
在按行划分的区域表中,个别行被优化为来自不同区域的访问。这个设置将一个表和它的所有索引划分为不同的分区,每个分区为来自不同区域的访问进行优化。和区域表一样,按行划分的区域表也是为来自单一区域的访问进行优化。然而,该区域是在隐藏的系统列中的行级指定的,而不是应用于整个表。
当你的应用程序需要在行级进行低延迟的读写时,使用按行划分的区域表,因为单个行主要是从一个区域访问的。例如,一个全局应用中的用户表可能由于法规(如GDPR)需要将一些用户的数据保留在特定的区域,以获得更好的性能,或者两者都是。
开发人员可以通过一个简单的SQL语句将一个表从默认的区域表转移到一个按行排列的区域表。
ALTER TABLE ... SET LOCALITY REGIONAL BY ROW;
区域按行表带有更多增强的自主行为。我们在上面谈到,许多传统的应用程序会要求你改变你的应用程序来跟踪全局唯一的标识符,如用户ID。CockroachDB可以直接在数据库中为你做到这一点,而不需要你去改变你的应用程序。CockroachDB会在任何新的插入区域表的过程中,根据请求来源的区域自动存储用户的信息。即使没有应用程序在插入语句中向数据库传递区域信息,我们也可以准确地看到每个请求的来源区域。
CockroachDB使得插入全局唯一的数据变得很容易,但是在读取数据方面呢?我们怎么知道要在哪个区域寻找用户?我们加强了基于成本的优化器,在平行检查其他区域之前,自动检查本地区域的任何读取。如果数据在本地区域,我们可以在2毫秒内返回一个读数。如果数据不在本地,我们在返回信息时只需要检查本地区域的时间的额外延迟(2ms),终端用户很可能不会注意到这一点。在大多数情况下,CockroachDB可以提供本地插入和本地读取,在全球唯一的用户基础设施上,所有这些都不需要你做什么。
全局表
全局表通过提供一个新的全局事务模型来优化数据库中每个区域的低延时读取。任何从全局表读取的事务都会收到一致的低延迟实时信息。为了实现优化的读取,我们交换了来自任何给定区域的增加的写延迟,因为写必须在每个区域复制,以使全球低延迟读取成为可能。我们有一篇单独的文章,将对这一主题进行更详细的探讨。
当你的应用程序有一个 "主要是读 "的参考数据表,而该表很少更新,并且需要对所有区域可用时,就使用全局表。
开发人员可以通过一个简单的SQL语句将一个表从默认的区域表转移到全局表。
ALTER TABLE ... SET LOCALITY GLOBAL;
当由一个为多区域世界设计的数据库提供支持时,多区域应用程序的构建、管理和部署就会明显容易。许多传统的数据库发现将多地区纳入其现有能力非常困难,甚至不可能。即使他们能做到这一点,传统的数据库也缺乏CockroachDB基于成本的优化器和全局事务模型中的本地低延迟优化。
CockroachDB使多区域的配置变得简单,使任何开发者都能在规模上提供更好的用户体验。