系列文章目录
Flink/Blink 原理漫谈(一)时间,watermark详解
Flink/Blink 原理漫谈(二)流表对偶性和distinct详解
Flink/Blink 原理漫谈(三)state 有状态计算机制 详解
Flink/Blink 原理漫谈(五)流式计算的持续查询实现 详解
Flink/Blink 原理漫谈(六)容错机制(fault tolerance)详解
文章目录
前言 谈谈blink和flink
在实习时候接触到了flink,这玩意实现了大促期间的实时大数据更新,这对我们这种只写过python,c++啥玩意的来说闻所未闻,所以了解了一下flink的原理,并且尝试使用了公司的blink,在学习时间之余,整理了所有的学习笔记,目的也是分享学习。
Apache Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行有 状态计算。Flink 被设计在所有常见的集群环境中运行,以内存执行速度和任意规模 来执行计算。
Blink是阿里巴巴实时计算部通过改进开源Apache Flink项目而创建的阿里内部产品。简单的说Blink就是阿里巴巴开发的Flink 企业版。
这俩东西最大的不同其实我感觉,就是blink在公司应用起来是一个十分上层的api,语法基本都是sql,只需要加上with后面的参数就可以实现很多流式计算的功能,使用起来十分方便,即使有些复杂功能不好用sql直接实现也可以使用udf补充实现;而flink使用更多的是datastream api,还是要用java写的,一些函数的使用需要去一步一步熟悉,相对来说,还是复杂了很多,其实flink也有sql api,但是功能不完善,很离谱,我竟然在完全开发完成之前就已经在学习了。总之,blink虽好,但是是人家内部用,flink也好,但是使用也是略微门槛要高一丢丢,我看到阿里云好像有flink,那个版本的应该也可以使用最上层的api,这个就不是特别了解了。
Blink原理漫谈
这部分内容来自blink漫谈系列ata,以及网络中关于flink原理的讲解和一些知识分享视频。我认为想要理解flink原理,可以先尝试从头到尾阅读一下《blink漫谈》,大概是有十篇左右,这部分其实讲的很好,但是如果有点糊涂,那还是和我一样……拿着一本书先啃吧,看完一本介绍flink的书,再看这一部分,就感觉很好理解了。话不多说,我尝试用简单的语言讲一下blink/flink的比较重要的实现原理。
零、 Flink运行时的组件
Flink 运行时架构主要包括四个不同的组件,它们会在运行流处理应用程序时协同工作: 作业管理器(JobManager)、资源管理器(ResourceManager)、任务管理器(TaskManager), 以及分发器(Dispatcher)。因为 Flink 是用 Java 和 Scala 实现的,所以所有组件都会运行在 Java 虚拟机上。
下图是整个flink的架构
JobManager
控制一个应用程序的主进程
接受要制定的应用程序:作业图(JobGraph),逻辑数据流图(Logic dataflow graph),打包了的jar包
JobManager将JobGraph转换成一个物理层面的数据流图(执行图execution Graph),包含所有可并发执行的任务。
TaskManager
Flink中的工作进程,通常会有多个TaskManager运行。
每个TaskManager中含一定量slot
TaskManger会向ResourceManager中注册它的插槽
TaskManager收到ResourceManager的指令后,会将slot供JobManager调用(JobManager流程图的第二步的后续)
JobManager可向slot分配任务来执行
运行同一任务的TaskManager可相互交换数据
TaskManager与JobManager的关系如图
ResourceManager
负责管理TaskManager的slot
不同环境有不同的ResourceManager
Dispatcher
为应用提供了REST接口,启动web,ui,展示监控作业的执行信息
应用被提交执行->Dispatcher启动->将应用移交给一个JobManager
任务提交流程
TaskManger和slot
Flink 中每一个 worker(TaskManager)都是一个 JVM 进程,它可能会在独立的线 程上执行一个或多个 subtask。为了控制一个 worker 能接收多少个 task,worker 通 过 task slot 来进行控制(一个 worker 至少有一个 task slot)。 每个 task slot 表示 TaskManager 拥有资源的一个固定大小的子集。假如一个 TaskManager 有三个 slot,那么它会将其管理的内存分成三份给各个slot。
通过调整 task slot 的数量,允许用户定义 subtask 之间如何互相隔离。如果一个 TaskManager 一个 slot,那将意味着每个 task group 运行在独立的 JVM 中(该 JVM 可能是通过一个特定的容器启动的),而一个 TaskManager 多个 slot 意味着更多的 subtask 可以共享同一个 JVM。而在同一个 JVM 进程中的 task 将共享 TCP 连接(基 于多路复用)和心跳消息。它们也可能共享数据集和数据结构,因此这减少了每个 task 的负载。
Task Slot 是静态的概念,是指 TaskManager 具有的并发执行能力,可以通过 参数 taskmanager.numberOfTaskSlots 进行配置;而并行度 parallelism 是动态概念, 即 TaskManager 运行程序时实际使用的并发能力,可以通过参数 parallelism.default 进行配置。 也就是说,假设一共有 3个 TaskManager,每一个 TaskManager 中的分配 3个 TaskSlot,也就是每个 TaskManager 可以接收 3个 task,一共 9个 TaskSlot,如果我 们设置 parallelism.default=1,即运行程序默认的并行度为 1,9个 TaskSlot 只用了 1个,有 8个空闲,因此,设置合适的并行度才能提高效率