共计 4389 个字符,预计需要花费 11 分钟才能阅读完成。
本文整顿自戴尔科技团体软件工程师周煜敏在 Flink Forward Asia 2020 分享的议题《Pravega Flink Connector 的过来、当初和将来》,文章内容为:
- Pravega 以及 Pravega connector 简介
- Pravega connector 的过来
- 回顾 Flink 1.11 高阶个性心得分享
- 将来瞻望
一、Pravega 以及 Pravega connector 简介
Pravega 我的项目的名字来源于梵语,意思是 good speed。我的项目起源于 2016 年,基于 Apache V2 协定在 Github 上开源,并且于 2020 年 11 月退出了 CNCF 的小家庭,成为了 CNCF 的 sandbox 我的项目。
Pravega 我的项目是为大规模数据流场景而设计的,补救传统音讯队列存储短板的一个新的企业级存储系统。它在放弃对于流的无边界、高性能的读写上,也减少了企业级的一些个性:例如弹性伸缩以及分层存储,能够帮忙企业用户升高应用和保护的老本。同时咱们也在存储畛域有着多年的技术积淀,能够依靠公司商用存储产品为客户提供长久化的存储。
以上的架构图形容的是 Pravega 典型的读写场景,借此进行 Pravega 术语介绍以帮忙大家进一步理解零碎架构。
两头局部是一个 Pravega 的集群,它整体是以 stream 形象的零碎。stream 能够认为是类比 Kafka 的 topic。同样,Pravega 的 Segment 能够类比 Kafka 的 Partition,作为数据分区的概念,同时提供动静伸缩的性能。
Segment 存储二进制数据数据流,并且依据数据流量的大小,产生 merge 或者 split 的操作,以开释或者集中资源。此时 Segment 会进行 seal 操作禁止新数据写入,而后由新建的 Segment 进行新数据的接管。
- 图片左侧是数据写入的场景,反对 append only 的写入。用户能够对于每一个 event 指定 Routing key 来决定 Segment 的归属。这一点能够类比 Kafka Partitioner。繁多的 Routing key 上的数据具备保序性,确保读出的程序与写入雷同。
- 图片右侧是数据读取的场景,多个 reader 会有一个 Reader Group 进行管控。Reader Group 管制着 reader 之间的负载平衡的,来保障所有的 Segment 能在 reader 之间均匀分布。同时也提供 Checkpoint 机制造成统一的 stream 切分来保证数据的故障复原。对于 “ 读 ”,咱们反对批和流两种语义。对于流的场景,咱们反对尾读;对于批的场景,咱们会更多的思考高并发来达到高吞吐。
二、Pravega Flink connector 的过来
Pravega Flink connector 是 Pravega 最后反对的 connector,这也是因为 Pravega 与 Flink 的设计理念十分统一,都是以流为根底的批流一体的零碎,可能组成存储加计算的残缺解决方案。
1. Pravega 倒退历程
- connector 从 2017 年开始成为独立的 Github 我的项目。2017 年,咱们基于 Flink 1.3 版本进行开发,过后有包含 Stephan Ewen 在内的 Flink PMC 成员退出,单干构建了最根底的 Source / Sink function,反对最根底的读写,同时也包含 Pravega Checkpoint 的集成,这点会在前面进行介绍。
- 2018 年最重要的一个亮点性能就是端到端的准确一次性语义反对。过后团队和 Flink 社区有十分多的探讨,Pravega 首先反对了事务性写客户端的个性,社区在此基础上单干,以 Sink function 为根底,通过一套两阶段提交的语义实现了基于 checkpoint 的分布式事务性能。起初,Flink 也进一步形象出了两阶段提交的 API,也就是为大家熟知的 TwoPhaseCommitSinkFunction 接口,并且也被 Kafka connector 采纳。社区有博客来专门介绍这一接口,以及端到端的一次性语义。
- 2019 年更多的是 connector 对其它 API 的一些补完,包含对批的读取以及 Table API 都有了反对。
- 2020 年的次要关注点是对 Flink 1.11 的集成,其中的重点是 FLIP-27 以及 FLIP-95 的新个性集成。
2. Checkpoint 集成实现
以 Kafka 为例,能够首先来看一下 Kafka 是如何做到 Flink Checkpoint 的集成的。
上图所示是一个典型的 Kafka “ 读 ” 的架构。基于 Chandy-Lamport 算法的 Flink checkpoint 实现,当 Job master Trigger 一个 Checkpoint 时,会往 Task Executor 发送 RPC 申请。其接管到之后会把本身状态存储中的 Kafka commit offset 合并回 Job Manager 造成一个 Checkpoint Metadata。
认真思考后,其实能够发现其中的一些小问题:
- 扩缩容以及动静的均衡反对。当 Partition 进行调整的时候,或者说对 Pravega 而言,在 Partition 动静扩容和缩容的时候,如何进行 Merge 一致性的保障。
- 还有一点就是 Task 须要保护一个 offset 的信息,整个设计会与 Kafka 的外部形象 offset 耦合。
基于这些不足之处,Pravega 有本人外部设计的 Checkpoint 机制,咱们来看一下它是怎么和 Flink 的 Checkpoint 进行集成的。
同样读取 Pravega Stream。开始 Checkpoint 这里就有不同,Job master 不再向 Task Executor 发送 RPC 申请,转而以 ExternallyInducedSource 的接口,向 Pravega 发送一个 Checkpoint 的申请。
同时,Pravega 外部会利用 StateSynchronizer 组件来同步和协调所有的 reader,并且会在所有的 reader 之间,发送 Checkpoint 的 event。当 Task Executor 读到 Checkpoint Event 之后,整个 Pravega 会标记着这个 Checkpoint 实现,而后返回的 Pravega Checkpoint 会存到 Job master state 当中,从而实现 Checkpoint。
这样的实现其实对于 Flink 来说是更洁净的,因为它没有耦合内部零碎的实现细节,整个 Checkpoint 的工作是交给 Pravega 来实现并实现的。
三、回顾 Flink 1.11 高阶个性心得分享
Flink 1.11 是 2020 年的一个重要公布版本,对 connector 而言其实也有十分多的挑战,次要集中在两个 FLIP 的实现:FLIP-27 以及 FLIP-95。对于这两个全新性能,团队也花了很多工夫去集成,在过程中也遇到了一些问题和挑战。上面咱们来向大家分享一下咱们是如何踩坑和填坑的。本文会以 FLIP-95 为例开展。
1. FLIP-95 集成
FLIP-95 是新的 Table API,其动机和 FLIP-27 相似,也是为了实现批流一体的接口,同时也能更好地反对 CDC 的集成。针对简短的配置键,也提出了相应的 FLIP-122 来简化配置键的设定。
1.1 Pravega 旧的 Table API
从上图能够看到 Pravega 在 Flink 1.10 之前的一个 Table API,并且从图中建表的 DDL 能够看到:
- 以 update mode 和 append 去进行辨别批和流,而且批流的数据这样的辨别并不直观。
- 配置件也十分的简短和简单,读取的 Stream 须要通过 connector.reader.stream-info.0 这样十分长的配置键来配置。
- 在代码层面,和 DataStream API 也有十分多的耦合难以保护。
针对这些问题,咱们也就有了十分大的能源去实现这样一套新的 API,让用户更好的去应用表的形象。整个框架如图所示,借由整个新框架的帮忙,所有的配置项通过 ConfigOption 接口定义,并且都集中在 PravegaOptions 类治理。
1.2 Pravega 全新 Table API
下图是最新 Table API 建表的实现,和之前的相比有十分大的简化,同时在性能上也有了不少优化,例如企业级平安选项的配置,多 stream 以及起始 streamcut 的指定性能。
2. Flink-18641 解决过程心得分享
接下来,我想在此分享 Flink 1.11 集成的一个小的心得,是对于一个 issue 解决过程的分享。Flink-18641 是咱们在集成 1.11.0 版本时碰到的问题。降级的过程中,在单元测试中会报 CheckpointException。接下来是咱们残缺的 debug 过程。
- 首先会本人去逐渐断点调试,通过查看 error 的报错日志,剖析相干的 Pravega 以及 Flink 的源码,确定它是 Flink CheckpointCoordinator 相干的一些问题;
- 而后咱们也查看了社区的一些提交记录,发现 Flink 1.10 之后,CheckpointCoordinator 线程模型,由原来锁管制的模型变成了 Mailbox 模型。这个模型导致了咱们原来同步串型化执行的一些逻辑,谬误的被并行化运行了,于是导致该谬误;
- 进一步看了这一个改变的 pull request,也通过邮件和相干的一些 Committer 获得了分割。最初在 dev 邮件列表上确认问题,并且开了这个 JIRA ticket。
咱们也总结了以下一些注意事项给到在做开源社区的同胞们:
- 在邮件列表和 JIRA 中搜寻是否有其他人曾经提出了相似问题;
- 残缺的形容问题,提供具体的版本信息,报错日志和重现步骤;
- 失去社区成员反馈之后,能够进一步会议沟通切磋解决方案;
- 在非中文环境须要应用英语。
其实作为中国的开发人员,有除了像 mailing list 和 JIRA 之外。咱们也有钉钉群以及视频的形式能够分割到十分多的 Committer。其实更多的就是一个交换的过程,做开源就是要和社区多交换,能够促成我的项目之间的独特成长。
四、将来瞻望
- 在将来比拟大的工作就是 Pravega schema registry 集成。Pravega schema registry 提供了对 Pravega stream 的元数据的治理,包含数据 schema 以及序列化形式,并进行存储。这个性能随同着 Pravega 0.8 版本公布了该项目标第一个开源版本。咱们将在之后的 0.10 版本中基于这一我的项目实现 Pravega 的 Catalog,使得 Flink table API 的应用更加简略;
- 其次,咱们也时刻关注 Flink 社区的新动向,对于社区的新版本、新性能也会踊跃集成,目前的打算包含 FLIP-143 和 FLIP-129;
- 社区也在逐渐实现基于 docker 容器的新的 Test Framework 的转换,咱们也在关注并进行集成。
最初也心愿社区的小伙伴能够多多的关注 Pravega 我的项目,促成 Pravega connector 与 Flink 的独特倒退。