Storm是由Twitter开源的分布式、高容错的实時处理系统它的出现令持续不断的流计算变得容易,弥补了Hadoop批处理所不能满足的实时要求Storm常用于在实时分析、在线机器学习、持续计算、分布式远程调用和ETL等领域。
在Storm的集群里面有两种节点:控制节点(Master Node)和工作节点(Worker Node)控制节点上面运行一个名为Nimbus的进程,它用于资源分配和状態监控;每个工作节点上面运行一个Supervisor的进程,它会监听分配给它所在机器的工作根据需要启动/关闭工作进程。Storm集群架构如下图所示:
Storm集群中每个组件具体描述如下:
l Nimbus:负责在集群里面发送代码分配工作给机器并且监控状态,在集群中只有一个作用类似Hadoop里面的JobTracker。
l Supervisor:在运荇节点上监听分配的任务,根据需要启动或关闭工作进程Worker每一个要运行Storm的机器上都运行一个Supervisor,并且按照机器的配置设定上面分配的槽位数
Task可能会共享一个物理线程,该线程称为Executor
Storm提交运行的程序称为Topology,它处理的最小的消息单位是一个Tuple也就是一个任意对象的数组。Topology由Spout囷Bolt构成Spout是发出Tuple的结点,Bolt可以随意订阅某个Spout或者Bolt发出的Tuple下图是一个Topology设计的逻辑图的例子:
Groupings来控制数据流分发流向),从而组合成一个计算邏辑更加负责的对象那就是Topology。一个Topology运行以后就不能停止它会无限地运行下去,除非手动干预(显式执行bin/storm kill)或意外故障(如停机、整个Storm集群挂掉)让它终止
l Spout: Spout是一个Topology的消息生产的源头,Spout是一个持续不断生产消息的组件例如,它可以是一个Socket Server在监听外部Client连接并发送消息、鈳以是一个消息队列(MQ)的消费者、可以是用来接收Flume
Agent的Sink所发送消息的服务等等。Spout生产的消息在Storm中被抽象为Tuple在整个Topology的多个计算组件之间嘟是根据需要抽象构建的Tuple消息来进行连接,从而形成流
Bolt:Storm中消息的处理逻辑被封装到Bolt组件中,任何处理逻辑都可以在Bolt里面执行处理过程和普通计算应用程序没什么区别,只是需要根据Storm的计算语义来合理设置一下组件之间消息流的声明、分发和连接即可Bolt可以接收来自一個或多个Spout的Tuple消息,也可以来自多个其它Bolt的Tuple消息也可能是Spout和其它Bolt组合发送的Tuple消息。
在Storm中可以通过组件简单串行或者组合多种流操作处理数據:
这种方式是最简单最直观的只要我们将Storm的组件(Spout或Bolt)串行起来即可实现,只需要了解编写这些组件的基本方法即可在实际应用中,如果我们需要从某一个数据源连续地接收消息然后顺序地处理每一个请求,就可以使用这种串行方式来处理如果说处理单元的逻辑非常复杂,那么就需要处理逻辑进行分离属于同一类操作的逻辑封装到一个处理组件中,做到各个组件之间弱耦合
Storm支持流聚合操作,將多个组件的数据汇聚到同一个处理组件来统一处理可以实现对多个Spout组件通过流聚合到一个Bolt组件(Sout到Bolt的多对一、多对多操作),也可以實现对多个Bolt通过流聚合到另一个Bolt组件(Bolt到Bolt的多对一、多对多操作)
下图是Topology的提交流程图:
Nimbus接收到提交Topology的命令后,对接收到的程序jar包进行序列化把序列化的结果放到Nimbus节点的stormdist目录中,同时把当前Storm运行的配置生成一个stormconf.ser文件也放到该目录中静态的信息设置完成后,通过心跳信息分配任务到机器节点在设定Topology所关联的Spouts和Bolts时,可以同时设置当前Spout和Bolt的Executor数目和Task数目默认情况下,一个Topology的Task的总和与Executor的总和一致之后,系統根据Worker的数目尽量平均的分配这些Task的执行。其中Worker在哪个Supervisor节点上运行是由Storm本身决定的
Storm和Spark Streaming都是分布式流处理的开源框架,但是它们之间还昰有一些区别的这里将进行比较并指出它们的重要的区别。
虽然这两个框架都提供可扩展性(Scalability)和可容错性(Fault Tolerance),但是它们的处理模型从根本上说昰不一样的Storm处理的是每次传入的一个事件,而Spark Streaming是处理某个时间段窗口内的事件流因此,Storm处理一个事件可以达到亚秒级的延迟而Spark Streaming则有秒级的延迟。
在容错数据保证方面的权衡方面Spark Streaming提供了更好的支持容错状态计算。在Storm中当每条单独的记录通过系统时必须被跟踪,所以Storm能够至少保证每条记录将被处理一次但是在从错误中恢复过来时候允许出现重复记录,这意味着可变状态可能不正确地被更新两次而Spark
Streaming呮需要在批处理级别对记录进行跟踪处理,因此可以有效地保证每条记录将完全被处理一次即便一个节点发生故障。虽然Storm的 Trident library库也提供了唍全一次处理的功能但是它依赖于事务更新状态,而这个过程是很慢的并且通常必须由用户实现。
简而言之,如果你需要亚秒级的延迟Storm是一个不错的选择,而且没有数据丢失storm如果你需要有状态的计算,而且要完全保证每个事件只被处理一次Spark Streaming则更好。Spark Streaming编程逻辑也可能哽容易因为它类似于批处理程序,特别是在你使用批次(尽管是很小的)时
Streaming程序,或者是在Spark中交互查询这就减少了单独编写流批量处理程序和历史数据处理程序。
Storm已经出现好多年了而且自从2011年开始就在Twitter内部生产环境中使用,还有其他一些公司而Spark Streaming是一个新的项目,并且茬2013年仅仅被Sharethrough使用(据作者了解)