知识卡片
数据流引擎的谱系重算容错与确定性算子的重要性
内容
[[数据流引擎用算子替代僵化的MapReduce角色]]带来性能提升的同时,也改变了容错的实现方式:MapReduce把中间状态完全物化到HDFS,天然具有持久性,任务失败时只需在另一台机器上重启、重新读取相同输入即可恢复;Spark、Flink、Tez为了避免把中间状态都落盘,改用另一种思路——如果某台机器的中间状态因故障丢失,就从其他仍可用的数据(前一步的中间状态,或者更早的原始输入)重新计算,为此框架必须记录清楚”这份数据是用哪些输入分区、经过哪些算子计算出来的”(Spark用弹性分布式数据集RDD跟踪这条数据谱系,Flink则对算子状态做存档)。这种重算式容错有一个隐藏前提:算子必须是确定性的,即给定相同输入总产生相同输出。如果算子行为不确定(常见的坑包括:哈希表遍历顺序不保证一致、概率/统计算法依赖随机数、依赖系统时钟或外部数据源),一旦部分丢失数据被重新计算出与原有下游已收到的数据不一致的结果,下游算子就很难调和新旧数据的矛盾,通常只能连带杀掉下游算子重跑——为了避免这种级联故障,实践上通常要求消除随机性(比如固定随机种子)来保证确定性。
参考来源
- 位置:《数据密集型应用系统设计》第十章《批处理》"容错"(源文件:_epub-src/ch10_split_003.html)
- 结论依据:原文对比MapReduce依赖HDFS物化实现容错与数据流引擎依赖谱系重算实现容错的差异,并说明重算依赖算子确定性、列举非确定性行为的常见来源及其导致的级联故障问题,直接支撑本卡片结论。
- 原始内容:如果一台机器发生故障,并且该机器上的中间状态丢失,则它会从其他仍然可用的数据重新计算……重要的是要知道计算是否是确定性的……为了能可靠地从故障中恢复,需要消除这种不确定性因素。