本文主要运行到Flink以下内容

  • 检查点机制(CheckPoint)

  • 状态管理器(StateBackend)

  • 状态周期(StateTtlConfig)

关系

首先要将state和checkpoint概念区分开,可以理解为checkpoint是要把state数据持久化存储起来,checkpoint默认情况下会存储在JoManager的内存中。checkpoint表示一个Flink job在一个特定时刻的一份全局状态快照,方便在任务失败的情况下数据的恢复。在启动 CheckPoint 机制时,状态会随着 CheckPoint 而持久化,以防止数据丢失、保障恢复时的一致性。状态内部的存储格式、状态在 CheckPoint 时如何持久化以及持久化在哪里均取决于选择的StateBackend。存储多长时间或者说是周期,取决于StateTtlConfig

1 检查点机制(CheckPoint)

Checkpoint 使 Flink 的状态具有良好的容错性,通过 checkpoint 机制,Flink 可以对作业的状态和计算位置进行恢复。

Checkpoint 在默认的情况下仅用于恢复失败的作业,并不保留,当程序取消时 checkpoint 就会被删除。当然,你可以通过配置来保留 checkpoint,这些被保留的 checkpoint 在作业失败或取消时不会被清除。这样,你就可以使用该 checkpoint 来恢复失败的作业。

参数设置与解释

  1. val env: StreamExecutionEnvironment =
  2.       StreamExecutionEnvironment.getExecutionEnvironment
  3. //只指定两个checkpoint的时间间隔,单位是毫秒
  4. //指定checkpoint时间间隔,并指定checkpoint的模式,是exactly-once(刚好一次)
  5. //还是AT_LEAST_ONCE(至少一次)。
  6. //大多数情况下是exactly-once(默认就是这个模式),少数情况下,如果要求超低延迟的处理情况,才会设置AT_LEAST_ONCE
  7. env.enableCheckpointing(1000CheckpointingMode.EXACTLY_ONCE) 
  8. // 两种方式
  9. // env.enableCheckpointing(1000)
  10. // env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
  11. /* 设置checkpoint上一个的结束点到下一个开始点之间的最短时间。
  12. checkpoint触发时,需要一定时间去完成整个checkpoint的过程,
  13. 1、这里的时间间隔,指的是上一个checkpoint完成的时间点,到下一个checkpoint开始的时间点的间隔,如果过短,会导致频繁checkpoint,影响性能。假设这个间隔为T
  14. 2、而上面设置的checkpoint时间间隔,指的是前一个checkpoint的开始时间到下一个checkpoint的开始时间。所以是始终大于1中的时间间隔的。假设这个间隔为 N
  15. 如果T小于这里设置的值,那么无论N设置多少,下一个checkpoint的开始时间必须是5000ms之后。如果T大于这里设置的值,那么正常按照N设置的间隔来触发下一个checkpoint,这里设置的间隔无关了。
  16. */
  17. env.getCheckpointConfig().setMinPauseBetweenCheckpoints(5000)
  18. // 设置checkpoint完成的超时时间
  19. env.getCheckpointConfig().setCheckpointTimeout(60000)
  20. // 设置checkpoint的最大并行度
  21. env.getCheckpointConfig().setMaxConcurrentCheckpoints(1)
  22. /*  开启checkpoints的外部持久化,但是在job失败的时候不会自动清理,需要自己手工清理state
  23. DELETE_ON_CANCELLATION:在job canceled的时候会自动删除外部的状态数据,但是如果是FAILED的状态则会保留;
  24. RETAIN_ON_CANCELLATION:在job canceled的时候会保留状态数据*/
  25. env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)
  26. // 当有更近的保存点时,优先采用savepoint来恢复成检查点
  27. env.getCheckpointConfig().setPreferCheckpointForRecovery(true)

目录结构

  1. /user-defined-checkpoint-dir
  2.     /{job-id}
  3.         |
  4.         + --shared/
  5.         + --taskowned/
  6.         + --chk-1/
  7.         + --chk-2/
  8.         + --chk-3/
  9.         ...

SHARED目录保存了可能被多个 checkpoint 引用的文件

TASKOWNED保存了不会被 JobManager 删除的文件

EXCLUSIVE则保存那些仅被单个 checkpoint 引用的文件

2 状态管理器(StateBackend)

可用的 State Backends

  • MemoryStateBackend

  • FsStateBackend

  • RocksDBStateBackend

MemoryStateBackend

在 MemoryStateBackend 内部,数据以 Java 对象的形式存储在堆中。Key/value 形式的状态和窗口算子持有存储着状态值、触发器的 hash table。

在 CheckPoint 时,State Backend 对状态进行快照,并将快照信息作为 CheckPoint 应答消息的一部分发送给 JobManager(master),同时 JobManager 也将快照信息存储在堆内存中。

MemoryStateBackend 能配置异步快照。强烈建议使用异步快照来防止数据流阻塞,注意,异步快照默认是开启的。用户可以在实例化 MemoryStateBackend 的时候,将相应布尔类型的构造参数设置为 false 来关闭异步快照(仅在 debug 的时候使用),例如:

  1.  new MemoryStateBackend(MAX_MEM_STATE_SIZE, false)

FsStateBackend

FsStateBackend 将正在运行中的状态数据保存在 TaskManager 的内存中。CheckPoint 时,将状态快照写入到配置的文件系统目录中。少量的元数据信息存储到 JobManager 的内存中(高可用模式下,将其写入到 CheckPoint 的元数据文件中)。

FsStateBackend 默认使用异步快照来防止 CheckPoint 写状态时对数据处理造成阻塞。用户可以在实例化 FsStateBackend 的时候,将相应布尔类型的构造参数设置为 false 来关闭异步快照,例如:

  1.  new FsStateBackend(path, false)

RocksDBStateBackend

RocksDBStateBackend 将正在运行中的状态数据保存在 RocksDB 数据库中,RocksDB 数据库默认将数据存储在 TaskManager 的数据目录。CheckPoint 时,整个 RocksDB 数据库被 checkpoint 到配置的文件系统目录中。少量的元数据信息存储到 JobManager 的内存中(高可用模式下,将其存储到 CheckPoint 的元数据文件中)。RocksDBStateBackend 只支持异步快照。

设置 State Backend

后面的案例也以RocksDBStateBackend为例

  1.  val backend:StateBackend = new RocksDBStateBackend("hdfs://djcluster/Test/")
  2.  
  3.  env.setStateBackend(backend)

3 状态周期(StateTtlConfig)

状态引入了TTL(time-to-live,生存时间)机制,支持Keyed State 的自动过期,有效解决了状态数据在无干预情况下无限增长导致 OOM 的问题。对于任何类型 Keyed State 都可以设定状态生命周期(TTL),以确保能够在规定时间内即时清理状态数据。

  1. val config: StateTtlConfig = StateTtlConfig
  2.               .newBuilder(Time.minutes(1))
  3.               .setUpdateType(StateTtlConfig.UpdateType.OnReadAndWrite)
  4.               .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
  5.               .build()
  6.               
  7.  val mapState = new MapStateDescriptor[String,Any]("aa",classOf[String],classOf[Any])
  8.  
  9.  mapState.enableTimeToLive(config)

参数说明:

  • UpdateType:表示状态时间戳的更新的时机

参数 说明
Disabled 不更新时间戳
OnCreateAndWrite 当状态创建或每次写入时都会更新时间戳
OnReadAndWrite 除了在状态创建和写入时更新时间戳外,读取也会更新状态的时间戳
  • StateVisibility:表示对已过期但还未被清理掉的状态如何处理

参数 说明
ReturnExpiredIfNotCleanedUp 即使这个状态的时间戳表明它已经过期了,但是只要还未被真正清理掉,就会被返回给调用方
NeverReturnExpired 那么一旦这个状态过期了,那么永远不会被返回给调用方,只会返回空状态,避免了过期状态带来的干扰

上面是理论论述,下面是代码实现与测试

4.理论实现与测试

描述

通过 nc -lk 8765 在机器上输入逗号隔开的字符串,比如:event,1,1 要保证中间的值和下次输入的值一样,这样keyBy分流到一个分区中,方便测试看到效果。状态值保存到Hdfs上。

  1. def main(args: Array[String]): Unit = {
  2.     val env: StreamExecutionEnvironment =
  3.       StreamExecutionEnvironment.getExecutionEnvironment
  4.     env.setParallelism(1)
  5.     val backend:StateBackend = new RocksDBStateBackend("hdfs://cluster/Test/")
  6.     env.setStateBackend(backend)
  7.     env.enableCheckpointing(5000)
  8.     env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
  9.     env.getCheckpointConfig.enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)
  10.     val dataDS: scala.DataStream[String] = env.socketTextStream("localhost", 8765)
  11.     dataDS.map(item => {
  12.       val str = item.split(",")
  13.       (str(0),str(1),str(2))
  14.     }
  15.     )
  16.       .keyBy(_._2)
  17.       .process(
  18.         new KeyedProcessFunction[String,(String, String, String), String] {
  19.           var leastValueState: MapState[String, Any] = _
  20.           override def open(parameters: Configuration): Unit = {
  21.             println("open")
  22.             val config: StateTtlConfig = StateTtlConfig
  23.               .newBuilder(Time.minutes(15))
  24.               .setUpdateType(StateTtlConfig.UpdateType.OnReadAndWrite)
  25.               .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
  26.               .build()
  27.             val aa = new MapStateDescriptor[String,Any]("aa",classOf[String],classOf[Any])
  28.             aa.enableTimeToLive(config)
  29.             leastValueState = getRuntimeContext.getMapState(aa)
  30.           }
  31.           override def processElement(i: (String, String, String),
  32.                                       ctx: KeyedProcessFunction[String, (String, String, String), String]#Context,
  33.                                       out: Collector[String]): Unit = {
  34.             println(leastValueState.get("3"))
  35.             i._1 match {
  36.               case "order" => leastValueState.put("order", 12)
  37.               case "event" => out.collect("打印event")
  38.               case _ => out.collect("什么都没有")
  39.             }
  40.             out.collect(leastValueState.get("3")+":")
  41.           }
  42.         }
  43.       )
  44.       .uid("bbbbbbb")
  45.       .print()
  46.     env.execute()
  47.   }

打包上传集群测试

执行命令

  1. ./bin/flink run -m yarn-cluster 
  2. -yqu spark -c com.wang.StateBackend /usr/local/jars/flink.jar  
  3. -yn 7 -ys 2 -14 -ytm 2048m -yjm 2048m

这个不管是你自己亲自kill掉application 或者是某些原因flink任务挂掉,这个时候你就可以这样恢复数据

找到RocksDBStateBackend设置的地址 hdfs://cluster/Test/

找到挂掉任务的checkpoint地址(可以通过Flink历史服务器去找,如果任务少,也可以直接去hdfs上找)

重新启动任务

这边遇到的一个坑就是命令参数位置不对,怎么设置都没有用,也不起效,下次一定记得。刚测试的时候 -s 写在后面的某一个位置,怎么测试都不起效,一直以为代码有问题,查询了好多资料,都是这样写的,没有问题,前前后后折腾好久。最后把 -s 参数调到最前面就神奇的好了......

  1. ./bin/flink run -m yarn-cluster 
  2. -s hdfs://cluster/Test/e45509db99014fd47971c6eaf3701f4b/chk-41/_metadata 
  3. -yqu spark -c com.wang.StateBackend /usr/local/jars/flink.jar 
  4. -yn 7 -ys 2 -14 -ytm 2048m -yjm 2048m

这个时候已经恢复到之前挂掉的数据了

Flink的状态与容错的更多相关文章

  1. 9、flink的状态与容错

    1.理解State(状态) 1.1.State 对象的状态 Flink中的状态:一般指一个具体的task/operator某时刻在内存中的状态(例如某属性的值) 注意:State和Checkpoint ...

  2. 第09讲:Flink 状态与容错

    Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...

  3. 关于 Flink 状态与容错机制

    Flink 作为新一代基于事件流的.真正意义上的流批一体的大数据处理引擎,正在逐渐得到广大开发者们的青睐.就从我自身的视角看,最近也是在数据团队把一些原本由 Flume.SparkStreaming. ...

  4. Flink之状态之checkpointing

    1.前言 在Flink中,函数和操作符都可以是有状态的.在处理每个消息或者元素时,有状态的函数都会储存信息,使得状态成为精密操作中关键的组成部分. 为了使状态能够容错,Flink会checkpoint ...

  5. Flink Streaming状态处理(Working with State)

    参考来源: https://www.jianshu.com/p/6ed0ef5e2b74 https://blog.csdn.net/Fenggms/article/details/102855159 ...

  6. Flink中的状态与容错

    1.概述 Flink支持有状态计算,根据支持得不同状态类型,分别有Keyed State和Operator State.针对状态数据得持久化,Flink提供了Checkpoint机制处理:针对状态数据 ...

  7. 「Flink」Flink的状态管理与容错

    在Flink中的每个函数和运算符都是有状态的.在处理过程中可以用状态来存储数据,这样可以利用状态来构建复杂操作.为了让状态容错,Flink需要设置checkpoint状态.Flink程序是通过chec ...

  8. Flink的状态编程和容错机制(四)

    一.状态编程 Flink 内置的很多算子,数据源 source,数据存储 sink 都是有状态的,流中的数据都是 buffer records,会保存一定的元素或者元数据.例如 : ProcessWi ...

  9. flink 有状态udf 引起血案一

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/rlnLo2pNEfx9c/article/details/83422587 场景 近期在做一个画像的 ...

随机推荐

  1. JAVA基础--cmd命令

    常用cmd命令行,很简单 md(make directory):创建文件夹 如:md test1: rd(remove directory):删除空文件夹 如:rd test1:若文件夹包含其他文件, ...

  2. C++libcurl的使用

    一.libcurl描述: 在curl的官方网站 **http://curl.haxx.se/download.html** 提供编译好libcurl包,  最后写一个demod工程,演示下libcur ...

  3. Python 中更优雅的日志记录方案

    在 Python 中,一般情况下我们可能直接用自带的 logging 模块来记录日志,包括我之前的时候也是一样.在使用时我们需要配置一些 Handler.Formatter 来进行一些处理,比如把日志 ...

  4. IntelliJ IDEA如何用maven命令打jar包

    IntelliJ IDEA如何用maven命令打jar包?下面给大家详细介绍一下具体步骤及说明. 工具/原料   IntelliJ IDEA maven 方法/步骤     第一步在CMD命令窗口输入 ...

  5. OAuth2.0的四种授权模式(转)

    1. OAuth2简易实战(一)-四种模式 1.1. 隐式授权模式(Implicit Grant) 第一步:用户访问页面时,重定向到认证服务器. 第二步:认证服务器给用户一个认证页面,等待用户授权. ...

  6. vue3系列:vue3.0自定义弹框组件V3Popup|vue3.x手机端弹框组件

    基于Vue3.0开发的轻量级手机端弹框组件V3Popup. 之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框 ...

  7. Linux嵌入式学习-交叉编译openssl

    利用arm-none-linux-gnueabi-gcc交叉编译openssl,生成静态库文件libcrypto.a ,libssl.a 1.从openssl官网下载openssl最新版本,我下载的是 ...

  8. [leetcode]222. Count Complete Tree Nodes完全二叉树的节点数

    /* 满二叉树的特点是2^n-1,对于完全二叉树,一个node如果左右子树深度相同,那么 是一个满二叉树.如果不是,那就把node算上,继续往下看,下边的可能是满二叉树 由于完全二叉树中有一些子满二叉 ...

  9. 论文翻译:2018_Deep Learning for Acoustic Echo Cancellation in Noisy and Double-Talk Scenarios

    论文地址:深度学习用于噪音和双语场景下的回声消除 博客地址:https://www.cnblogs.com/LXP-Never/p/14210359.html 摘要 传统的声学回声消除(AEC)通过使 ...

  10. 第十九章节 BJROBOT 安卓手机 APP 导航【ROS全开源阿克曼转向智能网联无人驾驶车】

    导航前说明:一定要确保你小车在构建好地图的基础上进行! 1.把小车平放在你想要构建地图区域的地板上,打开资料里的虚拟机,打开一个终端, ssh 过去主控端启动roslaunch znjrobot br ...