做中学, 学中做

2018-04-06
Flink-State

Flink 中 State 用于保存 Task 的状态,Checkpoint 的时候,会将 State 保存到外存中。

State 有两种,Keyed State 和 Operator State,每一种则可以有两种形式存在:Managed 和 Raw。其中 Keyed State 只能引用在 Keyed Stream 上,在 Flink 中使用 keyBy() 创建一个 keyed Stream. Flink 保证同一个 key 的 Tuple 会被发送到同一个 task 进行处理,Operator State 使用 ListState(用于 rescale),上层是一个 HashMap Key 是 name,value 是一个封装了 list 的 class。

Read More

2018-03-14
Java 内存泄漏分析和对内存设置

1 内存泄漏的背景知识

为了判断 Java 中是否有内存泄漏,我们首先必须了解 Java 是如何管理内存的。下面我们先给出一个简单的内存泄漏的例子,在这个例子中我们循环申请 Object 对象,并将所申请的对象放入一个 HashMap 中,如果我们仅仅释放引用本身,那么 HashMap 仍然引用该对象,所以这个对象对 GC 来说是不可回收的。

Read More

2018-02-28
通过 Java 线程堆栈进行性能瓶颈分析

改善性能意味着用更少的资源做更多的事情。为了利用并发来提高系统性能,我们需要更有效的利用现有的处理器资源,这意味着我们期望使 CPU 尽可能出于忙碌状态(当然,并不是让 CPU 周期出于应付无用计算,而是让 CPU 做有用的事情而忙)。如果程序受限于当前的 CPU 计算能力,那么我们通过增加更多的处理器或者通过集群就能提高总的性能。总的来说,性能提高,需要且仅需要解决当前的受限资源,当前受限资源可能是:

  • CPU: 如果当前 CPU 已经能够接近 100% 的利用率,并且代码业务逻辑无法再简化,那么说明该系统的性能以及达到上线,只有通过增加处理器来提高性能
  • 其他资源:比如连接数等。可以修改代码,尽量利用 CPU,可以获得极大的性能提升
Read More

2018-01-06
线程堆栈分析

本文为读书笔记,关于 Java 线程堆栈分析,在阅读并进行实验的基础上进行整理,如果有问题欢迎反馈
Read More

2017-12-22
millwheel

本文属于 MillWheel 论文的阅读与翻译稿,部分地方使用自己的语言进行描述,部分地方进行翻译(附带原文)
讲述 MillWhell 的编程模型以及具体实现。MillWhell 的逻辑时间(logical time)使得开发基于时间的聚合应用更方便,从设计之初,MillWhell 就考虑了容错性以及扩展性。

Read More

2017-12-03
tasksetmanager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Schedules the tasks within a single TaskSet in the TaskSchedulerImpl. This class keeps track of
* each task, retries tasks if they fail (up to a limited number of times), and
* handles locality-aware scheduling for this TaskSet via delay scheduling. The main interfaces
* to it are resourceOffer, which asks the TaskSet whether it wants to run a task on one node,
* and statusUpdate, which tells it that one of its tasks changed state (e.g. finished).
*
* THREADING: This class is designed to only be called from code with a lock on the
* TaskScheduler (e.g. its event handlers). It should not be called from other threads.
*
* @param sched the TaskSchedulerImpl associated with the TaskSetManager
* @param taskSet the TaskSet to manage scheduling for
* @param maxTaskFailures if any particular task fails this number of times, the entire
* task set will be aborted
*/

TaskSetManager 负责某个 TaskSet 的调度,对该 TaskSet 的所有 task 进行跟踪,如果有失败的 task,会负责重试(重试有上限),并且通过 delay scheduling(可以想想这个怎么实现的?) 实现 locality locality-aware scheduling. 主要的接口有 resourceOffer – 用于判断一个 TaskSet 中的 task 是否需要运行到某个 node 上,statusUpdate – 用于跟踪 task 的状态变化。不是线程安全的。

Read More

2017-11-27
TaskScheduler

本文属于自己看源码后的记录

与不同的后端调度器一起,进行 task 的调度(task 是 DAGScheduler 中划分的 Stage 中的具体任务),后端调度器包括 LocalBackendSparkDeploySchedulerBackendMesosSchedulerBackendYarnClientSchedulerBackendYarnClusterSchedulerBackendSimrSchedulerBackend

整个 TaskSchedulerImpl 比较简单,复杂的地方在于和各种 后端调度器联合,以及具体 TasksetManager 进行联合

Read More

2017-11-20
git inside

Git是一个分布式的版本控制系统,能够完成你能想到的关于版本相关的所有事情,但是 Git 却不是那么好上手,也就是所谓的入门门槛有点高。

本文会讲什么

本文会换一个角度讲述 Git 怎么做的,给大家提供一个另外的视角,这个视角主要设计 Git 的存储,这样给大家一个更深的认识,在平时想了解的时候,也能有合适的渠道进行。

Read More

2017-11-09
django-configuration in action

Django 中统一配置的做法

本文主要描述如何在 django 中统一 settings 文件

背景

django 服务会有多个环境,比如 开发环境、测试环境以及线上环境等。现在大部分使用的方案是针对每一种环境使用一个 settings 文件,然后在不同的环境中使用不同的 settings 文件。这样的设计我认为有至少两个问题:

  1. 很多公用的配置不太好公用
  2. 文件数会很多,项目中管理会比较麻烦
Read More

2017-10-16
spark_dagscheduler

基于 spark 1.6

面向 Stage 的调度器,负责计算每个 job 的 DAG,并将 DAG 图划分为不同的 stage,对哪些 RDD 以及相应输出进行记录,寻找一个运行相应 job 所需要的最小 stage。然后将 stageTaskSet 的形式提交到下层的 TaskScheduler 进行具体的 task 调度。每个 TaskSet 包含整个可以独立运行的 task,这些 task 能够利用集群上已有的数据立即运行起来,如果集群上已有的数据已经不存在了,那么当前 task 就会失败。

Spark 的 stage 以 RDD 的 shuffle 为界进行划分。窄依赖的 RDD 操作会被穿起来放到一个 task 中,比如 map(), filter() 这样的操作。但是需要使用到 shuffle 依赖的操作,需要多个 stage(至少一个将中间文件写到特定的地方,另外一个从特定的地方进行读取)。每个 Stage,只会对其他 Stage 有 shuffle 依赖,在同一个 stage 中会进行很多计算。实际的将计算串起来的操作在 RDD.compute 中完成。

DAGScheduler 同样会基于缓存状态决定 task 希望运行在那(preferred location),如果 shuffle 输出文件丢失造成的 Stage 失败,会重新被提交。在 Stage 内部 的不是由 shuffle 文件丢失造成的失败,由 TaskScheduler 来完成,TaskScheduler 会在取消整个 stage 前进行小部分重试。
Read More