小米业务线众多,从信息流,电商,广告到金融等覆盖了众多领域,小米流式平台为小米集团各业务提供一体化的流式数据解决方案,主要包括数据采集,数据集成和流式计算三个模块。目前每天数据量达到 1.2 万亿条,实时同步任务 1.5 万,实时计算的数据 1 万亿条。
伴随着小米业务的发展,流式平台也经历三次大升级改造,满足了众多业务的各种需求。最新的一次迭代基于 Apache Flink,对于流式平台内部模块进行了彻底的重构,同时小米各业务也在由 Spark Streaming 逐步切换到 Flink。
小米流式平台的愿景是为小米所有的业务线提供流式数据的一体化、平台化解决方案。具体来讲包括以下三个方面:
下图展示了流式平台的整体架构。从左到右第一列橙色部分是数据源,包含两部分,即 User 和 Database。
Talos Sink 和 Source 共同组合成一个数据流服务,主要负责将 Talos 的数据以极低的延迟转储到其他系统中;Sink 是一套标准化的服务,但其不够定制化,后续会基于 Flink SQL 重构 Talos Sink 模块。
下图展示了小米的业务规模。在存储层面小米每天大概有 1.2 万亿条消息,峰值流量可以达到 4300 万条每秒。转储模块仅 Talos Sink 每天转储的数据量就高达 1.6 PB,转储作业目前将近有 1.5 万个。每天的流式计算作业超过 800 个,Flink 作业超过 200 个,Flink 每天处理的消息量可以达到 7000 亿条,数据量在 1 PB 以上。
小米流式平台发展历史分为如下三个阶段:
Streaming Platform 1.0 整体是一个级联的服务,前面包括 Scribe Agent 和 Scribe Server 的多级级联,主要用于收集数据,然后满足离线计算和实时计算的场景。离线计算使用的是 HDFS 和 Hive,实时计算使用的是 Kafka 和 Storm。虽然这种离线加实时的方式可以基本满足小米当时的业务需求,但也存在一系列的问题。
为了解决 Streaming Platform 1.0 的问题,小米推出了 Streaming Platform 2.0 版本。该版本引入了 Talos,将其作为数据缓存区来进行流式数据的存储,左侧是多种多样的数据源,右侧是多种多样的 Sink,即将原本的级联架构转换成星型架构,优点是方便地扩展。
Streaming Platform 2.0 的优势主要有:
下图详细介绍一下 MySQL 同步的案例,场景是将 MySQL 的一个表通过上述的机制同步到消息队列 Talos。具体流程是 Binlog 服务伪装成 MySQL 的 Slave,向 MySQL 发送 Dump binlog 请求;MySQL 收到 Dump 请求后,开始推动 Binlog 给 Binlog 服务;Binlog 服务将 binlog 以严格有序的形式转储到 Talos。之后会接入 Spark Streaming 作业,对 binlog 进行解析,解析结果写入到 Kudu 表中。目前平台支持写入到 Kudu 中的表的数量级超过 3000 个。
Agent Source 的功能模块如下图所示。其支持 RPC、Http 协议,并可以通过 File 来监听本地文件,实现内存和文件双缓存,保证数据的高可靠。平台基于 RPC 协议实现了 Logger Appender 和 RPC 协议的 SDK;对于 Http 协议实现了 HttpClient;对于文件实现了 File Watcher 来对本地文件进行自动地发现和扫描,Offset Manager 自动记录 offset;Agent 机制与 K8S 环境深度整合,可以很容易地和后端的流式计算等相结合。
下图是 Talos Sink 的逻辑流程图,其基于 Spark Streaming 来实现一系列流程。最左侧是一系列 Talos Topic 的 Partition 分片,基于每个 batch 抽象公共逻辑,如 startProcessBatch() 和 stopProcessBatch(),不同 Sink 只需要实现 Write 逻辑;不同的 Sink 独立为不同的作业,避免相互影响;Sink 在 Spark Streaming 基础上进行了优化,实现了根据 Topic 流量进行动态资源调度,保证系统延迟的前提下最大限度节省资源。
下图是平台实现的端到端数据监控机制。具体实现是为每个消息都有一个时间戳 EventTime,表示这个消息真正生成的时间,根据 EventTime 来划分时间窗口,窗口大小为一分钟,数据传输的每一跳统计当前时间窗口内接受到的消息数量,最后统计出消息的完整度。延迟是计算某一跳 ProcessTime 和 EventTime 之间的差值。
Streaming Platform 2.0 目前的问题主要有三点:
为了解决 Streaming Platform 2.0 的上述问题,小米进行了大量调研,也和阿里的实时计算团队做了一系列沟通和交流,最终决定将使用 Flink 来改造平台当前的流程,下面具体介绍小米流式计算平台基于Flink的实践。
使用 Flink 对平台进行改造的设计理念如下:
下图是 Streaming Platform 3.0 版本的架构图,与 2.0 版本的架构设计类似,只是表达的角度不同。具体包含以下几个模块:
Job 管理提供 Job 全生命周期管理、Job 权限管理和 Job 标签管理等功能;支持Job 运行历史展示,方便用户追溯;支持 Job 状态与延迟监控,可以实现失败作业自动拉起。
主要包括以下四个环节:
外部表转换成 SQL DDL 的流程如下图所示。
不可修改的配置情况是假设消费的是 Talos 组件,那么 connector.type 一定是 talos,则该配置不需要改;而默认值是从 Topic 头部开始消费,但用户可以设置从尾部开始消费,这种情况属于带默认值但是用户可修改的配置;而一些权限信息是用户必须配置的。
之所以做三层配置管理,是为了尽可能减少用户配置的复杂度。Table Schema、Table Format 和 Connector 1 其他配置信息,组成了SQL DDL。将 SQL Config 返回给用户之后,对于可修改的需要用户填写,这样便可以完成从外部表到 SQL DDL 的转换,红色字体表示的是用户修改的信息。
SQL 管理引入了一个 External Table 的特性。假设用户在平台上选择消费某个 Topic 的时候,该特性会自动地获取上面提到的 Table 的 Schema 和 Format 信息,并且显示去掉了注册 Flink Table 的逻辑;获取 Schema 时,该特性会将外部表字段类型自动转换为 Flink Table 字段类型,并自动注册为 Flink Tab 了。同时将 Connector Properties 分成三类,参数带默认值,只有必须项要求用户填写;所有参数均采用 Map 的形式表达,非常便于后续转化为 Flink 内部的 TableDescriptor。
上面介绍了 SQL DDL 的创建过程,在已经创建的 SQL DDL 的基础上,如 Source SQL DDL 和 Sink SQL DDL,要求用户填写 SQL query 并返回给后端,后端会对 SQL 进行验证,然后会生成一个 SQL Config,即一个 SQL 语句的完整表达。
SQL Config 转换为 Job Config 的流程如下图所示。
下图展示了 Job Config 转换为 Job Graph 的过程。对于 DDL 中的 Schema、Format 和 Property 是和 Flink 中的 Table Descriptor 是一一对应的,这种情况下只需要调用 Flink 的相关内置接口就可以很方便地将信息转换为 Table Descriptor,如 CreateTableSource()、RegistorTableSource() 等。通过上述过程,DDL 便可以注册到 Flink 系统中直接使用。对于 SQL 语句,可以直接使用 TableEnv 的 sqlUpdate() 可以完成转换。
SQL Config 转换为一个 Template Job 的流程如下所示。前面填写的 Jar 包地址即该 Template 的 Jar 地址,MainClass 是该 Template Job。假设已经有了 SQL DDL,可以直接转换成 Table Descriptor,然后通过 TableFactorUtil 的 findAndCreateTableSource() 方法得到一个 Table Source,Table Sink 的转换过程类似。完成前两步操作后,最后进行 sqlUpdate() 操作。这样便可以将一个 SQL Job 转换为最后可执行的 Job Graph 提交到集群上运行。
Talos Sink 采用了下图所示的三种模式:
小米流式平台未来的计划主要有以下几点:
作者介绍:夏军,小米流式平台负责人,主要负责流式计算,消息队列,大数据集成等系统的研发工作,主要包括 Flink,Spark Streaming,Storm,Kafka 等开源系统和一系列小米自研的相关系统。
本文作者:夏军
上云就看云栖号,点此查看更多!
本文为阿里云内容,未经允许不得转载。