flink原理(一) 状态的TTL管理、容错机制

flink原理(一) 状态的TTL管理、容错机制

1、状态的ttl管理(time to live)

1、TTL的基本概念

  • flink可以对状态数据进行存活时长管理,即“新陈代谢”
  • 淘汰的机制主要是基于存活时间
  • 存活时长的计时器可以在数据被读、被写时候重置
  • Ttl存活管理粒度是元素级别的(list state中的每个元素,map state中的每个entry)

代码示例:

 public void open(Configuration parameters) throws Exception {
        StateTtlConfig config =  StateTtlConfig.newBuilder(Time.seconds(60))
                      .useProcessingTime()  //默认是用eventTime语义,如果要用processingTime语义,需要显示指定
                      .updateTtlOnCreateAndWrite() // ttl重置刷新的策略,数据被创建或者被写入更新,就将ttl计时重置
//                      .updateTtlOnReadAndWrite()   // ttl重置刷新的策略,数据被读取或者被写入更新,就将ttl计时重置
                      .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired) // 状态数据的可见性,如果状态中存在还未清理掉的,但是已经超出ttl的数据,是否让用户程序可见
                      .build();


        // 创建一个list状态的描述器
        ListStateDescriptor<String> stateDescriptor = new ListStateDescriptor<>("events", String.class);


        // 为描述器设置启用ttl功能
        stateDescriptor.enableTimeToLive(config);
    }

2、TTL的相关参数以及机制的解析

Ttl的相关配置参数全部封装在StateTtlConfig中

private StateTtlConfig(
        StateTtlConfig.UpdateType updateType,
        StateTtlConfig.StateVisibility stateVisibility,
        StateTtlConfig.TtlTimeCharacteristic ttlTimeCharacteristic,
        Time ttl, 
        StateTtlConfig.CleanupStrategies cleanupStrategies) {

StateTtlConfig参数详解:

public enum UpdateType {
        /** TTL is disabled. State does not expire. */
        Disabled,
        /**
         * 计时从写入或更新时开始(重置)
         */
        OnCreateAndWrite,
        /** 同上,不过读取时候也会计时重置 */
        OnReadAndWrite
    }

StateVisibility(过期数据可见策略)

public enum StateVisibility {
        /** Return expired user value if it is not cleaned up yet. */
        ReturnExpiredIfNotCleanedUp,
        /** Never return expired user value. */
        NeverReturnExpired
    }

TtlTimeCharacteristic(Ttl计时的时间语义)

  public enum TtlTimeCharacteristic {
        /**
         * Processing time, see also <code>
         * org.apache.flink.streaming.api.TimeCharacteristic.ProcessingTime</code>.
         */
        ProcessingTime
    }

Time ttl
数据存活时间,一个简单的长整形参数。

StateTtlConfig.CleanupStrategies(过期数据清理策略)

 /** Fixed strategies ordinals in {@code strategies} config field. */
        enum Strategies {
            FULL_STATE_SCAN_SNAPSHOT,
            INCREMENTAL_CLEANUP,
            ROCKSDB_COMPACTION_FILTER
        }

1)INCREMENTAL_CLEANUP:增量清除
可以选择增量式清理状态数据,在状态访问或/和处理时进行。如果某个状态开启了该清理策略,则会在存储后端保留一个所有状态的惰性全局迭代器。
每次触发增量清理时,从迭代器中选择已经过期的数进行清理。

每当访问状态时,都会驱动一次过期检查(算子注册了很多key的 state,一次检查只针对其中一部分,由参数cleanupSize决定)
算子持有一个包含所有key的迭代器,每次检查后,迭代器都会向前advance指定的key数量。

本策略,针对“本地状态空间”,且只用于HashMapStateBackend。

2)FULL_STATE_SCAN_SNAPSHOT
在进行全量快照(checkpoint)时,清理掉过期数据;

注意:只是在生成的checkpoint数据中不包含过期数据;在本地状态空间中,并没有做清理;

本策略,针对“快照”生效。

3)ROCKSDB_COMPACTION_FILTER
只针对rocksdbStateBackend有效;

它是利用rocksdb 的compact 功能,在rocksdb进行compact 时,清除掉过期数据;

本策略,针对“本地状态空间”,且只用于EmbeddedRocksDbStateBackend。

完整的api案例

        StateTtlConfig.newBuilder(Time.milliseconds(1000))
                // 配置数据存活时间为4s(覆盖builder构造传入的1s)
                .setTtl(Time.milliseconds(4000))
                // 当插入、更新时候,该数据的ttl计时重置
                .updateTtlOnCreateAndWrite()
                // 当读取、更新时候,该数据的ttl计时重置
                .updateTtlOnReadAndWrite()
                // 不允许返回已经过期但是还没清理的数据
                .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
                // 允许返回已经过期但是还没清理的数据
                .setStateVisibility(StateTtlConfig.StateVisibility.ReturnExpiredIfNotCleanedUp)
                //  ttl的时间语义:设置为处理时间
                .setTtlTimeCharacteristic(StateTtlConfig.TtlTimeCharacteristic.ProcessingTime)
                //  ttl的时间语义:设置为处理时间
                .useProcessingTime()
                // 增量清理(每一条状态数据被访问,会驱动过期检查以及清除)
                .cleanupIncrementally(1000,true)
                // 全量快照清理策略(ck时候,保存到快照文件的值包含未过期的状态数据,并不会清理算子状态数据)
                .cleanupFullSnapshot()
                // compact 过程中清理过期的状态数据
                .cleanupInRocksdbCompactFilter(1000)
                // 禁用默认后台清理策略
                .disableCleanupInBackground()
                .build();

2、flink的容错机制

Flink是一个stateful(带状态)的数据处理系统;系统在处理数据的过程中,各算子所记录的状态会随着数据的处理而不断变化;

一旦系统崩溃,需要重启后能够恢复出崩溃前的状态才能进行数据的接续处理;因此,必须要一种机制能对系统内的各种状态进行持久化容错;

1、EOS基本概念

Exactly-Once 语义:指端到端的一致性,从数据读取、引擎计算、写入外部存储的整个过程中,即使机器或软件出现故障,都确保数据仅处理一次,不会重复、也不会丢失。

对于flink程序来说,端到端EOS语义则包含source、 state、sink三个环节的紧密配合

2、flink的EOS

Flink在目前的各类分布式计算引擎中,对EOS的支持是最完善的;

在合理的数据源选择,合理的算子选择,合理的目标存储系统选择,合适的参数配置下,可以实现严格意义上的端到端EOS。

1)source端的保证

Flink的很多source算子都能为EOS提供保障,如kafka Source :

  • 能够记录偏移量;
  • 能够重放数据;
  • 将偏移量记录在state中,与下游的其他算子的state一起,经由checkpoint 机制实现了“状态数据的”快照统一。
2)算子状态的EOS语义保证

基于分布式快照算法: (Chandy-Lamport),flink实现了整个数据流中各算子的状态数据快照统一;

既:一次checkpoint后所持久化的各算子的状态数据,确保是经过了相同数据的影响;

这样一来,就能确保:
√ 一条(或一批)数据要么是经过了完整正确处理;

√ 如果这条(批)数据在中间任何过程失败,则重启恢复后,所有算子的state数据都能回到这条数据从未处理过时的状态。

3)sink端的保证

从前文所述的source端和内部 state的容错机制来看,一批数据如果在sink端写出过程中失败(可能已经有一部分数据进入目标存储系统),

则重启后重放这批数据时有可能造成目标存储系统中出现数据重复,从而破坏EOS;

对此,flink中也设计了相应机制来确保EOS

√ 采用幂等写入方式

√ 采用两阶段提交(2PC,two phase)事务写入方式

√ 采用预写日志2PC提交方式

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值