0%

在上一篇文章中( JStorm 源码分析 - tuple 在整个拓扑中的流转过程), 我们多次提到 JStorm 使用了 3 个队列来完成 tuple 的缓冲与消费. 因此这些队列的性能会制约 JStorm 的总体的吞吐量.

在日常的工程实践当中, 我们会使用一些 Java 的内置队列来完成这个工作, 比如 ArrayBlockingQueue. 实际上, 如果要追求更高的性能, DisruptorQueue 是一个更好的选择, 它虽然降低了 API 的易用性, 但是在性能上相比于 ArrayBlockingQueue 这类队列提升很大.

Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题 ( 在性能测试中发现竟然与I/O操作处于同样的数量级 ).需要特别指出的是,这里所说的队列是系统内部的内存队列,而不是Kafka这样的分布式队列.

关于 Disruptor 的原理与使用, 网上已经有很多优秀的文章, 可以阅读以下文章来学习:

  1. 美团技术团队 2016-11-18 高性能队列–Disruptor 这篇文章深入浅出,写的很好.
  2. 官方文档 https://lmax-exchange.github.io/disruptor/
阅读全文 »

我们先引入一些基本的概念, 对 JStorm 源码中使用的一些组件有一个基础的认识, 再在这个基础上加入源码的分析, 这样才能更好地学习源码. ^_^

下图展示了一个简单的拓扑结构.

上图中共有 3 个 task, 其中 1 个 spout, 2 个 bolt, 它们分别被分配在 Worker 1、Worker 2 中. Spout 与 Bolt A 处在同一个 Worker 中, 属于同一个 JVM. 而 Bolt B 在另一个 Worker 中, 属于另一台机器的另一个 JVM 中.

当我们的 spout 发送一个 tuple 后, JStorm 会将这个 tuple 发送给下游的 task 消费( Bolt A 与 Bolt B ). 但下游的 bolt 处于不同的 Worker 中. 那么下游的 task 是如何拿到这个 tuple 的, 这两种情况下 JStorm 是怎么处理的呢?

阅读全文 »

简介

本次 JStorm 源码分析文章, 主要是为在公司的内部学习分享会准备的.
生产环境使用的是 JStorm 2.2.1, 本次介绍的功能也以此为准 ( 本文不会涉及到一些高级特性, 主要还是围绕 Storm 的基本功能展开). 希望阅读本文的童鞋, 最好对 Storm/JStorm 的使用有一定的了解, 知道 Spout、Bolt 的一些基本的工作原理.

如果不太了解, 本文最下方也提供了一些学习资料, 可以先花上半天时间学习一下.

本文主要会介绍以下这些内容:

  1. tuple 在整个拓扑中的流动过程
    1. spout / bolt 如何接受并处理消息, 然后向后发送消息?
    2. 在发给内部的 task 和外部的 task 时, 发送方式有什么区别?
  2. JStorm 如何对这个步骤进行抽象,形成不同的组件(TaskReceiver,TaskTransfer,Task,Executor)
  3. 拓扑如何将这些组件启动?
阅读全文 »

原因

最近做的项目属于数据分析类型,要求数据分析功能做到快速上线。该项目当前使用的语言是Java + Groovy。 使用Groovy的原因很简单,因为 Groovy 脚本支持热加载功能。项目中,简单的数据分析工作,如一些统计、排序、过滤等,都放在Groovy里完成。需要上线新的数据分析功能时,只需要编写一个新的脚本,并热加载到JVM中即可。

现在希望将一些数据源访问、数据预处理的工作也放到 Groovy 脚本中完成,并具有这样的功能:项目在线上稳定运行期间,可以通过修改数据库中的脚本来完成新产品的上线。

解决方案

  • PlanA: Java + 热加载
  • PlanB: Groovy + 热加载
阅读全文 »

阅读源代码的第一个步骤是去了解这个项目解决了什么问题,并对这些问题进行一些深入的思考,如“如果是我来解决这个问题,那么我会怎么设计?”。

而了解项目解决了什么问题,最好的途径是浏览官网和阅读文档。当然我偷了点懒,选择的是阅读董西成的《Hadoop技术内幕》。下图是我简单做的思维脑图。

导图


参考

阅读全文 »

首先从github checkout最新的代码。现在Hadoop总体代码体积接近400MB了,还是比较大的。

1.尝试在Mac下编译最新版本

代码clone成功后,可以看到现在默认分支在trunk。

首先尝试进行maven编译

mvn package -Pdist,native -DskipTests -Dtar
阅读全文 »

吾常闻,非人勤以求知,乃知者勤以求人也。然吾知其谬。其知者非求人,实乃出而逐人矣。其刻深无情者,如鹰犬逐兔。

目录

  1. 为什么使用缓存
    1. 金字塔
    2. 2-8
  • 从零写一个本地缓存
    • 哈希
    • 本地缓存的设计与实现
    • 缓存更新算法(http://blog.jobbole.com/30940/)
      1. Least Frequently Used(LFU)
      2. Least Recently User(LRU
      3. Least Recently Used 2(LRU2)
      4. Two Queues(2Q)
      5. Adaptive Replacement Cache(ARC)
      6. Most Recently Used(MRU)
      7. First in First out(FIFO)
      8. Second Chance
      9. CLock
      10. Simple time-based
      11. Extended time-based expiration
      12. Sliding time-based expiration
      13. Random Cache
    • 现代化的缓存更新算法
  • 本地缓存
    • guava cache
  • 分布式缓存
    • memcache
    • redis
    • 数据分片
  • spring 注解缓存

案例

阅读全文 »

常用操作

  • 查找: Cmd+f
  • 自动完成: Cmd+;
  • 命令回放: Cmd+Alt+B
  • iTerm2 Exposé: Cmd+ Alt+E
    • Ctrl+a: 光标移动到行首
    • Ctrl+e: 光标移动到行末
  • Ctrl+l: 清屏
    • Ctrl+p: 显示历史命令
    • Ctrl+r: 倒转查找
    • Ctrl+w: 删除光标之前的单词
    • Ctrl+k: 删除光标之后整行
      command+enter进入与返回全屏模式

选中即复制:
1.鼠标 双击:词 三击:行 四击:智能
2.先command+f弹出iTerm2的查找模式
tab查找窗口将自动变化内容,并将其复制,或shift+lab自动将查找内容的左边选中并复制

完整版

  • 新建标签:command + t
  • 关闭标签:command + w
  • 切换标签:command + 数字 command + 左右方向键
  • 切换全屏:command + enter
  • 查找:command + f
  • 垂直分屏:command + d
  • 水平分屏:command + shift + d
  • 切换屏幕:command + option + 方向键 command + [ 或 command + ]
  • 查看历史命令:command +
  • 查看剪贴板历史:command + shift + h
  • 清除当前行:ctrl + u
  • 到行首:ctrl + a
  • 到行尾:ctrl + e
  • 前进后退:ctrl + f/b (相当于左右方向键)
  • 上一条命令:ctrl + p
  • 搜索命令历史:ctrl + r
  • 删除当前光标的字符:ctrl + d
  • 删除光标之前的字符:ctrl + h
  • 删除光标之前的单词:ctrl + w
  • 删除到文本末尾:ctrl + k
  • 交换光标处文本:ctrl + t
  • 清屏1:command + r
  • 清屏2:ctrl + l
阅读全文 »

有时候开发时为了方便,在代码中使用了不少嵌套类(nested class),但是使用过程中如果不了解嵌套类的特性,可能会造成意想不到的情况。

Java对象想要通过网络传输,必须实现序列化接口,于是我们在Service中定义了了一个实现了序列化接口的内部类,然后调用远程接口将其传输到网络上。
一运行报异常:不能将没有实现序列化接口的Object序列化。
怎么回事,这是一个很简单的内部类,的确已经实现了序列化接口了,其定义的成员都是可序列化的String类型;将其换成普通类没有问题。难道不能使用序列化的内部类?

其实我们使用的内部类是嵌套类(nested class)的一种,而nested class 共有四种:

  • static nested class 静态嵌套类
  • inner class 内部类(非静态)
  • local class 本地类(定义在方法内部)
  • anonymous class 匿名类

静态嵌套类的行为更接近普通的类,另外三个是真正的内部类。区别在于作用域的不同。

阅读全文 »

hsf的服务不能传guava的ImmutableListImmutableMap

原因

使用时,其内部实现如下:

public static <E> ImmutableList<E> of(E element) {
return new SingletonImmutableList<E>(element);
}

查看SingletonImmutableList可以看到内部通过一个element成员变量来持有传入的变量。

阅读全文 »