storm简介:
全量数据处理使用的是hadoop或者hive,作为一个批处理系统,hadoop有吐吞量大,自动容错等优点。但是hadoop不擅长实时计算。
而storm则是一个实时的分布式计算系统。他是多线程的。
storm的使用场景:
数据的实时分析,持续计算,分布式rpc等
storm可以用来处理源源不断进来的消息,处理之后将结果写入到分布式文件系统中。
storm的特点:
分布式
可扩展
高可靠性
编程模型简单
高效实时
storm概念:
几个概念的图示:
Topology:
一个实时计算应用程序的逻辑在storm里面被封装到topology对象里面,我们把它叫做计算
拓扑。相当于hadoop中的MapReduce的job
任
务,但是job的运行有结束点,而topology
则没有,它会一直运行下去,除非显式的杀死这个进程。一个topology是由spout和bolt组
成的图状结构,而链接spouts和bolts的则是stramgrouping
Spout:
消息源spouts是storm里面一个topology里面的消息生产者。一般来说消息源会从一个外部源读
取数据并向topology里面发出消息tuple。消息源
spouts
可以使可靠地也可以是不可靠的。
一个可靠地消息源重新发射一个tuple如果这个tuple没有被bolt成功处理,但是不可靠的就不会
发送。
消息源可以发射多条信息流stream,要达到这样的效果,使用OutFieldsDeclare.declareStream来
定义多个stream,
然后使用SpoutOutputCollector来发射指定的stream
Bolt:
消息处理者,所有的消息处理逻辑都被封装在bolts里面。bolts可以做很多事情:过滤,聚
合,查询数据库等等。
bolt的主要方法是exeute,它以一个tuple作为输入,tuple封装了从上一个组件发送来的信息,这个组件可以是boalt也可是spout。
bolt使用OutputCollector来发射tuple,bolt必须要为它处理的每一个tuple调用OutputCollector的ack方法,以通知storm这个tuple被处理
完成了。从而我们通知这个tuple的发射者spout。
一般的流程是:bolt处理一个输入tuple,发射0个或多个tuple,然后调用ack通知storm自己已经处理过这个tuple了,storm提供了一个
IBasicBolt会自动调用ack。
storm节点框架图:
nimbus:
storm的主节点,控制节点,用来提交,分发任务,集群监控,任务调度等。
zookeeper
:
协调共有数据的存放(如心跳信息,集群状态,配置信息等) ,nimbus将任务分配给supervisor的任务下载zookeeper中
supervisor:
工作节点,负责nimbus分配的任务,管理属于自己的任务
worker:
执行具体的逻辑进程,这个可以再代码中设置数量。
storm的工作框架:
Worker:
1.Supervisor会监听分配给他那台机器上的工作,根据需要启动、关闭工作进程,这个工作进程就是worker.
2.每个worker都会占用工作节点的一个端口,这个端口可以在stor.yaml中配置,有几个端口这台工作节点的服务器就能最大化的
启动几个worker。
3.一个topology可能会在一个或者多个工作进程里面执行,所以每个工作进程执行topology的一部分,所以一个运行的tipology由
运行在很多机器上的很多工作进程组成。
Task:
每一个Spout和Bolt会被当做很多task在整个集群中运行。默认情况下每一个task对应到一个线程(executor),这个线程用来执行这个task,
而steamgrouping则是定义怎么从一堆task发射tuple到另一个堆task中。
配置Configuration
storm里面有一堆参数可以用来配置调整nimbus,supervisor以及正在运行的topology的行为,一些配置是系统级别的,一些配置是
topology级别的。所有默认值得配置的默认配置是配置在default.xm里面的。可以通过定义storm.xml在classpath里面来覆盖这些
默认配置,并且也可以在代码里摄者一些topology相关的信息,使用StormSubmitter。
配置的优先级:default.xml < storm.xml , TOPOLOGY-SPECIFIC配置
Stream:
消息流是storm里面的最关键的抽象。一个消息流是一个没有边界的tuple序列, 而这些tuples会被以一种分布式的方式并行地创建和处
理。 对消息流的定义主要是对消息流里面的tuple的定义, 我们会给tuple里的每个字段一个名字。 并且不同tuple的对应字段的类型必须一样。
也就是说: 两个tuple的第一个字段的类型必须一样, 第二个字段的类型必须一样, 但是第一个字段和第二个字段可以有不同的类型。
在默认的情况下, tuple的字段类型可以是: integer, long, short, byte, string, double, float, boolean和byte array。 你还可以自定义类型 — 只要你实现对应的序列化器
StreamGrouping:
1.
Shuffle Grouping:随机分组,随机派发stream里面的tuple,保证每个bolt接收到的tuple数目相同。
2.
Fields Grouping:按字段分组,比如按userid来分组,具有同样userid的tuple会被分到相同的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)
7.
Local or shuffle grouping:如果目标bolt有一个或者多个task在同一个工作进程中,tuple将会被随机发生给这些tasks。否则,和普
通的
Shuffle Grouping行为一致。
执行流程: