当前位置: 首页 > 科技观察

流式数据库的四个关键设计原则和保证

时间:2023-03-18 22:28:27 科技观察

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