Flink Streaming 作业如何转化为 JobGraph

本篇文章是 Flink 系列 的第三篇,紧接着上一篇文章,本文主要讲述 StreamGraph 是如何转换成 JobGraph 的,在前面的文章中,我们知道 StreamGraph 是根据用户作业的处理逻生成初始的逻辑计划,它并没有做任何的优化,而 JobGraph 将会在原来的基础上做相应的优化(主要是算子的 Chain 操作,Chain 在一起的算子将会在同一个 task 上运行,会极大减少 shuffle 的开销)。刚开始接触的同学可能会有一个疑问,为什么要有 StreamGraph 和 JobGraph 两层的 Graph,这里最主要的原因是为兼容 batch process,Streaming process 最初产生的是 StreamGraph,而 batch process 产生的则是 OptimizedPlan,但是它们最后都会转换为 JobGraph,本文主要是以 Streaming 作业的 StreamGraph 转换为 JobGraph 的处理流程来介绍。

阅读更多

Flink DataStream API 概述及作业如何转换为 StreamGraph

本篇文章是 Flink 系列 的第二篇,将会给大家讲述一个 Flink 作业(DataStream 高阶 API 为例的作业)是如何转换为 StreamGraph 的, StreamGraph 可以认为是一个还未经过优化处理的逻辑计划,它完全是在 Client 端生成的。StreamGraph 然后再经过优化转换为 JobGraph,Client 端向 JobManager 提交的作业就是以 JobGraph 的形式提交的,也就是说对于 JobManager 来说,它从客户端接收的作业实际上就是一个 JobGraph,然后它再对 JobGraph 做相应处理,生成具体的物理执行计划进行调度。

阅读更多

Apache Flink 初探

本篇文章是 Flink 系列 的第一篇,最近计划花个一到两个月的时间以最新的 Flink-1.9 代码为例把 Flink 的主要内容梳理一遍,这个系列文章的主要内容见 Flink 源码分析,这个 issue 拖了好几个月,现在终于开动了,不容易。梳理的过程也是个人强化学习的过程,博客中有问题的地方也欢迎各位指正(邮件联系 or disqus 评论都行,我这边都会及时回复)。

阅读更多

Paper 阅读: Distributed Snapshots: Determining Global States of Distributed Systems

今天对分布式系统领域的一篇经典论文 —— Chandy-Lamport 算法做了一下总结,这篇论文对于分布式快照算法产生了非常巨大的影响,比如:Apache Flink、Apache Spark 的 Structured Streaming、Ray 等分布式计算引擎都是使用的这个算法做快照。这篇论文的其中一位作者 —— Lamport,他也是 Paxos 算法的提出者,2013 年图领奖得主(图领奖是计算机领域的诺贝尔奖,目前只有一位华裔 —— 姚期智院士获得过这个殊荣,没错,就是清华交叉学院姚班的姚院士)。这篇论文发表于 1985 年,算法的由来可以参考下面的小段子:

阅读更多

Paper 阅读: Lightweight Asynchronous Snapshots for Distributed Dataflow

本篇文章是对 Lightweight Asynchronous Snapshots for Distributed Dataflow 的一个总结,从文章题目也可以看出文章的主题 —— 分布式 dataflow 的轻量级异步 snapshot 算法,它是 Flink 团队在 2015 年发表的论文,主要讲述了对于 Streaming System 如何做 snapshot 的,它选取的是 Chandy-Lamport 算法(论文见 Distributed Snapshots: Determining Global States of Distributed Systems),关于这个算法后面会单独一篇文章来总结。在 Lightweight Asynchronous Snapshots for Distributed Dataflow 这篇论文中,作者更多向我们表达的是 Chandy-Lamport 算法如何在 Flink 中落地的以及如何解决分布式 dataflow 做 snapshot 时遇到的痛点。

阅读更多

Paper 阅读: Real-Time Machine Learning: The Missing Pieces

这周抽空看了关于 ray 的一篇论文,论文是 2017 年发表的(见:Real-Time Machine Learning: The Missing Pieces,他们比较新的论文是 18 年发表的,见:Ray: A Distributed Framework for Emerging AI Applications),虽然论文描述的架构与现在 ray 真正的构架实现已经有了较大的不同,主要也是 ray 这两年发展比较快,架构做了很多的优化,不过本篇论文依然值得仔细阅读学习 一下的,这篇论文也展示了 ray 最初设计实现的出发点。

阅读更多

Apache Calcite 优化器详解(二)

紧接上篇文章Apache Calcite 处理流程详解(一),这里是 Calcite 系列文章的第二篇,后面还会有文章讲述 Calcite 的实践(包括:如何开发用于 SQL 优化的 Rule)。本篇文章主要介绍 Apache Calcite 优化器部分的内容,会先简单介绍一下 RBO 和 CBO 模型,之后详细讲述 Calcite 关于这两个优化器的实现 —— HepPlanner 和 VolcanoPlanner,文章内容都是个人的一些理解,由于也是刚接触这块,理解有偏差的地方,欢迎指正。

阅读更多

Apache Calcite 处理流程详解(一)

关于 Apache Calcite 的简单介绍可以参考 Apache Calcite:Hadoop 中新型大数据查询引擎 这篇文章,Calcite 一开始设计的目标就是 one size fits all,它希望能为不同计算存储引擎提供统一的 SQL 查询引擎,当然 Calcite 并不仅仅是一个简单的 SQL 查询引擎,在论文 Apache Calcite: A Foundational Framework for Optimized Query Processing Over Heterogeneous Data Sources 的摘要(摘要见下面)部分,关于 Calcite 的核心点有简单的介绍,Calcite 的架构有三个特点:flexible, embeddable, and extensible,就是灵活性、组件可插拔、可扩展,它的 SQL Parser 层、Optimizer 层等都可以单独使用,这也是 Calcite 受总多开源框架欢迎的原因之一。

阅读更多

BookKeeper 原理浅谈

接着之前的一篇文章 BookKeeper 集群搭建及使用,本文是 BookKeeper 系列的第二篇,短期来看应该也是最后一篇,本篇文章主要聚焦于 BookKeeper 内核的实现机制上,会从 BookKeeper 的基本概念、架构、读写一致性实现、读写分离实现、容错机制等方面来讲述,因为我并没有看过 BookKeeper 的源码,所以这里的讲述主要还是从原理、方案实现上来介绍,具体如何从解决方案落地到具体的代码实现,有兴趣的可以去看下 BookKeeper 的源码实现。

阅读更多

如何高效学习

在这个知识爆炸、科技日新月异的时代,技术的变化远比我们想象的要快很多,这就对工程师的要求就提高了很多,特别是对于那些在技术上有所追求的工程师而言。对于一些互联网大厂,学习能力也成了面试中重点考察的内容。如何快速学习、掌握一门新的技术,如何提高自己的学习效率,对于有一定工作经验的人来说,可能每个人都有一个自己的学习方法论,但是我们也需要去学习借鉴别人(特别是那些有一定技术影响力的技术大咖)的经验,来不断更新和完善自己的方法轮。今天这篇《高效学习》,就是与大家一起探讨技术学习的方法论,本文的内容主要来自耗子叔的《左耳听风 —— 高效学习篇》,中间会穿插个人的一些经验,算是对这个系列的一个总结。如果想看原文内容,欢迎订阅耗子叔的这个专栏,这个专栏质量还是非常高的,耗子叔推荐了很多优秀的学习资源(通过文章末尾处的二维码链接购买)。

阅读更多

Kafka Exactly-Once 之事务性实现

这篇文章是 Kafka Exactly-Once 实现系列的第二篇,主要讲述 Kafka 事务性的实现,这部分的实现要比幂等性的实现复杂一些,幂等性实现是事务性实现的基础,幂等性提供了单会话单 Partition Exactly-Once 语义的实现,正是因为 Idempotent Producer 不提供跨多个 Partition 和跨会话场景下的保证,因此,我们是需要一种更强的事务保证,能够原子处理多个 Partition 的写入操作,数据要么全部写入成功,要么全部失败,不期望出现中间状态。这就是 Kafka Transactions 希望解决的问题,简单来说就是能够实现 atomic writes across partitions,本文以 Apache Kafka 2.0.0 代码实现为例,深入分析一下 Kafka 是如何实现这一机制的。

阅读更多

Kafka 事务性之幂等性实现

Apache Kafka 从 0.11.0 开始,支持了一个非常大的 feature,就是对事务性的支持,在 Kafka 中关于事务性,是有三种层面上的含义:一是幂等性的支持;二是事务性的支持;三是 Kafka Streams 的 exactly once 的实现,关于 Kafka 事务性系列的文章我们只重点关注前两种层面上的事务性,与 Kafka Streams 相关的内容暂时不做讨论。社区从开始讨论事务性,前后持续近半年时间,相关的设计文档有六十几页(参考 Exactly Once Delivery and Transactional Messaging in Kafka)。事务性这部分的实现也是非常复杂的,之前 Producer 端的代码实现其实是非常简单的,增加事务性的逻辑之后,这部分代码复杂度提高了很多,本篇及后面几篇关于事务性的文章会以 2.0.0 版的代码实现为例,对这部分做了一下分析,计划分为五篇文章:

阅读更多

BookKeeper 集群搭建及使用

随着 Apache Pulsar 成为 Apache 的顶级开源项目,其存储层的解决方案 Apache BookKeeper 再次受到业界广泛关注。BookKeeper 在 Pulsar 之前也有很多成功的应用,比如使用 BookKeeper 实现了 HDFS NameNode 的 HA 机制(可能大部分公司使用的还是 Quorum Journal Manage 方案)、Twitter 开源的 DistributedLog 系统(可参考Twitter开源分布式高性能日志复制服务),BookKeeper 作为一个高扩展、强容错、低延迟的存储服务(A scalable, fault-tolerant, and low-latency storage service optimized for real-time workloads),它相当于把底层的存储层系统服务化(BookKeeper 是更底层的存储服务,类似于 Kafka 的存储层)。这样可以使得依赖于 BookKeeper 实现的分布式存储系统(包括分布式消息队列)在设计时可以只关注其应用层和功能层的内容,存储层比较难解决的问题像一致性、容错等,BookKeeper 已经实现了,从这个层面看,BookKeeper 确实解决业内的一些问题,而且 BookKeeper (Ledger 化,Ledger 相当于 Kafka segment)天生适合云上部署,未来还是有很大潜力的。近段对 BookKeeper 做了一些相应的调研,做了一些总结,本文将会主要从集群部署和使用角度来介绍一下 Apache BookKeeper,后面准备再写一篇文章来深入讲述其架构设计及实现原理。

阅读更多

YARN 架构学习总结

关于 Hadoop 的介绍,这里就不再多说,可以简答来说 Hadoop 的出现真正让更多的互联网公司开始有能力解决大数据场景下的问题,其中的 HDFS 和 YARN 已经成为大数据场景下存储和资源调度的统一解决方案(MR 现在正在被 Spark 所取代,Spark 在计算这块的地位也开始受到其他框架的冲击,流计算上有 Flink,AI 上有 Tensorflow,两面夹击,但是 Spark 的生态建设得很好,其他框架想要在生产环境立马取代还有很长的路要走)。本片文章就是关于 YARN 框架学习的简单总结,目的是希望自己能对分布式调度这块有更深入的了解,当然也希望也这篇文章能够对初学者有所帮助,文章的主要内容来自 《Hadoop 技术内幕:深入解析 YARN 架构设计与实现原理》《大数据日知录:架构与算法》

阅读更多

如何学习开源项目

本篇文章的方法论内容基本来自订阅的极客时间-李运华老师的《从0开始学架构》中的一篇文章,会结合自己的学习经验、加上以 Flink 为例来做一个总结,也为了让自己再学习其他开源项目时能够按照这样的一个方法论高效的深入学习。先简单说一下开源项目,开源项目最早从上个世纪开始,我知道最早的是 linux 项目(其他的不是很了解),再到近几年大数据领域,发展非常迅速,开源给本公司带来的好处,首先是提高这家在技术界的影响力,然后如果这个项目比较受大家认可,那么这家公司的这个技术可能会成为业界的统一解决方案,就像 Hadoop、Kafka 等。对其他公司的好处是,节省成本、可以快速应用来解决业务中的问题。

阅读更多

JVM 之 ParNew 和 CMS 日志分析

在两年前的文章 JVM 学习——垃圾收集器与内存分配策略 中,已经对 GC 算法的原理以及常用的垃圾收集器做了相应的总结。今天这篇文章主要是对生产环境中(Java7)常用的两种垃圾收集器(ParNew:年轻代,CMS:老年代)从日志信息上进行分析,做一下总结,这样当我们在排查相应的问题时,看到 GC 的日志信息,不会再那么陌生,能清楚地知道这些日志是什么意思,GC 线程当前处在哪个阶段,正在做什么事情等。

阅读更多

HDFS 架构学习总结

HDFS(Hadoop Distributed File System)是一个分布式文件存储系统,几乎是离线存储领域的标准解决方案(有能力自研的大厂列外),业内应用非常广泛。近段抽时间,看一下 HDFS 的架构设计,虽然研究生也学习过相关内容,但是现在基本忘得差不多了,今天抽空对这块做了一个简单的总结,也算是再温习了一下这块的内容,这样后续再看 HDFS 方面的文章时,不至于处于懵逼状态。

阅读更多

Kafka Controller Redesign 方案

Kafka Controller 是 Kafka 的核心组件,在前面的文章中,已经详细讲述过 Controller 部分的内容。在过去的几年根据大家在生产环境中应用的反馈,Controller 也积累了一些比较大的问题,而针对这些问题的修复,代码的改动量都是非常大的,无疑是一次重构,因此,社区准备在新版的系统里对 Controller 做一些相应的优化(0.11.0及以后的版本),相应的设计方案见:Kafka Controller Redesign,本文的内容就是结合这篇文章做一个简单的总结。

阅读更多

分布式系统的一致性协议之 2PC 和 3PC

在分布式系统领域,有一个理论,对于分布式系统的设计影响非常大,那就是 CAP 理论,即对于一个分布式系统而言,它是无法同时满足 Consistency(强一致性)、Availability(可用性) 和 Partition tolerance(分区容忍性) 这三个条件的,最多只能满足其中两个。但在实际中,由于网络环境是不可信的,所以分区容忍性几乎是必不可选的,设计者基本就是在一致性和可用性之间做选择,当然大部分情况下,大家都会选择牺牲一部分的一致性来保证可用性(可用性较差的系统非常影响用户体验的,但是对另一些场景,比如支付场景,强一致性是必须要满足)。但是分布式系统又无法彻底放弃一致性(Consistency),如果真的放弃一致性,那么就说明这个系统中的数据根本不可信,数据也就没有意义,那么这个系统也就没有任何价值可言。

阅读更多

Java 守护线程

在 Java 并发编程实践或看涉及到 Java 并发相关的代码时,经常会遇到一些线程(比如做 metrics 统计的线程等)会通过 setDaemon() 方法设置将该线程的 daemon 变量设置为 True,也就是将这个线程设置为了守护线程(daemon thread),那么什么是守护线程呢?或者说守护线程与非守护线程(普通线程)的区别在什么地方呢?这个就是本文主要讲述的内容。

阅读更多