译者:陈军
在过去的十年里,分布式系统已经遍布全球。他们使用跨区域的编排技术来实现跨多个云服务提供商和本地基础架构的混合云部署、负载平衡和高可用性。在此基础上,数据库领域不断迭代发展。近年来,业界出现了大量为分布式数据库部署而设计的新型数据库系统。当然,有些数据库在原设计中加入了分布式架构组件。
DB-Engines.com前100名数据库
知名网站DB-engines.com使用加权算法来跟踪各种平台上各种数据库的提及次数、谷歌的搜索趋势、栈溢出的讨论频率、推文的专业技能数量以及linkedIn个人资料的数量。下图显示了截至2022年5月,榜单上394个数据库中市场占有率前100的数据库分布情况。
截至2022年5月,DB-Engines.com排名前100的数据库。
其中,作为传统的SQL系统,关系型数据库管理系统仍然占了最大的比重,高达47%。其中25%是NoSQL系统,涵盖多种类型,包括MongoDB等文档数据库,Redis等键值系统,ScyllaDB等宽列数据库,Secondary等图形数据库。占11%的“多模型”数据库包含在同一个系统中,支持SQL和NoSQL的混合,或者支持多种NoSQL数据模型的数据库。
什么是分布式数据库?
对于如何构建一个符合SQL的分布式RDBMS系统,人们有不同的理解。目前,ANSI、ISO、IETF或W3C都没有明确定义“NoSQL数据库”。在我看来,分布式数据库的基本特征是:首先定义一个集群,不同的数据分布在其中;然后,在集群中定义每个节点的角色。每个节点要么是对等节点,要么一些节点处于主导地位,而另一些节点则扮演跟随者的角色。然后,这些角色可以相互故障转移。最后,他们可以尽可能均匀地复制和切片数据。
在此基础上,我们可以从上述100强数据库中选择5个典型的,分为以下两类:
在表的左侧,Postgres和CockroachDB代表分布式SQL。其中,被称为“NewSQL”的CockroachDB是专门为分布式数据库设计的。在表格的右边,MongoDB、Redis和ScyllaDB属于分布式NoSQL。一般来说,如果需要表联合操作,可以遵循SQL和RDBMS。如果需要对数据进行反规格化,那么可以选择NoSQL。
多数据中心集群
前面提到了集群的概念。早在多数据中心的设计架构提出之前,PostgreSQL、MongoDB、Redis都是设计成单个数据中心的本地集群。
如上表所示,Postgres于1986年首次推出,完全早于云计算的概念。但随着时间的推移,它的设计和功能发生了很多改进。
作为NewSQL的代表,CockroachDB在设计时就考虑到了全球发行。
MongoDB发布于公有云之初。它最初的设计只考虑了单个数据中心集群,现在它增加了对各种拓扑的支持。使用MongoDB Atlas,您可以轻松地将其部署到多个领域。
根据低延迟的设计理念,Redis通常部署在单个数据中心。同时,它还提供允许部署多个数据中心的企业功能。
ScyllaDB和Cassandra一样,从一开始就在设计中考虑了多个数据中心的部署。
组
在分布式数据库的概念中,我们提到了复制和碎片。这完全取决于数据库模式的层次或同构程度。例如,MongoDB只有一个主节点,其余的都是主节点的副本。您只能写入主节点上的数据库。因为副本是只读的,所以不能直接更新它们,但是主节点必须更新其他副本。显然,这些节点是异构的,而不是同质的。
这种活动/备用架构有助于在重新读取工作负载中分配流量。在混合或重写的工作负载中,主节点成为瓶颈。也就是说,当主节点出现故障时,数据库将不得不暂停写操作,因为集群需要临时选择一个新的主节点。这就是所谓的单点故障。
相反,ScyllaDB和Cassandra属于“群龙无首”的P2P活跃度系统。由于客户端可以读取或写入任何同构节点,因此避免了单点故障。也就是说,每个节点都可以更新群集中任何其他副本的数据。
可以看出,虽然更多的活动会带来更多的计算量,但它解决了保持服务器相互同步的问题。最终,用户会得到一个适合重写的负载平衡系统。毕竟每个节点都可以提供读写服务。
下面,我们来看看上述五个数据库在主副本和P2P活跃度方面的表现:
CockroachDB和ScyllaDB是按照多主动模式设计的。
Postgres需要一些外在的方法来实现生动性,而不是内置的。
MongoDB不支持多活。
在Redis企业版中,我们可以使用无冲突复制数据类型来实现生动性模式。
注意Postgres、MongoDB、Redis默认都使用主副本的数据分发模式。
复制
分布式系统设计还会影响数据在不同部署的机架或数据中心之间的分布方式。例如,在给定的主副本系统中,只有具有主节点的数据中心可以服务任何写入负载。其他数据中心只能是只读副本。
在支持多数据中心集群的对等系统中,整个集群中的每个节点都可以接受读或写负载。显然,这将更容易将工作负载分布到多个地理位置。
例如,通过使用ScyllaDB,您可以确定每个站点具有相同甚至不同的复制因子。在图的右侧,我们展示了一个数据中心有三个数据副本,另一个数据中心有两个副本的情况。
不同层次的操作会有一致性。您可以在具有三个节点的数据中心中执行本地“仲裁”读取或写入。当然,您也可以通过集群范围的仲裁来决定一个或两个数据中心中的任意三个节点是否需要更新。
拓扑感知
我们已经了解了分布式数据库的本地集群,它可以有效地在多个系统之间分担负载。您还可以跨多个地理节点对数据库进行切片,或者通过确保相同数据在多个节点上的高可用性来确保数据复制。
下面,我们假设一个场景:如果你的所有节点都安装在同一个机架上,整个机架出现故障,你该怎么办?这时候我们就需要在同一个数据中心使用机架拓扑感知,保证数据分布在数据中心的多个机架中,最大限度地减少整个机架与另一个机架之间因电源或网络中断而失去连接的情况。
在分布式数据库中,我们需要数据库的多个副本运行在不同的数据中心,从而实现跨集群的更新机制。每个数据库都可以独立运行,它们的同步机制可以是单向、双向或多向的。这种地理分布可以通过允许附近用户的连接来最小化延迟,从而确保用户在单个数据中心发生灾难时不会丢失部分甚至全部数据。
让我们来看看上述五个数据库在拓扑感知方面的性能:
CockroachDB和ScyllaDB都有内置的拓扑感知特性。
MongoDB从2015年开始引入拓扑感知。
Postgres和Redis最初被设计为一个单一的数据中心方案。虽然它不是现成的,但您可以像添加活力一样手动添加拓扑感知服务。
下面,我们根据上面的分布式特点,总结比较五个数据库的属性。
一种数据库系统
Postgres是当今最流行的SQL实现之一。它提供了现成的本地集群。然而,由于Postgres仍在努力改进其多数据中心集群,您需要额外的配置和开发来实现它。
因为SQL是建立在高度一致的事务模型上的,所以它不适合广泛跨越地理区域的集群。所有相关数据中心之间的长时间延迟会放大每个查询。
同时,Postgres依赖于主副本模型。群集中的主节点和副本节点之间存在关系。您还可以添加额外的负载平衡器,或者激活额外的组件。另外,虽然Postgres在自动数据切片方面取得了一些进展,但是仍然需要用户手动切片数据。
蟑螂数据库
CockroachDB作为“NewSQL”不仅使用了Postgres的传输协议,还借用了大量Postgres创造的概念。当然不仅限于Postgres架构。例如,内置多数据中心集群和对等无领导拓扑。
此外,CockroachDB不仅具有自动切片和数据复制的功能,还内置了数据中心感知。您可以根据需要添加对机架的感知。
值得注意的是,由于CockroachDB要求所有事务高度一致,用户失去了最终一致性或可调一致性的灵活性。这不仅会降低吞吐量,还会在跨数据中心的任何部署中导致高基线延迟。
MongoDB
NoSQL的典型代表MongoDB开发了许多分布式数据库功能。例如,它已经能够实现多个数据中心的集群。虽然MongoDB在大多数情况下仍然需要遵循主副本模式,但是部分用户可以通过第三方工具使其实现P2P活泼模式。
使用心得
Redis作为一种典型的“键-值对”存储的数据库,其目标是内存缓存或数据存储。虽然它可以持久存储数据,但如果数据集不适合内存,性能将会大大降低。
默认情况下,Redis的设计考虑了本地集群。这就会导致,比如一旦你无法在5毫秒内从SSD获取数据,你就无法在145毫秒内完成网络传输从旧金山到伦敦的往返时间。当然,对于那些真正需要多区域分布式存储的企业,还是会在多数据中心搭建Redis集群。
同时,Redis更适合复读缓存服务器,因为它经常以主副本模式运行。也就是说,它要求首先写入数据,然后将数据分发到副本以平衡其缓存负载。
Redis的企业功能可以实现P2P活跃集群。同时,Redis可以自动切片和复制数据。但其拓扑感知功能仅限于具有企业特征的机架感知。
ScyllaDB
ScyllaDB是根据Apache Cassandra的分布式数据库模型设计的。默认情况下,它有多个数据中心集群,并采用无领导的主动拓扑。
ScyllaDB将自动切片,并为每个操作提供可调整的一致性。如果你想获得更强的一致性,它还可以支持轻量级事务,并提供编写的线性化。
在拓扑感知方面,ScyllaDB支持机架感知和数据中心感知。它甚至支持令牌感知和切片感知,ScyllaDB不仅可以知道数据存储在哪个节点,还可以知道与数据关联的CPU信息。
总结
在上面,我们分析了五个著名的分布式数据库系统。其中CockroachDB为SQL数据库提供了全面的开箱即用的特性和属性组合,而ScyllaDB则为NoSQL系统提供了全面的功能。目前分布式数据库还在不断迭代和完善中。它们变得更加灵活、可扩展,性能也更高。