初识flink
2016年的时候,开始关注flink,觉得是一个非常不错的流计算项目,当时也做了一些简单的demo,
了解其简单的应用,之后的两年里flink社区发展迅猛,包括阿里的强力支撑blink,在稳定性和性能
方面都有很大的提升,8月份我们开始筹划上线flink on k8s服务,做了一些基础性的调研工作。
flink on k8s
我们在github上搜索了不少关于flink on k8s的资料,基本上都不太靠谱,所以基础镜像方面我们
是自己制作的,这个过程非常耗时,但事后来看非常的必要,我们对flink有了更为深入的了解。
jobmanager和taskmanager我们是分为2个deployment,跟唯品会的方案不太相同(statefulset)。
我们将flink的shell脚本、yaml配置等内容进行了通读,对其参数做了详细的标注,最后将这些
参数进行合并,整理出大概20多个有效配置项和默认值,之后我们又将这些参数进行分类,大致分为
两类:容器级参数和业务参数。
举个例子:容器内存大小就属于容器级别参数,集群名称也属于容器级参数(相当于deploymentname)。
每个taskmanager有多少个slot,就属于业务参数。jvm的各种堆大小属于容器内存大小的衍生参数,
有一个统一的计算公式得到,并不进行传递。
容器级别的参数由docker的env进行传递,业务参数通过http接口获得。
所以我们的docker启动时,首先获取env中的参数,然后通过脚本调http接口获得一个json,再结合
本地的default.property文件中的默认值,进行合并,最后渲染配置文件和shell脚本,这里用了一个
python的模板引擎,类似javaweb中的velocity,freemaker等。
联通
flinkjobmanager的HA是通过zk来实现的,taskmanager和jobmanager之间的服务发现也要基于zk,
所以在docker模式下是可以很容易组成集群的。比较麻烦的一个问题是jobmanager的webui port,
由于我们的k8s上是使用物理机IP的,所以port是非常宝贵的资源,如果我们的port只能使用固定的端口,
意味着一台物理机只能启动一个jobmanager,所以在启动docker时,我们要指定要container的port,
这样k8s就能根据port来调度,不会发生冲突。为了解决port资源的问题,我们向k8s申请了专用port范围,
我们的集群随机从范围里选择一个port来启动任务。
内存使用比率
内存比例相关的参数是我们调试最多的一个环节,flink启动脚本中关于内存的计算非常复杂,
下面列举一些核心的点:
networkbuffer的大小
是否使用堆外内存来支持flink框架的计算逻辑
堆外与堆内的分配比例
jvm各个分代的大小
垃圾回收器的选择