状态(State)与一致性模型

接下来我们转向另一个在流处理中十分重要的点:状态(state)。状态在数据处理中是无处不在的。为了产生一个结果,函数一般会聚合某个时间段内(或是一定数量的)events的状态信息(例如计算聚合值,或是发现一个模式),有状态的 operators使用流的输入事件以及内部状态,计算出它们的输出。例如,一个滚动聚合operator输出当前它读入的所有的events的总和。Operator 持有当前sum的值作为它的内部状态,并在每次读入新值时对它做更新。类似,考虑一个operator在检测到“高温”后,若是在接下来的10分钟内检测到“烟”,则发出警报。此时operator需要将“高温”事件存储在它的状态信息中,直到看见“烟”事件,或是到达10分钟的过期时间。

由于流处理器可能会处理无限的数据,所以需要注意的是,不要让内部state无限地增长下去。为了限制state 大小,一般来说,operators会维护一些到目前为止看到的所有events的概要(synopsis)、或是总结(summary)信息。这个摘要信息可以是 计数、sum、 一个样本、亦或是用户自定义的一个数据结构(用于存储某些需要的属性)。

对于支持有状态的operators,会有以下挑战:

1. 状态管理

系统需要高效地管理state,并确保它可以被(合理地)并行更新

2. 状态分区

在并行处理时,场景较为复杂,因为输出的结果依赖于state以及持续输入的events。不过在大部分场景中,我们可以通过key将state分区,并单独的管理每个state。例如处理的输入流为一组传感器的events,这时可以使用分区的operator state 独立地维护每个传感器的状态信息。

3. 状态恢复

最大的挑战为:在发生错误时,有状态的operator需要确保state可以被恢复,并且仍能输出正确的结果。

接下来我们详细地讨论一下任务失败以及result guarantees。

任务失败

在流处理工作中,opratror state是非常重要的信息,需要对此有容错能力。如果在一次failure中,state丢失,则即使最终作业恢复了,输出的结果可能仍是不对的。流处理工作一般会持续运行较长时间,所以state可能会在几天(甚至几月)才会被收集一次。如果重新去处理所有的输入,以生成丢失的state,会是一个费时费算力的过程。

在实际场景中,可以经常见到有上百个并行任务(task)的流作业。而在长期运行的流作业中,每个任务在任何时间都有可能失败。如何确保这些故障可以被透明地处理,并让流工作继续运行?事实上,我们需要流处理器不仅可以在任务失败时仍能继续处理,还需要保证结果以及operator state的正确性。接下来我们会对此讨论具体细节。

什么是一个任务失败

对于输入流里的每一个event来说,一个任务是一个处理步骤,包含以下几步:(1)接收到event,将它存储在本地缓存;(2)可能会更新内部state;并(3)生成一个输出条目。而故障可能在以上任意一步发生。如果故障发生在第一步,event是否会丢失?如果在已经更新了state后发生故障,state的信息在任务恢复后是否再次被更新?而在这些场景下,最终输出的结果是否仍是准确的?

流系统通过提供结果保障(result guarantees)定义任务在故障发生时的行为。下面我们会介绍主流流处理器提供的保障(guarantees),以及为了达到这些guarantees,系统实现的一些机制。

至多一次(AT-MOST-ONCE

当一个任务失败时,最简单的做法是不做任何事。至多一次确保每个event仅被处理一次 。也就是说,失败了就失败了。events可以简单的被丢弃,并且不做任何事去确保结果的正确性。这种guarantee也被称为“没有保障“(no guarantee),因为一个丢弃所有events的系统也可以提供这种保障。没有保障这点可能听起来是一个比较差的想法,但是如果你关注的是尽量少的延迟,并且系统并不要求很高的准确性,则这也是一个可接受的选择。

至少一次(AT-LEAST-ONCE

在大部分真实应用中,我们会希望events不应该丢失。这种guarantee被称为至少一次,意思是:所有的events均会被处理,并且有些可能会被处理不止一次。如果应用的准确性仅取决于所有事件的完整性,则重复的处理可能也是能被接受的。例如,如果场景是判断某个特定的event是否在流中出现,则可以使用此guarantee。但是如果是判断此特定event在流中出现的次数,则使用此gurantee会返回错误的结果。

为了确保at-least-once结果的准确性,我们需要有一种方式replay events(从数据源或是缓冲区)。持久化的 event log会将events写入到可靠存储,所以在task失败时,这些events可以被replay。另一种达到同样效果的方法是使用 记录确认(record acknowledgments)。此方法会在缓存中存储每个event,直到某个event被管道中所有的task 确认处理后,此event才会被丢弃。

精确一次(EXACTLY-ONCE

精确一次是最严格的guarantee,并且很难达成。精确一次意思是:不仅没有event丢失,而且在更新state时,每个event仅被应用一次。本质上说,exactly-once guarantee 表示应用会提供准确的结果,就像故障没有发生一样。

提供exactly-once guarantee需要at-least-once guarantees,所以数据replay的机制也是必须的。此外,流处理器还需要确保internal state的一致性。也就是说,在从错误恢复后,它应该能够知道,一个event是否已经被state使用了。事务更新(transactional updates)是一种实现它的方式,但是它会引发大量性能开销的问题。在Flink中,它用了一个轻量级的快照机制(snapshotting)达成exactly-once result guarantee。会在之后的章节进一步讨论。

端到端精确一次END-TO-END EXACTLY-ONCE

到目前为止我们所见到的各种guarantees,都表示的是:由流处理器(stream processor)管理的application state。在真实的流应用中,除了流处理器外,都至少会有一个source和一个sink。End-to-end guarantees表示的是在整个数据处理pipeline中的结果准确性。每个组件提供了它自己的guarantee,所以整个pipeline的 end-to-end guarantee 是每个组件中最弱的那个guarantee。需要注意的是,有时候使用较弱的guarantees可能也能获取更强guarantee的语义。一个常见的案例是:当一个task求最大值或最小值的时,使用at-least-once guarantess即可达到exactly-once语义的效果。

总结

到现在为止,我们独立于Flink介绍了流处理中的一些概念,在之后的章节中,我们会介绍Flink是如何实现的这些概念,以及如何使用DataStream API 去编写应用程序并使用介绍到的这些功能。

References

Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019

Flink流处理(五)- 状态与一致性模型的更多相关文章

  1. Flink架构(五)- 检查点,保存点,与状态恢复

    检查点,保存点,与状态恢复 Flink是一个分布式数据处理系统,这种场景下,它需要处理各种异常,例如进程终止.机器故障.网络中断等.因为tasks在本地维护它们的state,Flink必须确保在出现故 ...

  2. Flink流处理(一)- 状态流处理简介

    1. Flink 简介 Flink 是一个分布式流处理器,提供直观且易于使用的API,以供实现有状态的流处理应用.它能够以fault-tolerant的方式高效地运行在大规模系统中. 流处理技术在当今 ...

  3. flink流处理从0到1

    一.DataStream API之Data Sources(消费者之数据源) 介绍: source是程序的数据源输入,你可以通过StreamExecutionEnvironment.addSource ...

  4. 带你玩转Flink流批一体分布式实时处理引擎

    摘要:Apache Flink是为分布式.高性能的流处理应用程序打造的开源流处理框架. 本文分享自华为云社区<[云驻共创]手把手教你玩转Flink流批一体分布式实时处理引擎>,作者: 萌兔 ...

  5. 转:Windows Socket五种I/O模型

    原文转自:  Windows Socket五种I/O模型 Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模 ...

  6. I/O模型之一:Unix的五种I/O模型

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  7. Windows Socket五种I/O模型——代码全攻略(转)

    Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操 ...

  8. State Processor API:如何读取,写入和修改 Flink 应用程序的状态

    过去无论您是在生产中使用,还是调研Apache Flink,估计您总是会问这样一个问题:我该如何访问和更新Flink保存点(savepoint)中保存的state?不用再询问了,Apache Flin ...

  9. CAP原理、一致性模型、BASE理论和ACID特性

    CAP原理 在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 一致性(Con ...

随机推荐

  1. 【剑指Offer】60、按之字形顺序打印二叉树

    题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 题解:BFS 主要的方法与BFS写法没什么区 ...

  2. python之路(列表,元组)

    列表 list:基础数据类型之一,可以索引,切片,步长,切片+步长可以增删改查,可迭代,可嵌套字典,元组,列表 一.索引,切片,步长 list01 = [1,2,3,'eric','west'] 1. ...

  3. Cloud保存时提示消息是否保存,点是保存,点否不保存。

    业务场景:保存时,检查上游的销售出库单数量,和发货通知单数量是否一致,不一致时提示信息,点是则保存,点否不保存. using System;using System.Collections.Gener ...

  4. 解决vmware每次打开无法上网

    vmware网络配置好了,但是每次打开都无法上网,记录下 在计算机管理中启动这几个服务,就ok了

  5. Python 高维数组“稀疏矩阵”scipy sparse学习笔记

    scipy 里面的sparse函数进行的矩阵存储 可以节省内存 主要是scipy包里面的 sparse 这里目前只用到两个 稀疏矩阵的读取 sparse.load() 转稀疏矩阵为普通矩阵 spars ...

  6. 为什么在linux系统下安装anaconda的时候会报错

    报错界面 一开始是在官网下载的最新的包,出现了上述的报错,但是换成清华镜像之后,就没有上述报错了? 我猜测可能是因为 官网最新的版本的anaconda和你安装的python版本不兼容,而在镜像上的不是 ...

  7. 在SQL中怎么把一列字符串拆分为多列

    --首先,你是按什么规则拆? 我举个例子 你要按字段中的逗号拆开,假设字段名叫text --用charindex和substring这2个函数    select substring(text,1,c ...

  8. Linux系统初学者的常见问题解决集结大全

    http://www.embeddedlinux.org.cn/html/xinshourumen/200809/22-86.html 一. 如何建立多用户 提醒大家一句,别一直使用root用户,因为 ...

  9. 解决Oracle ORA-01033: ORACLE initialization or shutdown in progress错误 和 ORA-01589错误 要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选项

    要打开数据库则必须使用 RESETLOGS 或 NORESETLOGS 选项 SQL> startupORACLE 例程已经启动. Total System Global Area  13533 ...

  10. php处理复选框

    1.HTML <form action="getData.php" method="post" enctype="multipart/form- ...