共计 2592 个字符,预计需要花费 7 分钟才能阅读完成。
本文作者胡梦宇,知乎大数据架构开发工程师,次要负责知乎外部大数据组件的二次开发和数据平台建设。
背景
Flink 因为其可靠性和易用性,曾经成为以后最风行的流解决框架之一,在流计算畛域占据了主导地位。早在 18 年知乎就引入了 Flink,倒退到当初,Flink 曾经成为知乎外部最重要的组件之一,积攒了 4000 多个 Flink 实时工作,每天解决 PB 级的数据。
Flink 的部署形式有多种,依据资源调度器来分类,大抵可分为 standalone、Flink on YARN、Flink on Kubernetes 等。目前知乎外部应用的部署形式是 Flink 官网提供的 native Kubernetes。谈到 Kubernetes,就不得不说容器镜像的问题,因为 Flink 工作的依赖多种多样,如何给 Flink 打镜像也是一个比拟头疼的问题。
Flink 镜像及依赖解决
Flink 的工作大抵可分为两类,第一类是 Flink SQL 工作,Flink SQL 工作的依赖大抵有以下几种:
- 官网的 connector JAR 包,如 flink-hive-connector、flink-jdbc-connector、flink-kafka-connector 等;
- 非官方或者是外部实现的 connector JAR 包;
- 用户的 UDF JAR 包,一些简单的计算逻辑,用户可能会本人实现 UDF。
第二类 Flink 工作是 Flink 的 jar 包工作,除了以上三种依赖,还须要依赖用户本人写的 Flink jar 程序包。
显然,对于每一个 Flink 工作,它的依赖不尽相同,咱们也不可能为每一个 Flink 工作独自打一个镜像,咱们目前的解决如下:
- 将依赖进行分类,分为稳固依赖和非稳固依赖;
- 稳固依赖包含组件(如 Flink、JDK 等)以及官网的 connector 包,这类依赖非常稳固,只会在 Flink 版本升级和 bug 修复这两种状况下进行改变,因而咱们会在构建镜像时,将这类依赖打入镜像;
- 非稳固依赖包含第三方的 connector 和用户本人的 JAR 包。第三方的 connector 因为不是 Flink 官网保护,所以出问题须要修复的概率绝对更大;用户本人的 JAR 包对于每个工作来说都不雷同,而且用户会常常改变从新提交。对于这类不稳固的依赖,咱们会动静注入,注入的形式是将依赖存入分布式文件系统,在容器启动的时候,利用 pre command 下载进容器里。
通过以上解决,Flink 镜像具备了肯定的动静加载依赖的能力,Flink Job 的启动流程大抵如下:
文件系统选取
HDFS 寄存依赖的痛点
寄存 Flink 依赖的文件系统在之前咱们始终都是选用的 HDFS, 然而在应用过程中咱们遇到了以下痛点:
- NameNode 在工作高峰期压力过大,容器在下载依赖时向 NameNode 申请文件元数据会存在卡顿的状况,有些小的批工作,工作自身可能只须要运行十几秒,然而因为 NameNode 压力过大,导致下载依赖可能须要几分钟;
- 目前 Flink 集群咱们是多数据中心部署,然而 HDFS 只有一个离线机房大集群,这样会存在跨数据中心拉文件的状况,耗费专线带宽;
- 有一些非凡的 Flink 工作齐全不依赖 HDFS,换句话说它既不应用 checkpoint 也不读写 HDFS,然而因为 Flink 容器的依赖寄存在 HDFS 上,导致这类工作仍然离不开 HDFS。
应用对象存储的痛点
前面咱们将 HDFS 换成了对象存储,解决了 HDFS 的一些痛点,然而很快咱们发现了新的问题 — 对象存储单线程下载的速度慢。对象存储下载减速可选的计划个别有以下几种:
- 应用多线程下载进行分段下载,然而容器的 pre command 其实只适宜执行一些比较简单的 shell 命令,如果采纳分段下载,就必须对这一块进行比拟大的革新,这是一个比拟大的痛点;
- 给对象存储加代理层做缓存,减速的事件由代理来做,客户端仍然能够单线程读取。这种方法的毛病是须要额定保护一个对象存储的代理组件,组件的稳定性也须要有保障。
尝试 JuiceFS
比拟凑巧的是公司外部正在做 JuiceFS 的 POC, 有现成的对象存储代理层可用,咱们对其进行了一系列测试,发现 JuiceFS 齐全满足咱们这个场景的需要,让咱们比拟惊喜的中央有以下几点:
- JuiceFS 自带 S3 gateway 完满兼容 S3 对象存储协定,可能让咱们很快上线,无需任何改变,并且 S3 gateway 自身无状态,扩缩容十分不便;
- JuiceFS 自带缓存减速性能,通过测试,用 JuiceFS 代理对象存储后,单线程读取文件的速度是原来的 4 倍;
- JuiceFS 提供本地文件系统挂载的形式,前面能够尝试依赖间接挂载进容器目录;
- JuiceFS 可选用元数据与存储拆散部署的形式,存储咱们选用原来的对象存储,云厂商保障 11 个 9 的可用性;元数据咱们选用分布式 KV 零碎—TiKV,选用 TiKV 的起因是咱们在线架构组的共事对 TiKV 有着丰盛的开发和运维教训,SLA 可能失去极大的保障。这样 JuiceFS 的可用性和扩展性是十分强的。
JuiceFS 上线
JuiceFS 的上线过程分为以下阶段:
- 数据迁徙,咱们须要将原先存储在 HDFS 和对象存储上的数据同步到 JuiceFS 上,因为 JuiceFS 提供了数据同步的工具,并且 Flink 的依赖也不是特地大,所以这部分工作咱们很快就实现了;
- 批改 Flink 镜像拉取依赖的地址,因为 JuiceFS 兼容对象存储协定,咱们只须要在平台侧批改原来的对象存储的 endpoint 为 JuiceFS S3 gateway 的地址即可。
JuiceFS 上线后,咱们 Flink 工作启动的流程图大抵如下:
相比于应用 HDFS 的形式,咱们能失去一个可预期的容器启动工夫,容器下载依赖的速度不会受业务高峰期的影响;相比于原生的对象存储,容器下载依赖的速度进步约 4 倍。
瞻望
从开始调研 JuiceFS 到 JuiceFS 上线破费工夫不到半个月,次要是因为 JuiceFS 的文档非常齐备,让咱们少走了很多弯路,其次是 JuiceFS 社区的搭档也有问必答,因而咱们的上线过程非常顺利。
初步尝试 JuiceFS 给咱们带来的收益还是比拟显著的,后续咱们会思考将 JuiceFS 利用在数据湖场景和算法模型加载的场景,让咱们数据的应用更加灵便和高效。
举荐浏览
JuiceFS CSI Driver 的最佳实际
我的项目地址 :Github(https://github.com/juicedata/juicefs)如有帮忙的话 欢送关注咱们哟! (0ᴗ0✿)