这次学习主要是流式处理框架——Strom
之前所学习的都是离线处理,把数据存放好了一起计算,strom与他们不同就是能边数据存储边进行计算
一、Strom的介绍
Apache Storm是一个免费的开源分布式实时计算系统。Apache Storm使得可靠处理无限数据流变得容易,实时处理就像Hadoop批处理一样。Apache Storm很简单,可以与任何编程语言一起使用,并且使用起来很有趣!
Apache Storm有许多用例:实时分析,在线机器学习,连续计算,分布式RPC,ETL等。Apache Storm速度很快:基准测试表明它每秒可处理每个节点超过一百万个元组。它具有可扩展性,容错性,可确保您的数据将得到处理,并且易于设置和操作。
二、Storm的计算模型
strom好比做水龙头在滴水,可以由一个或者多个tuple(水龙头)组成,spout发出数据源,不断的向bolt推送数据,bolt进行快速的处理,图中的水滴加上闪电可代表bolt,有多个bolt可以完成复杂的需求,从而降低耦合,保证数据处理时候的速度和高并发。
- Nimbus:即Storm的Master,负责资源分配、任务调度和接受jar包。类似namenode。(好比老板)
- Supervisor:即Storm的Slave,负责接受nimbus接受的任务,启动、停止自己管理的worker进程。(好比每层的经理)
- Worker:工作进程,运行具体处理运算组件的进程(每个Worker对应执行一个Topology的子集),worker任务类型,即spout任务、bolt任务两种。(好比工人)
- Topology:计算拓扑(DAG有向无环图的实现),对于Storm实时计算逻辑的封装,由一系列通过数据流相互关联的Spout、Bolt所组成的拓扑结构;相当于mapreduce中的job。
- Tuple:元组,Stream中最小数据组成单元。
- Stream:数据流,从Spout中源源不断传递数据给Bolt、以及上一个Bolt传递数据给下一个Bolt,所形成的这些数据通道即叫做Stream。
- Spout:数据源,一般会从指定外部的数据源读取元组(Tuple)发送到拓扑(Topology)中
一个Spout可以发送多个数据流(Stream)。
可先通过OutputFieldsDeclarer中的declare方法声明定义的不同数据流,发送数据时通过SpoutOutputCollector中的emit方法指定数据流Id(streamId)参数将数据发送出去;Spout中最核心的方法是nextTuple,该方法会被Storm线程不断调用、主动从数据源拉取数据,再通过emit方法将数据生成元组(Tuple)发送给之后的Bolt计算。----这些是在java的api中所应用的,由于只是简单的看了下,如需深入研究可参考其他博客。 - Bolt:数据流处理组件,拓扑中数据处理均有Bolt完成。对于简单的任务或者数据流转换,单个Bolt可以简单实现;更加复杂场景往往需要多个Bolt分多个步骤完成。
- Stream grouping:数据流组,后面会介绍八种内置的数据流分组。
三、Strom的容错保障机制
- 1、集群节点宕机(物理问题)
– nimbus服务器:挂了不会对集群产生影响。
– 非nimbus服务器:故障时,该节点上所有Task任务都会超时,Nimbus会将这些Task任务重新分配到其他服务器上运行。 - 2、进程挂掉
– Worker:挂掉时,Supervisor会重新启动这个进程。如果启动过程中仍然一直失败,并且无法向Nimbus发送心跳,Nimbus会将该Worker重新分配到其他服务器上
– Supervisor
无状态(所有的状态信息都存放在Zookeeper中来管理)
快速失败(每当遇到任何异常情况,都会自动毁灭)
– Nimbus
无状态(所有的状态信息都存放在Zookeeper中来管理)
快速失败(每当遇到任何异常情况,都会自动毁灭)
自动毁灭机制:不会再去做已经分配好的任务,继续做未完成的任务。
zookeeper:某一节点失效 ,通过投票机制 follower 提上来 200ms解决问题 - 3、消息的完成性
从Spout中发出的Tuple,以及基于他所产生Tuple(例如上个例子当中Spout发出的句子,以及句子当中单词的tuple等),由这些消息就构成了一棵tuple树,当这棵tuple树发送完成,并且树当中每一条消息都被正确处理,就表明spout发送消息被“完整处理”,即消息的完整性。
通过acker来实现。
四、Storm Grouping—数据流分组
-
1.List item
随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同。
轮询,平均分配 -
2.Fields Grouping
按字段分组,比如,按"user-id"这个字段来分组,那么具有同样"user-id"的 tuple 会被分到相同的Bolt里的一个task, 而不同的"user-id"则可能会被分配到不同的task。 -
3.All Grouping
广播发送,对于每一个tuple,所有的bolts都会收到 -
4.Global Grouping
全局分组,把tuple分配给task id最低的task 。 -
5.None Grouping
不分组,这个分组的意思是说stream不关心到底怎样分组。目前这种分组和Shuffle grouping是一样的效果。 有一点不同的是storm会把使用none grouping的这个bolt放到这个bolt的订阅者同一个线程里面去执行(未来Storm如果可能的话会这样设计)。 -
6.Direct Grouping
指向型分组, 这是一种比较特别的分组方法,用这种分组意味着消息(tuple)的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为 Direct Stream 的消息流可以声明这种分组方法。而且这种消息tuple必须使用 emitDirect 方法来发射。消息处理者可以通过 TopologyContext 来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id) 。 -
7.Local or shuffle grouping
本地或随机分组。如果目标bolt有一个或者多个task与源bolt的task在同一个工作进程中,tuple将会被随机发送给这些同进程中的tasks。否则,和普通的Shuffle Grouping行为一致。 -
8.customGrouping
自定义,相当于mapreduce那里自己去实现一个partition一样。
五、Storm DRPC—分布式远程过程调用
1、DRPC设计目的
为了充分利用Storm的计算能力实现高密度的并行实时计算。
(Storm接收若干个数据流输入,数据在Topology当中运行完成,然后通过DRPC将结果进行输出。)
客户端通过向 DRPC 服务器发送待执行函数的名称以及该函数的参数来获取处理结果。实现该函数的拓扑使用一个DRPCSpout 从 DRPC 服务器中接收一个函数调用流。DRPC 服务器会为每个函数调用都标记了一个唯一的 id。随后拓扑会执行函数来计算结果,并在拓扑的最后使用一个名为 ReturnResults 的 bolt 连接到 DRPC 服务器,根据函数调用的 id 来将函数调用的结果返回。
2、创建方法
- 半自动
通过LinearDRPCTopologyBuilder (该方法也过期,不建议使用)
该方法会自动为我们设定Spout、将结果返回给DRPC Server等,我们只需要将Topology实现
- 手动*
直接通过普通的拓扑构造方法TopologyBuilder来创建DRPC拓扑
需要手动设定好开始的DRPCSpout以及结束的ReturnResults
3、运行模式
运行模式分为 本地模式 和 集群模式,在代码中declareOutputFields模块中修改即可。
这里只是简单介绍了一下 strom 中的drpc,了解下其运行架构。