运维驿站人工智能/模式识别/机器学习精华专题机器学习与数据挖掘

技术选型:为什么批处理我们却选择了Flink

2020-10-28  本文已影响0人  又小拍

最近接手了一个改造多平台日志服务的需求,经过梳理,我认为之前服务在设计上存在缺陷。经过一段时间的技术方案调研,最终我们决定选择使用 Flink 重构该服务。

目前重构后的服务已成功经受了国庆节流量洪峰的考验,今日特来总结回顾,和大家分享一下经验。

业务需求及背景

在了解改造服务的需求前,我们首先要明确,要解决什么问题以及目前的服务是如何解决的。

当前的业务逻辑还是比较清晰的:

我们面临的痛点和难点:

方案1:我们需要一个数据库吗?

针对以上业务需求,有同学提出:“我们可以把所有原始数据放到数据库中,后续的 ETL 可以通过 SQL 实现。”

如果你一听到"数据库"想到的就是 Pg、Mysql、Oracle 等,觉得这个方案不具有可行性,那你就错了。数据库的类型和维度是非常丰富的,如下图所示:

数据库行业全景图

按业务负载特征,关系型数据库可分为 OLTP 数据库(交易型)和 OLAP 数据库(分析型) :

方案 1 小结

OLAP 的使用场景符合我们的需求,为此我们还专门去调研了一下 ClickHouse。但是有一个因素让我们最终放弃了使用 OLAP。请注意,数据库存储的数据都是二维的,有行和列两个维度。但是日志只有行一个维度。如果说为了把日志存入数据库把每行日志都切分,那统计字段的需求也就顺手实现了,又何必存到数据呢?

所以,OLAP 使用场景隐含的一个特点是:存入的数据需要被多维度反复分析的。这样才有把数据存入数据库的动力,像我们当前的需求对日志进行简单的变形后仍旧以文本日志的形式输出,使用 OLAP 是不合适的。

方案2:Hive 为什么不行?

看到这,熟悉大数据的同学可能会觉得我们水平很 Low,因为业务需求归根到底就是三个字:批处理。

那我们为什么第一时间没有考虑上大数据呢?

大数据处理流程

大数据确实如雷贯耳,但现在我们的日志处理这块大部分都是用 Golang 实现的,团队内的其他业务用了 Python、Lua、C,就是没有用过到 Java。而目前大数据都是基于 JVM 开发的。Golang 调用这些服务没有一个好用的客户端。

所以基于团队目前的技术储备,大数据才没有成为我们的首选。但是从目前的状况来看大数据是最优解了。那么我们该选用大数据的什么组件实现需求呢?

放弃使用数据库直接使用 HDFS 存储日志文件,应该是毋庸置疑的。

我们需求是离线批处理数据,对时效性没有要求,MapReduce 和 Hive 都能满足需求。但是 MapReduce 与 Hive 相比,Hive 在 MapReduce 上做了一层封装并且支持 SQL。看起来 Hive 是非常合适的。

那为什么最终放弃了 Hive 呢?

大数据生态图

方案 2 小结

再合适的技术方案不能落地也是空谈。但是技术方案想要落地时,已经不是一个单纯的技术问题了,资源限制,团队限制等都需要考虑在内。

一个优秀的技术方案立足于解决当下的问题,并且能放眼未来勾画蓝图,这样大家觉得 "有利可图",才愿意跟你一起折腾。

方案3:为什么我们放弃了 Spark?

通用的计算引擎

虽然使用 HDFS 的团队不赞成在他们的机器上跑 Hive,但是我们把日志数据存到他们的 HDFS 上还是没问题的。在已知 "存储和分离是趋势" 是前提的基础下,"我们到底需要什么" 这个问题已经有答案了。

我们需要的是一个通用的计算引擎。存储已经剥离给 HDFS 了,所以我们只需要找一个工具,帮我们处理 ETL 就可以了。Spark 和 Flink 正是这样的场景。

Spark 与 Flink 初次交锋

Spark 和 Flink 之间,我们毫不犹豫地选择了 Spark。原因非常简单:

Scala

挥泪斩 Spark

前文已经交代过了,我们否决掉 Hive 的一个重要因素是没有足够的机器资源。所以我们把 Spark 直接部署到云平台上。

对于我司的云平台要补充一些细节。

我们的云平台是基于 K8S 二次开发的,目前还在迭代当中,因此"Spark on K8S" 的运行模式我们暂时用不了。在这样的情况下,我们采用了 "Spark Standalone" 的模式。Standalone 模式,也就是Master Slaver 模式,类似于 Nginx 那样的架构,Master 节点负责接收分发任务,Slaver 节点负责"干活"。

等到我们在云平台上以 "Spark Standalone" 模式部署好了,跑了几个测试 Case 发现了新问题。我们的云平台与办公网络是隔离的,如果办公网络想访问云平台的某个 Docker 容器,需要配置域名。而 Spark 的管理页面上很多 URL 的 domain 是所在机器的 IP,容器的 IP 是虚拟 IP,容器重启后IP 就会改变。具体如图:

部署在云平台的 spark

Spark 的管理平台非常重要,因为能从这上面看到当前各个节点运行情况,任务的异常信息等,现在很多链接不能访问,不利于我们对 Spark 任务进行问题排查和调优。基于这个原因,我们最终放弃了 Spark。

方案 3 小结

Spark 你真的很优秀,擅长批处理,如此成熟,还有函数式的基因 。。。这些优点早让我倾心不已。

Spark 你真的是个好人,如果不是云平台的限制,我一定选择你。

Spark,对不起。

方案4:Flink,真香!

给 Spark 发完好人卡后,我们看一看新欢 Flink。不客气的说,Flink 初期时很多实现都是抄的 Spark,所以二者的很多概念相似。所以 Flink 同样有 Standalone 模式,我们在部署阶段没遇到任何问题。

在跑了几个 Flink 测试 Case 后,我们由衷的感叹 Flink 真香。

放弃 Spark 时我们的痛点在于 "部署在云平台上的 Spark 服务的管理界面很多功能无法使用",而 Flink 的管理平台完全没有这个问题。除此之外,Flink 管理平台的 "颜值" 和功能都是 Spark 无法比拟的。

管理平台颜值对比

Spark管理平台页面 Flink管理平台页面

对比之下,Spark 的页面完全是个"黄脸婆"。

Flink 管理平台功能

由于 Spark 的功能很多不能使用,所以就不重点和 Flink 做比较了。这里只说 Flink 几个让人眼前一亮的功能。

部署了 Flink 或 Spark 服务后,该如何下发计算任务呢? 一般是通过 bin 目录下的一个名称中包含 submit 的可执行程序。那如果想把 Flink 或 Spark 做成微服务,通过 http 接口去下发任务呢?

Spark1.0 的时候支持 http,2.0时这个功能基本上废掉了,很多参数不支持了,把 http 这个功能交由 jobService 一个第三方开源组件去实现。这个 jobService 的开源组件对云平台的支持也非常不友好。所以在我们看来,Spark 通过 Http 下发任务的路子基本被堵死了。

反观 Flink,管理平台的接口是 Restful 的,不仅支持 Http 下发计算任务,还可以通过相关接口查看任务状态和获取异常或返回值。

Flink 的任务分为几个不同的阶段,每个不同的阶段有不同的颜色。这样仅从颜色就可以判断出当前 Flink 任务执行的大致情况。如下图:

Flink管理平台页面

在任务详情页面,会有任务分解图和任务执行耗时表格,这两个结合起来能够知道当然 Flink 任务是如何分解的,是否出现数据倾斜的情况,哪个步骤耗时最多,是否有优化的空间。

管理平台页面

这就是做批处理技术选型时候的心路历程,随笔记了下来,希望对大家有所帮助。

上一篇下一篇

猜你喜欢

热点阅读