DataX源码解析-调度流程
前言 书接上回,继续来聊一聊DataX源码,在上篇文章中我们已经对DataX的整体架构以及运行流程有了一个比较细致的了解,这篇文章我们将更深层次的研究DataX在调度方面的细节。 调度流程解析 确认最终任务需要的channel数量 注:channel是子任务数据传输的内存模型,后续文章将详细剖析,在这里可以暂且认为就是任务分片数量 在任务周期中含有一个split()阶段,在这个阶段做了两件事情: 通过配置项计算出建议的并发channel数量 执行reader插件中的的实际切片逻辑,并根据数量切分configuration,请注意,这一步计算出的数量可能小于第一步配置的并发数 所以在真正调度阶段,需要根据split()阶段中计算的两个值,计算出最终的channel数量 通过channel数量分配taskGroup 在计算出真正需要的channel数量之后,根据每个TaskGroup应该被分配任务的个数,计算TaskGroup的个数: 由上图可知,任务的分配是由JobAssignUtil去进行,而且从方法名称assignFairly也可以知晓,分配的逻辑是公平分配,使用的Round ...
DataX源码解析-整体架构
前言 近期在工作中需要用到DataX去作为公司内部的数据同步引擎,特花了一些时间研究了DataX的整体架构和设计思想,从中吸收了很多优秀的设计思路,作为一款纯Java实现的数据同步工具,相对于市面上已存在的基于大数据框架为背景的数据同步工具有着易部署、易扩展的优点,但不足的地方是alibaba只是开源了DataX单机模式代码,并未开源分布式部分代码,目前在Github中的只是阉割版是DataX,对此我表示很遗憾。 DataX简介 DataX 是阿里云 DataWorks数据集成 的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS 等各种异构数据源之间高效的数据同步功能,项目地址:https://github.com/alibaba/DataX 以上摘抄自DataX项目首页README 架构浅析 数据统一抽象 DataX作为一款高性能的 ...
数据结构系列32-插入排序
1234567891011121314151617181920212223242526272829303132333435363738394041/************************************************************************** File Name: insertSort.c* Author: TyrantLucifer* E-mail: TyrantLucifer@gmail.com* Blog: https://tyrantlucifer.com* Created Time: Sun 20 Mar 2022 08:32:01 PM CST ************************************************************************/#include <stdio.h>void printArray(int array[], int length) { for (int i = 0; i < length; i++) ...
数据结构系列31-哈希表
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253/************************************************************************** File Name: hashList.c* Author: TyrantLucifer* E-mail: TyrantLucifer@gmail.com* Blog: https://tyrantlucifer.com* Created Time: Sun 20 Mar 2022 12:28:03 AM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#define NUM 5typedef struct HashList ...
Apache Calcite 文档翻译 - 代数
代数 关系代数是Calcite的核心。每个查询都被表示为一棵关系运算符的树。你可以将一条SQL语句翻译为关系代数,也可以直接建立树状结构。 规则器规则使用保留语义的数学特性来转换表达树。例如,如果一个过滤操作没有引入其他输入的列,那么可以将一个过滤器下推至连接之前。 Calcite通过对关系表达式进行反复应用规划器规则来优化查询。一个成本模型指导了优化的整个过程,规划器生成一个替代的表达式,语义与之前表达式相同,但具有更低的成本。 规划过程是可扩展的。你可以添加自己的关系运算符、规划器规则、成本模型和统计数据。 代数构建 建立关系表达式的最简单方法时使用代数构建器RelBuilder,下面是一个示例: 表扫描 123456final FrameworkConfig config;final RelBuilder builder = RelBuilder.create(config);final RelNode node = builder .scan("EMP") .build();System.out.println(RelOptUtil.toString(n ...
Apache Calcite 文档翻译 - 基础教程
教程 这是一个手把手并循序渐进的教程,展示了如何和Calcite建立连接。它使用了一个简单的适配器,使得一个包含了csv文件的目录看起来是一个包含数据库表的模式(schema)。Calcite负责其他工作,并提供了一个完整的SQL接口。 Calcite-example-CSV是Calcite的一个全功能适配器,可以读取CSV(逗号分割的值)格式的文本文件。值得注意的是,几百行的Java代码就足以提供完整的SQL查询能力。 CSV适配器也可以作为构建其他适配器的模板。尽管代码行数不多,但它涵盖了几个重要的概念: 使用SchemaFactory和Schema接口实现用户自定义的模式 在一个模型的JSON文件声明了模式 在一个模型的JSON文件声明了视图 使用Table接口实现用户自定义的表 确定了一个表的记录类型 一个表的最简单实现,实现了ScannableTable接口,直接枚举所有的行 一个更高级的实现,实现了FilterableTable接口,使得用户可以根据简单的谓词过滤出行 表的高级实现,实现了TranslatableTable接口,使其可以使用规划器规则翻译成关系运算符 下 ...
Apache Calcite 文档翻译 - 背景概览
背景概述 Apache Calcite是一个动态数据管理框架。 它包含了构成典型数据库管理系统的许多部分,但是省略了一些关键性的功能:数据存储、处理数据的算法和一个用于存储元数据的元数据库。 Calcite有意不参与存储和处理数据的业务,正如我们将看到的,这个特性使得它成为在应用程序和一个或多个数据存储位置和数据处理引擎之间进行调解的绝佳选择。它也是建立数据库的一个完美的基础:只需要添加数据给它,它就可以成为你的最佳数据管理工具。 为了说明这一点,让我们创建一个空的Calcite的实例,然后添加一些数据给它: 1234567891011121314151617181920212223242526public static class HrSchema { public final Employee[] emps = 0; public final Department[] depts = 0;}Class.forName("org.apache.calcite.jdbc.Driver");Properties info = new Prope ...
深入理解jvm虚拟机-常用垃圾回收器解读
概览 CMS(Concurrent Mark Sweep)垃圾回收器 采用标记清除算法 分为四阶段 初始标记,用户线程需要停顿 并发标记,用户线程不需要停顿 重新标记,使用增量更新,用户线程不需要停顿 并发清除,用户线程不需要停顿 缺点: 占用资源过高,降低程序吞吐量 浮动垃圾无法清理,需要等到下一次再处理,这就导致了cms不能等到老年代快要占满了才去进行垃圾回收,得需要预留一些空间给浮动垃圾,如果在并发清理期间无法分配内存至新的对象,那么会导致并发失败,此时虚拟机启用serial old垃圾回收进行处理 内存碎片过多 Garbage First垃圾回收器 面向局部回收的收集思路和基于Region的内存布局形式,在JDK9中,G1取代了Parallel Scavenge组合,G1的开创基于region的堆内存布局是他能够实现这个目标的关键,G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分成为多个大小相等的独立区域,每一个region都可以根据需要,扮演新生代的Eden区、Survivor区、或者老年代空间,收集器可以根据扮演不同角色的r ...
深入理解jvm虚拟机-Hotspot虚拟机垃圾回收算法细节实现
GC流程 一般虚拟机要开始GC的话需要进行GC Root的寻找和扫描,在找到GC Root之后进行遍历,进行可达性分析,标记然后清除 GC Root枚举实现 基于GC Root虚拟机要进行垃圾回收,但垃圾回收的第一个拦路虎出现了,如何快速找到GC Root?虚拟机它在开始垃圾回收的时候面对的是一块内存地址,如何从内存地址中快速找到GC Root的起始,这是我们要解决的议题,针对这个问题,虚拟机采用了一个OopMap的数据结构去记录GC Root的起始位置,这样虚拟机利用这个数据结构就可以快速找到GC Root并进行遍历 跨代引用? 在垃圾回收中,分Minor GC和Full GC,也就是新生代GC和老年代GC,如果程序中存在着老年代中的对象引用了新生代对象的情况,那么在Minor GC的过程中为了寻找GC Root就会去扫描整个老年代的内存区域,这样代价是巨大的,为了解决这种跨代引用的问题,虚拟机同样采用了一个叫记忆集的数据结构去记录老年代中的哪块内存存在着跨代引用的情况,那么即使在出现跨代引用的情况之后,Minor GC也不需要去扫描整个老年代的内存区域,记忆集的实现在不同的虚拟机 ...
深入理解jvm虚拟机-java内存区域与内存溢出异常
Jvm内存区域划分 新建对象流程 Java程序是如何运行起来的 对象的内存布局 jdk6与jdk7的不同 12345678class Test { public static void main(String[] args) { String str1 = new StringBuilder("hello").append("world").toString(); System.out.println(str1.intern() == str1) // false String str2 = new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern() == str2) // true sun.misc.Version }} 1intern() 去查看当前字符串常量池里面是否有这个字符串的变量 ...