谢谢你的帮助,NoSQL,但我们是从这里得到的


是时候让我们承认我们都知道的事情是真实的了。对于许多现代应用程序用例来说,NoSQL是错误的工具,现在是我们继续前进的时候了。

NoSQL的出现是因为当时的数据库无法处理所需的规模。这种新一代数据服务的兴起解决了十多年前创建时网络规模和快速增长的数据集的许多问题。NoSQL还提供了一种新的、经济高效的方法,用于冷存储/偶尔批量访问千兆字节级的数据。然而,在急于解决大数据和大量并发用户的挑战时,NoSQL放弃了数据库的一些核心特性,这些特性使它们具有高性能和易用性。

处理这些权衡可能是NoSQL对数据库世界的最大贡献。它推动了一场进化,将大数据的最佳能力与成熟的关系模型的结构和灵活性结合起来,以产生一个可扩展的关系数据库。

关系数据库的发展创造了全新的一代系统,可以处理几乎所有的工作负载,并具有现代应用程序所要求的可伸缩性、可靠性和可用性。从事务性应用程序和业务分析等传统工作负载,到多租户服务和运营分析等较新的工作负载。诸如谷歌扳手、Azure数据仓库和我们的同名数据库MemSQL等新数据库的兴起已经证明,对于大多数用例来说,关系数据库更容易使用,并且通常比NoSQL系统性能更好。

我知道这可能会引起争议。我也知道你可能很快会认为我的观点有偏见。但是让我来分析这些数据库的历史、架构和应用,然后自己判断。

NoSQL的崛起

NoSQL在2000年代后期全力登场,尽管它开始得更早。它的开发主要是为了解决现有数据库系统的规模问题。很明显,横向扩展是构建大型系统的更具成本效益的模式。对于最大的系统,如谷歌、脸书、微软和雅虎建立的电子邮件和搜索系统,这是唯一的扩展方式。

当我阅读詹姆斯·汉密尔顿的著作时,我第一次体会到了横向扩展的价值paper on designing and deploying Internet-Scale Services in 2007。首先是扩展应用层,因为扩展无状态系统更容易。存储层是另一回事。根据定义,数据库是有状态的,维护保证(即ACID)在分布式系统的状态上是非常困难的。因此,层是建立在现有的数据库系统之上的。)来创建分布式存储层。

我在微软做产品经理的时候遇到过几个这样的例子。第一个例子是微软内部,该公司建立了网络商店,这是一个在热邮件和相关服务使用的SQL服务器之上的分片层。事实上,网络商店是构建今天的蓝色数据库的动机。Webstore很笨重,缺乏很多核心功能,但它很有效,让微软能够根据所需的数据规模进行扩展,并实现高可用性。但是网络商店需要一个完整的工程师团队来构建和维护。

在2000年代中期,我的空间有大量的服务器来管理快速增长的网站。该公司增加用户的速度如此之快,以至于每天都需要添加新的服务器。运行所有这些服务器并在它们之间进行查询是一项非常复杂的工作,需要大量的工程师来维护。

同样的模式在脸书和其他网站上重复出现,因为所有新兴的科技巨头都在与规模做斗争。

很明显,随着它们的大量使用和增长,这些新的数字服务需要一种新的解决方案来接收、管理和显示数据。理想情况下,我们需要一种能够在本地呈现单个接口,但在许多机器上扩展并具有内置高可用性的东西。

最终,大规模的云服务(谷歌、脸书、雅虎、微软等)都建立了自己的定制系统来处理规模需求。这些系统都是不同的,但基本的想法是共享的,要么直接共享,要么通过学术界共享。最终,开源系统开始使用同样的想法,NoSQL运动诞生了。

为了解决网络规模的问题,NoSQL在几个关键方面背离了传统数据库,所以让我们来看看为什么要做出这些选择。

最终一致性的表现和风险

酸代表原子性、一致性、隔离性和持久性。它涵盖了大多数关系数据库的保证。ACID保证在向客户端返回成功之前,写操作必须等待数据到达磁盘。此外,如果您对持久性(即不丢失数据)非常偏执,那么您可以将数据库配置为等待,直到写操作通过网络传输到另一台机器,并到达该机器的磁盘。所以有一个保证,数据总是你写的,但你放弃了写速度的一些性能。

BASE是典型的NoSQL系统,代表基本可用、软状态和最终一致。最终的一致性在写入时更快,因为应用程序不必等待来查看写入是否持久。一旦数据存储捕获了写操作,但在它被保存到磁盘或另一台机器之前,它可以告诉应用程序写操作成功,应用程序可以继续下一个操作。因此,您可以获得性能优势,但有可能看不到您刚刚写入的数据,或者数据可能会在出错的情况下完全丢失。

最终一致性是耐久性风险与可用性之间的合理权衡。如果您的业务是消费者参与,并且延迟对您的收入有直接影响(对于所有内容、社区和商业应用程序都是如此),那么您希望获得最具响应性的用户界面。如果你必须扩展到数百万并发用户,你不能容忍任何瓶颈。通过在数据库体系结构中采用最终的一致性,您所要权衡的是偶尔会失去某人的帖子或评论,这对于这些类型的应用程序来说是可以接受的风险。

耐久性和风险的另一面是金融应用。你不希望你的银行使用最终一致性来存储你的自动取款机交易或股票销售的结果。在这些情况下,用户仍然要求很少甚至没有延迟,但是不愿意接受没有写入磁盘的事务。

最终的一致性是存在的,但它并不总是唯一的答案。数据系统的架构师和开发人员应该能够选择他们想要的一致性级别。这种选择应该在用例级别,而不是平台级别。

走向无模式

不清楚为什么图式在NoSQL运动中丢失了。是的,早期很难构建一个分布式元数据管理器来维护分布式系统中的模式以支持操作,例如添加一个列。因此,早期设计中忽略模式并不奇怪。但是后来没有找到添加它的方法,模式被简单地完全删除了。这也可以理解为什么人们认为它会让你变得不那么敏捷。好的模式设计很难,需要仔细的前期思考。当事情变化很快时(就像过去那样,一直持续到现在),你不想被模式所束缚。

但这是一个谬论。

的确,缺乏模式增加了负责将数据放入系统的工程师的灵活性。然而,它将问题归结到数据的读者身上,他们通常数量级更大,并且通常不了解数据被写入时的状态。这些用户通常是那些从数据中创造价值的人,他们应该有尽可能少的障碍。

举个例子,想象一下图书馆说他们正在废除杜威十进制系统,只是把书扔进了地上的一个大洞,然后宣称这是一个更好的系统,因为它对图书馆员来说工作量要少得多。半结构化数据是有时间和地点的,因为有时你不能提前知道一些数据的形状,或者数据很稀疏。但是,如果你真的不明白任何即将到来的数据或者它看起来会是什么样子,那么它有什么好处呢?

事实是,总有模式。数据对某些人来说总是有意义的。有人应该花时间将这些知识编码到平台中,以便下一个人可以使用。如果这是一个被理解的数据和一些快速变化的数据的混合,将后者放入数据库的半结构化列中,然后计算出以后从其中投影出哪些列。15年前,SQL Server和Oracle可以用XML做到这一点。MemSQL和许多其他现代数据库现在可以用JSON数据来实现。文档数据存储(和密钥/值)应该是现代数据库的一个特征,而不是产品的唯一功能。

查询的非SQL语法

NoSQL数据库设计中的这一决定遵循无模式原则。如果你没有模式,那么放弃SQL语法是有意义的。此外,查询处理器很难为单个盒子构建,而构建一个分布式的要困难得多。最值得注意的是,如果你是一个试图启动并运行一个新应用程序的开发人员,这种系统感觉更容易。

MongoDB完善了简单安装和首次使用体验的艺术。但事实证明,关系模型相当强大。只是有getput如果你不想回答除了“获取id为2的对象”之外的任何问题,函数是很棒的。但是大多数应用程序最终需要的不止这些。如果你想读一篇很棒的文章,作者是在与MongoDB合作了两个独立的项目后得出这个结论的人(他不在数据存储产品上工作)。这是文档数据库不足的一个很好的例子。

在除了最琐碎的系统之外的任何系统中,您总是希望以不同于存储数据的方式来查询数据。具有讽刺意味的是,关系模型是在20世纪60年代发明的,目的是用当时的数据存储解决这个精确的问题。具有连接能力的关系模型是获取数据的唯一合理方式。是的,这在开始时比较困难,但是这比把所有的数据都放到你的应用程序中并自己建立连接要容易得多。我看到客户试图用NoSQL数据库一遍又一遍地这样做,这总是导致疯狂。

许多这样的NoSQL系统实现了它们的主要目标。他们提供了一个具有单一接口的数据存储,该接口可以扩展到具有内置高可用性的多台机器。虽然肯定取得了一些成功,但NoSQL的收养遇到了阻碍。

有几个不同的原因。性能是一个关键因素,尤其是在使用任何服务级别协议进行分析查询时。可管理性是另一个原因,因为分布式系统是出了名的难以管理。然而,阻碍NoSQL发展的最大因素是需要对人们进行再培训。在关系世界里有很多受过训练和教育的人。过去10年来,NoSQL一直试图改变世界,但收效甚微。NoSQL公司总共只占数据库市场500亿美元的几个百分点。虽然软件工程师似乎喜欢NoSQL,但数据人员(数据库管理员、数据架构师、分析师)不情愿地进入了NoSQL世界,这似乎是实现必要规模的唯一途径。但这意味着他们必须重新学习新的应用编程接口、工具和生态系统,抛弃多年来成功的方法、模式和资产。他们希望使用经过验证的模型,但仍能在不影响系统耐用性、可用性和可靠性的情况下获得规模。

从NoSQL到新闻生活——不折不扣的性能和规模

当我们构建MemSQL时,我们从这样一个前提开始:客户喜欢关系数据库的功能,但希望横向扩展系统的可用性和可靠性。我们的目标是让客户两全其美。

MemSQL是一个分布式关系数据库,支持事务和分析,并在商用硬件上扩展。您将获得熟悉的关系模型、SQL查询语法和巨大的工具生态系统,以及现代云本地系统的可伸缩性和可用性。

让我们在NoSQL体系的核心差异的背景下重新审视这个问题。

平衡一致性和性能

MemSQL有旋钮,让你调整你想要在一致性和性能之间权衡多少。权衡总是存在的,但是现在你不必在平台级别的这些事情之间进行选择。您可以为每个有意义的用例做出选择。

一致性和性能并不是某种核心的哲学选择,它是对什么更适合您的应用和需求的选择。MemSQL有两种设置可以让您对此进行调整。第一个让你决定是否等待 disk persistence or not 。内存中有一个缓冲区,用于在事务被保存到磁盘之前存储它们。您可以让成功返回,只要它到达缓冲区或当它到达磁盘。如果当它到达缓冲区时返回,在它被持久化和数据丢失之前,有可能发生机器故障或重新启动。另一方面,等待它持续到磁盘将花费更长的时间。

此外,有了高可用性,您可以two modes of replication同步和异步,确保数据在另一台机器上有第二份拷贝。如果将复制设置为同步模式,则在将成功返回给客户端之前,您需要等到在辅助服务器上接收到事务。如果启用了异步复制模式,则事务会在数据复制到辅助服务器之前返回成功。这使您能够针对符合您的风险/性能特征的性能,在一致性和持久性之间进行权衡。

在分布式系统中维护模式

MemSQL通过将元数据存储在一个小的内部数据库中,并在元数据发生变化时将它同步复制到所有节点上来实现模式。它使用两阶段提交来确保DDL更改在集群中正确传播,并且以不会阻止选择查询的方式构建。但是,MemSQL支持的不仅仅是关系。您可以将一个列键入为JSON,并在其中存储一个JSON文档。如果您决定以后要查询某些列,您可以将这些属性作为列进行投影,并对它们进行索引。内存SQL还支持空间类型和全文索引。我们理解客户需要在一个熟悉的系统中混合数据类型,并且所有类型的数据可以自然共存。

保留SQL“通用语言”

MemSQL解决了在大规模分布式数据库中使用SQL语法的问题。分布式查询处理器允许您使用标准的SQL语法来表达您的查询,系统负责在集群中的节点间分发您的查询,并为您聚合结果。内存SQL支持所有常见的ANSI SQL操作符和函数,这为您提供了一个强大的模型来表达任何查询。

MemSQL通过在系统中有两种节点类型来做到这一点:聚合器和叶子。聚合器处理分布式系统的元数据、路由查询和聚合结果。叶子存储数据,并在分区上执行查询。在可能的情况下,MemSQL将在本地执行连接,这就是模式设计非常重要的原因。如果不能,MemSQL将根据需要打乱数据。因此,客户可以使用SQL语言,而不知道下面的数据是如何划分的。如果你想了解更多, MemSQL docs have more detail on how this已经建成。

这意味着您可以使用您公司中已经拥有的技能、投资和工具来使用MemSQL,或者人们可以像使用任何其他关系数据库一样使用MemSQL,而无需经过再培训。此外,由于MemSQL支持MySQL有线协议,现有的大规模商业智能生态系统、ETL和其他中间件工具只能与MemSQL一起工作。你不必雇佣新员工,学习一堆新工具,或者引进新软件。它只是工作。

向NoSQL告别

随着网络应用和多租户服务的兴起,NoSQL开始处理规模需求。考虑到这些问题有多难解决,可以理解的是,这些在存储层处理扩展的早期尝试迫使客户进行了一系列艰难的权衡。

但是关系数据库已经进化了。他们可以处理几乎所有的工作负载,具有现代应用程序所要求的可扩展性、可靠性和可用性要求。

运营分析等工作负载。随着所有公司都认识到数据驱动的价值,他们希望为所有员工提供最新的数据。要做到这一点,需要一种新型的分析系统,该系统可以扩展到数百个并发查询,无需预聚合即可提供快速查询,并在创建数据时将其接收。除此之外,他们希望向客户和合作伙伴公开数据,这需要运营服务级别协议、安全功能、性能以及当前数据存储无法实现的扩展。这只是推动对新功能需求的几种新工作负载之一,这些新功能超出了传统数据库和NoSQL系统所能提供的范围。

关系模型经受住了时间的考验。此外,它还吸收了新的数据类型(搜索、空间、半结构化等)。)和一致性模型,因此它们可以共存于一个系统中。关系模型或SQL查询语法没有内在的可伸缩性挑战。它只需要不同的存储实施来利用横向扩展体系结构。

像MemSQL这样的新数据库已经证明,对于大多数用例来说,关系数据库比NoSQL系统更容易使用,通常性能也更好。

谢谢你,NoSQL。您向数据库社区施加压力,迫使其解决云规模世界的挑战。奏效了。关系数据库已经发展到满足这些需求。我们从这里得到的。