实时数据处理是运行现代技术型企业的一个基础方面。客户比以往任何时候都希望有更快的结果,只要有一点机会,他们就会叛变。因此,现在的组织都在不断追寻从他们的反应中减去几毫秒的时间。
实时处理正在接管早期使用批处理的大部分方面。实时处理需要在传入的数据流上执行业务逻辑。这与传统的将数据存储在数据库中然后执行分析查询的方式形成鲜明对比。这类应用无法承受先将数据加载到传统数据库然后再执行查询所涉及的延迟。这就为流式数据库提供了舞台。流式数据库是能够接收高速数据并在移动中处理它们的数据存储,而不需要传统数据库的参与。它们不是传统数据库的替代品,但擅长处理高速数据。本文将介绍流数据库的4个关键设计原则和保证。
◆了解流式数据库
流数据库是能够实时收集和处理传入的一系列数据点(即,数据流)的数据库。传统的数据库存储数据,并期望用户执行查询以获取基于最新数据的结果。在现代社会,实时处理是一个关键标准,等待查询不是一个选项。相反,查询必须连续运行,并始终返回最新的数据。流数据库为此提供了便利。
在流式数据库的情况下,查询不是被执行,而是被注册,因为执行永远不会被完成。它们运行的时间是无限的,对新进来的数据做出反应。应用程序还可以回溯查询,以了解数据随时间变化的情况。
与传统的数据库相比,流式数据库在编写时做了所有的工作。实现这一点伴随着很多挑战。首先,人们期望从传统数据库中获得最低限度的耐久性和正确性。当数据总是在运动时,保持这种耐久性和正确性需要复杂的设计。然后,还有一个挑战是如何使用户能够查询运动中的数据。长期以来,SQL一直是满足所有查询要求的标准。很自然,流式数据库也支持SQL,但是当数据一直在移动时,实现像窗口化、聚合等结构是很复杂的。
持久性查询是一种对移动数据进行操作的查询。它们无限期地运行,并不断地输出行数。持久性查询在更新逻辑方面带来了独特的挑战。关键问题是关于用改进后的查询替换时的行为--它是对所有在此之前到达的数据进行操作还是只对下一组数据进行操作?第一种操作模式的名称是回填,后者是完全一次性处理。为了实现完全一次性处理,执行引擎必须有一个本地存储。有时,查询可以反馈给其他数据流。这样的操作被称为级联模式。
既然这些概念已经很清楚了,让我们花些时间来了解一下流式数据库的架构细节。流式数据库通常建立在一个基于生产者-消费者范式的流处理系统之上。生产者是一个创建事件的实体。消费者消费这些事件并对其进行处理。事件通常被分组为主题的逻辑分区,以方便业务逻辑的实现。
在它们之间有一个经纪人,他确保生产者和消费者所需的流和格式转换的可靠性。代理人通常分布在一个分布式平台上,以确保高可用性和稳健性。一个流查询引擎位于处理平台的顶部。一个将SQL查询转换为流处理逻辑的SQL抽象层也是存在的。将所有的东西拼接起来,架构看起来如下。
现在我们已经理解了流式数据库和持久性查询的概念,让我们花些时间来了解它们的典型用例。
◆物联网平台
物联网平台要处理来自世界各地设备的大量事件。他们需要根据实时处理催生警报,并在反应时间方面有严格的服务水平协议。物联网平台还需要永远存储所有收到的事件,并需要对流媒体数据进行基于窗口的聚合分析。流式数据库和持久性查询在这里很适合。
◆事件源
事件源是一种范式,应用逻辑是根据一段时间内发生的事件而不是实体的最终状态来执行的。这有助于提高应用程序的耐用性和可靠性,因为应用程序的状态可以通过对事件的回复随时重新创建。在审计跟踪是一个强制性要求的情况下,这很有用。
◆点击流分析
点击流分析平台处理作为应用程序使用的一部分产生的点击事件。来自点击事件的数据有时会被直接输入机器学习模型,为客户提供建议和意见。持续的事件和对点击流的实时处理是经营电子商务等业务的一个重要部分。
◆交易系统
交易系统每秒处理数以百万计的交易请求,并将其与需求和供应方程相匹配以结算交易。在这种情况下,审计跟踪是一项强制性要求,即使是最轻微的延迟也会给相关各方带来巨大的金钱损失。
◆欺诈检测系统
欺诈检测系统需要在检测到与典型的欺诈开始密切相关的情景时立即采取行动。他们还必须保留触发警报的记录和事件发生后的后续事件。考虑一个金融系统的欺诈检测系统,根据合法所有者的消费模式检测欺诈。它需要将事件的特征实时反馈给欺诈检测模型,并在标记出可能的违规行为时立即采取行动。实时数据库是实现此类用例的优秀解决方案。
◆IT系统监控
集中监控有助于组织保持其IT系统始终运行 流数据库通常用于收集系统的日志,并在满足特定条件时产生警报。通过事件存储产生的实时警报和审计跟踪是可观察系统实施的关键因素。
流媒体数据库市场并不拥挤,只有少数几个数据库是经过战斗考验的,可以处理生产工作负载。Kafka、Materialize、Memgraph等是其中几个稳定的数据库。选择一个适合用例的数据库需要对其功能进行详细的比较和用例剖析。
现在让我们把重点转移到学习流式数据库背后的关键数据库设计原则和保证。
◆4 关键的流数据库设计原则和保证
一个数据库系统的完整性通常以数据库是否符合ACID标准来表示。ACID抱怨构成了良好的数据库设计原则的基础。ACID兼容是指原子性、一致性、隔离性和持久性。完整性指的是保证逻辑操作中的一组语句在其中一个语句出现错误时能够优雅地失败。这样的一组语句被称为事务。在早期的流式数据库中,经常缺少对事务的支持,因此也缺少原子性。但是较新的版本确实支持事务。
一致性是指遵守数据库执行的规则,如唯一键约束、外键约束等。如果结果的状态不符合这些规则,一个一致的数据库将恢复交易。隔离是单独执行事务的概念,这样一个事务不会影响另一个。这使得事务的平行执行成为可能。像KSQLDB这样的数据库支持强一致性和查询的平行执行。持久性是指从故障点恢复。架构的分布式性质确保了现代流式数据库的强大耐久性。
在流式数据库的情况下,保证是指对处理事件的保证。由于数据是不断移动的,很难保证事件的处理顺序或避免重复处理。确保所有的数据被准确地处理一次是一个昂贵的操作,需要状态存储和确认。同样,在分布式应用的情况下,确保消息按照收到的相同顺序被处理,需要复杂的架构。
现在让我们来看看核心设计原则以及它们是如何在流式数据库中完成的。
◆自动恢复
自动恢复是流数据库中最关键的数据库设计原则之一。流数据库被用于高度监管的领域,如医疗、金融系统等。在这样的领域中,故障是没有借口的,事故可能导致巨大的金钱损失,甚至是生命损失。想象一下,一个流式数据库被整合为医疗保健物联网平台的一部分。传感器监测病人的生命参数,并将其发送到托管在云端的流数据库。这样的系统永远不会瘫痪,根据阈值产生警报的查询应该无限期地运行。
由于故障不是流式数据库的选项,它们通常是基于分布式架构来实现的。基于节点集群设计的流式数据库提供了很好的容错性,因为即使有几个节点发生故障,系统的其他部分仍然可以接受查询。这种容错性必须在开发周期的早期就被纳入流数据库的设计中。现在让我们看看流式数据库的自动恢复所涉及的关键活动。
分布式流媒体数据库的自动恢复涉及以下活动。
故障检测
再平衡和智能路由
最终恢复
故障检测是自动恢复的第一步。系统必须有足够的自我意识来检测故障情况,这样它才能采取必要的恢复措施。在分布式系统中,故障检测通常是通过心跳机制完成的。心跳是一个周期性的轻量级信息,节点每一次都会向集群的主站发送。这让其他人知道它还活着。如果没有收到一个节点的心跳信息,系统就会认为它已经死亡,并启动恢复程序。心跳信息的大小、其中捆绑的信息以及心跳信息的频率对于优化资源非常重要。非常频繁的心跳将有助于更早地发现故障,但它也会占用处理时间并产生开销。
当分布式系统中的一个节点发生故障时,该节点所拥有的资源必须重新平衡到其他节点。分布式系统使用受控的复制来确保数据不会丢失,即使有几个节点宕机。一旦一个节点瘫痪,系统就会确保数据在其他节点上得到重新平衡,并尽可能地保持复制策略,以减少数据丢失的风险。
为了维持一个高可用的流媒体数据库,在部分故障期间进行再平衡是不够的。因为在流式数据库的情况下,查询总是在运行,系统需要确保它们持续运行。这就是智能路由的作用。智能路由有助于确保查询持续运行并返回结果。使用故障节点上的资源的查询被无缝地路由到其他节点。这需要精心设计,是流式数据库的基础要求的一部分。
最后的恢复涉及到恢复事件中丢失的状态存储。状态存储被要求确保系统完全满足用户配置的约束条件一次,最多一次,或者至少是处理保证。分布式数据库通常使用一个无限的日志作为真理的来源。他们还使用单独的主题,在那里保留时间偏移作为恢复机制。在发生故障的情况下,这个时间偏移主题可以用来重新创建事件的时间线。
◆刚好一次的语义
在流式数据库的情况下,故障情况下的自动恢复是不够的。与传统的数据库设计不同,流式数据库的设计应该确保在故障时丢失的结果不会影响下游的消费者。要完成这个任务有几个方面。首先,系统需要确保没有记录错过处理。这可以通过重新处理所有的记录来实现,但这其中存在着风险。首先,没有充分考虑的重新处理会导致记录被处理一次以上。这导致不准确的结果。例如,考虑到同样的健康护理物联网平台,警报是决定生命的警报。重复处理会导致重复的警报,从而造成资源的浪费。重复处理也会导致汇总的结果,如平均数、百分数计算等。
根据不同的要求,有时,事件处理中的一些错误可能是可以接受的。流数据库定义了不同的消息处理保证,以支持具有不同要求的用例。有三种类型的消息保证可以使用--最多一次、至少一次和正好一次。最多一次保证定义了消息不会被处理超过一次的情况,但有时可能会错过处理。最少一次保证定义了允许重复处理的情况,但错过记录是不允许的。
精确一次语义保证了一个消息只被处理一次,而且结果足够准确,以至于消费者对失败事件视而不见。让我们借助一张图来探讨这个概念。
假设系统正在处理按顺序来的消息。为了表示,消息在这里从1开始排序。处理器接收消息,根据逻辑对其进行转换或聚合,并将其传递给消费者。在上图中,绿色表示尚未处理的消息,红色表示已处理的消息。每当一个消息被处理,处理器就会用偏移量更新一个状态存储。这是为了在发生故障时能够恢复。现在我们假设,处理器在处理完第二条消息后出现错误,并崩溃了。当处理器回来的时候,它必须从第3条而不是第2条消息重新开始处理。它应该避免对状态存储进行重复更新或将消息2的结果再次反馈给消费者。
换句话说,系统从结果的角度和系统间通信的角度都掩盖了故障。这需要生产者、消息传递系统和消费者根据约定的合同进行合作。消息传递确认是最简单的保证,可以帮助流式数据库完成这个任务。契约应该能够承受经纪人的失败、生产者与经纪人之间的通信失败,甚至是消费者的失败。
◆处理无序的记录
好的数据库设计将处理失序记录作为一个重要方面。流媒体数据库由于许多原因会遇到记录丢失的情况。这些原因包括网络延迟、生产者不可靠、时钟不同步等。由于它们被用于高度敏感的应用,如金融和医疗,其中处理的顺序是非常重要的,流数据库必须很好地处理它们。为了更好地理解这个问题,让我们考虑同一个物联网医疗平台的例子。假设由于一时的互联网连接故障,其中一个设备在很短的时间内无法发送数据。当它恢复时,它开始从恢复的时间开始发送数据。一段时间后,设备中的固件又发送了之前未能发送的其余数据。这就导致了无序的记录到达流数据库。
为了更好地了解情况,现在让我们用一个图来解释这个问题。下图有一个生产者,它发送的消息的数字从1开始。绿色的块代表尚未发送的事件,红色的代表这里已经发送的事件。当消息。1,2和3按照时间戳的顺序到达,一切都很好。但是,如果其中一个消息在途中或从源头本身被延迟,它将导致流平台的结果被破坏。在这种情况下,消息1和3比2早到。流平台在1和3之后收到2,但它必须确保下游的消费者按实际顺序收到消息。
如果不正确处理失序的记录,处理这些记录的流数据库将向下游系统提供不准确的结果。例如,让我们说,消息表示一个温度值,有一个持久性的查询,找到过去一分钟的平均温度。一个延迟的温度值会导致一个错误的平均值。流数据库用两种方法处理这些情况。第一种方法涉及一个配置参数,该参数定义了处理器在每个微批开始之前等待失序记录到达的时间。微批是一组记录,是实时查询的一部分。微批的概念是持久性查询的基础。
解决失序记录的第二种方法是允许处理器更新已经计算的结果。这需要与消费者达成一个协议。这个概念与交易的概念直接冲突,因此在实现时需要仔细设计。这只在下游消费者能够产生相同输出的情况下起作用,即使它以不同的顺序收到输入。例如,如果下游消费者的输出是一个允许修订的表,那么流式数据库就可以使用这种策略。
◆一致的查询结果
实现流式数据库通常是基于分布式架构的。传统的数据库设计原则认为原子性和一致性是良好数据库设计的关键支柱。但是在流式数据库中,由于其分布式的性质,要完成写入的一致性是很困难的。考虑一个使用复制分区概念的流数据库,并部署在一个节点集群上。收入流将根据存储模式进入不同的分区或节点。为了确保真实的写入一致性,人们需要确保只有当所有分区都反映它是成功的时候,流才被确认。当有多个消息作为逻辑事务的一部分时,这是很困难的。在将交易标记为成功之前,分别跟踪和确认每条信息是非常重要的。
确保写的一致性的困难也会渗透到读的一致性。只有在读取一致的情况下,才有可能返回一致的查询结果。考虑一个作为多个持久性查询的数据源的流,该查询根据不同的业务逻辑对流进行聚合。一个流式数据库必须确保这两个查询都作用于一个单一的真理源,并且查询的结果反映出不冲突的值。这是一个非常困难的命题,因为为了处理失序的记录,大多数数据库以连续的更新模式运行,经常改变它们之前计算的结果。在串联查询的情况下,这种更新会在不同的时间涓涓细流地流向下游,一些衍生的查询状态可能反映了不同的源数据状态。
有两种方法可以解决查询结果一致性的问题。第一种方法是通过确保在所有来自该流的查询完成之前不确认写入来解决这个问题。这对生产者来说是很昂贵的。因为为了满足精确的一次处理要求,大多数流式数据库都依赖于经纪人和生产者之间的联系(aknwoedlegemtns)。如果所有的写入都是在查询完成后才确认,那么生产者就会被蒙在鼓里更久。这种方法就是写时受阻的方法。
解决一致性问题的第二种方法是在查询引擎层面进行。在这里,查询引擎推迟需要强一致性保证的特定查询的结果,直到所有的写入被确认。这比第一种方法成本低,因为输入流的写入性能不受影响。这种方法不是延迟确认作为查询基础的输入流,而是在查询层面进行操作。因此,如果一个查询不需要强大的一致性保证,其结果将比其他依赖于相同输入流的查询更早发出。因此,不同的查询根据其一致性配置在同一输入流的不同版本上操作。这就要求流式数据库保持所有计算的线性化历史,这样它就可以很容易地总结出多个查询所执行的数据的版本。
流数据库必须在数据的滞后性和一致性水平之间取得平衡,以优化性能。提高一致性水平可能会导致处理速度下降,反之亦然。
◆总结
流数据库是实时处理应用程序的基础。它们不是传统数据库的替代品,而是帮助满足那些需要在永不停息的数据流上始终进行处理的独特要求。设计一个流式数据库是一项复杂的任务,因为在处理流式数据时涉及到一些限制。实现读取一致性、处理过期数据、确保一次处理和自动恢复是设计流数据库时考虑的典型设计原则。
来源:
https://www.toutiao.com/article/7167792751663284772/?log_from=b30ddbd4e6ff4_1668996967149
“IT大咖说”欢迎广大技术人员投稿,投稿邮箱:aliang@itdks.com

IT大咖说 | 关于版权
由“IT大咖说(ID:itdakashuo)”原创的文章,转载时请注明作者、出处及微信公众号。投稿、约稿、转载请:ITDKS10(备注:投稿),茉莉小姐姐会及时与您联系!
感谢您对IT大咖说的热心支持!