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() 去查看当前字符串常量池里面是否有这个字符串的变量 ...
深入理解jvm虚拟机-垃圾回收器与内存分配策略
什么是垃圾回收?(Garbage Collection) 对于高级语言动态内存分配而言,一些对象随着程序线程的消亡不再进行使用,为了使程序效率更加高效,特有垃圾回收的技术来保证程序运行状态下能够健康的使用宿主机内存 如何判断对象已死,需要回收? 引用计数法:对于一个对象而言,在对象中添加一个计数器,如果有人引用这个对象,计数器加一,反之,计数器减一,当计数器的值为0的时候,表示对象已经无人在使用,需要回收,但引用计数法也有缺点: 无法解决循环引用 有更多的不确定性 可达性分析算法:基本思路通过一系列称之为“GC Root”的节点开始向下搜索,如果对象到“GC Root”之间路不通,那么表示这个对象需要被回收,用数据结构的思想去解释,“GC Root”与对象之间形成了有向无环图,如果从“GC Root”去进行遍历,无法到达对象节点,那么表示这个对象已经无人再去使用,可以被定义为“GC Root”的路径有以下几点: 虚拟机栈帧中本地变量表引用的对象,例如当前方法中的参数、局部变量、临时变量 方法区中类属性静态属性引用的对象,例如Java类的引用类型静态变量 方法区中常量引用的对象 ...
2021年终总结
ff2c4537276fa5cbd14f53c68cacf7a78e0a3cfb1b59ec5dd13d56c6df145edddb4180b45d58934fba2ad1bb9f6c1b0720d13761e83d1e9c10517f3e6194560d597936745d68384c5d4965c34824e4a90c095d7483c6f46c3fa925b1356811aded45c8f0c059e1f599859312ab7de9ec4a0ea21d0321ba118ecebb8c635683469ccf0c623b423b5f953d6660c6287c3a2985c35af388d650d79d0adfcd665d5c244aa9cccf6fd0e64f5c2c2ea07c40f71dbad44be8a56c9b9472a1327e2798ff444c0ff06257d831d572e55d72cdaa82e3bdabc0d266c73252356468e8bf43311bf849505f560cf8901433339c91eaced635d9257d63c117b ...
浅析SparkContext中的组件与创建流程
前言 在Spark框架中,应用程序的提交离不开Spark Driver,而Spark Driver的初始化始终围绕SparkContext的初始化,可以说SparkContext是Spark程序的发动机引擎,有了它程序才能跑起来,在spark-core中,SparkContext重中之重,它提供了很多能力,比如生成RDD,比如生成广播变量等,所以学习SparkContext的组件和启动流程有助于剖析整个Spark内核的架构。 SparkContext组件概览 在SparkContext中包含了整个框架中很重要的几部分: SparkEnv:Spark的运行环境,Executor会依赖它去执行分配的task,不光Executor中有,同时为了保证本地模式任务也能跑起来,Driver中也有 SparkUI:Spark作业的监控页面,底层并没有采用前端技术,纯后端实现,用以对当前SparkJob的监控和调优,可以从页面观察到目前的Executor的jvm信息,每个job的stage划分和task划分,同时还可以观察到每个task处理的数据,用以发现数据是否倾斜 DAGScheduler:DA ...
数据结构系列30-B树
前言 在面试中,面试官很容易问到B树这种数据结构,要去熟练的掌握这个数据结构还是有一定的难度,为了提升自身的技术深度,我特地花了一定的时间梳理和总结一下B树的全部概念与操作。 B树的概念 B树是一种多路平衡查找树,不同于二叉平衡树,他不只是有两个分支,而是有多个分支,一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树,B树用于磁盘寻址,它是一种高效的查找算法。 B树的性质 根节点至少有2个子女 每个非根节点所包含的关键字个数x满足以下关系:⌈m/2⌉−1⩽x⩽m−1\lceil m/2 \rceil - 1 \leqslant x \leqslant m - 1⌈m/2⌉−1⩽x⩽m−1 所有叶子结点都在同一层 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:⌈m/2⌉⩽k⩽m\lceil m/2 \rceil \leqslant k \leqslant m⌈m/2⌉⩽k⩽m B树数据结构描述 一个B树结点包含了以下关键信息: 关键字数量 关键字数组指针 孩子数组指针 父亲结点指针 ...
SparkConf源码解读
在新启动一个spark作业的同时,我们需要去创建一个上下文对象,不论是spark-sql,还是spark-core亦或是spark-streaming,每一个上下文都会依赖一个SparkConf对象,在spark作业调优的过程中,SparkConf这个对象起了至关重要的作用。 1. 核心参数在SparkConf对象中如何保存: 1private val settings = new ConcurrentHashMap[String, String]() 所有配置项都保存在对应的ConcurrentHashMap当中,而且配置的key和value都是string类型的变量 2. 核心方法set 12345678910111213private[spark] def set(key: String, value: String, silent: Boolean): SparkConf = { if (key == null) { throw new NullPointerException("null key") } ...