查询您的数据库无法回答

2021-06-05 00:59:00

如果我告诉你有一个查询你的数据库无法回答怎么办?这可能会让你感到惊讶。随着数十年的努力,数据库是存在最强大的软件之一。因为他们在目前的形式中保持极大地流行,所以许多工程师假设他们的数据库可以回答他们拥有的任何查询,如果他们愿意等待足够长。

然而,这不是一个伟大的假设。为什么?几乎所有数据库都是由一个常见的特征链接的:它们完全查询休息时的数据。发出查询时,数据库通过扫描数据并返回结果来执行它。问题是,这种架构本身就是遥不可及的疑问。即,您无法编写一个查询,其结果更新每次底层数据更改。您对两个查询调用之间发生的所有内容都盲目。如果您正在做的是由软件驱动的那么重要。

如果您有一个数据库,可以每次数据更改时都可以更新查询结果,您可能会说它是有动的。虽然反应性是许多数据库中缺失的作品,但它是事件流和流处理的核心 - 随着收到新事件,应用程序立即通过处理数据来采取一些动作进行反应。

流处理的反应性几乎使其成为为应用程序查询提供理想的拟合。虽然这可以工作,但它有一个严重的弱点 - 它引爆了数据库的整洁抽象。数据库 - 特别是SQL-WATE查询执行,索引,并发控制,崩溃恢复,复制等的所有基础复杂性。当您制作负责服务查询的流处理器时,您可以使用数据库整齐地隐藏的组件并将其移植到您的应用程序上。你现在正在勾手上,让更多的事情正常工作。

我认为更好的路径是识别隐藏的关系:流处理是另一半数据库。数据库在休息时管理数据;流处理管理运动中的数据。他们只是不合适。

Confluent一直在研究一个名为KSQLDB的新类型数据库,它试图完成这一点。它可以帮助您对数据进行查询并对变化作出反应。但是,您可以完全通过类似于关系数据库的Postgres的抽象来管理所有的复杂性。对于其事务日志,它仅依赖于ApacheKafka®。

让我走了前线:虽然ksqldb今天有一个强大的功能,但完成了它的结婚数据库的更大愿景,并且流处理仍然是一个雄心勃勃的工作。这进步 - 这次职位的主题依赖于Kafka生态系统的大量深入工作。

因此,让我们看看堆栈从数据捕获的每层深度工作,以存储到处理,查询执行 - 以了解回答不可批售查询所需的内容。

每当您想象建立一个事件驱动的系统时,它很容易创建一个至关重要的,但对其运作方式的假设是一个至关重要的假设:您想要的事件将已在流中捕获。

但这不是它在实践中的工作原理。事件出生在流之外:在其他数据库中,其他Web应用程序,其他服务器。某些代码,某个代码需要足够智能,可以将数据发送到流(或从)流的数据。这几乎总是被忽视,因为它直觉感觉就像一个解决的问题;您听到与事件流相关的所有酷计算机科学工作往往是关于处理或存储。你倾向于听到更少的字节铲。

但就像生活中的任何东西一样,没有什么是自由的。一开始,没有内置的软件与Kafka这样做。您必须编写自己的专业程序,以以可扩展,容错,正确的方式运输数据。您必须为您想要与来源和汇总的每个数据系统执行此操作。这不仅仅是令人讨厌的咕噜声;对于未自然地公开更改数据捕获机制的系统,建立系统非常困难。

如果这部分不好,那就没有别的重要。没有事件,这一切是什么点?第一阶的业务是制作框架,以便我们可以隔离所有与外部系统通信的共同复杂性。 Kafka Connect于2015年添加到Apache Kafka进行。

从那时起,连接的使命已经令人愉快地单身令人愉悦:将一个连接器从一切中建造。现在有超过200个连接器集成,其中许多是工程的珍珠。考虑Debezium连接器的套件,这些连接器会更改针对MySQL,Postgres,MongoDB和朋友的数据捕获。或者拍摄与Salesforce等SaaS应用集成的连接器。甚至还有一个连接器来源来自Oracle的数据。

焦点是力量。 ksqldb构建它可以轻松地使用连接器管理来源于源和汇。使用SQL,您可以交互式创建连接器对象:

创建源连接器骑手( '连接器.Class' =' jdbcsourceConnector', ' connection.url' =' jdbc:postgreSQL://...', '主题.prefix' ='骑手', ' table.whitelist' ='地理位置,概况', ' key' =' profile_id' ......);

突破你的铲子字节现在正常。连接器以容错,可扩展的方式运行,横跨ksqldb的服务器,都感谢Kafka Connect。

一旦您设法捕获事件,您需要为他们提供一个家。在数据库中,我们称之为日志。如果将日志存储为Kafka流,将成为架构的骨干,您的思想毫无疑问是它的稳定性。

但十年前,情况并非如此。在关键任务用例中使用Kafka,有很多未解决的问题。

是的,它很酷,我们说,但它可以存储所有的数据吗? Kafka用于仅在经纪人的磁盘上存储数据,这意味着它是符合最少容量的存储器的存储空间。您必须在供应昂贵的高容量磁盘之间进行选择,并存储更少的数据。但它比那更糟糕。许多用例,如审计和在线机器学习,不能与具有短暂保留的流。

什么可能更好?像Amazon S3和Google云存储等对象存储,提供有效的无限存储容量。如果Kafka要将这些服务用作存储后端,可以存储大量数据。在2020年,汇合引入了分层存储,以使现实。而对于Apache Kafka,KIP-405旨在引入类似的功能。这种技术使得可以将无限量的数据存储在流中以获得荒谬廉价的成本。

当然,但它可以在区域中断吗?我们生活在一个永远在的世界,24×7。数据中心中断不再是不方便的 - 它可能会损坏。如果Kafka将用于任何关键的任何问题,即使在整个可用性区域丢失时,您需要计算您的数据。直到最近,用于使Kafka免受停电的传统技术是简单地“拉伸”跨数据中心的集群节点。这个想法有点努力,但它远非完美。该节点的另一个节点地理位置地远离彼此移动,操作群集越硬。

没有一个与Kafka合作的灵魂,并且不希望更容易做跨数据中心复制。在2020年,实际上有一二。 Apache Kafka添加了Geo-Replication(在项目名称MirrorMaker2下),这是一块位于两个Kafka集群中间的软件,它们之间复制(它巧妙地构建在Kafka Connect上)。第二个是与Confluent的补充,命名群集链接 - 而不是使用Middleman进行复制,它使用Kafka的本机复制协议直接复制数据。

好的,但我可以留下来吗?谈到基础设施时,一切都在骑自信地骑在网上保持信心。如果它很难运作,它不会留下来,它不会给你一个价值。运行Kafka自己曾经很难过。它并不像今天那样战斗,没有人有时间专注于操作它。您必须仔细选择您的群集大小,然后警察每个使用它的行政规则播放的人。

软件作为云中的服务完全改变了这一点。 Kafka仅适用于大项目或大批量工作负载,不再是这种情况。您可以从许多云供应商那样获得一个廉价的Kafka集群,如Confluent云 - 带有SLA。你被掩负的所有艰苦的工作都是保持经纪人健康的。运行Kafka现在是别人的问题。

简单地,数据库没有存储引擎。同样,KSQLDB没有Kafka。它只有用,因为它的交易日志是宽敞的,可共同,耐用的,廉价的。但在我们存储后,我们如何处理该数据?

充满事件的流仅在处理它时才有用。这是流处理符合数据库的核心 - 您写入查询后,只要收到新信息就会修改结果。

对于新人来说,这个想法听起来很异落,但很容易用类比理解:处理数据就像求解拼图拼图。通过传统的数据库查询处理,每个查询都像一个全新的拼图。你把所有的碎片放在前面,但你看不到图片拼图将揭示,直到所有的碎片都很合适。

通过流处理,查询无限期地运行 - 它就像是连续解决一个拼图,在那里你一次只给出几件。你立即适合你可以尽可能地放入拼图的作品。与传统查询处理相比,流处理允许您在演变时看到拼图的图片。这就像解决真正的拼图 - 你不需要等到结束,了解它将揭示什么。

类比的作品是因为看到拼图的面部就像看到查询的结果一样。但这不仅仅是有吸引力的,因为您可以早期接收查询结果。它具有吸引力,因为查询的中介状态通常具有价值。

流处理的效用是明确的 - 但是如何构建系统要做的?在Kafka之前,答案并不明显。流处理仍然是一个新的编程范例。然后,它有限的API,它背后的理论仍然被弄清楚。让我们看看以来的三个最重要的概念:时间,规模和同步。

第一次。要离开隐喻,流程处理拼图从未完成,因为您是否不知道您是否拥有所有碎片。这是反映的现实生活 - 很难知道你是否拥有你将得到的所有数据。 2015年,谷歌数据流纸张探讨了这一紧张局势,在正确性,延迟和成本之间造成权衡。

不了解您是否拥有所有数据的后果,尚未处理从订单中接收数据。根据定义,事件数据携带时间戳 - 事件发生的时间。如果您在“较新”事件之后收到“较旧”事件会发生什么?有很多情况会发生这种情况。

这是一个快速的例子。考虑一个简单的流处理程序,略高于每天制作多少钱。随着订单流入,收入总结为今天的任何日子。但现在想象一批订单迟到了。订单昨天被下了,但你今天只收到了​​他们。适当的行动是昨天调整日常收入总额。但是,如果您的所有计划都知道如何做到今天的总数,您就会增加今天。

在过去,你必须选择你的毒药:要么扔掉数据,要么使用批处理器来稍后搞定问题。后者,被称为Lambda架构,特别是有害的,因为它意味着您必须在您的流处理和批处理框架中两次编写您的程序。

没有单一的东西改变为使超级流处理更容易。相反,在2014年到现在的过程中,一系列解决方案的集合也在演变。

Kafka Streams,Flink和Dataflow所有内置API,默认情况下主要处理无序数据。这意味着除了暗示流处理框架,在哪里找到时间戳,您不必做任何事情来获得正确的答案。大多数API通过窗口翻滚,跳跃,滑动和会话窗口完成了这一点,帮助您以不同方式切片时间,但所有处理障碍都透明地。

与此同时,我们必须处理“太晚”的数据是有用的。 Kafka Streams开创了流时间,宽限期和保留的概念。 Flink Spearhead水印和用于批量和流处理的统一API。

现在,规模。将某人与事件流有人激励某人是什么?其中一个原因通常是可扩展性。使用流处理器保持状态时,您将在查询运行的位置分散;您将它们放在不同的应用程序服务上,而不是将它们全部运行在一起。这允许您调整有多少资源专用于每个查询。如果您有一个需要处理大量数据的查询,则可以添加更多计算机来并行化工作。

想象一下,您有一个处理有状态查询的两个节点集群。两个节点划分keyspace并创建本地化,聚合状态。现在,如果将第三个点添加到群集时会发生什么?早期,这是一个痛苦的配方。您需要做的是冗余键空间并均匀地将数据均匀地跨越三个节点。数据洗牌一直是一个难题,但它在始终是流动系统中更具挑战性。直到最近,Kafka Streams对这个问题的解决方案是阻止世界。全球重新平衡将发生,并且在重新平衡完成时才会恢复可用性。你所拥有的州越多,越长。

全球重新平衡 - 再见。打招呼,合作,渐进重新平衡。添加在2020年,增量重新平衡有助于Kafka Streams在群集更改大小时将跨节点跨节点的最小数据量进行破坏。分布式处理系统中没有避免随机播放,但您可以最大限度地减少暂停和数据移动量。默认情况下,Kafka Streams会这样做。

最后,同步。如果事件是您系统的货币,则在遵循指示时,出纳员必须精确。但只要涉及分布式系统,肯定会有很简单的方法来犯错误。特别是,当分布式节点交换消息时,失败可以创建重试,这又可以创建重复的消息,丢失消息或部分执行指令。 Kyle Kingsbury展现了一个乱七八糟的生活。

当Kafka起飞时,它无法担心如何在故障情景下兑换消息。没有办法解决这个问题 - 这些是基础架构需要为您提供的低级保证。

如果Kafka将用于关键任务工作负载,这需要改变。因此,2017年,Apache Kafka完全添加了一旦语义(EOS)。 EOS意味着三件事:IDEMPotent消息发送,事务和幂等的状态处理。您需要所有三个来完全解决可靠的消息处理问题。在此到位,Kafka是值得信赖的,其中没有错误的空间。

所有这些在哪里ksqldb?愉快地解决七巧板拼图。由于Kafka Streams的API,透明地处理了无序数据。群集缩放工作没有大部分思考。正好 - 一旦可以使用单个服务器标志激活一次语义。

我们已经在堆栈中工作了:从数据采集,存储到处理。还剩什么?数据库最醒目的功能是剩下的。

关闭你的(比喻)的眼睛。想想坐在笔记本电脑上使用数据库。你看到了什么?

您可能会看到自己将一些文本键入控制台。该文本可能是SQL。

基于SQL的数据库已经占据了几十年,而且正确的数据库。他们的查询型号易于使用,易于理解。如果流处理是成为其他一半的数据库,我们需要追求类似的抽象,这些抽象包括到目前为止所讨论的一切。

它的查询层围绕SQL构建,使用简单的客户端/服务器架构 - 就像Postgres如何工作一样。您可以使用SQL来创建流,检查表,导出verticizations并发出查询来而不是直接与底层组件进行通信。您只看到两层:存储(通过Kafka)并计算(通过KSQLDB)。彼此独立弹性地缩放。

当您想查询数据时,访问状态表很简单。因为更新查询的状态(拟合每个拼写件)的所有工作发生在处理时间时,读取查询的结果(看到拼图的面部)是可预测的快速。没有工作要做。虽然这个想法在理论上是直截了当的,但在它周围建立你的建筑是更具挑战性的。

例如,在分布式群集中,您如何找到正确的服务器来发出查询的?如果您要查找的数据最近移动到另一台服务器,那么应​​该发生什么?您如何在客户端和服务器之间进行网络,这对于有查询的每个人都没有问题?

KSQLDB使用双查询支持轻松实现此功能。当您向KSQLDB的服务器发出查询时,它能够自动将查询路由到右侧节点 - 即使在故障面上也是如此。这一切都感谢Kip-535在Kafka Streams中,这增加了其州商店API支持副本信息。使用此,ksqldb可以提供拉出查询(请求/响应样式)和推送查询(流样式)。

对于我们所取得的所有进展,我们还没有那里。一本书可以充满剩下的差距,但现在我将简要触及三个较大的差距。在后续帖子中,我将详细讨论更多。

具有一系列打开问题的第一个区域位于堆栈的顶部,查询层。为了支持请求 - 响应样式查询,KSQLDB应该处理ad hoc sql。今天,它具有更多有限的富有关键型,这是其产生额外索引的能力。为了支持流式样式查询,需要将SQL语言重新升级和扩展。有一个正在进行的标准委员会(DM32佣金技术委员会),由Microsoft,Google,Oracle,IBM和Confluent等公司组成,在那个问题上拍摄。

需要更多思想的图片的另一部分是跨副本和源/下沉之间的容错容差的一致性。所有的东西都是平等的,它更容易构建与数据系统的应用程序,比较弱的一致性保证。如今,KSQLDB是一个容错的,最终一致的系统。其他项目通过以强的一致性和没有容错来开始反向沿反向方向接近这一点。最终目标显然是为了获得两者。

最后,流处理世界上有一个隐藏的宝石,值得记住。使用流处理以实现状态的特权是您可以选择存储后端。如果您需要快速查找,可以使用键/值存储。如果需要进行分析查询,则可以插入柱状商店。关系数据库支持可交换的存储引擎到某种程度,但传统上的流处理器传统上给您更加纬度。如今,KSQLDB在选择RocksdB中烘焙。 B.

......