简介:58 同城的实时 SQL 建设以及如何从 Storm 迁徙至 Flink。
本文整顿自 58 同城实时计算平台负责人冯海涛在 Flink Forward Asia 2020 分享的议题《Flink 在 58 同城利用与实际》,内容包含:
实时计算平台架构
实时 SQL 建设
Storm 迁徙 Flink 实际
一站式实时计算平台
后续布局
一、实时计算平台架构
实时计算平台的定位是为 58 团体海量数据提供高效、稳固的实时计算一站式服务。一站式服务次要分为三个方向:
第一个方向是实时数据存储,次要负责为线上业务接入提供高速度的实时存储能力。
第二是实时数据计算,次要为海量数据的解决提供分布式计算框架。
第三是实时数据散发,次要负责将计算后的数据散发到后续的实时存储,供下层利用。
平台建设次要分为两个局部:
第一局部是根底能力建设,目前次要包含 Kafka 集群、storm 集群、Flink 集群、SparkStreaming 集群。
另一部分是平台化建设,次要是包含两点:
第一个是数据散发,咱们的数据散发是基于 Kafka Connect 打造的一个平台,指标是实现异构数据源的集成与散发。在理论应用数据场景过程中,常常须要将不同的数据源汇聚到一起进行计算剖析。
传统形式可能须要针对不同的存储采纳不同的数据同步计划。咱们的数据散发是通过提供一套残缺的架构,实现不同数据源的集成和散发。
第二个是咱们基于 Flink 打造的一站式实时计算平台,后文会有具体的介绍。
上图是咱们的实时计算平台的架构。
- 在实时数据接入这部分,咱们采纳的是 Kafka,binlog 提供 canal 和 debezium 两种形式进行接入。
- 在业务日志这部分,咱们次要采纳 flume 进行线上业务的 log 的采集。
- 在实时计算引擎这部分,依据开源社区倒退以及用户的需要,从最早的 Storm 到起初引入 SparkStreaming,以及当初支流的 Flink。
- 在实时存储这部分,为了满足多元化的实时需要,咱们反对 Kafka、Druid、Hbase、ES、ClickHouse。
- 同时在计算架构之上,咱们建设了一些治理平台,比方集群治理,它次要负责集群的扩容,稳定性的治理。
- 另一个是 Nightfury,次要负责集群治理,包含数据接入、权限治理、资源管理等等。
咱们在业务倒退过程中,引入了 Flink 计算框架。首先从业务来说,58 是一个一站式生存服务平台,蕴含很多业务线。随着业务的倒退,数据量越来越大,场景越来越丰盛,须要一个更加弱小的计算框架来满足用户的需要。
- 第一个场景是实时 ETL,次要是针对原始日志进行信息转化,结构化解决,使用于后续计算,须要高吞吐低提早的计算能力。
- 第二块是实时数仓,它作为离线数仓的一个补充,次要是晋升一些实时指标的时效性。第三种场景是实时监控,它须要比拟灵便的工夫窗口反对。
- 最初一种场景是实时数据流剖析,比如说,数据乱序的解决、中间状态的治理、Exactly once 语义保障。
咱们后期基于 Storm 和 SparkStreaming 构建的计算集群在很大水平上并不能满足这些场景需要。于是对 Flink 进行了调研,发现 Flink 不论是在计算性能,还是流数据个性反对上,都体现出了十分大的劣势。因而,咱们决定采纳 Flink 作为支流的计算框架。
上图是咱们 Flink 集群的建设状况。Flink 作为实时计算框架,常常须要 7×24 小时的可用性。咱们在建设底层集群的时候,须要思考高可用的架构。
- 首先在部署模式上,次要是采纳 Flink On YARN,实现集群的高可用。
- 在底层的 HDFS 上,采纳 HDFS federation 机制,既能够防止离线集群的抖动对实时这边造成影响,同时也缩小了保护的 HDFS 数量。
- 在集群隔离上,次要是采纳 Node Labe 机制,就能够实现把重要业务运行在一些指定节点上。同时在这个根底之上,引入了 Cgroup,对 CPU 进行隔离,防止工作间的 CPU 抢占。
- 在治理层面,不同的业务提交到不同的队列进行治理,防止业务间的资源抢占。
- 在计算场景上,依据不同的计算场景,比如说计算型、IO 型,会提交到不同的节点,从而晋升整个集群的资源利用率。
Flink 计算框架在 58 经验了大略两年多的倒退。目前咱们的集群有 900 多台机器,2000 多个实时工作,每天解决大略 2.5 万亿的实时数据,数据量峰值达到了 3000 万每秒。
二、实时 SQL 建设
1. 实时 SQL 演进
SQL 编程具备低门槛、主动优化、版本对立等特点。同时 Flink SQL 作为实时数仓的次要工具,是咱们在建设 Flink 平台时思考的一个次要方向。
咱们最早上线的 Flink 是基于 1.6 版本的,过后这个版本只反对 DML,咱们在过后的版本根底上进行了一些扩大,次要是在 DDL 语法上的扩大反对。在用户应用层面,为了简化 DDL 的定义,也通过一个配置化的形式来实现主动生成 DDL。在开发的时候,提供可视化开发的性能和在线调试的性能。
随着社区的开源,咱们将 Flink SQL 切换到了社区版本,之后也降级相干的版本,以及合并比拟多的社区版本个性,比如说 Blink 相干、批流合一、对 Hive 的反对。
最初针对 Flink SQL 这块的实时数仓,也做了一些数仓化的工作,次要包含元数据管理、血缘关系、数仓分层、权限治理等等。
2. 存储扩大
对于存储扩大这一块,最开始咱们是基于 Flink 本人实现的一套 DDL。随着社区开源,切换到社区的 Flink SQL 版本,而后在下面做了一些扩大,次要有几个方面:
- 第一,买通了支流存储和外部的实时存储。比如说,在源表上反对了外部的 wmb,它是一个分布式音讯队列。在维表上反对这种 redis,外部的 wtable。在后果表上反对了 ClickHouse,redis,以及咱们外部的 wtable;
- 第二,定制 format 反对。因为在理论业务中,很多数据格式并不是规范的,没法通过 DDL 来定义一个表。咱们提供了一种通用的形式,能够采纳一个字段来代表一条日志,让用户能够通过 udf 去自定义,并解析一条日志。
- 最初,在 source 和 sink DDL 定义根底上,减少了并发度的设置。这样用户就能够更灵便地管制工作的并发。
3. 性能优化
对于性能优化,次要是两方面:
第一个是对 Blink 个性的引进,Blink 提供了大量的个性,比方通过 mini batch 的解决形式,进步工作的吞吐。通过 local global 两阶段聚合,缓解数据热点问题。还有通过 emit,加强窗口的性能。把这些性能集成到咱们的计算平台,用户通过一些按钮能够间接关上。
另一个是对异步 lO 的利用。在实时数仓化建设过程中,维表之间的关联是比拟大的利用场景,常常因为维表的性能导致整个工作的吞吐不高。因而咱们减少了一个异步 IO 的机制,次要有两种实现:
- 一种针对指标存储反对异步 client,间接基于异步 client 来实现。比方 MySQL 和 redis。
- 另一种不反对异步 client 的,咱们就借助现成的机制来模仿,同时在这个根底之上减少了一套缓存的机制,防止所有的数据间接查问到指标存储,缩小指标存储的压力。同时在缓存根底上,也减少 LRU 机制,更加灵便的管制整个缓存。
同样,数据写入这一块遇到大并发量写入的时候,尽量进步并发来解决写入性的问题,这样就会导致整个工作的 CPU 利用率比拟低,所以就采纳单并发度多线程的写入机制,它的实现是在 sink 算子外面减少一个 buffer,数据流入到 sink 之后会首先写入到 buffer,而后会启动多线程机制去生产这个 buffer,最终写到存储外面。
4. 数仓化建设
实时数仓作为 Flink 的一个比拟典型的利用场景,相较于离线数仓它可能存在一些平台化不欠缺的方面:
- 首先,元数据管理性能不欠缺。
- 而后,Flink SQL 这一块,对于每个工作咱们都可能须要从新定义一个数据表。并且因为数据没有分层的概念,导致工作比拟独立,烟囱式开发,数据和资源使用率比拟低下。
- 另外,也不足数据血统信息。
为了晋升实时数仓建设的效率,咱们提供了面向数仓化实时 SQL 能力,在数仓设计,工作开发,平台化治理方面全面对齐离线数仓的建设模式。
4.1 数仓化
数仓化次要是参考离线数仓的模型,对咱们实时数仓这一块进行模型建设。
比如说,最原始的数据会进入 ODS 层,通过一些荡涤落入到行为明细层,之后会拆分到具体的主题明细层,而后再将一些相干的维表信息进行计算,再到汇总层,最终提供给最上层的利用,包含一些实时报表,Ad-hoc 查问等。
4.2 数仓平台
实时数仓目前次要还是基于这种 Lambda 架构来进行平台化的建设。
- 首先,在元数据管理这一块,Flink 默认采纳内存对元数据进行治理,咱们就采纳了 HiveCatalog 机制对库表进行长久化。
- 同时咱们在数据库的权限治理上,借助 Hive ACL 来进行权限治理。
- 有了元数据长久化之后,就能够提供全局的元数据检索。
- 同时工作模式就能够由传统的 DDL+DML 简化为 DML。
- 最初,咱们也做了血缘关系,次要是在 Flink SQL 提交过程中,主动发现 SQL 工作血统依赖关系。
三、Storm 迁徙 Flink 实际
1. Flink 与 Storm 比照
Flink 绝对于 Storm 来说,有比拟多的劣势。
- 在数据保障上,Flink 反对 Exactly once 语义,在吞吐量、资源管理、状态治理,用户越来越多的基于 Flink 进行开发。
- 而 Storm 对用户来说,编程模型简略,开发成本高,流式计算个性不足,吞吐低无奈满足性能。在平台侧,独立集群多、运维艰难、工作短少平台化治理、用户体验差。
因而咱们决定迁徙到 Flink。
2. Flink-Storm 工具
在 Storm 迁徙到 Flink 的时候,如果让用户从新基于 Flink 进行逻辑开发,可能须要比拟大的工作量。因而咱们对 Flink 进行了调研,发现有个 Flink-Storm 工具。它实现了将 Storm Topology 转到 Flink Topology。比如说,把 spout 转换到 Flink 的 source function,把 bolt 转换到 Transform 和 sink function。
在应用的过程中咱们也发现一些问题,Flink-Storm 工具无奈反对 Yarn 模式,短少 Storm 引擎性能,最初还有一个比拟大的问题,咱们的 storm 在倒退过程中保护了很多版本,然而 Flink-Storm 工具只反对基于一个版本进行开发。于是,咱们做了一些改良。
3. 对 Flink-Storm 的改良
3.1 音讯保障
Storm 有三个特点:
第一,ack 机制;
第二,依赖 zookeeper;
第三,at least once 语义保障。
咱们做了四点改良:
第一,Flink-Storm 去掉 ack 反对;
第二,KafkaSpout 实现 CheckpointListener;
第三,KafkaSpout 实现 CheckpointedFunction;
第四,Flink-Storm 关上 checkpoint。
3.2 对 Storm 定时器的反对
在晚期版本外面其实是没有窗口机制的,咱们借助 Storm 定时机制来实现窗口计算。它的机制是这样的,Storm 引擎会定时向 bolt 外面发送一个零碎信号,用户就能够通过这个零碎信号进行一个切分,模仿窗口操作。
同样,Flink 也没有这样一个定时器的机制,于是咱们就思考从 Flink-Storm 层面来实现,革新了 BoltWrapper 类,它作为 bolt 类的一个封装,实现机制跟 bolt 是一样的,包含 5 点:
- 初始化 open 形式启动异步线程。
- 模仿结构 tick 的 StreamRecord;
- 调用 processeElement 函数发送 tuple;
- 频率由内部参数全局管制;
- close 中敞开线程。
3.3 Storm on Yarn
Storm on yarn 并不是间接提交到 YARN 集群,它只是提交到 local 或者 stand alone 的模式。Flink on yarn 次要是提供了 ClusterClient 这样一个代理,实现形式有三个步骤:
- 初始化 YarnClusterConfiguration Flink 配置 执行 jar 包 / 资源配置 加载 classpath;
- 启动 yarn client;
- 复用 Flink on yarn 机制 deploy 转换后的 jobGraph。
4. 工作迁徙
在欠缺上述的一些改良之后,迁徙就比拟容易了。首先咱们会把革新后的版本打包,上传到公司的私服上。而后用户在他的工程外面只须要引入 jar 包。在代码这一块,只须要将原来基于 storm 的提交形式革新成基于 Flink 的提交形式,逻辑是齐全不必动的。在工作部署模式这一块,也提供了 Flink 提交的模式,这样一个脚本能够实现 Flink Perjob 模式。
总结一下,除了一些比拟极其的简单状况,基本上做到了无缝迁徙所有的工作。迁徙到 Flink 之后,大部分工作的提早都升高到毫秒级别,整个吞吐晋升 3~5 倍。同时,整体资源节俭了大略 40%,约等于 80 台机器。实现了 5 个 storm 集群齐全下线,实现了工作平台化治理。
四、一站式实时计算平台
1. Wstream 平台
咱们为了晋升管理效率而打造了 Wstream 平台,它构建在底层引擎和下层利用之间,对用户能够屏蔽底层的集群信息,比方跨机房多集群的一些信息。
- 在工作接入形式上,反对 Flink Jar,Flink SQL,Flink-Storm,PyFlink 这 4 种形式,来满足多元化的用户需要。
- 在产品性能上,次要反对了工作治理、工作的创立、启动删除等。
- 另外,为了更好的让用户治理本人的工作和对工作进行问题定位,咱们也提供了一个监控告警和工作诊断的零碎。
- 针对数仓,提供了一些数仓平台化的性能,包含权限治理、血缘关系等等。
- 针对 Flink SQL 也提供了调试探查的性能。
用户能够在 Wstream 平台之上很好的去构建他们的利用。
2. 状态治理
状态作为 Flink 一个比拟重要的个性,在理论场景中有大量的利用。用户在应用平台的时候,没法跟底层的 Flink 工具进行交互,于是咱们就将底层的一些能力进行了集成。
- 在工作保留方面,反对 Checkpoint,Savepoint,Cancel With Savepoint。
- 在容错方面,反对 allowNonRestoredState,跳过无奈复原的状态。
- 在剖析方面,反对 Queryable State 实时查问,基于离线的 State Processor 的剖析形式,咱们会帮用户把这个状态下载进行剖析。
对于整个工作状态治理来说,咱们通过 jobgraph 设置定向到指定 Hdfs 目录,进行对立目录治理。在状态小文件这块,管制并发度,jobgraph 优化,checkpoint 间隔时间,保留版本数量。
3. SQL 调试
针对 Flink SQL,咱们也提供了一些调试性能。这里次要包含两块:
第一,语法层面的性能包含:
- 智能提醒;
- 语法校验;
- 转换 graph 逻辑校验。
第二,逻辑层面的性能包含:
- 模仿输出,DataGen 自定义数据源;
- 后果输入,Print 重定向到规范输入。
- 这样咱们能够更不便的对整个业务逻辑进行调试。
- 工作监控
对于工作监控,对于 Flink 实时计算工作来说,咱们次要关怀的是工作的稳定性、性能方面、以及业务逻辑是否合乎预期。对于如何监控这些指标,次要包含 4 个层面:
- 第一个是 Flink 自带的 Flink-metrics,提供大量的信息,比方流量信息、状态信息、反压、检查点、CPU、网络等等;
- 第二个是 yarn 层面,提供运行时长、工作状态;
- 第三,从 kafka 层面提供音讯沉积;
- 最初,通过用户自定义的一些 metrics,咱们能够理解业务逻辑是否合乎预期。
5. 监控体系
为了采集这些指标,咱们也基于 Prometheus 搭建了一套监控体系。对于所有的 Flink 工作,会实时将 metrics 推到 pushgateway,而后会将收集到的指标推到 Prometheus,这一块咱们次要是采纳的 federation 的机制。所有子节点负责指标采集,之后汇聚到一个核心节点,由核心节点对立对外提供服务。最终能够实现整个指标的计算和告警。
6. 监控告警
有了下面这些指标之后,咱们在告警这一块就能够比拟不便。针对实时计算比拟关注的工作稳定性方面,咱们能够从 Topic 音讯生产沉积、工作计算 qps 稳定、Flink task Restart、Flink Checkpoint failed、工作失败、提早等信息来察看整个工作的运行状况。
7. 指标可视化
在指标可视化这一块,次要是两个层面:
- 第一个层面是 Job 层面,这一块次要是把一些比拟外围的指标汇聚到咱们的实时计算平台。比如说,qps 信息、输入输出的信息、提早的信息等等;
- 对于更底层的 task 级别的 metrics,通过 Grafana 能够理解具体的一些 task 信息,比方流量信息、反压信息等。
五、后续布局
咱们的后续布局,次要包含 4 个方面:
- 第一个是社区比拟风行的批流合一。因为咱们以后这个实时架构大部分还是基于 Lambda 架构,这种架构会带来很大的保护工作量,所以咱们也心愿借助批流合一的能力来简化架构;
- 第二个是资源调优,因为作为流式计算来说,短少一些动静资源管理的机制,因而咱们也心愿有伎俩来进行这样一些调优;
- 第三个是智能监控,咱们以后的监控和告警是预先的,心愿有某种形式在工作呈现问题之前进行预警;
- 最初是拥抱社区的新能力,包含对新场景的摸索。
原文链接
本文为阿里云原创内容,未经容许不得转载。