这篇文章列举出了storm topology里面的一些常见模式:

  • 流聚合(stream join)
  • 批处理(Batching)
  • BasicBolt
  • 内存内缓存 + fields grouping 组合
  • 计算top N
  • 用TimeCacheMap来高效地保存一个最近被更新的对象的缓存
  • 分布式RPC: CoordinatedBolt和KeyedFairBolt

流聚合(stream join)

流聚合把两个或者多个数据流聚合成一个数据流 — 基于一些共同的tuple字段。流聚合和SQL里面table join很像,只是table join的输入是有限的,并且join的语义是非常明确的。而流聚合的语义是不明确的并且输入流是无限的。

流类型的聚合类型跟具体的应用是有关了。一些应用把两个流发出的所有的tuple都聚合起来 — 不管多长时间;而另外一些应用则只会聚合一些特定的tuple。而另外一些应用的聚合逻辑又可能完全不一样。而这些聚合类型里面最常见的类型是把所有的输入流进行一样的划分, 这个在storm里面用fields grouping在相同字段上进行grouping就可以了,比如:

1
2
3
4
builder.setBolt(5, new MyJoiner(), parallelism)
    .fieldsGrouping(1, new Fields("field1", "field2"))
    .fieldsGrouping(2, new Fields("field1", "field2"))
    .fieldsGrouping(3, new Fields("field1", "field2"));

当然,不同的数据流的“相同”字段可以有不一样的名字。

批处理(Batching)

有时候为了性能或者一些别的原因, 你可能想把一组tuple一起处理, 而不是一个个单独处理。比如,你可能想批量更新数据库。

如果你想让你的数据处理具有可靠性,正确的方式是保存这些tuple对象的引用直到bolt批量处理这些tuple了。一旦这个批量操作结束, 你可以批量的ack这些tuple。

如果一个bolt发射tuple, 那么你可能想用multi-anchoring来保证可靠性。这一切都取决于具体的应用。关于storm的消息传递的工作原理可以看这篇: Twitter Storm如何保证消息不丢失

BasicBolt

很多bolt有些类似的模式:

  1. 读一个输入tuple
  2. 根据这个输入tuple发射一个或者多个tuple
  3. 在execute的方法的最后ack那个输入tuple

遵循这类模式的bolt一般是函数或者是过滤器, 这种模式太常见,storm为这类模式单独封装了一个接口: IBasicBolt。更多的信息请看: Twitter Storm如何保证消息不丢失

内存内缓存 + fields grouping 组合

在bolt的内存里面缓存一些东西非常常见。缓存在和fields grouping结合起来之后就更有用了。比如,你有一个bolt把短链接变成长链接(bit.ly, t.co之类的)。你可以把短链接到长链接的对应关系利用LRU算法缓存在内存里面以避免重复计算。比如组件一发射短链接,组件二把短链接转化成长链接并缓存在内存里面。看一下下面两段代码有什么不一样:

1
2
builder.setBolt(2, new ExpandUrl(), parallelism)
  .shuffleGrouping(1);
1
2
builder.setBolt(2, new ExpandUrl(), parallelism)
  .fieldsGrouping(1, new Fields("url"));

第二种方式的缓存会比第一种方式的缓存的效率高很多,因为同样的短链接始终被发到同一个task。这会避免不同的机器上有同样的缓存  — 浪费内存, 同时也使得同样的短域名更可能在内存里面找到缓存。

计算top N

storm的一个常见的持续计算的模式叫做: “streaming top N”。

比如你有一个bolt发射这样的tuple: ["value", "count"]并且你想一个bolt基于这些信息算出top N的tuple。最简单的办法是有一个bolt可以做一个全局的grouping的动作并且在内存里面保持这top N的值。

这个方式对于大数据量的流显然是没有扩展性的, 因为所有的数据会被发到同一台机器, 单机的处理能力始终是有极限的。一个更好的方法是在多台机器上面并行的计算这个流每一部分的top N, 然后再有一个bolt合并这些机器上面所算出来的top N以算出最后的top N(Map Reduce的思想), 代码大概是这样的:

1
2
3
4
builder.setBolt(2, new RankObjects(), parallellism)
  .fieldsGrouping(1, new Fields("value"));
builder.setBolt(3, new MergeObjects())
  .globalGrouping(2);

这个模式之所以可行是因为第一个bolt的fields grouping使得这种并行算法在语义上是正确的。

用TimeCacheMap来高效地保存一个最近被更新的对象的缓存

有时候你想在内存里面保存一些最近活跃的对象,以及让那些不再活跃的对象自动过期(删除掉)。TimeCacheMap是一个非常高效的数据结构,它提供了一些callback函数使得我们在对象不再活跃的时候做一些事情。关于TimeCacheMap为什么高效,可以看看这篇分析文章

分布式RPC: CoordinatedBolt和KeyedFairBolt

用storm做分布式RPC应用的时候有两种比较常见的模式:它们被封装在 CoordinatedBoltKeyedFairBolt里面。

CoordinatedBolt包装你的bolt,并且确定什么时候你的bolt已经接收到所有的tuple。它主要使用Direct Stream来做这个。

KeyedFairBolt同样包装你的bolt并且保证你的topology同时处理多个DRPC调用,而不是串行地一次只执行一个。

更多有关分布式RPC的信息可以看这里

Twitter Storm: storm的一些常见模式的更多相关文章

  1. Storm常见模式——分布式RPC

    Storm常见模式——分布式RPC 本文翻译自:https://github.com/nathanmarz/storm/wiki/Distributed-RPC,作为学习Storm DRPC的资料,转 ...

  2. 浅议NetMQ常见模式和消息加密机制

    浅议NetMQ常见模式和消息加密机制 概述 在传统企业级开发中,消息队列机制已经成为一种非常常见的技术实现手段,而基于NetMQ则看起来有点像一朵"奇葩",看起来从名字似乎是一个消 ...

  3. Storm常见模式——批处理

    Storm对流数据进行实时处理时,一种常见场景是批量一起处理一定数量的tuple元组,而不是每接收一个tuple就立刻处理一个tuple,这样可能是性能的考虑,或者是具体业务的需要. 例如,批量查询或 ...

  4. Storm入门(九)Storm常见模式之流聚合

    流聚合(stream join)是指将具有共同元组(tuple)字段的数据流(两个或者多个)聚合形成一个新的数据流的过程. 从定义上看,流聚合和SQL中表的聚合(table join)很像,但是二者有 ...

  5. Storm常见模式——流聚合

    转自:http://www.cnblogs.com/panfeng412/archive/2012/06/04/storm-common-patterns-of-stream-join.html 流聚 ...

  6. [Storm] Storm与asm的恩恩怨怨

    asm的引用冲突 1. Jersey & Storm 0.9.3 jersey 1.8 (which depends on asm 3.0) Storm 0.93 (which depends ...

  7. 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)

    一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...

  8. RabbitMQ Queue一些常见模式

    懒队列:lazy Queue,即用到的时候才会加载,3.6.0及之后新添加的.当新添加数据后,不会将其放入到内存中,而是将其放入到磁盘中. 普通队列:1).in-memory,数据直接放入到内存中. ...

  9. rabbitmq系列(二)几种常见模式的应用场景及实现

    一.简单模式 原理:生产者将消息交给默认的交换机,交换机获取消息后交给绑定这个生产者的队列(投递规则为队列名称和routing key 相同的队列),监听当前队列的消费者获取信息并执行消费逻辑. 场景 ...

随机推荐

  1. 使用HTML5实现刮刮卡效果

    你玩过刮刮卡么?一不小心可以中奖的那种.今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果. 我们利用HTML5 ...

  2. EL表达式取整数或者取固定小数位数的简单实现

    EL表达式取整数或者取固定小数位数的简单实现 例如${8/7} ,${6/7} ,${12/7 } 在页面的显示结果分别为: 1.1428571428571428 0.8571428571428571 ...

  3. Spring笔记——配置Hibernate框架事务

    原文:http://www.iteye.com/topic/1123347 Spring配置文件中关于事务配置总是由三个组成部分,DataSource.TransactionManager和代理机制这 ...

  4. [c/c++]指针数组 pk 数组指针

    首先强调 指针数组归根结底是个数组:数组指针归根结底是个指针. 数组指针 以int (*int)[10]为例 ()的优先级大于[],因此首先它是一个指针,它指向一个数组,数组的维数是10.因此数组指针 ...

  5. 大众点评开源分布式监控平台 CAT 深度剖析

    一.CAT介绍 CAT系统原型和理念来源于eBay的CAL的系统,CAT系统第一代设计者吴其敏在eBay工作长达十几年,对CAL系统有深刻的理解.CAT不仅增强了CAL系统核心模型,还添加了更丰富的报 ...

  6. ubuntu安装postgresql与postgis

    版本信息 ubuntu    14.04.1LTS postgresql   9.3.5 postgis       2.1.2 今天尝试着安装了postgis 2.1.2,(较简便的包安装,不是源码 ...

  7. php克隆 自动加载

    PHP加载 include() 函数 include() 函数可获得指定文件中的所有文本,并把文本拷贝到使用 include 函数的文件中. 例子 1 假设您拥有一个标准的页眉文件,名为 " ...

  8. 设置Windows Azure Linux虚拟机中的root账户

    使用Windows Azure 创建好Linux虚拟机之后,如果你使用默认的用户密码登陆root是不行的,如下图所示: 其原因是Windows Azure创建Linux虚拟机时并没有同时设置root密 ...

  9. opencv显示鼠标所在位置的rgb值

    #include"highgui.h" #include"cv.h" #include"cxcore.h" #include<stdl ...

  10. 在LINUX上创建GIT服务器【转】

    转自:http://blog.csdn.net/xiongmc/article/details/9176785 如果使用git的人数较少,可以使用下面的步骤快速部署一个git服务器环境. 1. Cli ...