暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SeaTunnel Zeta 同步引擎首次曝光核心设计!

SeaTunnel 2023-01-10
4176
点亮 ⭐️ Star · 照亮开源之路
https://github.com/apache/incubator-seatunnel


作者 | 高俊
    

在最近刚刚发布的 SeaTunnel 2.3.0 正式版本中,社区筹备开发一年多的自己的引擎——SeaTunnel Zeta 正式发布,今后将作为 SeaTunnel 默认使用的引擎,为用户提供高吞吐,低延时,强一致性的同步作业运行保障。


SeaTunnel 为什么要研发自己的同步引擎?SeaTunnel Engine 的定位是什么?与传统的计算引擎有何不同?设计的思路是怎样的?架构设计有何独到之处?这些问题都将在本文得到解答。


  • 为什么开发自己的引擎
  • SeaTunnel Engine 定位
  • 设计思路
  • 架构设计
  • 独特优势和特点
  • 目前基本功能和特性
  • 未来优化方向

01

为什么要开发自己的引擎


SeaTunnel 社区首次对外公开表示将要研发一套自己的引擎,已经是一年前了。为什么当时团队决定要自研一个引擎,是因为 SeaTunnel 的连接器必须在 Flink或 Spark 上运行,而 Flink 和 Spark 作为计算引擎,在做数据集成和数据同步时,有很多无法解决的问题。

参考:

为什么我们要自研全球首款大数据同步引擎 SeaTunnel Engine?

https://github.com/apache/incubator-seatunnel/issues/1954 

02

设计思路


引擎设计的总体思路如下:

  1. 简单易用,新的引擎尽量减小第三方服务的依赖,可以不依赖zookeeper,hdfs等大数据组件实现集群管理、快照存储和集群HA功能。这对于那些没有大数据平台或者不愿意依赖大数据平台进行数据同步的用户非常有用。
  2. 更省资源,在CPU层面SeaTunnel Engine内部使用dynamic thread sharing技术 ,在实时同步的场景下,如果表的数量很多但每张表的数据量又很小,SeaTunnel Engine会将这些同步任务在共享线程中运行,这种方式可以减少不必要的线程创建,节省系统资源。在读取和数据写入端,SeaTunnel Engine的设计目标是尽量减少JDBC连接的个数。在CDC的场景下SeaTunnel Engine会尽量复用日志读取解析资源。
  3. 更稳定,在这个版本中,SeaTunnel Engine将数据同步的任务以Pipeline做为Checkpoint和容错的最小粒度,一个task的失败只会影响到和它有上下游关系的task,尽量避免task失败造成整个Job失败或回滚。同时对于那些源端数据有存储时间限制的场景,SeaTunnel Engine支持开启数据Cache,开启Cache后SeaTunnel Engine会自动将从源端读取的数据缓存起来,然后由下游任务读取缓存数据并写入目标端。这种场景下即使目标端出现故障导致数据无法写入,也不会影响源端的正常读取,防止源端数据过期被删除。
  4. 更快速,SeaTunnel Engine的执行计划优化器会以减小数据可能的网络传输为目标来做执行计划的优化,从而降低数据序列化和反序列化带来的整体同步性能的损耗,更快地完成数据同步操作。当然我们也会支持速度限制,让同步作业以一个合理的速度进行。
  5. 全场景数据同步支持。SeaTunnel的目标是支持离线批量同步下的全量同步和增量同步。支持实时同步。支持CDC。

03

架构设计


SeaTunnel Engine 主要由一套数据同步处理的 API 和核心计算引擎组成。这里主要介绍 SeaTunnel Engine 核心引擎的架构设计。

SeaTunnel Engine 由三个主要的服务组成:CoordinatorService、TaskExecutionService 和 SlotService。

CoordinatorService


CoordinatorService 是集群的 Master 服务,提供了每个作业从 LogicalDag 到 ExecutionDag,再到 PhysicalDag 的生成流程,并最终创建作业的 JobMaster 进行作业的调度执行和状态监控。CoordinatorService中 主要由 4 个大的功能模块组成:
  1. JobMaster,负责单个作业的 LogicalDag 到 ExecutionDag,再到 PhysicalDag 的生成流程,并由 PipelineBaseScheduler 进行调度运行。
  2. CheckpointCoordinator,负责作业的 Checkpoint 流程控制。
  3. ResourceManager,负责作业资源的申请和管理,目前支持 Standalone 模式,未来会支持 On Yarn 和 On K8s。
  4. Metrics Service,负责作业监控信息的统计和汇总。

TaskExecutionService


TaskExecutionService 是集群的 Worker 服务,提供了作业中每个 Task 的真正运行时环境,TaskExecutionService 使用了 Dynamic Thread Sharing 技术降低 CPU 使用。

SlotService


SlotService 在集群每个节点上都会运行,主要负责节点上资源的划分、申请和回收。

04

独特优势和特点


自治集群

SeaTunnel Engine 已实现自治集群(无中心化),为了在不依赖第三方服务组件(如 Zookeeper)的情况下实现集群的自治和作业的容错,SeaTunnel Engine 使用了 Hazelcast作为底层依赖。Hazelcast 提供了一个分布式内存网络,让用户可以像在本地操作普通 Java 集合一样来操作一个分布式的集合,SeaTunnel 将作业的状态信息保存在Hazelcast 的内存网格中,当 Master 节点切换后,可以基于 Hazelcast 内存网格中的数据进行作业状态的恢复。同时,我们还实现了 Hazelcast 内存网格数据的持久化,以WAL 的方式将作业状态信息持久化到存储中(JDBC 协议的数据库、HDFS、云存储)。这样,即使整个集群挂掉重启,也可以修复作业的运行时信息。

数据缓存

SeaTunnel Engine 与传统的Spark/Flink计算引擎不同,是专门用来做数据同步的引擎。SeaTunnel 引擎天然支持数据 Cache,当集群中有多个同步作业共用一个数据源时,SeaTunnel 引擎会自动启用数据 Cache,由一个作业的 Source 将数据读取后写入 Cache 中,其它所有作业不再从数据源读取数据,而是自动被优化为从 Cache 中读取数据。这样做的好处是可以降低数据源的读取压力,降低数据同步对数据源的影响。

速度控制

SeaTunnel Engine 支持数据同步时的速度限制,这在高并发读取数据源时非常有用,合理的速度限制既可以保证数据按时同步完成,又可以尽量减小对数据源造成的压力影响。

共享连接池,降低数据库压力

目前使用 Spark/Flink 等计算引擎提供的底层运行工具和数据同步工具无法解决整库同步时每张表需要一个 JDBC 连接的问题。数据库连接对数据库来说是资源,过多的数据库连接会对数据库造成极大的压力,导致数据库读写延迟稳定性降低,这对业务数据库来说是非常严重的事故。为了解决这个问题,SeaTunnel Engine 使用共享连接池的方式,保证多张表可以共用 JDBC 连接,从而降低数据库连接的使用。

断点续传(增量/全量),让用户无感知

SeaTunnel Engine 支持离线同步下的断点续传。在数据量较大时,一次数据同步作业往往需要运行几十分钟或几个小时,如果中间作业挂了重跑,那意味着浪费时间。SeaTunnel Engine 会在离线同步的过程中不断地进行状态的保存(检查点),作业挂掉重跑时会从上一次的检查点继续运行,这有效解决了节点宕机等硬件问题可能导致的数据延迟。

Schema revolution 的路线

模式演化是一种允许用户轻松更改表的当前模式以适应随时间变化的数据的功能。最常见的是,在执行追加或覆盖操作时使用它,以自动调整模式以包括一个或多个新列。

实时数据仓库场景中需要此功能。目前,Flink 和 Spark 引擎不支持此功能。

更细粒度的容错设计

Flink 的设计是整个作业级别的容错和回滚,表现为如果某一个 task 失败,那整个作业都会进行回滚重启操作。SeaTunnel Engine 在设计时考虑到了在数据同步场景下,很多q情况下一个 task 的失败应该只需要和它有上下游关系的 task 需要关注容错。基于这一设计原则,SeaTunnel Engine 会先按用户配置的作业配置文件生成逻辑 DAG,再对逻辑DAG 进行优化,最终生成以 Pipeline(一个作业 DAG 中的一个连通子图)为粒度进行作业的调用和容错。

一个典型的使用场景是:

使用 CDC 连接器从 MySQL 的 binlog 中读取数据后写入另一个 MySQL,如果使用 Flink 或 Spark 引擎,一旦目标端 MySQL 无法写入,会导致 CDC 读取 binlog 的任务也会中止,如果 MySQL 被设置了 log 的过期时间,会出现目标端 MySQL 问题解决了,但源 MySQL 的日志被清除了,进而引发数据丢失等问题。

SeaTunnel Engine 会自动优化这一同步任务,自动添加源到目标端的 Cache,再进一步将这个作业优化成两个 Pipeline,pipeline#1 负责从 CDC 读取数据并写入 SeaTunnel Cache,pipeline#2 负责从 SeaTunnel Cache 读取数据并写入目标MySQL。如果目标端 MySQL 有问题导致无法写入,这个同步作业的 pipeline#2 会中止,pipeline#1 依然正常运行。这种设计从根本上解决了上述的问题,更符合数据同步引擎的处理逻辑。

动态共享线程,减少资源占用

SeaTunnel Engine 的 Task 设计使用了共享线程的技术,区别于 Flink/Spark,SeaTunnel Engine 不会简单的让一个 Task 占用一个线程,而是通过一种动态感知的方式——动态线程共享(Dynamic Thread Sharing)来判断一个 Task 应该和其它 Task 共享一个线程还是应该独占一个线程。

多线程并行计算和单线程串行计算相比有更好的性能优势,但如果每个 Task 都占使用一个独立线程来运行,当数据同步的表比较多,Task 数量大时,会在 Worker 节点上启动非常多的线程。在 CPU 核心数固定的情况下,线程数并不是越多越好,当线程数量过多时,CPU 需要花大量的时间进行线程的上下文切换,这反而会影响计算性能。

Flink/Spark 通常会限制每个节点上最大运行的 Task 的数量,通过这种方式来可避免起动太多的线程,而 SeaTunnel Engine 为了能在一个节点上运行更多的 Task,通过共享线程技术可以让那些数据量较少的 Task 共享线程,而数据量较大的 Task 独占线程,这种方式使 SeaTunnel Engine 在一个节点上运行几百上千张表同步任务成为了可能,以更少的资源占用,完成更多的表的同步。

05

目前基本功能和特性


2.3.0 是 SeaTunnel Engine的第一个正式版本,实现了一些基本的功能,这部分的详细设计可以参考:https://github.com/apache/incubator-seatunnel/issues/2272

[ 集群管理 ]
  • 支持单机运行
  • 支持集群运行
  • 自治集群(无中心化),不需要为SeaTunnel Engine集群指定Master节点,SeaTunnel Engine在运行中自行选举Master节点,Master节点挂掉后会自动选出新的Master节点。
  • 集群节点自动发现,具体相同cluster_name的节点会自动组成集群。

[ 核心功能 ]
  • 支持以Local模式运行作业。作业运行完成后集群自动销毁。
  • 支持以Cluster的模式(单机或集群)运行作业,通过SeaTunnel Client提交作业到SeaTunnel Engine服务中,作业运行完成后服务继续运行等待下次作业提交。
  • 支持离线批量同步。
  • 支持实时同步。
  • 批流一体,所有SeaTunnel V2版本连接器都可以运行在SeaTunnel Engine中。
  • 支持分布式快照算法,配合SeaTunnel V2连接器支持二阶段提交,保证数据的exactly-once。
  • 支持以Pipeline级别的作业调用,保证在资源有限的情况下也能启动。
  • 支持以Pipeline级别作业容错,Task失败只影响到它所在的Pipeline,只需要对该Pipeline下的Task进行回滚处理。
  • 支持dynamic thread sharing,以实现大量小数据集的实时同步。

06

未来优化方向


  1. 支持Cache模式,并先支持Kafka做为Cache
  2. 支持JobHistory,支持JobHistory的持久化。
  3. 支持指标(Reader Rows, QPS, Reader Bytes)监控和指标查询
  4. 支持动态修改执行计划。
  5. 支持CDC。
  6. 支持整库同步
  7. 支持多表同步
  8. 支持Schema Revolution

活动推荐





关注视频号预约直播!

文章转载自SeaTunnel,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论