转发请注明原创地址 http://www.cnblogs.com/dongxiao-yang/p/6381037.html

流式计算中我们经常会遇到需要将数据根据时间窗口进行批量统计的场景,窗口性质一般由两个参数规定:1 Window length: 可以用时间或者数量来定义窗口大小;2 Sliding interval: 窗口滑动的间隔 。通过这两个参数一般把window分成滚动窗口和滑动窗口。

Sliding Window(滑动窗口)

Tuples are grouped in windows and window slides every sliding interval. A tuple can belong to more than one window.

For example a time duration based sliding window with length 10 secs and sliding interval of 5 seconds.

| e1 e2 | e3 e4 e5 e6 | e7 e8 e9 |...
0 5 10 15 -> time |<------- w1 -------->|
|------------ w2 ------->|

Tumbling Window(滚动窗口)

Tuples are grouped in a single window based on time or count. Any tuple belongs to only one of the windows.

For example a time duration based tumbling window with length 5 secs.

| e1 e2 | e3 e4 e5 e6 | e7 e8 e9 |...
0 5 10 15 -> time
w1 w2 w3

storm直到1.0.0版本后才官方加入了IWindowedBolt接口用来实现窗口计算,在此之前storm-starter里有一个稍微复杂点的RollingTopWords滑动窗口计算top N实现的demo。topology主要组件的流程设置如下:

(1)TestWordSpout负责产生单词源数据并通过fieldsGrouping发送到下游bolt

(2)RollingCountBolt负责统计Window length范围内的所有单词计数并每Sliding interval时间发送一次汇总信息到下游。

(3)  IntermediateRankingsBolt,这是个中间bolt,主要是为了预先计算部分word的top-N排行榜出来,减少最终节点的排序工作。

(4)TotalRankingsBolt 最终top-N排序并输出计算结果。

     String spoutId = "wordGenerator";
String counterId = "counter";
String intermediateRankerId = "intermediateRanker";
String totalRankerId = "finalRanker";
builder.setSpout(spoutId, new TestWordSpout(), 5);
builder.setBolt(counterId, new RollingCountBolt(9, 3), 4).fieldsGrouping(spoutId, new Fields("word"));
builder.setBolt(intermediateRankerId, new IntermediateRankingsBolt(TOP_N), 4).fieldsGrouping(counterId, new Fields(
"obj"));
builder.setBolt(totalRankerId, new TotalRankingsBolt(TOP_N)).globalGrouping(intermediateRankerId);

RollingCountBolt初始化参数正好就是上面提到的windowLengthInSeconds和emitFrequencyInSeconds,new RollingCountBolt(300, 60)表示每分钟输出一下最近五分钟内的数据统计。

counter = new SlidingWindowCounter<Object>(deriveNumWindowChunksFrom(this.windowLengthInSeconds,this.emitFrequencyInSeconds));

RollingCountBolt内部存放了一个SlidingWindowCounter的结构,SlidingWindowCounter内部存储了SlotBasedCounter,SlotBasedCounter才是具体实现了怎样进行

窗口计算,滑动的窗口不停对应到一个环形的slot列表中。SlidingWindowCounter在窗口滑动的时候采取了如下动作:

   public Map<T, Long> getCountsThenAdvanceWindow() {
Map<T, Long> counts = objCounter.getCounts();
objCounter.wipeZeros();
objCounter.wipeSlot(tailSlot);
advanceHead();
return counts;
}

1. 取出Map<T, Long> counts, 对象和窗口内所有slots求和值的map

2. 调用wipeZeros, 删除已经不被使用的obj, 释放空间 
3. 最重要的一步, 清除tailSlot, 并advanceHead, 以实现滑动窗口 
advanceHead的实现, 如何在数组实现循环的滑动窗口

  private void advanceHead() {
headSlot = tailSlot;
tailSlot = slotAfter(tailSlot);
}

SlotBasedCounter主要用于按照窗口对应的slot进行incrementCount,getCounts和computeTotalCount,用于数据新增统计,全窗口数据提取和对应元素窗口内全部slot数据求和。

  public void incrementCount(T obj, int slot) {
long[] counts = objToCounts.get(obj);
if (counts == null) {
counts = new long[this.numSlots];
objToCounts.put(obj, counts);
}
counts[slot]++;
} public Map<T, Long> getCounts() {
Map<T, Long> result = new HashMap<T, Long>();
for (T obj : objToCounts.keySet()) {
result.put(obj, computeTotalCount(obj));
}
return result;
} private long computeTotalCount(T obj) {
long[] curr = objToCounts.get(obj);
long total = 0;
for (long l : curr) {
total += l;
}
return total;
}

 

如上所述, RollingCountBolt在没有窗口接口的情况下通过代码结构巧妙的实现了一个滑动窗口(理论上滚动窗口也一样可以实现),感觉还是很巧妙地。

参考资料:

Storm starter - RollingTopWords

Implementing Real-Time Trending Topics With a Distributed Rolling Count Algorithm in Storm














storm RollingTopWords 实时top-N计算任务窗口设计的更多相关文章

  1. Storm简介——实时流式计算介绍

    概念 实时流式计算: 大数据环境下,流式数据将作为一种新型的数据类型,这种数据具有连续性.无限性和瞬时性.是实时数据处理所面向的数据类型,对这种流式数据的实时计算就是实时流式计算. 特征 实时流式计算 ...

  2. Storm分布式实时流计算框架相关技术总结

    Storm分布式实时流计算框架相关技术总结 Storm作为一个开源的分布式实时流计算框架,其内部实现使用了一些常用的技术,这里是对这些技术及其在Storm中作用的概括介绍.以此为基础,后续再深入了解S ...

  3. 使用Storm实现实时大数据分析

    摘要:随着数据体积的越来越大,实时处理成为了许多机构需要面对的首要挑战.Shruthi Kumar和Siddharth Patankar在Dr.Dobb’s上结合了汽车超速监视,为我们演示了使用Sto ...

  4. Kafka项目实战-用户日志上报实时统计之分析与设计

    1.概述 本课程的视频教程地址:<Kafka实战项目之分析与设计>  本课程我通过一个用户实时上报日志案例作为基础,带着大家去分析Kafka这样一个项目的各个环节,从而对项目的整体设计做比 ...

  5. 使用Storm实现实时大数据分析!

    随着数据体积的越来越大,实时处理成为了许多机构需要面对的首要挑战.Shruthi Kumar和Siddharth Patankar在Dr.Dobb's上结合了汽车超速监视,为我们演示了使用Storm进 ...

  6. 实时流式计算框架Storm 0.9.0发布通知(中文版)

    Storm0.9.0发布通知中文翻译版(2013/12/10 by 富士通邵贤军 有错误一定告诉我 shaoxianjun@hotmail.com^_^) 我们很高兴宣布Storm 0.9.0已经成功 ...

  7. 用Storm轻松实时大数据分析【翻译】

    原文地址 简单易用,Storm让大数据分析变得轻而易举. 如今,公司在日常运作中经常会产生TB(terabytes)级的数据.数据来源包括从网络传感器捕获的,到Web,社交媒体,交易型业务数据,以及其 ...

  8. [转载] 使用 Twitter Storm 处理实时的大数据

    转载自http://www.ibm.com/developerworks/cn/opensource/os-twitterstorm/ 流式处理大数据简介 Storm 是一个开源的.大数据处理系统,与 ...

  9. Storm实现实时大数据分析(storm介绍,与Hadoop比较,)

    一.storm与Hadoop对比 Hadoop: 全量数据处理使用的大多是鼎鼎大名的hadoop或者hive,作为一个批处理系统,hadoop以其吞吐量大.自动容错等优点,在海量数据处理上得到了广泛的 ...

随机推荐

  1. 转 linux任务调度之crontab命令

    crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. 在 ...

  2. (15)oracle序列

    1.创建序列 CREATE SEQUENCE EMP_SEQ START WITH 1 MAXVALUE 9999999999999999999999999999 MINVALUE 1 NOCYCLE ...

  3. MySql笔记之操作数据库

    看前引导 ♦MySQL默认的端口号:3306 ♦MySQL中的超级用户:root ♦SQL语句结尾必须以分号结尾 ♦语法使用介绍 花括号  必须有的部分 中括号  可选项 ,可有可无 竖线  从这个当 ...

  4. Oracle remove duplicate

    DELETE FROM your_table WHERE rowid not in (SELECT MIN(rowid) FROM your_table GROUP BY column1, colum ...

  5. Spring 依赖注入(控制反转)介绍

    耦合性是软件工程中的一个重要概念.对象之间的耦合性就是对象之间的依赖性.对象之间的耦合越高,维护成本越高.因此对象的设计应使类和构件之间的耦合最小. spring Ioc思想 控制翻转也就是sprin ...

  6. luogu P2828 Switching on the Lights(开关灯)

    题目背景 来源:usaco-2015-dec Farm John 最近新建了一批巨大的牛棚.这些牛棚构成了一个N*N的矩形网络.(1<n<100) 然而bessie十分怕黑,他想计算可以把 ...

  7. [POI2014]Ant colony

    题目大意: 给定一棵$n(n\le10^6)$个结点的树.在每个叶子结点,有$g$群蚂蚁要从外面进来,其中第$i$群有$m_i$只蚂蚁.这些蚂蚁依次爬树(一群蚂蚁爬完后才会爬另一群),若当前经过结点度 ...

  8. linux安装mysql数据库(5.7之前的版本)

    到mysql官网下载mysql编译好的二进制安装包   解压32位安装包: 进入安装包所在目录,执行命令:tar mysql-5.6.17-linux-glibc2.5-i686.tar.gz   复 ...

  9. IntelliJ IDEA 14.x 的 project 和 module 是啥关系?

    使用基于IntelliJ的IDE,如phpstorm.android studio都会对project和module的关系比较糊涂,简单的概括如下: IntelliJ系中的 Project 相当于Ec ...

  10. 转换vmware的vmdk格式到qcow2或者raw格式

    qemu-img convert  xxxx-disk1.vmdk -f  vmdk  -O qcow2 xxxx-disk1.qcow2 qemu-img convert xxxx-disk1.vm ...