实时计算的Flink状态管理与容错


本文总结了2018年8月11日史晓刚在北京Flink Meetup上分享的演讲。史晓刚目前在阿里巴巴大数据团队从事瞬眼研发,负责瞬眼状态管理和容错的研发。阿里巴巴Blink是基于Apache的Flink构建的实时计算框架,旨在简化阿里巴巴生态系统上实时计算的复杂性。

在本文中,我们将涵盖以下内容:

  1. 有状态流数据的处理。
  2. Flink中的状态接口。
  3. 实施状态管理和容错。
  4. 阿里巴巴对Flink的贡献。

有状态流数据的处理

什么是有状态计算?

计算任务的结果不仅依赖于输入对象,还依赖于数据的当前状态。事实上,大多数计算任务都涉及有状态数据。例如,WordCount是一个用于计算单词计数的变量。字数是将新输入对象累加到现有字数中的输出。在这种情况下,字数是一个有状态变量。

传统流计算的问题

传统的流计算系统缺乏对程序状态的高效支持,例如:

  1. 状态数据的存储和访问。
  2. 状态数据的备份和恢复。
  3. 状态数据分区和动态调整大小。

在传统的批处理中,数据是分区的,每个任务处理一个分区。当执行所有分区时,输出被聚合为最终结果。在这个过程中,国家并不苛求。

而流计算对状态的要求很高,因为一个无限量的流导入到流系统中,流系统运行时间很长,比如说几天甚至几个月,不间断。在这种情况下,必须正确管理状态数据。遗憾的是,传统的流计算系统并不完全支持状态管理。例如,Storm不支持任何程序状态。一个解决方案是将Storm与HBase一起使用。状态数据存储在HBase中,Storm读取状态数据进行计算,然后将更新后的数据再次写入HBase中。可能会出现以下问题:

  1. 如果Storm任务和HBase数据存储在不同的服务器上,则性能较差。运行Storm任务的服务器必须频繁访问通过网络和存储介质运行HBase的对等服务器。
  2. 由于HBase不支持回滚,很难实现精确一次的一致性,因此备份和恢复非常困难。在分布式环境中,如果程序失败,必须重新启动Storm。在这种情况下,HBase数据不能回滚到以前的状态。例如,将Storm与HBase一起使用在广告计费中是不适用的,因为成本可能会加倍。另一种解决方案是将Storm与MySQL一起使用,这确保了数据的一致性,因为MySQL支持回滚。但是体系结构变得复杂,性能较差。COMMIT语句是确保数据一致性所必需的。
  3. 状态数据分区和动态调整大小对于Storm来说是困难的。一个严重的问题是,所有用户都要在Storm上重复同样的任务,例如,搜索和广告服务,这制约了业务发展。

闪烁的好处

Flink提供了丰富的访问状态接口和高效的容错能力。Flink已经被设计为提供丰富的API用于状态访问和高效的容错,如下图所示:

Flink状态管理

基于数据分区和大小调整模式,Flink有两类状态:键控状态和运算符状态。

键控状态

键控状态的使用:

Flink还在键控状态下提供多种数据结构类型。

键控状态的动态大小调整:

操作员状态

操作员状态的使用:

运算符状态支持的数据结构不如键控状态多。它们目前只支持列表。

运算符状态的多种大小调整模式:

运算符状态支持动态和灵活的大小调整。下面介绍运算符状态支持的三种大小调整方法:

  1. ListState:当并行性改变时,并行实例中的列表被提取并合并到一个新列表中。新列表中的元素被均匀地重新分配到新任务中。
  2. UnionListState:与ListState相比更灵活。您可以确定分区方法。当并发性改变时,原始列表将被联接。加入的列表不进行分区,直接发送给您。
  3. Broadcastate:当一个大表和一个小表连接在一起时,可以直接将小表广播到大表的分区中。每个并发任务上的数据完全相同。更新是一样的。当并发发生变化时,数据被复制到新任务中。

前面是Flink运算符状态支持的三种大小调整方法。您可以根据需要选择其中的任何一个。

使用检查点提高程序可靠性

可以为程序启用检查点。Flink以一定的间隔备份程序状态。如果出现故障,Flink会将所有任务恢复到最后一个检查点的状态,并从该检查点重新开始运行任务。

Flink支持两种模式来保证一致性:至少一次和精确一次。

备份未存储在状态中的程序状态数据

Flink还提供了一种机制,允许将状态存储在内存中。Flink在检查点操作期间恢复状态。

从停止的作业恢复

在升级组件之前,必须停止正在运行的作业。组件升级完成后,必须恢复作业。Flink提供了两种恢复作业的模式:

  1. 保存点:它是一个特殊的检查点。与系统定期触发的检查点不同,保存点由运行命令触发。保存点的存储格式也不同于检查点,数据以标准格式存储。无论配置如何,Flink都会从检查点恢复状态。保存点是一个很好的版本升级工具。
  2. 外部检查点:是现有检查点的扩展。内部检查点操作完成后,检查点数据也存储在指定的目录中。

实现状态管理和容错

下面列出了Flink为状态管理和容错提供的三个StateBackends:

  1. 内存状态后端
  2. FSStateBackend
  3. RockDBStateBackend

您可以根据需要选择任何模式。您可以在MemoryStateBackend或FsStateBackend中存储少量数据,在RocksDbStateBackend中存储大量数据。

以下描述了HeapKeyedStateBackend和RockSDBKeyedStateBackend:

HeapkeyedStateBackend

RocksDbKeyedStateBackEnd

检查点实施过程

检查点操作是基于Chandy-Lamport算法实现的。

检查站路障的定线

完全检查点

在备份每个节点的数据时,Flink遍历并将所有数据写入外部存储,影响了备份性能。对全检查点进行了优化,提高了性能。

RocksDB的增量检查点

RocksDB数据更新到内存中,并在内存满时写入磁盘。通过使用增量检查点机制,新生成的文件被复制到持久存储,而之前生成的文件不需要被复制到持久存储。这样就减少了要复制的数据量,从而提高了性能。

Flink与阿里巴巴

阿里巴巴从2015年开始支持Flink的研究。2015年10月,其启动了Flink项目,并在大规模生产环境下对Flink进行了优化和改进。在Double 11 Shopping Festival2016年,阿里巴巴使用Blink系统提供搜索,推荐和广告服务。2017年5月,Blink成为阿里巴巴的实时计算引擎。