Flink on TiDB —— 便捷可靠的实时数据业务支撑
作者介绍
林佳,网易互娱计费数据中心实时业务负责人,实时开发框架 JFlink-SDK 和实时业务平台 JFlink 的主程,Flink Code Contributor。
本文由网易互娱计费数据中心实时业务负责人林佳老师分享,主要介绍网易数据中心在处理实时业务时为什么选择 Flink 和 TiDB,以及两者的结合应用情况。
今天主要从开发的角度来跟大家聊一聊为什么网易数据中心在处理实时业务时,选择 Flink 和 TiDB。
首先,TiDB 是一个混合型的 HTAP 分布式数据库,具备一键水平伸缩、强一致性的多副本数据安全、分布式事务、实时 OLAP 等重要特性,同时兼容 MySQL 协议和生态,迁移便捷,运维成本极低。而 Flink 是目前最热门的开源计算框架,在处理实时数据方面,其高吞吐量、低延迟的优异性能以及对 Exactly Once 语义的保障为网易游戏实时业务处理提供了便捷支持。
Flink on TiDB 究竟可以创造怎样的业务价值?本文将从一个实时累加值的故事来跟大家分享。
从一个实时累加值的故事说起
整个过程看起来非常简单又完美, Flink 解决计算问题,TiDB 解决海量存储问题。但,事实真的如此吗?
实际接触线上数据的同学可能会遇到类似的问题,如:
多种数据源:各个业务方的外部系统日志,并且存在有的数据存储在数据库,有的需要以日志的方式调用,还有以 rest 接口调用的方式。
数据格式多样:各个业务或渠道打的数据格式完全不同,有的是 JSON,有的是 Encoded URL。
乱序到达:数据到达顺序被打乱。
Flink 的准确保证
Flink 的准确保证
计算状态的保存
Exactly Once 语义支持
从上图的代码可以看出,Exactly Once CheckPoint 是无法保证端到端的,只能保证 Flink 内部算子的 Exactly Once。因此,将计算数据去写入 TiDB 时,如果 TiDB 无法与 Flink 联动,就无法保证端到端的 Exactly Once 了。
类比一下什么是端到端,其实 Kafka 就支持这种语义,因为 Kafka 对外暴露了 2PC 的接口,允许用户手动调整接口来控制 Kafka 事务的 2PC 过程,也因此可以利用 CheckPoint 机制来避免算错的情况。
但如果不能手动控制,那会怎么样呢?
我们来看看如下实例,假设仍然将用户设置为 1000,购买道具为 A 的数据写入到 TiDB 的累加表,会生成如下 SQL:INSERT VALUES ON DUPLICATE UPDATE。当 CheckPoint 发生时,能否保证该语句被执行到 TiDB?
如果不加特殊处理,简单执行这条 SQL 的话,其实不能保证这条 SQL 究竟有没有被执行,如未执行,则会报错,退回到上一个 CheckPoint,皆大欢喜。因为它实际上没有计算,没有累加,也不会重复计算一遍,所以是对的。但如果已经写出,再去重复的退回上一个 CheckPoint,那么将会出现重复累加 3 的情况。
Flink 为了解决这个问题,提供了一种接口,可以手动实现 SinkFunction,控制事务的开始,Pre Commit、Commit、Rollback。
而 CheckPoint 机制本质是一种 2PC,当分布式算子在执行内部事务时,其实算子关联到 Pre Commit。同理,假设在 Kafka 中,可以通过 Pre Commit 事务将 Kafka 事务预提交。当算子收到 Job Manager(即 Master)同步的所有算子 CheckPoint 的状态保存都已完成时,此时 Commit,事务是必定成功的。
如果其他算子失败了,则需要进行 Rollback,确保事务没有被成功地提交到远端。这里如果有 2PC SinkFunction 加上 XA 全 section 语义的话,其实就可以做到严格意义的 Exactly Once。
但不是所有的 sink 都支持二阶段提交协议,比如 TiDB 内部是二阶段提交来管理协调其事务,但是目前来说,并没有把二阶段提交协议提供给用户手动控制。
幂等计算
那么,如何做到保证业务的 Exactly Once 结果落到 TiDB?其实也很简单,采用 At Least Once 语义加上一个 Unique Key,即幂等计算。
如何选择 Unique Key?如果一份数据有一个唯一标志,我们自然会选择其唯一标志。比如一份数据有唯一 ID,当一张表通过 Flink 同步到另一张表的时候,这就是很经典的利用其 Primary key 做 insert ignore 或者 replace into 的语义去重。如果是日志,可以选择日志文件特有的属性。而如果通过 Flink 去计算聚合结果,则可以用聚合的 Key 加上窗口边界值,或者其他的幂等方式来计算出数值,作为最终计算的唯一键。
如此,就可以实现结果是可重入的。既然可重入,再加上 CheckPoint 的可回退特性,就可以把 Flink 跟 TiDB 结合起来,做到精准的 Exactly Once 结果写入。
Flink on TiDB
数据连接器的设计
首先,是数据连接器的设计。因为 Flink 对于 TiDB 的支持或者说对关系型数据库的支持都比较慢,Flink Conector JDBC 在 Flink 1.11 版本才出现,时间还不太长。
目前,我们将 TiDB 作为数据源,把数据放在 Flink 处理,主要是通过 TiDB 官方提供的 CDC 工具,相当于通过监听 TiDB 的变更,将数据落到 Kafka。而 Kafka 又是非常经典的流式数据管道,所以通过 Kafka 将数据进行消费处理,然后再通过 Flink 进行处理。
但不是所有业务都可以用 CDC 模式,比如落数据时要增加一些比较复杂的过滤条件,或者落数据时需要定期读取某些配置表,亦或者先需要了解外部的一些配置项才能知道切分情况时,可能就需要手动的自定义 source。
而 JFlink 在封装时,其实是封装了业务字段的单调表来进行切片读取。单调是指某张表一定会有某个字段,单调变化的,或者是 append only。
对于 Flink 的主线程,主要通过监听阻塞队列上的有非空信号。当收到非空信号时,就把数据拉出来,通过反序列化器作为整个实时处理框架的流转对象,然后可以对接后面各种模块化了的 UDF。在实现 source 的 At Least Once 语义时,如果借助 Flink 的 CheckPoint 机制,就变得非常简单了。
因为我们已经有个大前提,即这张表是一张由某个字段组成的单调表,在单调表上进行数据切分时,就可以记下当前的切分位置。如果发生故障,让整条流回退到上一个 CheckPoint,source 也会回退到上一个保存的切片位置,此时就能够保证不漏数据的消费,即实现了 source 的 At Least Once。
对于 sink,其实 Flink 官方是提供了 JDBC sink,当然 source 也提供了JDBC sink,但是 Flink 官方提供的 JDBC sink 实现比较朴素,使用同步批量插入的语义。
其实同步批量插入是比较保守的,当数据量比较大时,且没有严格的先来先提交的语义,此时使用同步提交相对来说性能不是很高,如果使用异步提交的话,性能就会提升很多,相当于充分利用了 TiDB 分布式数据库的特性,支持小事务高并发,有助于提升 QPS。
不过在实现 sink 的 At Least Once 语义的时候就相对来说复杂一点。回想 CheckPoint 机制,如果我们要实现 sink 的 At Least Once,就必须保证 CheckPoint 完成时,sink 是干净的,即所有数据都刷出了,这样才能保证其 At Least Once。在这种情况下,可能就需要将 CheckPoint 的线程、普通刷出的主线程以及其他的换页线程等都加上。当触发 CheckPoint 的时候,同步把所有数据都保证刷干净之后,才去完成 CheckPoint。如此,一旦 CheckPoint 完成,sink 必然是干净的,也意味着前面流过来的所有数据都正确更新到 TiDB 了。
业务场景
我们目前技术中心计费数据中心使用 TiDB 跟 Flink 结合的应用场景非常多。如:
海量业务日志数据的实时格式化入库;
基于海量数据的分析统计;
实时 TiDB / Kafka 双流连接的支付链路分析;
对通数据地图;
时序数据。
所以,可以看到其实 Flink on TiDB 在网易数据中心业务层的应用是遍地开花的,此处引用一句,“桃李不言,下自成蹊”,既然能用到这么广泛,也就证明了这条路其实是非常有价值的。
DevCon 2021,邀你共同「预见」
数据库技术变革的拐点已经到来,我们期待与你一起推动这场变革的降临。2020 年,我们邀请了 80 + 位 Ti 星人来到直播间,讲述他们和 TiDB 的故事。2021 年,我们将举办一场 Ti 星人的大聚会,从「开放」讲起,「连接」你我。
“PingCAP DevCon”是由 PingCAP 举办的年度顶级数据技术盛会,大会已连续举办三年,成为观测开源产业、数据库前瞻趋势的风向标。本次大会旨在探讨前沿科技与数字化趋势的融合,解读行业领袖观点,分享技术大咖实战经验,展示用户场景的多元化创新,并展现多元化数据技术生态。扫描下方二维码立即预约,共同「预见」 DevCon 2021。
了解更多详情:
💡 更多 TiDB、TiKV、TiSpark、TiFlash 等技术问题可登录 AskTUG.com ,与全球 TiDB User 随时随地交流使用心得~ 另外,AskTUG 「认证功能」最新上线,完成团队认证可额外获得 +200 经验值和 200 积分 ,授予 “认证会员”徽章。更有问题处理「加急」特权等你~详情了解请点击「阅读原文」!