流式计算之Storm简介

Storm是一个分布式的、容错的实时计算系统,遵循Eclipse Public License 1.0,Storm可以方便地在一个计算机集群中编写与扩展复杂的实时计算,Storm之于实时处理,就好比Hadoop之于批处理。Storm保证每个消息都会得到处理,而且它很快——在一个小集群中,每秒可以处理数以百万计的消息。可以使用任意编程语言来做开发。
主要商业应用及案例:Twitter
Storm的优点
1. 简单的编程模型。类似于MapReduce降低了并行批处理复杂性,Storm降低了进行实时处理的复杂性。
2. 服务化,一个服务框架,支持热部署,即时上线或下线App.
3. 可以使用各种编程语言。你可以在Storm之上使用各种编程语言。默认支持Clojure、Java、Ruby和Python。要增加对其他语言的支持,只需实现一个简单的Storm通信协议即可。
4. 容错性。Storm会管理工作进程和节点的故障。
5. 水平扩展。计算是在多个线程、进程和服务器之间并行进行的。
6. 可靠的消息处理。Storm保证每个消息至少能得到一次完整处理。任务失败时,它会负责从消息源重试消息。
7. 快速。系统的设计保证了消息能得到快速的处理,使用ZeroMQ作为其底层消息队列。
8. 本地模式。Storm有一个“本地模式”,可以在处理过程中完全模拟Storm集群。这让你可以快速进行开发和单元测试。


Storm目前存在的问题

1. 目前的开源版本中只是单节点Nimbus,挂掉只能自动重启,可以考虑实现一个双nimbus的布局。
2. Clojure
是一个在JVM平台运行的动态函数式编程语言,优势在于流程计算, Storm的部分核心内容由Clojure编写,虽然性能上提高不少但同时也提升了维护成本。

Storm架构

Storm集群由一个主节点和多个工作节点组成。主节点运行了一个名为“Nimbus”的守护进程,用于分配代码、布置任务及故障检测。每个工作节点都运行了一个名为“Supervisor”的守护进程,用于监听工作,开始并终止工作进程。NimbusSupervisor都能快速失败,而且是无状态的,这样一来它们就变得十分健壮,两者的协调工作是由Zookeeper来完成的。ZooKeeper用于管理集群中的不同组件,ZeroMQ是内部消息系统,JZMQZeroMQMQJava Binding。有个名为storm-deploy的子项目,可以在AWS上一键部署Storm集群.

Storm术语解释

Storm的术语包括StreamSpoutBoltTaskWorkerStream GroupingTopologyStream是被处理的数据。Sprout是数据源。Bolt处理数据。Task是运行于SpoutBolt中的 线程。Worker是运行这些线程的进程。Stream Grouping规定了Bolt接收什么东西作为输入数据。数据可以随机分配(术语为Shuffle),或者根据字段值分配(术语为Fields),或者 广播(术语为All),或者总是发给一个Task(术语为Global),也可以不关心该数据(术语为None),或者由自定义逻辑来决定(术语为Direct)。Topology是由Stream Grouping连接起来的SpoutBolt节点网络.下面进行详细介绍:

  • Topologies 用于封装一个实时计算应用程序的逻辑,类似于HadoopMapReduce Job

  • Stream 消息流,是一个没有边界的tuple序列,这些tuples会被以一种分布式的方式并行地创建和处理
  • Spouts 消息源,是消息生产者,他会从一个外部源读取数据并向topology里面面发出消息:tuple
  • Bolts 消息处理者,所有的消息处理逻辑被封装在bolts里面,处理输入的数据流并产生输出的新数据流,可执行过滤,聚合,查询数据库等操作

  • Task 每一个SpoutBolt会被当作很多task在整个集群里面执行,每一个task对应到一个线程.

  • Stream groupings 消息分发策略,定义一个Topology的其中一步是定义每个tuple接受什么样的流作为输入,stream grouping就是用来定义一个stream应该如果分配给Bolts.

stream grouping分类

1. Shuffle Grouping: 随机分组, 随机派发stream里面的tuple 保证每个bolt接收到的tuple数目相同.
2. Fields Grouping
:按字段分组, 比如按userid来分组, 具有同样useridtuple会被分到相同的Bolts 而不同的userid则会被分配到不同的Bolts.
3. All Grouping
 广播发送, 对于每一个tuple 所有的Bolts都会收到.
4. Global Grouping:
 全局分组,这个tuple被分配到storm中的一个bolt的其中一个task.再具体一点就是分配给id值最低的那个task.
5. Non Grouping:
 不分组,意思是说stream不关心到底谁会收到它的tuple.目前他和Shuffle grouping是一样的效果,有点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程去执行.
6. Direct Grouping:
 直接分组,这是一种比较特别的分组方法,用这种分组意味着消息的发送者举鼎由消息接收者的哪个task处理这个消息.只有被声明为Direct Stream的消息流可以声明这种分组方法.而且这种消息tuple必须使用emitDirect方法来发射.消息处理者可以通过TopologyContext来或者处理它的消息的taskid (OutputCollector.emit方法也会返回taskid)

Storm如何保证消息被处理

storm保证每个tuple会被topology完整的执行。storm会追踪由每个spout tuple所产生的tuple(一个bolt处理一个tuple之后可能会发射别的tuple从而可以形成树状结构), 并且跟踪这棵tuple树什么时候成功处理完。每个topology都有一个消息超时的设置, 如果storm在这个超时的时间内检测不到某个tuple树到底有没有执行成功, 那么topology会把这个tuple标记为执行失败,并且过一会会重新发射这个tuple

一个tuple能根据新获取到的spout而触发创建基于此的上千个tuple

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout(1, new KestrelSpout("kestrel.backtype.com",

                                     22133,

                                     "sentence_queue",

                                     new StringScheme()));

builder.setBolt(2, new SplitSentence(), 10)

        .shuffleGrouping(1);

builder.setBolt(3, new WordCount(), 20)

        .fieldsGrouping(2, new Fields("word"));

这个topologykestrel queue读取句子,并把句子划分成单词,然后汇总每个单词出现的次数,一个tuple负责读取句子,每一个tuple分别对应计算每一个单词出现的次数,大概样子如下所示:

一个tuple的生命周期:

public interface ISpout extends Serializable {

    void open(Map conf, TopologyContext context, SpoutOutputCollector collector);

    void close();

    void nextTuple();

    void ack(Object msgId);

    void fail(Object msgId);

}

首先storm通过调用spoutnextTuple方法来获取下一个tuple, Spout通过open方法参数里面提供的SpoutOutputCollector来发射新tuple到它的其中一个输出消息流, 发射tuple的时候spout会提供一个message-id, 后面我们通过这个tuple-id来追踪这个tuple。举例来说, KestrelSpoutkestrel队列里面读取一个消息,并且把kestrel提供的消息id作为message-id, 看例子:

collector.emit(new Values("field1", "field2", 3) , msgId);

 

接下来, 这个发射的tuple被传送到消息处理者bolt那里, storm会跟踪这个消息的树形结构是否创建,根据messageid调用Spout里面的ack函数以确认tuple是否被完全处理。如果tuple超时就会调用spoutfail方法。由此看出同一个tuple不管是acked还是fail都是由创建他的那个spout发出的,所以即使spout在集群环境中执行了很多的task,这个tule也不会被不同的taskackedfailed.
kestrelspoutkestrel队列中得到一个消息后会打开这个他,这意味着他并不会把此消息拿走,消息的状态会显示为pending,直到等待确认此消息已经处理完成,处于pending状态直到ack或者fail被调用,处于"Pending"的消息不会再被其他队列消费者使用.如果在这过程中spout中处理此消息的task断开连接或失去响应则此pending的消息会回到"等待处理"状态.

Storm的一些常用应用场景

1.流聚合
流聚合把两个或者多个数据流聚合成一个数据流  基于一些共同的tuple字段。

builder.setBolt(5, new MyJoiner(), parallelism)

  .fieldsGrouping(1, new Fields("joinfield1", "joinfield2"))

  .fieldsGrouping(2, new Fields("joinfield1", "joinfield2"))

  .fieldsGrouping(3, new Fields("joinfield1", "joinfield2"))

 

2.批处理
有时候为了性能或者一些别的原因, 你可能想把一组tuple一起处理, 而不是一个个单独处理。

3.BasicBolt
1.
 读一个输入tuple
2.
 根据这个输入tuple发射一个或者多个tuple
3.
 execute的方法的最后ack那个输入tuple
遵循这类模式的bolt一般是函数或者是过滤器, 这种模式太常见,storm为这类模式单独封装了一个接口: IbasicBolt

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

builder.setBolt(2, new ExpandUrl(), parallelism)

  .shuffleGrouping(1);

builder.setBolt(2, new ExpandUrl(), parallelism)

  .fieldsGrouping(1, new Fields("url"));

5.计算top N
比如你有一个bolt发射这样的tuple: "value", "count"并且你想一个bolt基于这些信息算出top Ntuple。最简单的办法是有一个bolt可以做一个全局的grouping的动作并且在内存里面保持这top N的值。
这个方式对于大数据量的流显然是没有扩展性的, 因为所有的数据会被发到同一台机器。一个更好的方法是在多台机器上面并行的计算这个流每一部分的top N, 然后再有一个bolt合并这些机器上面所算出来的top N以算出最后的top N, 代码大概是这样的:

builder.setBolt(2, new RankObjects(), parallellism)

  .fieldsGrouping(1, new Fields("value"));

builder.setBolt(3, new MergeObjects())

  .globalGrouping(2);

这个模式之所以可以成功是因为第一个boltfields grouping使得这种并行算法在语义上是正确的。
TimeCacheMap来高效地保存一个最近被更新的对象的缓存

6.TimeCacheMap来高效地保存一个最近被更新的对象的缓存
有时候你想在内存里面保存一些最近活跃的对象,以及那些不再活跃的对象。 TimeCacheMap 是一个非常高效的数据结构,它提供了一些callback函数使得我们在对象不再活跃的时候我们可以做一些事情.

7.分布式RPC:CoordinatedBoltKeyedFairBolt
storm做分布式RPC应用的时候有两种比较常见的模式:它们被封装在CoordinatedBoltKeyedFairBolt里面. CoordinatedBolt包装你的bolt,并且确定什么时候你的bolt已经接收到所有的tuple,它主要使用Direct Stream来做这个.
KeyedFairBolt
同样包装你的bolt并且保证你的topology同时处理多个DRPC调用,而不是串行地一次只执行一个。


转自:http://www.cnblogs.com/jmdhappy/p/3549273
2019-03-02 23:47

知识点

相关教程

更多

流式计算之Storm简介

http://blog.sina.com.cn/s/blog_406d9bb00100ui5p.html  流式计算之Storm简介     (2011-11-04 14:51:39)     转载▼         Storm是一个分布式的、容错的实时计算系统,遵循Eclipse Public License 1.0,Storm可以方便地在一个计算机集群中编写与扩展复杂的实时计算,Storm之于

[zz]流式计算之Storm简介

转载自:http://blog.sina.com.cn/s/blog_406d9bb00100ui5p.html Storm是一个分布式的、容错的实时计算系统,遵循Eclipse Public License 1.0,Storm可以方便地在一个计算机集群中编写与扩展复杂的实时计算,Storm之于实时处理,就好比Hadoop之于批处理。Storm保证每个消息都会得到处理,而且它很快——在一个小集群中

【译】流式计算框架-Storm简介

在当前的数据分析领域,对实时数据的计算需求越来越强烈,在此领域,出现了各类计算框架,如:Storm、S4等。目前本土公司对这些流式计算框架的应用也比较广泛,但苦于相关文档英文居多,缺少成系列且与官方相对应的中文手册。本系列试图从官方文档翻译入手,给大家呈现较为完备的中文资料,同时也是对自身知识的总结沉淀。 在这个系列博客中,我们选择了twitter的Storm框架,原因很简单,因为本人长期使用的就

storm实时流式计算框架集群搭建过程

Storm集群安装配置过程  ——by comaple.zhang  这几天在其他同事的帮助下,调研了twitter的开源流式计算框架storm的使用,下面分享一下storm集群的安装配置过程。以作备忘之用。 我的实验机器为:195和196 如果转载请注明出处:comaple的博客 首先:安装依赖包 1, ZeroMQ 2.1.7 2, JZMQ 3, Java 4, Python 5, Unzi

实时计算、流式处理系统简介和资料搜集

实时计算、流式处理系统简介与简单分析 一、实时计算一些基本概念 http://www.cnblogs.com/panfeng412/archive/2011/10/28/2227195.html 二、早期产品 1. IBM的StreamBase: StreamBase是IBM开发的一款商业流式计算系统,在金融行业和政府部门使用 官方网站:http://www.streambase.com 2. B

实时计算、流式处理系统简介与简单分析

一、实时计算一些基本概念 http://www.cnblogs.com/panfeng412/archive/2011/10/28/2227195.html 二、早期产品 1.IBM的StreamBase: StreamBase是IBM开发的一款商业流式计算系统,在金融行业和政府部门使用 官方网站:http://www.streambase.com 2. Borealis:Brandeis Uni

从Storm和Spark 学习流式实时分布式计算的设计

0. 背景 最近我在做流式实时分布式计算系统的架构设计,而正好又要参加CSDN博文大赛的决赛。本来想就写Spark源码分析的文章吧。但是又想毕竟是决赛,要拿出一些自己的干货出来,仅仅是源码分析貌似分量不够。因此,我将最近一直在做的系统架构的思路整理出来,形成此文。为什么要参考Storm和Spark,因为没有参照效果可能不会太好,尤其是对于Storm和Spark由了解的同学来说,可能通过对比,更能体

【流式计算】Twitter Storm源代码分析之Tuple是如何发送的

作者:    xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明    网址:    http://xumingming.sinaapp.com/727/twitter-storm-code-analysis-tuple-send-proc/   这篇文章里面我们来看一下Storm里面的tuple到底是如何从一个tuple是怎么从一个bolt到另一个bol

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

Storm0.9.0发布通知中文翻译版(2013/12/10 by 富士通邵贤军 有错误一定告诉我 shaoxianjun@hotmail.com^_^)  我们很高兴宣布Storm 0.9.0已经成功发布,你可以从the downloads page下载. 本次发布对茁壮成长的Storm来说是一次巨大的进步。  我们追加了一些新特性,你会在下面看到详细的介绍, 此外这次发布的另一个着重点是修复了

Storm 简介

https://github.com/nathanmarz/storm/wiki/Documentation 安装和配置  Storm的安装比较简单, 下载storm的release版本, 解压, 并且把bin/目录加到环境变量PATH里面去, 就ok了. 参考配置storm开发环境  当然为了运行Storm, 需要装一些其他的依赖的包, 可以参考Twitter Storm 安装实战 Storm支

storm简介

伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样、更加便捷,同时对于信息的时效性要求也越来越高。举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这个宝贝马上就可以被卖家搜索出来、点击、购买啦,相反,如果这个宝贝要等到第二天或者更久才可以被搜出来,估计这个大哥就要骂娘了。再举一个推荐的例子,如果用户昨天在淘宝上买了一双袜子,今天想买一副泳镜去游泳

storm简介[ZZ]

场景   伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样、更加便捷,同时对于信息的时效性要求也越来越高。举个搜索 场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这个宝贝马上就可以被卖家搜索出来、点击、购买啦,相反,如果这个宝贝要等到第二天或者更 久才可以被搜出来,估计这个大哥就要骂娘了。再举一个推荐的例子,如果用户昨天在淘宝上买了一双袜子,今天想买

storm简介

场景     伴随着信息科技日新月异的发展,信息呈现出爆发式的膨胀,人们获取信息的途径也更加多样、更加便捷,同时对于信息的时效性要求也越来越高。举个搜索场景中的例子,当一个卖家发布了一条宝贝信息时,他希望的当然是这个宝贝马上就可以被卖家搜索出来、点击、购买啦,相反,如果这个宝贝要等到第二天或者更久才可以被搜出来,估计这个大哥就要骂娘了。再举一个推荐的例子,如果用户昨天在淘宝上买了一双袜子,今天想买

Twitter storm 命令简介

Storm命令简介             提交Topologies    命令格式:storm jar 【jar路径】 【拓扑包名.拓扑类名】 【拓扑名称】  样例:storm jar /storm-starter.jar storm.starter.WordCountTopology wordcountTop   #提交storm-starter.jar到远程集群,并启动wordcountTo

跟我一起云计算(1)——storm

概述  最近要做一个实时分析的项目,所以需要深入一下storm。 为什么storm  综合下来,有以下几点: 1. 生逢其时 MapReduce 计算模型打开了分布式计算的另一扇大门,极大的降低了实现分布式计算的门槛。有了MapReduce架构的支持,开发者只需要把注意力集中在如何使用 MapReduce的语义来解决具体的业务逻辑,而不用头疼诸如容错,可扩展性,可靠性等一系列硬骨头。一时间,人们拿

最新教程

更多

java线程状态详解(6种)

java线程类为:java.lang.Thread,其实现java.lang.Runnable接口。 线程在运行过程中有6种状态,分别如下: NEW:初始状态,线程被构建,但是还没有调用start()方法 RUNNABLE:运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行状态” BLOCK:阻塞状态,表示线程阻塞

redis从库只读设置-redis集群管理

默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:READONLY You can't write against a read only slave.  127.0.0.1:6382> set k3 111  (error) READONLY You can't write against a read only slave. 如果你要开启从库

Netty环境配置

netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。

Netty基于流的传输处理

​在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据

Netty入门实例-使用POJO代替ByteBuf

使用TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。

Netty入门实例-时间服务器

Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现

Netty入门实例-编写服务器端程序

channelRead()处理程序方法实现如下

Netty开发环境配置

最新版本的Netty 4.x和JDK 1.6及更高版本

电商平台数据库设计

电商平台数据库表设计:商品分类表、商品信息表、品牌表、商品属性表、商品属性扩展表、规格表、规格扩展表

HttpClient 上传文件

我们使用MultipartEntityBuilder创建一个HttpEntity。 当创建构建器时,添加一个二进制体 - 包含将要上传的文件以及一个文本正文。 接下来,使用RequestBuilder创建一个HTTP请求,并分配先前创建的HttpEntity。

MongoDB常用命令

查看当前使用的数据库    > db    test  切换数据库   > use foobar    switched to db foobar  插入文档    > post={"title":"领悟书生","content":"这是一个分享教程的网站","date":new

快速了解MongoDB【基本概念与体系结构】

什么是MongoDB MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

windows系统安装MongoDB

安装 下载MongoDB的安装包:mongodb-win32-x86_64-2008plus-ssl-3.2.10-signed.msi,按照提示步骤安装即可。 安装完成后,软件会安装在C:\Program Files\MongoDB 目录中 我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的mongod.exe,为了方便我们每次启动,我

Spring boot整合MyBatis-Plus 之二:增删改查

基于上一篇springboot整合MyBatis-Plus之后,实现简单的增删改查 创建实体类 添加表注解TableName和主键注解TableId import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baom

分布式ID生成器【snowflake雪花算法】

基于snowflake雪花算法分布式ID生成器 snowflake雪花算法分布式ID生成器几大特点: 41bit的时间戳可以支持该算法使用到2082年 10bit的工作机器id可以支持1024台机器 序列号支持1毫秒产生4096个自增序列id 整体上按照时间自增排序 整个分布式系统内不会产生ID碰撞 每秒能够产生26万ID左右 Twitter的 Snowflake分布式ID生成器的JAVA实现方案