分布式 Data Warebase - 探索数据系统物理极限
ProtonBase 研究员
本文整理自 QCon 北京站演讲《分布式 Data Warebase - 探索数据系统物理极限》,点击查看完整版演讲视频。
分布式 Data Warebase 是性能、正确性、实时性这三个业务核心需求的必然推论,它不是一个发明,而是一个发现。
本文从一个民宿应用出发阐述现有数据系统的弊端,总结出业务的三个核心需求和四个典型场景。然后探索在这四个典型场景下满足最苛刻业务需求的数据系统分别是什么。最后解释什么是分布式 Data Warebase 以及它意味着什么。
- 当前数据系统的弊端
- 业务的核心需求
- 探索各场景数据系统的物理极限
- 分布式 Data Warebase
一、当前数据系统的弊端
假设现在有一个民宿应用,房东可以将自己的房源上架民宿平台,潜在住客可以通过该应用查找心仪的民宿,并且在应用平台上完成预定。住客也可以通过平台办理入住和离店手续,以及在平台上输入评论,帮助其他用户更精准地筛选适合自己的民宿。
为了实现这一系统,起初只需要开发一个应用服务,并将所有数据存储在 MySQL 或 PostgreSQL 这样的关系型数据库中,就能实现简单查询。由于数据量足够小,应用的需求也足够简单,一个数据库就能满足应用的所有需求。然而,随着客户数量的快速增长,应用的数据量和查询请求已超出单机 MySQL 或 PostgreSQL 的处理能力,遭遇性能瓶颈。为解决性能问题,引入了 MongoDB,MongoDB 的优点是可以通过增加机器这种水平扩展方式来提升性能,以满足业务日益增长的性能需求。
随着用户数的进一步增长,用户不再满足于通过全名去查找民宿,而是希望能够通过关键词搜索符合需求的民宿。无论是关系型数据库还是 MongoDB ,用于关键词搜索时均无法满足用户对搜索的性能需求。此时需要引入一个搜索引擎,比如 Elasticsearch。为了能让搜索引擎提供服务,需要先把数据导入搜索引擎中,此时就需要数据同步链路。数据同步一般有两种方式:一种是全量数据同步,即周期性地全量将数据写入搜索引擎。另外一个则是增量数据的同步,适用于有实时性需求的场景。增量链路通常会使用 Kafka/Flink 这类产品。当数据都同步到搜索引擎之后,系统就能通过搜索引擎高性能的搜索能力给用户提供关键词搜索。比如用户可以在民宿应用中输入“无烟 停车位”,系统就能够帮他找到无烟的,并且带停车位的民宿。
过去两年大语言模型取得巨大突破,机器终于开始理解自然语言,这给业务带来一种全新的可能。除了使用关键词搜索,用户也可以使用自然语言去寻找自己喜欢的民宿。为了满足这种语义搜索的需求,系统又引入了向量数据库。比如用户可以搜索“对宠物友好的简约风格的民宿”。系统同样需要通过全量和增量的同步链路把数据先同步到向量数据库之中,再结合大语言模型的能力完成语义搜索。
最后是汇总分析需求,用户可能希望知道过去三天某个城市评价最高的民宿有哪些,为了提供这种分析的能力,系统又引入像 Clickhouse、Hive、Snowflake 这类数仓产品。同样需要开发新的同步链路,将数据同步到数仓之中。除此之外,还可以将应用和服务的性能信息写入数仓以便发现和定位性能问题。有了数仓后就可以通过 BI 工具去满足用户的复杂的分析需求了。
这个民宿应用从一个简单的关系型数据库出发,随着业务的增长,数据量越来越大,需求越来越复杂,系统逐渐发展出一个较为复杂的数据架构。
简单总结一下这个民宿应用对数据存储的需求和使用场景。从数据存储需求上,这些数据可以分为以下几类:
- 结构化的数据:民宿的名字、地理位置、房间数、价格等基本信息,这些可以用结构化数据来描述。
- 半结构化数据:各类设施的款式、功能参数等,比如冰箱的参数可能是冰箱的容积,微波炉的参数可能是微波炉的功率等等,这些涉及到半结构化数据,需要更复杂的方式去存储。
- 非结构化数据:如民宿照片和文字评论等,是典型的非结构化数据。
从数据使用场景来说,我们刚才讲到了四种场景:
- 简单查询:比如打开一个民宿的详情页,我们需要能够快速地获得该民宿的相关信息。
- 关键词查询:比如刚才提到的“无烟 停车位”这类查询。
- 语义搜索:如刚才提到的“对宠物友好的简约风格的民宿”这类查询。
- 汇总分析:用户希望查看过去几天或一个月内某城市评价最高的民宿,这需要系统对城市内所有民宿的评价进行汇总分析。
为了应对这些复杂的业务需求,系统逐渐发展出一套复杂的数据架构,这种架构在许多业务中都非常典型,然而,它也存在明显的弊端。接下来,我们将从三个视角分析这些弊端。
- 研发视角:构建这样一套复杂系统需要研发人员理解多个不同的产品,了解每个产品的局限性以及如何绕开这些局限性,这显著提高了开发的门槛。对于一些中小企业而言,招募资深的数据工程师可能是一个挑战,因此,很多时候企业由于人才短缺而无法充分挖掘数据的业务价值。即使一些公司有幸拥有优秀的数据工程师,但为了实现多个产品之间的数据同步,数据工程师需要开发各种数据同步链路,这无疑增加了开发工作量,降低了数据的开发效率,减缓了业务的迭代速度,阻碍了业务的增长。
- 运维视角:同时运维如此多的产品也给运维带来了复杂度,特别是数据同步任务。数据同步任务往往是一个数据系统中最薄弱的环节,容易因为各种原因出问题。一旦数据同步出现问题,就可能导致系统中不同部分看到的数据不一致。此外,由于同一份数据需要通过数据同步存储到不同的产品中,这就意味着数据的重复存储,会耗费更多的资源,增加成本。
- 业务视角:尽管整个数据架构是根据业务需求逐步发展而来的,但即使从满足业务需求的角度来看,我们刚才描述的架构也不能完全满足需求。首先,系统中存在多处数据同步,必然导致一定的数据延迟。其次,这种架构可能会导致数据不一致的情况,这将在后文中具体解释。
二、业务的核心需求
马斯克最近在 X 平台发表分享:“评价一个产品正确的方式,不是跟竞争对手比(太容易),而应当跟物理极限比。”。如果把追求物理极限当做目标,数据系统的物理极限究竟是什么?我们应该从哪些维度评估数据系统的物理极限?
技术服务于业务,让我们先从业务视角出发总结业务的核心需求,我认为业务的核心需求有三个:性能、正确性和实时性。
性能:随着业务规模的不断扩张,对性能的需求也会越来越高。我们希望无论业务对性能的需求有多高,都能够在合理的资源条件下满足它。随着业务功能越来越多,也将在更多场景中有性能的需求,我们希望无论业务以什么样的方式使用数据,性能都能够得到满足。因为不满足性能需求会导致系统立即出现问题,所以性能需求是过去二十年驱动大数据领域蓬勃发展的重要动力。我们民宿应用之所以采用这么复杂的数据架构,正是为了解决性能问题。
正确性:我们希望系统中存储的数据永远是正确的,并且所有场景查询的结果都是正确的。只有确保数据的准确性,我们依赖数据所做的一切决策才有可靠的基础。因为数据错误可能比较隐蔽,这个需求往往容易被忽视,但是对一个挑战物理极限的数据系统来说这必须是一个核心而基本的需求。
实时性:不同业务对实时性的需求各不相同,有的业务可能满足于小时级的实时性,有的则需要分钟级甚至秒级的实时性。作为一个挑战物理极限的数据系统,它必须能够满足所有业务对实时性的需求,即数据的延迟能够做到任意低。
接下来我们探讨如何为刚才所讲到的四个场景分别构建一个数据系统,在性能、正确性和实时性这三个维度上达到极致,挑战物理极限。
三、探索各场景数据系统的物理极限
简单查询
第一个场景是简单查询,我们从性能、正确性和实时性三个维度来评估。用户希望查看民宿的详情页,需要系统获取民宿的相关信息。初始阶段,系统采用的是关系型数据库,由于关系型数据库存储的是原始数据,因此自然满足了数据的实时性需求。同时,由于关系型数据库支持事务,事务保证了数据的强一致性,因此也满足了数据正确性的需求。
关系型数据库所遇到的唯一挑战是性能问题,它的性能受单机性能的制约,当业务性能需求超出单机性能上限时,单机关系型数据库就难以满足性能需求。一种自然的解决思路是将数据分片存储到多台机器上,通过水平扩展来满足性能需求。然而,在解决性能问题的同时,如何保证数据的正确性将成为挑战。例如,系统中有两张表,一张是住户表,记录了住户的基本信息,另一张是订单表,记录了所有的订单。当这两张表通过分片方式分配到多台机器上时,可能出现住户信息和他的订单信息被分配到不同机器的情况。当需要执行某些操作,如删除某住户时,我们需要删除该住户的基本信息及其所有订单,就需要同时修改多台机器上的数据,而保证这些写操作是原子的且读取时也是原子的,则需要分布式事务。然而,不幸的是实现分布式事务在技术上充满挑战。
为了绕开分布式事务实现水平扩展,NoSQL 数据库应运而生。在 NoSQL 数据库中,文档型数据库是最成功的一类。接下来我们就以文档型数据库为例来分析 NoSQL 数据库如何解决水平扩展的问题。水平扩展的主要挑战是需要实现跨机分布式事务。如果我们能保证把需要同时修改的多个实体分配到同一台机器上,我们就可以避免跨机分布式事务的需求。
文档模型正是基于这样的想法,把需要同时修改的关联实体组织成一个文档,一个文档能够保证存储在一台机器上不会被拆分。在这个例子中,左边是用关系模型表达的数据,右边是同样的数据在文档模型里的表示。在引入文档模型后,我们刚才所做的操作,比如删除一个住户和它的所有订单信息就变得非常简单,只需要删除这个住户对应的文档。
通过这种方式,文档型数据库巧妙地避开了跨机分布式事务的需求,从而实现了水平扩展的能力,这样就能通过水平扩展来满足业务日益增长的性能需求。文档模型能够很好地描述实体之间一对一和一对多的关系,用户可以把相关的实体放在同一个文档之中。但是如果两个实体之间是多对多的关系,文档模型的局限性就显现了。针对多对多关系,存在两种常见方案:
- 第一种方案是将实体复制多份存储在不同文档中。缺点是当修改实体时,需要同时修改存储了它的所有文档,而这些文档可能分布在不同的机器上。为了保证这种修改原子生效,又回到了对分布式事务的需求。
- 另外一种方案是不同实体用不同的文档表示,文档之间通过 ID 引用互相关联。然而如何保证这些引用的一致性是一个挑战。当创建一个文档时,需要保证它引用的所有文档都已经存在。当删除一个文档时,要保证引用它的所有文档都已经被删除。一个文档和它引用的文档也可能分布在多台机器上,要保证引用关系的一致性,仍然需要分布式事务。
综上所述,要在文档型数据库中完整地表达所有实体之间的关系,分布式事务是一个绕不过去的坎。只有真正实现分布式事务,才能确保数据永远正确,永远一致。
这个时候我们面临着两种选择:
- 第一种选择是基于文档型数据库实现分布式事务,从而解决数据正确性的问题。
- 另一种选择是在关系型数据库上实现分布式事务,并在此基础上增加水平扩展的能力来解决性能问题。
那么应该如何选择呢?为了回答这个问题,我们来比较一下这两种选择的最终结果。
文档型数据库除了水平扩展能力之外,另一个很大的优势是对半结构化数据的支持。文档的结构无需事先声明,用户能够很方便地修改文档结构,而不需要像关系型数据库那样需要找 DBA 才能修改表结构。这种特性特别适合于数据的敏捷开发,以文档型数据库为代表的 NoSQL 曾经一度被视为水平扩展和敏捷开发的代名词。
然而,从另外一个角度看,关系型数据库也有着诸多优势,其中最重要的一点是 SQL 查询语言,SQL 查询大大简化了业务的数据开发。并且 SQL 有着强大的生态,各种工具都能很好地支持 SQL。综合起来,我们认为关系型数据库拥有更多文档型数据库所不具备的能力。
因此我认为以关系型数据库为基础是更好的选择。挑战在于分布式事务的实现,但值得庆幸的是,Google 的 Spanner 已经成功实现了分布式事务,并发表了一篇详细的论文来解释其实现。Spanner 在 Google 内部取得了巨大成功,这表明分布式事务不仅在理论上可行,而且在工程实现上也是可行的。有了分布式事务后,我们就可以通过数据分片的方式来水平扩展满足性能的需求了。
以关系型数据库为基础并不意味着放弃文档型数据库在半结构化数据上的能力。关系模型的类型系统可以灵活扩展,只要在关系型数据库引入 JSON 数据类型,就能够方便地表达半结构化数据。
关系型数据库加持了分布式事务和半结构化数据能力之后,它就涵盖了 NoSQL 的所有优势。我们也在简单查询的场景构建了一个同时保证性能、正确性和实时性的极致系统。
关键词搜索
接下来是关键词搜索的场景,让我们通过一个例子解释为什么搜索的场景需要实时性。
在民宿应用的架构中,我们通过数据同步将数据库和 MongoDB 中的数据同步到搜索引擎,然后通过搜索引擎进行关键词搜索。假设有一个民宿管理员搜索“无烟 停车位”希望能够搜到自己的民宿,但搜索结果中却没有他的民宿。经过分析后发现,原来他忘了在民宿信息中添加停车位的信息,于是他前往管理台添加了停车位的信息。然后他立刻再次搜索,却仍然没找到自己的民宿,这让管理员感到困惑。实际上,问题出在他通过管理台修改了数据库,但数据库的修改同步到搜索引擎存在一定的延迟。正是因为这个同步延迟,管理员没有搜到自己的民宿。所以我们可以看到在搜索场景下,实时性也可能是非常重要的需求。
从三个维度看,搜索引擎比较好地解决了性能问题,但现有的搜索引擎不能满足极致的正确性和实时性需求。
为了解决正确性和实时性的问题,保证搜索引擎返回的结果永远是最新的,实际上只有一个办法,那就是不通过数据同步而是直接在原始数据上进行搜索。原始数据存储在关系型数据库中,而关系型数据库自然满足了正确性和实时性的要求,剩下的唯一问题就是性能。在这个场景下,性能问题和可扩展性并不是同一个问题,因为即使数据量不是很大,完全可以在单机上处理,使用关系型数据库进行搜索仍然会导致性能较慢。这里的性能问题是数据的新使用场景带来的单机的性能问题。
我们的想法是以分布式数据库为基础,来解决搜索的性能问题。搜索引擎具有良好的搜索性能,其中一个核心技术是倒排索引。倒排索引将文章分成一个一个关键词,找出每个关键词出现在哪些文档中,把这些文档 ID 排序形成一个列表,这个列表就是这个关键词的倒排链。当用户进行搜索时,系统首先找到每个关键词的倒排链,然后对这些倒排链进行并集或者交集的操作,就可以找到满足查询条件的文档了。
除了类型外,关系型数据库另一个扩展机制是索引类型。我们可以在关系型数据库中引入倒排索引来实现高性能搜索。而且这种倒排索引的应用不仅局限在关键词搜索上,我们同样可以用倒排索引来索引表中的结构化数据。这些倒排索引就可以用来加速这些结构化数据的联合搜索和过滤。因此,我们再次以关系型数据库为基础,通过吸收搜索引擎的倒排索引技术,打造了一个同时满足性能、正确性和实时性的极致方案。
语义检索
过去两年,生成式 AI 取得了突飞猛进的进展,基于它的大语言模型对很多问题都有出人意料的高质量回答,但由于这些模型在训练时只能接触到公共领域的数据,因此在涉及私有领域数据的提问时,它们的能力并不能得到充分发挥。解决这个问题有两种主要方法:
- 首先是用私有领域的数据对大语言模型进行微调。这种方法的一个缺点是门槛相对较高,另一个缺点是微调过程可能无法学习到私有领域数据的某些重要细节。这是因为大语言模型学习知识的本质是对知识进行有损压缩,你感兴趣的某些重要细节可能恰巧在这个过程中丢失了,而仅给模型留下了一个大体的印象。
- 另外一种做法,检索增强生成也就是 RAG 出现了。
简单介绍下 RAG 的工作流程:当用户向系统提出问题时,系统会将问题提交给召回系统。召回系统可以在知识库中进行搜索,这种搜索可以是基于关键词的。例如,对于提到的“无烟 停车位”,知识库会返回与这些关键词相关的文档。然后,将系统提示、用户问题和这些召回的文档作为上下文输入给大语言模型,在充分理解问题并阅读召回的文档后,大语言模型生成答案并返回给用户。通过这种方式,我们可以把大语言模型的能力在私有领域数据上发挥出来。
需要指出的是,检索的方式有多种多样,前文提到的基于关键词的检索只是其中一种可能。随着大语言模型对自然语言的理解能力增强,另一种检索模式即语义检索也逐渐兴起。
语义检索能够让用户使用自然语言去寻找自己感兴趣的民宿。其基本工作原理是:利用嵌入模型为每个文档生成一个高维向量,也就是嵌入向量,该向量在一定程度上概括了文档的信息。不同的文档被转化为高维空间中的不同向量,向量之间的欧氏距离或内积表示了文档之间的相似程度。当用户提出一个自然语言问题时,系统会使用相同的嵌入模型为问题本身生成一个向量。然后,在高维空间中找到与该向量相近的一些向量,这些向量所对应的文档就是与问题相关的文档。将这些文档和提示作为上下文输入给大语言模型,大语言模型就有了足够的信息生成答案。
如果使用一个专门的向量数据库,就会依赖同步任务去同步数据,就可能有数据延迟。更好的做法是在关系型数据库中引入向量类型,这样能够很好地表达高维向量。当系统有上亿的文档的时候,在高维空间中它们对应着上亿个向量,找出和某个向量最近的一些向量计算量非常大。这时我们就需要用到关系型数据库的索引的扩展能力。我们会为这些向量创建一种新的索引,也就是向量索引,最常见的向量索引有 IVFFlat 或者 HNSW。在创建了向量索引后,寻找一个向量相近的向量就变得非常高效。把向量检索和大语言模型的能力结合起来就能够进行高效的语义搜索。我们并不需要一个专门的向量数据库,以关系型数据库为基础能够打造出一个同时保证性能、正确性和实时性的语义检索系统。
汇总分析
我们仍然先解释一下实时性在汇总分析的场景中的重要性。前文架构里的数仓中不仅存储了民宿和客户信息,还存储了应用和服务运行的性能信息,以帮助发现和定位性能问题。运维在监控上发现性能问题后,需要快速理解应用为何慢,是全体用户都慢还是部分用户慢。如果是部分用户慢,运维会检查在不同应用版本、不同手机型号、网络类型等情况下性能是否存在差异。经过一系列即席查询,运维最终定位到可能是某些特定情况下的配置问题。修改配置后,运维立即再次检查受影响用户的性能是否已恢复。数据的实时性直接影响了运维解决问题的迭代速度,因此实时性越高越好。
而数据的实时性取决于它如何写入数仓,这里有两种常见的做法:
- 一种常见的做法是批量写入数据到数仓。例如,每五分钟积累一批数据,然后一次性将这些数据写入数仓。这种做法可以实现较好的性能和数据正确性,但在实时性方面可能不理想。数据延迟可以做到小时级或五分钟级,最多降至一分钟级,在合理利用资源的情况下很难实现更低的数据延迟。大部分数仓和数据湖都采用了这种方案,虽然它们满足了性能和正确性的需求,但是准实时不等于实时,它无法做到真正的实时。
- 另一类数仓支持数据的实时写入,但是这类系统往往只保证最终一致性。最终一致性可以简单理解为如果系统一段时间没有写入数据后再去查询,此时看到的数据是一致的。最终一致性的问题在于有持续不断的实时写入时,“最终”可能永远不会发生,因此在查询时可能遇到数据不一致的情况。比如当上游同步过来一笔转账交易,它包含为两个更新:一个是从原账户的转出;另一个是在新账户的转入。虽然我们在同步的时候保证了这两个修改都被正确地同步到数仓中,但是在读取时候有可能只读到了当中的一个修改,如果我们计算总金额就会得到错误的结果。在这个例子中,上游的修改在一个事务里,同步后丢失了这个事务的属性导致了不一致。再举另外一个例子,一些民宿的管理员决定在平台上做广告来提高入住率。广告会出现一个曝光事件和一个点击事件,这两个事件不是在一个事务发生的,但是它们有因果关系。为了提升性能,实时写入时可能把它们合在一个请求写入,虽然这两个事件从写入层面原子性地成功了,但是读取的时候仍然有可能读到了点击事件而没有读到曝光事件,从而违反了因果律。我们往往比较重视写入的原子性,而容易忽略读取的原子性,但读取的原子性对保证数据的正确至关重要。这种做法虽然满足了业务的性能和实时的需求,但是最终一致不等于一致,读取的数据可能会不一致,无法真正满足业务对数据正确性的要求。
可以看到这两类数仓都不能同时满足正确性和实时性的需求,为了能够同时实现这两点,我们必须支持数据的实时写入,并在写入时保证强一致的语义。全文提到的分布式数据库能够很好地实现这两点,剩下的唯一的挑战就是性能。这里的性能同样不是扩展性的问题,而是数据新的使用场景下的单机性能问题。我们可以借鉴数仓高性能的分析能力,数仓的性能主要得益于以下三个技术:
- 列式存储:列式存储将相同列的数据存储在一起,从而实现更好的压缩率,减少了读取数据所需的 IO。同时在执行查询时,可能只需要读取部分列的数据,这进一步减少了 IO,提高了查询性能。
- 向量化执行:在查询执行过程中,不是逐行处理数据,而是以微批的方式处理数据。这种执行方式称为向量化执行,它显著提高了查询性能。不要将向量化执行(vectorized execution)与前述提到的嵌入向量 (embedding vector)混淆,它们完全没有关系。
- 物化视图:将常用的查询预先计算并把结果存储下来,以提高查询性能。例如,可以预先计算并存储一些常用的聚合指标,当用户需要这些指标时,就可以直接使用预先计算的结果,而无需重新计算。预计算最通用的抽象是物化视图。
通过引入列式存储、向量化执行和物化视图等核心技术,系统可以高性能地支持分析场景。我们再次得到了一个同时做到性能、正确性和实时性的极致汇总分析系统。
四、分布式 Data Warebase
博采众长
麦克斯韦是历史上最伟大的物理学家之一,他将前人关于电和磁的四个方程放在一起,构成了麦克斯韦方程组。这四个方程合并后就产生了电磁波,这是任何单个方程都不具备的物理现象。
在刚才讨论的四个场景,我们都决定以关系型数据库为基础,吸收了其他系统在性能上的优化技术,从而在性能、正确性和实时性方面都达到了极致。这些性能优化技术不仅互相不冲突,而且相辅相成。我们完全可以像麦克斯韦一样,将这些性能优化技术同时吸收到一个系统中。这样我们就拥有了一个能够同时存储和处理结构化数据、半结构化数据和非结构化数据的系统,而且在简单查询、关键词查询、语义查询和汇总分析场景下都能够满足业务对性能、正确性和实时性的极致需求。
除了支持这四个场景外,这个系统还能够支持一些新的场景,例如同时使用关键词和自然语言进行查询,这是以前任何一个单独产品都无法做到的。
如果麦克斯韦仅仅因为博采众长就成为世界上最伟大的物理学家之一,也许你会觉得他的成功来得太容易。但事实上,没有人能够如此轻易地取得成功。麦克斯韦在写下方程组后意识到电和磁的不对称:变化的磁场可以产生电场,但变化的电场却不能产生磁场,这与他的美学观念不符。因此,他做了一个“小”修改,添加了一项位移电流。这个修改的意义非常深远,它解决了麦克斯韦方程组与电荷守恒定律之间的矛盾。同时,也正是由于这个修改才使得电磁波得以产生,于是就有了光。
极简体验
我们不禁会问:什么才是数据系统中的位移电流?我认为是极简体验。刚才我们所讨论的一切只是在满足业务的三个基本需求上做到了极致。当业务的基本需求得到满足后,我们需要同样在开发和运维的需求(也就是体验)上追求极致。体验将会成为区分各个产品的重要标准。
为了给开发和运维提供良好的体验,我们的系统需要做到以下几点:
-
首先需要有一个统一的 API。无论是简单搜索,关键词搜索、语义搜索,还是汇总分析的场景,我们希望 API 都是统一的,用户感觉是在使用一个产品,而不是多个产品的缝合。
-
其次我们需要统一的数据存储,系统必须能在一份数据上满足多种场景。数据同步应该是可选而非必须。
-
第三兼容已有生态。我们希望减少系统的学习成本,虽然这是一类全新的产品,但是我们不希望用户去从零学习,而是希望用户能一见如故,以已有的知识就能很好地驾驭这一类新产品。
-
第四因为这类新的产品能够同时支持多种场景,如何做好多种场景之间的隔离也至关重要。这种隔离可以通过软件的方式实现软隔离,也可以通过硬件的方式,使用不同的计算资源实现硬隔离。
-
最后,也是最重要的是自适应能力。因为我们的系统支持不同的场景,如果需要用户告知使用哪个场景,那仍然将会是一个割裂的体验。因此,我们的系统必须能自动针对不同的场景调优。例如,在查询的并发度上,对于简单查询,我们只需要单个并发,这样效率最高。但对于复杂的分析查询,我们需要更多并发以及采用分布式执行计划,以提供更好的性能。自适应也适用于刚才提到的分布式事务。当我们引入 JSON 后,用户可以使用 JSON 组织实体以减少跨机器的事务需求。如果用户修改的数据恰好位于一台机器上,我们可以通过一阶段提交的方式避免分布式事务带来的额外开销。类似的例子还有很多,不再一一列举。要真正实现自适应,必须在架构设计阶段就充分考虑,而不是在产品开发完成后将其作为一种优化。
我们从业务的核心需求出发的论证有一个漏洞:我们在为最苛刻的业务场景,也就是最高的性能要求、最高的一致性要求和最高的实时性要求设计一个极致的系统。你可能会问,如果我的实际业务要求并不那么苛刻,例如我可以牺牲一定的实时性,那么选择这样一个为最严苛需求而设计的系统是否会造成资源浪费?在我的实际业务场景中,这样的系统是否是最佳选择?
自适应在这里至关重要。如果业务要求并不那么严格,系统完全可以根据业务特点做相应的优化,避免不必要的成本。举个例子,如果实时性并不是某个分析业务最重要的考量因素,业务可以采用批量的方式写入数据,系统对批量数据的导入做了相应的优化,从而避免为极低延迟设计带来的额外性能开销,真正实现针对具体业务场景的最优。
通过这一系列的技术发展,终于诞生了一种全新的数据产品,即分布式 Data Warebase。Data Warebase 这个词是由 Data Warehouse (数据仓库)和 Database (数据库)两个词融合而来。这也意寓它包含了数仓和数据库的所有能力。
所有数据:它能够存储所有数据,包括结构化数据,半结构化数据和非结构化数据。
所有场景:它能够支持所有场景,包括简单查询、关键词查询、语义搜索和汇总分析,以及它们的各种组合。
挑战极限:它在业务的基本需求即性能、正确性和实时性上挑战极限。分布式 Data Warebase 在数据库场景是个更好的数据库,因为它通过分布式解决了数据库的水平扩展问题。分布式 Data Warebase 在数仓场景是个更好的数仓,因为它同时解决了数仓的正确性和实时性问题。
极简体验:同时它为开发和运维提供了极简体验,对外提供统一的 API,统一的数据存储,兼容已有生态,提供不同工作负载间的隔离,通过自适应根据场景做针对性的优化。
分布式 Data Warebase 是从业务场景出发追求极致的一个必然推论:分布式 Data Warebase 不是一个发明,而是一个发现。
在有了分布式 Data Warebase 之后,我们就开启了数据开发的新范式。比如,对于民宿应用的数据架构,通过使用分布式 Data Warebase,我们可以看到数据架构得到了大幅简化。并且更为重要的是,它能够满足业务在性能、正确性和实时性方面的极致需求。
最后给大家分享一个小故事:一个小女孩第一次看到一本纸质杂志,试图通过双指去放大和缩小内容,几次尝试无效之后,她终于意识到原来这本杂志是一个坏了的 iPad!
也许有一天我们也会意识到:现有的数据库,或者数仓,都是一个能力不完整的分布式 Data Warebase!
蒋晓伟
曾任阿里巴巴研究员,创建了阿里云 Flink 和 Hologres 团队和产品;曾任 Facebook 调度系统,时间轴和 Messenger 的技术主管;曾任微软 SQL Server 引擎架构师;美国西北大学理论物理硕士学位,中国科学技术大学理论物理学士学位。