美文网首页
Flink的可靠性保证 - 状态存储

Flink的可靠性保证 - 状态存储

作者: flywind800 | 来源:发表于2018-12-25 11:18 被阅读0次

    一 为什么需要State存储

    与批计算相比,State是流计算特有的,批计算的failover机制,是失败后重新计算;流计算在大多数场景下是增量计算,数据逐条处理,每次计算是在上一次计算结果之上进行处理的,这就要求对上一次的计算结果进行存储,当因为机器,网络,脏数据等原因导致程序错误的时候,可以重启Job进行state恢复。Flink就是基于state存储,通过CheckPoint机制来保证数据的准确性。

    此外,State存储的内容还有流计算过程中计算节点的中间结果或元数据属性,比如Window方面的操作,需要累加数据;在aggregation过程中的中间聚合结果;在以Apache Kafka作为数据源时候,记录已经读取数据的offset等

    二 State存储的实现

    Flink内部有三种state的存储实现,如果不做配置,Flink默认使用的是MemoryStateBackend,三种实现分别是:

    1 基于内存的MemoryStateBackend- 在debug模式使用,在生产模式下不建议使用;

    2基于HDFS的FsStateBackend –基于分布式文件系统的持久化,每次读写都产生网络IO,整体性能不太好;

    3基于RocksDB的RocksDBStateBackend - 本地文件+异步HDFS持久化,当前版本在生产环境下使用的

    选择用RocksDB+HDFS的方式进行State的存储,State存储分两个阶段,首先本地存储到RocksDB,然后异步的同步到远程的HDFS。 这样的而设计既消除了HeapStateBackend的局限(内存有限,宕机数据丢失),也减少了纯分布式存储的网络IO开销。RocksDBStateBackend存储value的大小是有限制的,

    RocksDB’s的bridge API是基于byte[]的,所以这种state存储支持的每个key的value最大不超过2^31,有些merge操作的值可能会超过2^31 bytes,这点要注意。

    StateBackend的控制粒度到job级别,如果想为所有job设置StateBackend,可以通过更改flink-conf.yaml文件里state.backend的值 ,上述3类sate backend对应的值是;

    jobmanager(MemoryStateBackend),filesystem(FsStateBackend),和 rocksdb(RocksDBStateBackend);也可为单独的job设置StateBackend的方法:

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setStateBackend(new FsStateBackend("hdfs://namenode:40010/flink/checkpoints"));

    KeyedState和OperatorState:

    KeyedState - 这里面的key就是我们用KeyBy(x)里面的key,key与key之间的State是不可见的。KeyedState只能用在KeyedStream上的数据处理上。OperatorState是和Operator联系在一起的,比如Source Connector的实现中会用OperatorState来记录source数据读取的offset。

    无论选用何种stateBackend,这些state都是优先存在本机上,当计算并行度发生变化,这些state也会被重新分发到不同机器上去。

    OperatorState的分发,需要在Source Connector中实现,重点是把source的partition重新分配,并把之前记录的每个partition的offset也告诉新分配到的Source Connector。

    KeyedState存的数据量比较大,如果调整并发度,copy的东西可能比较多,Flink为了避免过多的拷贝,采用了一个keygroup的机制。每个key通过hash方法分配到不同的keygroup中,当并发度调整的时候,调整粒度是keygroup,也就是一个key通过hash后所在的keygroup保持不变。

    RawState 和  Managed State

    managed state是我们常用的那些ValueState,ListState,MapState等,这些State类型,由Flink控制它们的数据结构和存取方法。

    Raw state是在自己实现operator的时候使用,相当于自定义state类型,自己控制数据结构和存取方式。

    State可以手动地删除已存的值,也可以设置Time-To-Live (TTL),让state过期自动失效。存取State前,要先创建StateDescriptor,StateDescriptor含有state名称和state值的数据类型,有时候还需要自定义函数。在keyedstream上应用的函数,存取state的时候,key是由Flink自动提供的,直接使用xxx.value()函数就可以取到当前key对应的值;由Flink自动控制的话,可以统一控制state和stream的分区。

    欢迎阅读,有问题可以通过邮件kaiyuan0989爱特163.com一起探讨。

    相关文章

      网友评论

          本文标题:Flink的可靠性保证 - 状态存储

          本文链接:https://www.haomeiwen.com/subject/wcoxlqtx.html