滑动窗口在监控和统计应用的场景比较广泛,比如每隔一段时间(10s)统计最近30s的请求量或者异常次数,根据请求或者异常次数采取相应措施。在storm1.0版本之前,没有提供关于滑动窗口的实现,需要开发者自己实现滑动窗口的功能(storm1.0以前实现滑动窗口的实现原理可以自行百度)。

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/6481588.html

微信:intsmaze

这里主要演示在storm1.0以后如何通过继承storm1.0提供的类来快速开发出窗口滑动的功能。窗口可以从时间或数量上来划分,由如下两个因素决定:窗口的长度,可以是时间间隔或Tuple数量;滑动间隔(sliding Interval),可以是时间间隔或Tuple数量。比如:每两秒统计最近6秒的请求数量;每接收2个Tuple就统计最近接收的6个Tuple的平均值......。

storm1.0支持的时间和数量的排列组合有如下:

withWindow(Count windowLength, Count slidingInterval)

  每收到slidingInterval条数据统计最近的windowLength条数据。

withWindow(Count windowLength)

  每收到1条数据统计最近的windowLength条数据。

withWindow(Count windowLength, Duration slidingInterval)

  每过slidingInterval秒统计最近的windowLength条数据。

withWindow(Duration windowLength, Count slidingInterval)

  每收到slidingInterval条数据统计最近的windowLength秒的数据。

withWindow(Duration windowLength, Duration slidingInterval)

  每过slidingInterval秒统计最近的windowLength秒的数据。

public withWindow(Duration windowLength)

  每收到1条数据统计最近的windowLength秒的数据。

接下来,简单的演示如何使用storm1.0实现滑动窗口的功能,先编写spout类,RandomSentenceSpout负责发送一个整形数值,数值每次发送都会自动加一,且RandomSentenceSpout固定每隔两秒向bolt发送一次数据。RandomSentenceSpout和前面关于spout的讲解一样。

1.public class RandomSentenceSpout extends BaseRichSpout {
2.
3. private static final long serialVersionUID = 5028304756439810609L;
4.
5. private SpoutOutputCollector collector;
6.
7. int intsmaze=0;
8.
9. public void declareOutputFields(OutputFieldsDeclarer declarer) {
10. declarer.declare(new Fields("intsmaze"));
11. }
12.
13. public void open(Map conf, TopologyContext context,
14. SpoutOutputCollector collector) {
15. this.collector = collector;
16. }
17.
18. public void nextTuple() {
19. System.out.println("发送数据:"+intsmaze);
20. collector.emit(new Values(intsmaze++));
21. try {
22. Thread.sleep(2000);
23.// Thread.sleep(1000);
24. } catch (InterruptedException e) {
25. e.printStackTrace();
26. }
27. }
}

滑动窗口的逻辑实现的重点是bolt类,这里我们编写SlidingWindowBolt类让它继承一个新的类名为BaseWindowedBolt来获得窗口计数的功能。BaseWindowedBolt和前面的BaseBaseBolt和BaseWindowedBolt提供的方法名都一样,只是execute方法的参数类型为TupleWindow,TupleWindow参数里面装载了一个窗口长度类的tuple数据。通过对TupleWindow遍历,我们可以计算这一个窗口内tuple数的平均值或总和等指标。具体见代码12-16行,统计了一个窗口内的数值型数据的总和。

1.public class SlidingWindowBolt extends BaseWindowedBolt {
2.
3. private OutputCollector collector;
4.
5. @Override
6. public void prepare(Map stormConf, TopologyContext context,
7. OutputCollector collector) {
8. this.collector = collector;
9. }
10.
11. public void execute(TupleWindow inputWindow) {
12. int sum=0;
13. System.out.print("一个窗口内的数据");
14. for(Tuple tuple: inputWindow.get()) {
15. int str=(Integer) tuple.getValueByField("intsmaze");
16. System.out.print(" "+str);
17. sum+=str;
18. }
19. System.out.println("======="+sum);
20. // collector.emit(new Values(sum));
21. }
22.
23. @Override
24. public void declareOutputFields(OutputFieldsDeclarer declarer) {
25.// declarer.declare(new Fields("count"));
26. }
}

我们已经实现了窗口计数的逻辑代码,现在我们需要提供topology来指明各个组件的关系,以及指定SlidingWindowBolt的窗口的组合,这里我们演示了如何每两秒统计最近6秒的数值总和,如果注释掉10-13行代码,去掉5-8行的注释,这个topology就是告诉SlidingWindowBolt每接收到两条tuple就统计最近接收到的6条tuple的数值的总和。

1.public class WindowsTopology {
2.
3. public static void main(String[] args) throws Exception {
4. TopologyBuilder builder = new TopologyBuilder();
5. builder.setSpout("spout1", new RandomSentenceSpout(), 1);
6.// builder.setBolt("slidingwindowbolt", new SlidingWindowBolt()
7.// .withWindow(new Count(6), new Count(2)),1)
8.// .shuffleGrouping("spout");
9.//滑窗 窗口长度:tuple数, 滑动间隔: tuple数 每收到2条数据统计当前6条数据的总和。
10.
11. builder.setBolt("slidingwindowbolt", new SlidingWindowBolt()
12. .withWindow(new Duration(6, TimeUnit.SECONDS),
13. new Duration(2, TimeUnit.SECONDS)),1)
14. .shuffleGrouping("spout");//每两秒统计最近6秒的数据
15.
16. Config conf = new Config();
17. conf.setNumWorkers(1);
18. LocalCluster cluster = new LocalCluster();
19. cluster.submitTopology("word-count", conf, builder.createTopology());
20. }
}

这里演示的是bolt节点并发度为1的窗口功能,实际生产中,因为数据量很大,往往将bolt节点的并发度设置为多个,这个时候我们的SlidingWindowBolt就无法统计出一个窗口的数值总和了。因为每一个bolt的并行节点只能统计自己一个窗口接收到数据的总和,无法统计出一个窗口内全局数据的总和,借助redis来实现是可以的,但是必须引入redis的事务机制或者借助分布式锁,否则会出现脏数据的情况。在这里我们介绍另一种实现方式就是灵活的使用storm提供的窗口功能,只是窗口的tuple数。

仍然是使用上面提供的类,只是我们增加一个bolt类,来统计每个SlidingWindowBolt节点发送给它的数值。

1.public class CountWord extends BaseWindowedBolt{
2.
3. private static final long serialVersionUID = -5283595260540124273L;
4.
5. private OutputCollector collector;
6.
7. public void prepare(Map stormConf, TopologyContext context
8. , OutputCollector collector) {
9. this.collector = collector;
10. }
11.
12. public void execute(TupleWindow inputWindow) {
13. int sum=0;
14. for(Tuple tuple: inputWindow.get()) {
15. int i=(Integer) tuple.getValueByField("count");
16. System.out.println("接收到一个bolt的总和值为:"+i);
17. sum+=i;
18. }
19. System.out.println("一个窗口内的总值为:"+sum);
20. }
21.
22. public void declareOutputFields(OutputFieldsDeclarer declarer) {
23. }
}

然后我们注释RandomSentenceSpout第22行代码,取消对23行代码的注释,方便观察结果。去掉SlidingWindowBolt类20和25行代码。

topology启动类如下:

1.public class WindowsTopology {
2.
3. public static void main(String[] args) throws Exception {
4. TopologyBuilder builder = new TopologyBuilder();
5. builder.setSpout("spout", new RandomSentenceSpout(), 1);
6.
7. builder.setBolt("slidingwindowbolt", new SlidingWindowBolt()
8. .withWindow(new Duration(6, TimeUnit.SECONDS),
9. new Duration(2, TimeUnit.SECONDS)),2)
10. .shuffleGrouping("spout");//每两秒统计最近6秒的数据
11.
12. builder.setBolt("countwordbolt", new CountWord()
13. .withWindow(new Count(2), new Count(2)),1)
14. .shuffleGrouping("slidingwindowbolt");
15. //每收到2条tuple就统计最近两条统的数据
16. Config conf = new Config();
17. conf.setNumWorkers(1);
18. LocalCluster cluster = new LocalCluster();
19. cluster.submitTopology("word-count", conf, builder.createTopology());
20. }
}

storm 1.0版本滑动窗口的实现及原理的更多相关文章

  1. TCP滑动窗口控制流量的原理

    TCP的滑动窗口机制       TCP这个协议是网络中使用的比较广泛,他是一个面向连接的可靠的传输协议.既然是一个可靠的传输协议就需要对数据进行确认.TCP协议里窗口机制有2种:一种是固定的窗口大小 ...

  2. 【编程之美】超时重传,滑动窗口,可靠性传输原理C语言实现

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://www.cnblogs.com/lihuidashen/p/128003 ...

  3. Storm 1.0.0

    Storm 1.0.0版本增加了很多新的特性,可用性以及性能也得到了很大的改善,该版本是Storm发展历程上一个里程碑式的版本,主要特点如下. 性能提升 Storm 1.0.0版本最大的亮点就是性能提 ...

  4. Storm 1.0 新特性

    Storm 1.0.0版本增加了很多新的特性,可用性以及性能也得到了很大的改善,该版本是Storm发展历程上一个里程碑式的版本,主要特点如下. 性能提升 Storm 1.0.0版本最大的亮点就是性能提 ...

  5. TCP/IP 协议中的滑动窗口

    一个例子明白发送缓冲区.接受缓冲区.滑动窗口协议之间的关系. 在上面的几篇文章中简单介绍了上述几个概念在TCP网络编程中的关系,也对应了几个基本socket系统调用的几个行为,这里再列举一个例子,由于 ...

  6. LeetCode295-Find Median from Data Stream && 480. 滑动窗口中位数

    中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操 ...

  7. 图像滑动窗口 利用opencv和matlab

    1.利用opencv实现图像滑动窗口操作 功能:利用opencv实现图像滑动窗口操作(即利用已知尺寸的窗口遍历整幅图像,形成许多子图像)  vs2015+opencv3.1  2016.10 函数实现 ...

  8. 面试连环炮系列(二十):TCP的滑动窗口协议是什么

    TCP的滑动窗口协议是什么 滑动窗口协议,用于网络数据传输时的流量控制,以避免拥塞的发生.该协议允许发送方在停止并等待确认前发送多个数据分组.由于发送方不必每发一个分组就停下来等待确认,因此该协议可以 ...

  9. 滑动窗口经典题 leetcode 3. 无重复字符的最长子串

    题目 解题思路 题目要求找出给定字符串中不含有重复字符的最长子串的长度.这是一个典型的滑动窗口的题目,可以通过滑动窗口去解答. 滑动窗口 具体操作如下图示:找到一个子串 s[left...right] ...

随机推荐

  1. javascript中的字典

    1.概念 字典是一种以键值对的形式存储的数据结构,就系那个电话本中的名字和电话号码一样.要找到一个电话首先要找到名字,再根据名字找到电话号码.这里的键就是指用来查找的东西,值就是查找得到的结果. Ja ...

  2. centos 6.5下安装文件上传下载服务

    centos 6.5下安装文件上传下载服务 由于每次在CentOS中要下载一些配置文件到物理机,和上传一些文件到服务器,导致来回的开启ftp软件有点麻烦,这里我们可以使用文件上传下载服务,来解决上传和 ...

  3. The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

    skip-grant-tables下 GRANT ALL PRIVILEGES ON *.* TO helei IDENTIFIED BY 'MANAGER' WITH GRANT OPTION; 执 ...

  4. mysql5.5慢日志设置和查询

    mysql> showvariables like '%version%'; +-------------------------+---------------------+ | Variab ...

  5. 数据库设计的误区—>CHAR与VARCHAR

    字符型字段是数据库表中最常见的字段,而字符型字段又分为定长和变长两种.一般来说,VARCHAR类型用于存储内容长度变化较大的数据,CHAR类型用于存储内容长度没有变化或变化不大的数据. 在数据的内部存 ...

  6. 算法一之N皇后问题

    (写这篇文章主要是明天就要考试了,算法考试,今天不想再复习了,xiang着今天也开通了博客,于是在这个平台上进行复习,应该会更高效.最后祝愿我明天考个好成绩.嘻嘻...) n皇后问题,主要是应用到回溯 ...

  7. Bootstrap入门(九)组件3:按钮组

    Bootstrap入门(九)组件3:按钮组   先引入本地的CSS文件和JS文件(注:1.bootstrap是需要jQuery支持的.2.需要在<body>当中添加) <link h ...

  8. Accessibility辅助功能--一念天堂,一念地狱

    0x00什么是Accessibility(辅助功能) 考虑到部分用户不能很好地使用Android设备,比如由于视力.身体.年龄方面的限制,造成阅读内容.触控操作.声音信息等方面的获取困难,Androi ...

  9. Java如何判断字符串中包含有全角,半角符号

    首先介绍下全角跟半角之间的区别: 在计算机屏幕上,一个汉字要占两个英文字符的位置,人们把一个英文字符所占的位置称为"半角",相对地把一个汉字所占的位置称为"全角" ...

  10. css3 过渡和2d变换——回顾

    1.transition 语法:transition: property duration timing-function delay; transition-property 设置过渡效果的css ...