最近接手了一个改造多平台日志服务的需求,通过梳理,我认为以前服务在设计上存在缺陷。通过一段时间的技术方案调研,最终咱们决定选择使用 Flink 重构该服务。html
目前重构后的服务已成功经受了国庆节流量洪峰的考验,今日特来总结回顾,和你们分享一下经验。sql
在了解改造服务的需求前,咱们首先要明确,要解决什么问题以及目前的服务是如何解决的。数据库
当前的业务逻辑仍是比较清晰的:编程
咱们面临的痛点和难点:网络
针对以上业务需求,有同窗提出:“咱们能够把全部原始数据放到数据库中,后续的 ETL 能够经过 SQL 实现。”架构
若是你一听到"数据库"想到的就是 Pg、Mysql、Oracle 等,以为这个方案不具备可行性,那你就错了。数据库的类型和维度是很是丰富的,以下图所示:dom
按业务负载特征,关系型数据库可分为 OLTP 数据库(交易型)和 OLAP 数据库(分析型) :编程语言
方案 1 小结函数式编程
OLAP 的使用场景符合咱们的需求,为此咱们还专门去调研了一下 ClickHouse。可是有一个因素让咱们最终放弃了使用 OLAP。请注意,数据库存储的数据都是二维的,有行和列两个维度。可是日志只有行一个维度。若是说为了把日志存入数据库把每行日志都切分,那统计字段的需求也就顺手实现了,又何须存到数据呢?函数
因此,OLAP 使用场景隐含的一个特色是:存入的数据须要被多维度反复分析的。这样才有把数据存入数据库的动力,像咱们当前的需求对日志进行简单的变形后仍旧以文本日志的形式输出,使用 OLAP 是不合适的。
看到这,熟悉大数据的同窗可能会以为咱们水平很 Low,由于业务需求归根到底就是三个字:批处理。
那咱们为何第一时间没有考虑上大数据呢?
大数据确实如雷贯耳,但如今咱们的日志处理这块大部分都是用 Golang 实现的,团队内的其余业务用了 Python、Lua、C,就是没有用过到 Java。而目前大数据都是基于 JVM 开发的。Golang 调用这些服务没有一个好用的客户端。
因此基于团队目前的技术储备,大数据才没有成为咱们的首选。可是从目前的情况来看大数据是最优解了。那么咱们该选用大数据的什么组件实现需求呢?
放弃使用数据库直接使用 HDFS 存储日志文件,应该是毋庸置疑的。
咱们需求是离线批处理数据,对时效性没有要求,MapReduce 和 Hive 都能知足需求。可是 MapReduce 与 Hive 相比,Hive 在 MapReduce 上作了一层封装而且支持 SQL。看起来 Hive 是很是合适的。
那为何最终放弃了 Hive 呢?
方案 2 小结
再合适的技术方案不能落地也是空谈。可是技术方案想要落地时,已经不是一个单纯的技术问题了,资源限制,团队限制等都须要考虑在内。
一个优秀的技术方案立足于解决当下的问题,而且能放眼将来勾画蓝图,这样你们以为 "有利可图",才愿意跟你一块儿折腾。
通用的计算引擎
虽然使用 HDFS 的团队不同意在他们的机器上跑 Hive,可是咱们把日志数据存到他们的 HDFS 上仍是没问题的。在已知 "存储和分离是趋势" 是前提的基础下,"咱们到底须要什么" 这个问题已经有答案了。
咱们须要的是一个通用的计算引擎。存储已经剥离给 HDFS 了,因此咱们只须要找一个工具,帮咱们处理 ETL 就能够了。Spark 和 Flink 正是这样的场景。
Spark 与 Flink 初次交锋
Spark 和 Flink 之间,咱们坚决果断地选择了 Spark。缘由很是简单:
挥泪斩 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。
方案 3 小结
Spark 你真的很优秀,擅长批处理,如此成熟,还有函数式的基因 。。。这些优势早让我倾心不已。
Spark 你真的是个好人,若是不是云平台的限制,我必定选择你。
Spark,对不起。
给 Spark 发无缺人卡后,咱们看一看新欢 Flink。不客气的说,Flink 初期时不少实现都是抄的 Spark,因此两者的不少概念类似。因此 Flink 一样有 Standalone 模式,咱们在部署阶段没遇到任何问题。
在跑了几个 Flink 测试 Case 后,咱们由衷的感叹 Flink 真香。
放弃 Spark 时咱们的痛点在于 "部署在云平台上的 Spark 服务的管理界面不少功能没法使用",而 Flink 的管理平台彻底没有这个问题。除此以外,Flink 管理平台的 "颜值" 和功能都是 Spark 没法比拟的。
管理平台颜值对比
对比之下,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 任务是如何分解的,是否出现数据倾斜的状况,哪一个步骤耗时最多,是否有优化的空间。
这就是作批处理技术选型时候的心路历程,随笔记了下来,但愿对你们有所帮助。