Apache InLong 技术解析
- 编程
- 大数据
- 源码
目录
- 一、InLong 是什么
- 二、核心设计思想
- 2.1 收敛(Convergence)
- 2.2 解耦(Decoupling)
- 2.3 插件化(Pluggability)
- 三、核心抽象:Group 与 Stream 两级模型
- 3.1 模型定义
- 3.2 关键点:连接数是 O(实例数),不是 O(表数)
- 四、整体架构与数据流
- 五、核心技术拆解
- 5.1 CDC 数据捕获:伪装成从库”偷”数据
- 5.2 消息队列中继:管道的”水库”
- 5.3 DataProxy:汇聚与缓冲的网关层
- 5.4 Sort:基于 Flink 的数据分拣车间
- 5.5 插件化的 SPI 机制
- 六、可靠性保障:数据一条都不能少
- 七、典型应用场景
- 八、与同类方案的对比
一、InLong 是什么
Apache InLong(应龙)是腾讯开源、后捐赠给 Apache 基金会的一站式海量数据集成平台,已于 2022 年从孵化器毕业成为 Apache 顶级项目。它的定位是:在数据从”产生端”到”分析端”的整个搬运链路上,提供采集、汇聚、缓存、分拣、落地的全流程能力。
它要解决的核心场景是:企业里有成百上千的数据源(MySQL、Oracle、PostgreSQL、Kafka、Pulsar、日志文件、IoT 设备等),需要稳定、高效、低运维成本地把这些数据汇入数据湖(Iceberg/Hudi)、数仓(Hive/ClickHouse)或检索引擎(Elasticsearch)。
一句话概括 InLong 的价值:把”写一堆零散的数据管道”这件事,变成”在一个平台上配置数据流”。
二、核心设计思想
InLong 的全部技术设计,可以收敛到三个关键词。理解了它们,就抓住了 InLong 的灵魂。
2.1 收敛(Convergence)
传统做法是每个同步需求写一条管道脚本。10 个库 × 30 张表 × 2 条链路(实时+离线)= 600 条独立管道,每条都要单独配置、监控、容错。运维复杂度是 O(n)。
InLong 用 Group + Stream 模型把所有需求收敛到一个统一的数据模型里,管道的创建从”写代码”变成”填配置”,运维对象从成百上千条脚本收敛成少量平台实体。
2.2 解耦(Decoupling)
InLong 在数据源(Source)和数据目标(Sink)之间,永远插入一个消息队列作为缓冲。读和写被彻底分成两个独立阶段:上游抖动不影响下游,下游变慢不会反压拖死上游,任意一端故障都能各自恢复。
2.3 插件化(Pluggability)
数据源协议千奇百怪,但管道的生命周期管理(启动、监控、停用、恢复)是高度统一的。InLong 用 SPI(Service Provider Interface)机制把”协议差异”隔离在插件层,把”管道共性”沉淀在平台层,新增数据源/目标只需实现接口、打包投放,平台零改动。
三、核心抽象:Group 与 Stream 两级模型
这是 InLong 最重要的概念,也是新手最容易困惑的地方。
3.1 模型定义
| 概念 | 对应 | 职责 |
|---|---|---|
| InLong Group | 一个数据源实例(一台 MySQL、一个 Kafka 集群) | 配置连接信息、认证、连接池、消息队列类型 |
| InLong Stream | Group 下的一个数据单元(一张表、一个 topic、一个文件) | 声明 Schema、转换逻辑、落地目标 |
一个 Group 包含多个 Stream。Group 是”物理资源的拥有者”,Stream 是”逻辑数据流的描述者”。
3.2 关键点:连接数是 O(实例数),不是 O(表数)
很多人看到”一张表一个 Stream”,会担心 100 张表就是 100 个连接,连接爆炸。实际不是这样。
- 物理连接在 Group 层以连接池形式共享。你配置的是”这个 MySQL 用几个连接”(比如 5~10 个),跟表数量无关。
- Stream 只是逻辑分桶,它不持有自己的连接。从 MySQL 拉 binlog 时,一个连接就能拉到所有表的变更事件,InLong 在内存里按表名分发给各自的 Stream。
所以连接开销是 O(数据库实例数)。一个 MySQL 不管挂 50 张表还是 500 张表,都只用那一组连接池。Flink CDC 也是同样思路——你看到的”一张表一个任务”是管理粒度,不是连接粒度。
四、整体架构与数据流
InLong 的标准链路由四大模块串联,每一步都解耦、都有独立容错。
数据源 (MySQL / Kafka / 文件 ...)
│
▼
┌─────────────────┐
│ InLong Agent │ 采集层:CDC 解析 / 文件读取 / 消息消费
│ (Source 插件) │ 全量快照 → 增量续接
└─────────────────┘
│
▼
┌─────────────────┐
│ DataProxy │ 汇聚层:负载均衡、限流、加密、压缩
│ │ 统一接收 Agent 上报,转发到消息队列
└─────────────────┘
│
▼
┌─────────────────┐
│ TubeMQ/Pulsar │ 缓存层:可靠暂存、保序、削峰、零拷贝
│ (MQ 中继) │
└─────────────────┘
│
▼
┌─────────────────┐
│ InLong Sort │ 分拣层:基于 Flink,Schema 映射、分区、
│ (Flink 任务) │ 小文件合并、Exactly Once 落盘
└─────────────────┘
│
▼
数据湖/数仓 (Iceberg / Hudi / Hive / ClickHouse / ES ...)
辅助模块:
- Manager:元数据管理、任务调度、Group/Stream 配置下发的控制中枢。
- Dashboard:可视化操作界面,建任务、看监控、查血缘。
- Audit:全链路对账,统计每个环节的进出条数,定位丢数据发生在哪一段。
五、核心技术拆解
5.1 CDC 数据捕获:伪装成从库”偷”数据
为什么不用轮询:定时 SELECT * WHERE update_time > last 有三大硬伤——全量太重、两次查询间的更新有漏窗、感知不到 DELETE、主库压力大。
Binlog 的本质:MySQL 的 binlog 是为主从复制设计的事务日志,完整记录每一行 INSERT/UPDATE/DELETE,且不干扰正常查询。InLong 的 MySQL Source 把自己伪装成一个 MySQL 从库,发送 COM_BINLOG_DUMP 命令,主库就实时推送 binlog 事件流,InLong 解析还原成数据行。
三个关键技术细节:
- 全量+增量无缝衔接:首次接入先做一致性快照(
START TRANSACTION WITH CONSISTENT SNAPSHOT),记录快照时刻的 binlog 位点,再从该位点切到增量消费。快照和增量之间严密衔接,不多不少。 - Schema 演化:上游加字段,binlog 里会出现新列。InLong 能感知 DDL 变更,支持”告警 / 忽略新列 / DDL 同步”等策略。这是入湖最容易出问题的点——Schema 不一致会导致下游写不进、整条链路卡死。
- GTID 模式:binlog 位点(文件名+偏移)在主从切换后会失效,因为不同机器的 binlog 文件是独立的。GTID(全局事务标识符)给每个事务一个全局唯一 ID,InLong 记 GTID 而非文件偏移,主从切换后可无缝续接。
5.2 消息队列中继:管道的”水库”
为什么必须有中间缓存:直连管道(Source 直接写 Sink)的致命问题是——写 Sink 慢会反压堵住读 Source 的线程;写 Sink 失败重试时,Source 侧的事务窗口已过,数据就丢了。
解法:在 Source 和 Sink 之间插入消息队列。Source 读到的数据先入队,Sink 从队列消费。两阶段彻底解耦,持久化、保序、消费位点维护全部下沉到队列层,失败自动从上次位点重放。
TubeMQ —— 为数据集成而生的 MQ:InLong 自带的 TubeMQ 与 Kafka/Pulsar 有本质区别,它的设计出发点是”数据集成的中继缓存”而非”通用消息系统”:
- 百万级轻量 Topic:Kafka 里 Topic 是重资源(独立分区文件、Leader 选举),几千个就吃力。InLong 场景下每个 Stream 对应一个 Topic(100 张表=100 个 Topic),TubeMQ 把 Topic 做成轻量逻辑概念,底层按 Broker 分片共享存储,Topic 多了也不炸。
- “数据 + 索引”分离存储:这是 TubeMQ 实现”Topic 轻量化”的核心手段。写入时,所有 Topic 的消息顺序追加到 Broker 共享的 data 文件里,不为每个 Topic 单独开物理文件;消费时,每个 Topic 维护一份独立索引,记录”本 Topic 的消息落在 data 文件的哪些 offset 上”,消费者先查索引、再按 offset 定向读取,只取自己 Topic 的数据,不会把别人的也捞出来。这样加一个 Topic 主要就是加一份索引元数据,物理文件数量近乎不变——文件句柄、磁盘 IO 都不会随 Topic 数量线性增长。
- 顺序写优先:集成场景写远多于读,消费基本是顺序拉取。TubeMQ 存储走顺序追加+分区切片,写入路径极短。共享文件不会无限增长,而是切成固定大小的数据段(segment)。写满一个就滚动到下一个,旧段按 TTL 过期删除时整段丢弃(而非逐条删),回收成本极低;同时分段也便于并行写入和定位。
- 零拷贝消费:用 mmap + sendfile 把数据从磁盘直送网卡,不经应用层拷贝,吞吐量数量级提升。
后续版本也支持对接 Pulsar/Kafka,但理解 TubeMQ 的取舍,就理解了 InLong 团队对”集成需要什么样的队列”的回答。
5.3 DataProxy:汇聚与缓冲的网关层
Agent 数量可能成千上万(每台业务机器一个),它们不直接连消息队列,而是统一上报给 DataProxy 集群。DataProxy 负责:
- 负载均衡:把海量 Agent 的上报均匀分散到后端 MQ。
- 本地磁盘缓冲:MQ 短暂不可用时,DataProxy 落本地磁盘暂存,恢复后补发,提供额外一层可靠性。
- 加密压缩:数据在传输前压缩、敏感数据加密。
它本质是采集层和缓存层之间的”减震器”和”集线器”。
5.4 Sort:基于 Flink 的数据分拣车间
数据出了消息队列不直接写湖,中间还有 Sort 这个基于 Flink 的分拣落盘层。它做四件事:
- 按表分流:解析消息里的表名和 Schema,把不同表的数据行路由到各自的写入逻辑。
- 类型转换:MySQL 的
DATETIME→ Hive 的TIMESTAMP,DECIMAL(10,2)→ Parquet 的对应类型,Sort 负责映射对齐。 - 分区策略:按小时/天分区,确定分区 key,把数据写到对应分区目录。
- 小文件合并:若每条消息直接写一个文件,一天能产出几百万小文件。Sort 利用 Flink Checkpoint 周期批量写入,配合 Iceberg/Hudi 的 compaction 控制文件数。
为什么用 Flink:Exactly Once 语义(基于 Checkpoint)、内置状态后端、毫秒级延迟、SQL+DataStream 双 API。Sort 用 Checkpoint 保证”消费位点推进”和”文件提交”是原子操作,绝不出现”位点走了但文件没落”的情况。
5.5 插件化的 SPI 机制
InLong 的 Source / Sink / Transform 三类插件,通过 Java SPI 发现:Agent 启动时扫描 classpath 下的 META-INF/services,自动加载所有注册实现。
- Source:MySQL binlog、Oracle LogMiner、Kafka、Pulsar、文件、MongoDB Change Stream…
- Sink:Hive、Iceberg、Hudi、ClickHouse、Elasticsearch、Kafka、MySQL…
- Transform:字段映射、类型转换、脱敏、过滤、分流(在 Stream 级配置)。
写一个新 Sink,打 jar 包丢进 Agent 的 lib 目录重启即可,平台一行代码不用改。本质是把”协议差异性”和”管道共性”彻底解耦。
六、可靠性保障:数据一条都不能少
InLong 在多个层面构建了端到端的可靠性:
| 机制 | 作用 |
|---|---|
| MQ 持久化 + 位点重放 | 任意环节失败,从上次消费位点重新消费,不丢数据 |
| Flink Exactly Once | 落盘环节位点与文件提交原子化,不重不漏 |
| DataProxy 磁盘缓冲 | MQ 不可用时本地暂存补发 |
| Audit 全链路对账 | 统计每段进出条数,精确定位丢数据发生在哪一段 |
| GTID / 一致性快照 | 主从切换、全量增量切换时数据严密衔接 |
数据语义上,InLong 支持 At Least Once 和 Exactly Once 两种级别,可按业务对一致性和性能的要求选择。
七、典型应用场景
- 数据库实时入湖:MySQL/Oracle 通过 CDC 实时同步到 Iceberg/Hudi,构建实时数据湖。
- 日志采集汇聚:海量服务器日志通过 Agent 采集,汇聚到数据仓库做分析。
- 多源异构整合:把分散在不同数据库、消息队列、文件系统的数据统一汇入分析平台。
- 实时数仓:作为实时数仓的数据接入层,为下游 Flink/实时计算提供稳定数据流。
八、与同类方案的对比
| 维度 | InLong | Flink CDC | DataX | Canal |
|---|---|---|---|---|
| 定位 | 一站式集成平台 | 流式 CDC 框架 | 离线批同步工具 | binlog 订阅组件 |
| 管道管理 | 平台化、可视化 | 写代码 | 写 JSON 配置 | 自己开发消费端 |
| 缓存解耦 | 内置 MQ 中继 | 无(直连) | 无 | 需自接 MQ |
| 全链路对账 | 内置 Audit | 无 | 无 | 无 |
| 运维粒度 | Group/Stream 收敛 | 任务级 | 任务级 | 实例级 |
| 适用规模 | 海量、企业级 | 中大规模 | 中小规模 | 单点订阅 |
简单说:Canal 只管”偷 binlog”,Flink CDC 是”会写代码就能用的流式框架”,DataX 偏离线批量,而 InLong 是把这一切平台化、规模化、可运维化的完整方案。