这四个项目能放在一起比较的背景应该是分布式计算的演进过程。
开源分布式计算的第一个流行的框架是 Hadoop 项目中的 MapReduce 模块。它将所有计算抽象成 Map 和 Reduce 两个阶段,在计算时通过增加机器,并行的读取数据文件,进行 Map 或 Reduce 的操作,并将结果写到文件中。如此反复得到最终的结果。
上面过程中,每个 Map 和 Reduce 阶段所能表达的计算逻辑是有限的,因此完整的业务逻辑往往包含了多个阶段。注意到每个阶段都有读取数据文件和数据写出到文件的开销,对于同一个任务的中间结果,其唯一用途就是被下一阶段读取,且读后就成为垃圾文件,对中间结果落盘显然是不合理的重大开销。
基于这样的观察,Spark 提出了内存计算的概念,核心思想就是中间结果尽量不落盘。依靠这样的基础思想,Spark 相对 Hadoop MapReduce 获得了千百倍的性能提升,代价是更高的内存开销以及 OOM 风险。经历过 Spark 1.x 年代的研发和运维应该都对此深有体会。
Storm 和 Flink 完全是另一个路数。我们这里讨论 Flink 的流计算部分,而不讨论它早年被 Spark 全方位吊打的 DataSet 批计算部分。
前面讨论的批计算,其特点是输入数据集是事先知晓且有限的,而流计算的世界观认为输入数据集是无限的消息流。因此,它们的计算逻辑处理的不是一批一批的数据,而是一条一条连绵不断的消息。
Storm 通过产生数据流的源头和消费数据流的管道来抽象流计算的世界,Flink 的流计算部分其实大同小异。两者最大的区别或者说 Flink 最大的优势是它拥有内置的状态管理和精确一次送达语义的容错机制。Flink 的官方标语就是状态化的流计算,因此这才是它的核心竞争力。有了内置的状态管理,Flink 相比 Storm 就少了对接外部状态存储的负担。要知道,每次手动对接外部存储,重复开发量是巨大的,而且涉及两个分布式项目的端到端一致性保证,将变得非常复杂。
以上就是对这四个项目口水化的介绍,其使用场景大抵如下。
Spark 作为批计算的王者存在,基本处理所有分布式批处理的场景。有的时候会使用 Hadoop MapReduce 是因为存量业务没有明显的性能瓶颈,不需要故意开发迁移。另一种情况是在没有严格性能要求的情况下,减少 Spark 的部署运维成本,简单使用 HDFS 集群直接支持的 MapReduce 计算任务。还有一种情况是早年某些 MapReduce 作业的 DSL 的存量,传递依赖 MapReduce 且同样没有升级的强需求,例如 Pig 程序。
Flink 作为流计算的标杆,基本覆盖了阿里巴巴内部的流计算场景。但是,在阿里强推之前,或者从技术上说被双十一磨砺之前,大部分公司的伪实时需求可以通过 Spark Streaming 或者 Storm 乃至订阅 Kafka 加消费者任务来解决。因此市面上非 Flink 的流计算大抵是过时或者有局限性技术的存量。Flink 的核心优势在于内置状态管理以及先发优势带来的较为完善的功能支持,这方面解决了流计算开箱即用的问题,以及双十一磨砺的性能优势,目前仍然是流计算框架的跑分榜第一。
当然,这些项目都还有其他内容。例如 Hadoop 的 YARN 资源管理框架,Spark 跟高迭代的机器学习的整合等等。同时,外围还有数据湖技术和 HTAP 以及其他流计算框架在争夺这四款软件的业务场景,那就不是这里一两句话能说完的了。